Merge branch 'core-headers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 16 Sep 2019 23:11:41 +0000 (16:11 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 16 Sep 2019 23:11:41 +0000 (16:11 -0700)
Pull header documentation fix from Ingo Molnar:
 "Fix the parameter description <asm-generic/div64.h>"

* 'core-headers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  asm-generic/div64: Fix documentation of do_div() parameter

2013 files changed:
.clang-format
.mailmap
Documentation/ABI/testing/debugfs-moxtet [new file with mode: 0644]
Documentation/ABI/testing/sysfs-bus-moxtet-devices [new file with mode: 0644]
Documentation/ABI/testing/sysfs-devices-soc
Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm [new file with mode: 0644]
Documentation/admin-guide/kernel-parameters.txt
Documentation/admin-guide/perf/imx-ddr.rst [new file with mode: 0644]
Documentation/arm64/index.rst
Documentation/arm64/kasan-offsets.sh [new file with mode: 0644]
Documentation/arm64/memory.rst
Documentation/arm64/tagged-address-abi.rst [new file with mode: 0644]
Documentation/arm64/tagged-pointers.rst
Documentation/devicetree/bindings/arm/amlogic.yaml
Documentation/devicetree/bindings/arm/arm,scmi.txt
Documentation/devicetree/bindings/arm/cpus.yaml
Documentation/devicetree/bindings/arm/fsl.yaml
Documentation/devicetree/bindings/arm/mediatek.yaml
Documentation/devicetree/bindings/arm/qcom.yaml
Documentation/devicetree/bindings/arm/rockchip.yaml
Documentation/devicetree/bindings/arm/sunxi.yaml
Documentation/devicetree/bindings/bus/imx-weim.txt
Documentation/devicetree/bindings/bus/moxtet.txt [new file with mode: 0644]
Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt
Documentation/devicetree/bindings/clock/amlogic,gxbb-clkc.txt
Documentation/devicetree/bindings/clock/imx8mn-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/cpu/cpu-topology.txt [moved from Documentation/devicetree/bindings/arm/topology.txt with 66% similarity]
Documentation/devicetree/bindings/eeprom/at25.txt
Documentation/devicetree/bindings/firmware/cznic,turris-mox-rwtm.txt [new file with mode: 0644]
Documentation/devicetree/bindings/firmware/qcom,scm.txt
Documentation/devicetree/bindings/gpio/gpio-aspeed.txt
Documentation/devicetree/bindings/gpio/gpio-davinci.txt
Documentation/devicetree/bindings/gpio/gpio-moxtet.txt [new file with mode: 0644]
Documentation/devicetree/bindings/gpio/gpio-mpc8xxx.txt
Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt [new file with mode: 0644]
Documentation/devicetree/bindings/hwmon/as370.txt [new file with mode: 0644]
Documentation/devicetree/bindings/hwmon/ibm,cffps1.txt
Documentation/devicetree/bindings/hwmon/lm75.txt
Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml
Documentation/devicetree/bindings/iio/adc/ads1015.txt [moved from Documentation/devicetree/bindings/hwmon/ads1015.txt with 100% similarity]
Documentation/devicetree/bindings/iio/adc/allwinner,sun8i-a33-ths.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/interrupt-controller/mediatek,sysirq.txt
Documentation/devicetree/bindings/interrupt-controller/snps,archs-idu-intc.txt
Documentation/devicetree/bindings/iommu/mediatek,iommu.txt
Documentation/devicetree/bindings/media/amlogic,vdec.txt
Documentation/devicetree/bindings/media/renesas,csi2.txt [moved from Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt with 100% similarity]
Documentation/devicetree/bindings/media/renesas,imr.txt [moved from Documentation/devicetree/bindings/media/rcar_imr.txt with 100% similarity]
Documentation/devicetree/bindings/media/renesas,vin.txt [moved from Documentation/devicetree/bindings/media/rcar_vin.txt with 100% similarity]
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.txt
Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.txt
Documentation/devicetree/bindings/memory-controllers/renesas,dbsc.txt [moved from Documentation/devicetree/bindings/memory-controllers/renesas-memory-controllers.txt with 100% similarity]
Documentation/devicetree/bindings/mfd/allwinner,sun4i-a10-ts.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt [deleted file]
Documentation/devicetree/bindings/net/can/rcar_can.txt
Documentation/devicetree/bindings/net/can/rcar_canfd.txt
Documentation/devicetree/bindings/net/dsa/ksz.txt
Documentation/devicetree/bindings/net/macb.txt
Documentation/devicetree/bindings/power/amlogic,meson-ee-pwrc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/act8865-regulator.txt
Documentation/devicetree/bindings/regulator/fixed-regulator.yaml
Documentation/devicetree/bindings/regulator/mt6358-regulator.txt [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.txt
Documentation/devicetree/bindings/regulator/sy8824x.txt [new file with mode: 0644]
Documentation/devicetree/bindings/regulator/twl-regulator.txt
Documentation/devicetree/bindings/regulator/uniphier-regulator.txt
Documentation/devicetree/bindings/reset/fsl,imx7-src.txt
Documentation/devicetree/bindings/reset/snps,dw-reset.txt [new file with mode: 0644]
Documentation/devicetree/bindings/serial/fsl-lpuart.txt
Documentation/devicetree/bindings/serial/mtk-uart.txt
Documentation/devicetree/bindings/soc/amlogic/clk-measure.txt
Documentation/devicetree/bindings/soc/fsl/cpm_qe/qe.txt
Documentation/devicetree/bindings/soc/qcom/qcom,aoss-qmp.txt
Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
Documentation/devicetree/bindings/spi/nuvoton,npcm-fiu.txt [new file with mode: 0644]
Documentation/devicetree/bindings/spi/spi-controller.yaml
Documentation/devicetree/bindings/spi/spi-fsl-dspi.txt
Documentation/devicetree/bindings/spi/spi-fsl-qspi.txt
Documentation/devicetree/bindings/spi/spi-mt65xx.txt
Documentation/devicetree/bindings/spi/spi-sprd-adi.txt
Documentation/devicetree/bindings/trivial-devices.yaml
Documentation/devicetree/bindings/vendor-prefixes.yaml
Documentation/driver-api/gpio/driver.rst
Documentation/driver-api/sgi-ioc4.rst [deleted file]
Documentation/features/core/jump-labels/arch-support.txt
Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
Documentation/hwmon/ads1015.rst [deleted file]
Documentation/hwmon/index.rst
Documentation/hwmon/inspur-ipsps1.rst [new file with mode: 0644]
Documentation/hwmon/lm75.rst
Documentation/hwmon/pxe1610.rst [moved from Documentation/hwmon/pxe1610 with 82% similarity]
Documentation/hwmon/shtc1.rst
Documentation/hwmon/submitting-patches.rst
Documentation/process/embargoed-hardware-issues.rst [new file with mode: 0644]
Documentation/process/index.rst
Documentation/riscv/boot-image-header.txt
Documentation/security/tpm/index.rst
Documentation/security/tpm/tpm_ftpm_tee.rst [new file with mode: 0644]
MAINTAINERS
Makefile
arch/Kconfig
arch/arc/boot/dts/Makefile
arch/arc/include/asm/entry-arcv2.h
arch/arc/include/asm/linkage.h
arch/arc/include/asm/mach_desc.h
arch/arc/kernel/mcip.c
arch/arc/kernel/unwind.c
arch/arc/mm/dma.c
arch/arc/plat-hsdk/platform.c
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/Makefile
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/am335x-boneblue.dts
arch/arm/boot/dts/am335x-cm-t335.dts
arch/arm/boot/dts/am33xx-l4.dtsi
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am4372.dtsi
arch/arm/boot/dts/am437x-l4.dtsi
arch/arm/boot/dts/am571x-idk.dts
arch/arm/boot/dts/am572x-idk.dts
arch/arm/boot/dts/am574x-idk.dts
arch/arm/boot/dts/am57xx-beagle-x15-common.dtsi
arch/arm/boot/dts/am57xx-beagle-x15-revb1.dts
arch/arm/boot/dts/am57xx-beagle-x15-revc.dts
arch/arm/boot/dts/aspeed-ast2500-evb.dts
arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts [new file with mode: 0644]
arch/arm/boot/dts/aspeed-bmc-facebook-tiogapass.dts
arch/arm/boot/dts/aspeed-bmc-facebook-wedge100.dts [new file with mode: 0644]
arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts [new file with mode: 0644]
arch/arm/boot/dts/aspeed-bmc-inspur-fp5280g2.dts
arch/arm/boot/dts/aspeed-bmc-lenovo-hr855xg2.dts [new file with mode: 0644]
arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts [new file with mode: 0644]
arch/arm/boot/dts/aspeed-bmc-opp-swift.dts
arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts
arch/arm/boot/dts/aspeed-g4.dtsi
arch/arm/boot/dts/aspeed-g5.dtsi
arch/arm/boot/dts/at91-ariag25.dts
arch/arm/boot/dts/at91-ariettag25.dts
arch/arm/boot/dts/at91-cosino.dtsi
arch/arm/boot/dts/at91-cosino_mega2560.dts
arch/arm/boot/dts/at91-kizboxmini.dts
arch/arm/boot/dts/at91sam9261ek.dts
arch/arm/boot/dts/at91sam9263ek.dts
arch/arm/boot/dts/at91sam9g15.dtsi
arch/arm/boot/dts/at91sam9g15ek.dts
arch/arm/boot/dts/at91sam9g25ek.dts
arch/arm/boot/dts/at91sam9g35ek.dts
arch/arm/boot/dts/at91sam9m10g45ek.dts
arch/arm/boot/dts/at91sam9rlek.dts
arch/arm/boot/dts/at91sam9x25ek.dts
arch/arm/boot/dts/at91sam9x35ek.dts
arch/arm/boot/dts/at91sam9x5.dtsi
arch/arm/boot/dts/at91sam9x5_lcd.dtsi
arch/arm/boot/dts/at91sam9x5dm.dtsi
arch/arm/boot/dts/at91sam9x5ek.dtsi
arch/arm/boot/dts/bcm2835-rpi-a-plus.dts
arch/arm/boot/dts/bcm2835-rpi-a.dts
arch/arm/boot/dts/bcm2835-rpi-b-plus.dts
arch/arm/boot/dts/bcm2835-rpi-b-rev2.dts
arch/arm/boot/dts/bcm2835-rpi-b.dts
arch/arm/boot/dts/bcm2835-rpi-cm1-io1.dts
arch/arm/boot/dts/bcm2835-rpi-cm1.dtsi
arch/arm/boot/dts/bcm2835-rpi-zero-w.dts
arch/arm/boot/dts/bcm2835-rpi-zero.dts
arch/arm/boot/dts/bcm2835-rpi.dtsi
arch/arm/boot/dts/bcm2836-rpi-2-b.dts
arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts
arch/arm/boot/dts/bcm2837-rpi-3-b-plus.dts
arch/arm/boot/dts/bcm2837-rpi-3-b.dts
arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts
arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi
arch/arm/boot/dts/bcm283x.dtsi
arch/arm/boot/dts/da850-evm.dts
arch/arm/boot/dts/dra7-evm.dts
arch/arm/boot/dts/dra7-l4.dtsi
arch/arm/boot/dts/dra74x-mmc-iodelay.dtsi
arch/arm/boot/dts/ep7211-edb7211.dts
arch/arm/boot/dts/exynos3250.dtsi
arch/arm/boot/dts/exynos4412-itop-scp-core.dtsi
arch/arm/boot/dts/exynos5250-arndale.dts
arch/arm/boot/dts/exynos5250-snow-common.dtsi
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5420-peach-pit.dts
arch/arm/boot/dts/exynos5420.dtsi
arch/arm/boot/dts/exynos5800-peach-pi.dts
arch/arm/boot/dts/exynos5800.dtsi
arch/arm/boot/dts/gemini-nas4220b.dts
arch/arm/boot/dts/gemini-sl93512r.dts
arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-cmo-qvga.dts
arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-svga.dts
arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard-dvi-vga.dts
arch/arm/boot/dts/imx25-pdk.dts
arch/arm/boot/dts/imx27-apf27dev.dts
arch/arm/boot/dts/imx27-eukrea-mbimxsd27-baseboard.dts
arch/arm/boot/dts/imx27-phytec-phycard-s-rdk.dts
arch/arm/boot/dts/imx27-phytec-phycore-rdk.dts
arch/arm/boot/dts/imx53-m53menlo.dts
arch/arm/boot/dts/imx6qdl-colibri.dtsi
arch/arm/boot/dts/imx6qdl-nit6xlite.dtsi
arch/arm/boot/dts/imx6qdl-phytec-pbab01.dtsi
arch/arm/boot/dts/imx6qdl-wandboard.dtsi
arch/arm/boot/dts/imx6qdl.dtsi
arch/arm/boot/dts/imx6sl.dtsi
arch/arm/boot/dts/imx6sll.dtsi
arch/arm/boot/dts/imx6sx.dtsi
arch/arm/boot/dts/imx6ul-kontron-n6310-s-43.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6ul-kontron-n6310-s.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6ul-kontron-n6310-som.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6ul-opos6uldev.dts
arch/arm/boot/dts/imx6ul-phytec-phycore-som.dtsi [moved from arch/arm/boot/dts/imx6ul-phytec-pcl063.dtsi with 71% similarity]
arch/arm/boot/dts/imx6ul-phytec-segin-ff-rdk-nand.dts [moved from arch/arm/boot/dts/imx6ul-phytec-phyboard-segin-full.dts with 51% similarity]
arch/arm/boot/dts/imx6ul-phytec-segin-peb-eval-01.dtsi [moved from arch/arm/boot/dts/imx6ul-phytec-peb-eval-01.dtsi with 84% similarity]
arch/arm/boot/dts/imx6ul-phytec-segin.dtsi [moved from arch/arm/boot/dts/imx6ul-phytec-phyboard-segin.dtsi with 91% similarity]
arch/arm/boot/dts/imx6ul.dtsi
arch/arm/boot/dts/imx6ull-phytec-phycore-som.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-emmc.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-nand.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6ull-phytec-segin-lc-rdk-nand.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6ull-phytec-segin-peb-eval-01.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6ull-phytec-segin.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx7-colibri.dtsi
arch/arm/boot/dts/imx7d-cl-som-imx7.dts
arch/arm/boot/dts/imx7d-zii-rmu2.dts [new file with mode: 0644]
arch/arm/boot/dts/imx7d-zii-rpu2.dts
arch/arm/boot/dts/imx7d.dtsi
arch/arm/boot/dts/imx7s.dtsi
arch/arm/boot/dts/imx7ulp.dtsi
arch/arm/boot/dts/kirkwood-ts219.dtsi
arch/arm/boot/dts/meson8b-ec100.dts
arch/arm/boot/dts/meson8b-mxq.dts
arch/arm/boot/dts/meson8b-odroidc1.dts
arch/arm/boot/dts/meson8b.dtsi
arch/arm/boot/dts/mt7629-rfb.dts [new file with mode: 0644]
arch/arm/boot/dts/mt7629.dtsi [new file with mode: 0644]
arch/arm/boot/dts/nspire-classic.dtsi
arch/arm/boot/dts/nspire-cx.dts
arch/arm/boot/dts/nspire.dtsi
arch/arm/boot/dts/omap3-gta04.dtsi
arch/arm/boot/dts/omap3-n950-n9.dtsi
arch/arm/boot/dts/r8a77470.dtsi
arch/arm/boot/dts/r8a7779.dtsi
arch/arm/boot/dts/rk3036.dtsi
arch/arm/boot/dts/rk3229-xms6.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3288-evb.dtsi
arch/arm/boot/dts/rk3288-fennec.dts [deleted file]
arch/arm/boot/dts/rk3288-tinker.dtsi
arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
arch/arm/boot/dts/rk3288-veyron-edp.dtsi [new file with mode: 0644]
arch/arm/boot/dts/rk3288-veyron-fievel.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3288-veyron-jaq.dts
arch/arm/boot/dts/rk3288-veyron-jerry.dts
arch/arm/boot/dts/rk3288-veyron-minnie.dts
arch/arm/boot/dts/rk3288-veyron-pinky.dts
arch/arm/boot/dts/rk3288-veyron-speedy.dts
arch/arm/boot/dts/rk3288-veyron-tiger.dts [new file with mode: 0644]
arch/arm/boot/dts/rk3288-veyron.dtsi
arch/arm/boot/dts/socfpga.dtsi
arch/arm/boot/dts/socfpga_arria10.dtsi
arch/arm/boot/dts/socfpga_arria10_socdk_nand.dts
arch/arm/boot/dts/socfpga_cyclone5_vining_fpga.dts
arch/arm/boot/dts/ste-ab8500.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-dbx5x0.dtsi
arch/arm/boot/dts/ste-href-ab8500.dtsi
arch/arm/boot/dts/ste-href-family-pinctrl.dtsi
arch/arm/boot/dts/ste-href-stuib.dtsi
arch/arm/boot/dts/ste-href.dtsi
arch/arm/boot/dts/ste-hrefprev60-stuib.dts
arch/arm/boot/dts/ste-hrefv60plus-stuib.dts
arch/arm/boot/dts/ste-nomadik-nhk15.dts
arch/arm/boot/dts/ste-snowball.dts
arch/arm/boot/dts/stm32429i-eval.dts
arch/arm/boot/dts/stm32f429.dtsi
arch/arm/boot/dts/stm32f746.dtsi
arch/arm/boot/dts/stm32h743i-eval.dts
arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
arch/arm/boot/dts/stm32mp157a-dk1.dts
arch/arm/boot/dts/stm32mp157c-ed1.dts
arch/arm/boot/dts/stm32mp157c-ev1.dts
arch/arm/boot/dts/stm32mp157c.dtsi
arch/arm/boot/dts/sun4i-a10-a1000.dts
arch/arm/boot/dts/sun4i-a10-ba10-tvbox.dts
arch/arm/boot/dts/sun4i-a10-cubieboard.dts
arch/arm/boot/dts/sun4i-a10-hackberry.dts
arch/arm/boot/dts/sun4i-a10-itead-iteaduino-plus.dts
arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts
arch/arm/boot/dts/sun4i-a10-marsboard.dts
arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts
arch/arm/boot/dts/sun4i-a10-pcduino.dts
arch/arm/boot/dts/sun4i-a10.dtsi
arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts
arch/arm/boot/dts/sun5i-a13-q8-tablet.dts
arch/arm/boot/dts/sun5i.dtsi
arch/arm/boot/dts/sun6i-a31-colombus.dts
arch/arm/boot/dts/sun6i-a31-hummingbird.dts
arch/arm/boot/dts/sun6i-a31-i7.dts
arch/arm/boot/dts/sun6i-a31-m9.dts
arch/arm/boot/dts/sun6i-a31-mele-a1000g-quad.dts
arch/arm/boot/dts/sun6i-a31.dtsi
arch/arm/boot/dts/sun6i-a31s-cs908.dts
arch/arm/boot/dts/sun6i-a31s-sina31s.dts
arch/arm/boot/dts/sun6i-a31s-sinovoip-bpi-m2.dts
arch/arm/boot/dts/sun7i-a20-bananapi-m1-plus.dts
arch/arm/boot/dts/sun7i-a20-bananapi.dts
arch/arm/boot/dts/sun7i-a20-bananapro.dts
arch/arm/boot/dts/sun7i-a20-cubieboard2.dts
arch/arm/boot/dts/sun7i-a20-cubietruck.dts
arch/arm/boot/dts/sun7i-a20-hummingbird.dts
arch/arm/boot/dts/sun7i-a20-i12-tvbox.dts
arch/arm/boot/dts/sun7i-a20-icnova-swac.dts
arch/arm/boot/dts/sun7i-a20-itead-ibox.dts
arch/arm/boot/dts/sun7i-a20-lamobo-r1.dts
arch/arm/boot/dts/sun7i-a20-m3.dts
arch/arm/boot/dts/sun7i-a20-olimex-som-evb.dts
arch/arm/boot/dts/sun7i-a20-olimex-som204-evb.dts
arch/arm/boot/dts/sun7i-a20-olinuxino-lime.dts
arch/arm/boot/dts/sun7i-a20-olinuxino-lime2.dts
arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
arch/arm/boot/dts/sun7i-a20-orangepi-mini.dts
arch/arm/boot/dts/sun7i-a20-orangepi.dts
arch/arm/boot/dts/sun7i-a20-pcduino3-nano.dts
arch/arm/boot/dts/sun7i-a20-pcduino3.dts
arch/arm/boot/dts/sun7i-a20-wits-pro-a20-dkt.dts
arch/arm/boot/dts/sun7i-a20.dtsi
arch/arm/boot/dts/sun8i-a23-a33.dtsi
arch/arm/boot/dts/sun8i-a23-q8-tablet.dts
arch/arm/boot/dts/sun8i-a83t-cubietruck-plus.dts
arch/arm/boot/dts/sun8i-a83t.dtsi
arch/arm/boot/dts/sun8i-r40.dtsi
arch/arm/boot/dts/sun8i-s3-lichee-zero-plus.dts [new file with mode: 0644]
arch/arm/boot/dts/sun8i-v3.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sun8i-v3s.dtsi
arch/arm/boot/dts/sun9i-a80-cubieboard4.dts
arch/arm/boot/dts/sun9i-a80-optimus.dts
arch/arm/boot/dts/sun9i-a80.dtsi
arch/arm/boot/dts/sunxi-h3-h5.dtsi
arch/arm/boot/dts/vexpress-v2m-rs1.dtsi
arch/arm/boot/dts/vexpress-v2m.dtsi
arch/arm/boot/dts/vf610-bk4.dts
arch/arm/boot/dts/vf610-zii-cfu1.dts
arch/arm/boot/dts/vf610-zii-scu4-aib.dts
arch/arm/boot/dts/vf610-zii-spb4.dts
arch/arm/common/scoop.c
arch/arm/configs/acs5k_defconfig [deleted file]
arch/arm/configs/acs5k_tiny_defconfig [deleted file]
arch/arm/configs/aspeed_g4_defconfig
arch/arm/configs/aspeed_g5_defconfig
arch/arm/configs/bcm2835_defconfig
arch/arm/configs/davinci_all_defconfig
arch/arm/configs/exynos_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/iop13xx_defconfig [deleted file]
arch/arm/configs/iop33x_defconfig [deleted file]
arch/arm/configs/ks8695_defconfig [deleted file]
arch/arm/configs/lpc32xx_defconfig
arch/arm/configs/multi_v5_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/nuc910_defconfig [deleted file]
arch/arm/configs/nuc950_defconfig [deleted file]
arch/arm/configs/nuc960_defconfig [deleted file]
arch/arm/configs/qcom_defconfig
arch/arm/include/asm/topology.h
arch/arm/include/debug/ks8695.S [deleted file]
arch/arm/include/debug/renesas-scif.S
arch/arm/include/debug/ux500.S
arch/arm/kernel/topology.c
arch/arm/lib/backtrace.S
arch/arm/mach-aspeed/Kconfig
arch/arm/mach-aspeed/Makefile [new file with mode: 0644]
arch/arm/mach-aspeed/platsmp.c [new file with mode: 0644]
arch/arm/mach-at91/.gitignore [new file with mode: 0644]
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/pm_suspend.S
arch/arm/mach-davinci/Kconfig
arch/arm/mach-davinci/Makefile
arch/arm/mach-davinci/board-da850-evm.c
arch/arm/mach-davinci/da830.c
arch/arm/mach-davinci/da850.c
arch/arm/mach-davinci/davinci.h
arch/arm/mach-davinci/dm355.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/dm644x.c
arch/arm/mach-davinci/dm646x.c
arch/arm/mach-davinci/include/mach/time.h
arch/arm/mach-davinci/time.c
arch/arm/mach-dove/bridge-regs.h [moved from arch/arm/mach-dove/include/mach/bridge-regs.h with 96% similarity]
arch/arm/mach-dove/cm-a510.c
arch/arm/mach-dove/common.c
arch/arm/mach-dove/dove-db-setup.c
arch/arm/mach-dove/dove.h [moved from arch/arm/mach-dove/include/mach/dove.h with 95% similarity]
arch/arm/mach-dove/include/mach/hardware.h [deleted file]
arch/arm/mach-dove/include/mach/uncompress.h
arch/arm/mach-dove/irq.c
arch/arm/mach-dove/irqs.h [moved from arch/arm/mach-dove/include/mach/irqs.h with 98% similarity]
arch/arm/mach-dove/mpp.c
arch/arm/mach-dove/pcie.c
arch/arm/mach-dove/pm.h [moved from arch/arm/mach-dove/include/mach/pm.h with 97% similarity]
arch/arm/mach-ep93xx/edb93xx.c
arch/arm/mach-ep93xx/simone.c
arch/arm/mach-ep93xx/ts72xx.c
arch/arm/mach-ep93xx/vision_ep9307.c
arch/arm/mach-exynos/Kconfig
arch/arm/mach-imx/mach-imx7d.c
arch/arm/mach-iop13xx/Kconfig [deleted file]
arch/arm/mach-iop13xx/Makefile [deleted file]
arch/arm/mach-iop13xx/Makefile.boot [deleted file]
arch/arm/mach-iop13xx/include/mach/adma.h [deleted file]
arch/arm/mach-iop13xx/include/mach/entry-macro.S [deleted file]
arch/arm/mach-iop13xx/include/mach/hardware.h [deleted file]
arch/arm/mach-iop13xx/include/mach/iop13xx.h [deleted file]
arch/arm/mach-iop13xx/include/mach/iq81340.h [deleted file]
arch/arm/mach-iop13xx/include/mach/irqs.h [deleted file]
arch/arm/mach-iop13xx/include/mach/memory.h [deleted file]
arch/arm/mach-iop13xx/include/mach/time.h [deleted file]
arch/arm/mach-iop13xx/include/mach/uncompress.h [deleted file]
arch/arm/mach-iop13xx/io.c [deleted file]
arch/arm/mach-iop13xx/iq81340mc.c [deleted file]
arch/arm/mach-iop13xx/iq81340sc.c [deleted file]
arch/arm/mach-iop13xx/irq.c [deleted file]
arch/arm/mach-iop13xx/msi.c [deleted file]
arch/arm/mach-iop13xx/msi.h [deleted file]
arch/arm/mach-iop13xx/pci.c [deleted file]
arch/arm/mach-iop13xx/pci.h [deleted file]
arch/arm/mach-iop13xx/setup.c [deleted file]
arch/arm/mach-iop13xx/tpmi.c [deleted file]
arch/arm/mach-iop32x/Makefile
arch/arm/mach-iop32x/adma.c [moved from arch/arm/plat-iop/adma.c with 75% similarity]
arch/arm/mach-iop32x/cp6.c [moved from arch/arm/plat-iop/cp6.c with 100% similarity]
arch/arm/mach-iop32x/em7210.c
arch/arm/mach-iop32x/glantank.c
arch/arm/mach-iop32x/glantank.h [moved from arch/arm/mach-iop32x/include/mach/glantank.h with 78% similarity]
arch/arm/mach-iop32x/hardware.h [moved from arch/arm/mach-iop32x/include/mach/hardware.h with 90% similarity]
arch/arm/mach-iop32x/i2c.c [moved from arch/arm/plat-iop/i2c.c with 81% similarity]
arch/arm/mach-iop32x/include/mach/adma.h [deleted file]
arch/arm/mach-iop32x/include/mach/entry-macro.S
arch/arm/mach-iop32x/include/mach/iop32x.h [deleted file]
arch/arm/mach-iop32x/include/mach/irqs.h
arch/arm/mach-iop32x/include/mach/time.h [deleted file]
arch/arm/mach-iop32x/include/mach/uncompress.h
arch/arm/mach-iop32x/iop3xx.h [moved from arch/arm/include/asm/hardware/iop3xx.h with 96% similarity]
arch/arm/mach-iop32x/iq31244.c
arch/arm/mach-iop32x/iq31244.h [moved from arch/arm/mach-iop32x/include/mach/iq31244.h with 89% similarity]
arch/arm/mach-iop32x/iq80321.c
arch/arm/mach-iop32x/iq80321.h [moved from arch/arm/mach-iop32x/include/mach/iq80321.h with 89% similarity]
arch/arm/mach-iop32x/irq.c
arch/arm/mach-iop32x/irqs.h [new file with mode: 0644]
arch/arm/mach-iop32x/n2100.c
arch/arm/mach-iop32x/n2100.h [moved from arch/arm/mach-iop32x/include/mach/n2100.h with 89% similarity]
arch/arm/mach-iop32x/pci.c [moved from arch/arm/plat-iop/pci.c with 99% similarity]
arch/arm/mach-iop32x/pmu.c [moved from arch/arm/plat-iop/pmu.c with 79% similarity]
arch/arm/mach-iop32x/restart.c [moved from arch/arm/plat-iop/restart.c with 82% similarity]
arch/arm/mach-iop32x/setup.c [moved from arch/arm/plat-iop/setup.c with 95% similarity]
arch/arm/mach-iop32x/time.c [moved from arch/arm/plat-iop/time.c with 97% similarity]
arch/arm/mach-iop33x/Kconfig [deleted file]
arch/arm/mach-iop33x/Makefile [deleted file]
arch/arm/mach-iop33x/Makefile.boot [deleted file]
arch/arm/mach-iop33x/include/mach/adma.h [deleted file]
arch/arm/mach-iop33x/include/mach/entry-macro.S [deleted file]
arch/arm/mach-iop33x/include/mach/hardware.h [deleted file]
arch/arm/mach-iop33x/include/mach/iop33x.h [deleted file]
arch/arm/mach-iop33x/include/mach/iq80331.h [deleted file]
arch/arm/mach-iop33x/include/mach/iq80332.h [deleted file]
arch/arm/mach-iop33x/include/mach/irqs.h [deleted file]
arch/arm/mach-iop33x/include/mach/time.h [deleted file]
arch/arm/mach-iop33x/include/mach/uncompress.h [deleted file]
arch/arm/mach-iop33x/iq80331.c [deleted file]
arch/arm/mach-iop33x/iq80332.c [deleted file]
arch/arm/mach-iop33x/irq.c [deleted file]
arch/arm/mach-iop33x/uart.c [deleted file]
arch/arm/mach-ks8695/Kconfig [deleted file]
arch/arm/mach-ks8695/Makefile [deleted file]
arch/arm/mach-ks8695/Makefile.boot [deleted file]
arch/arm/mach-ks8695/board-acs5k.c [deleted file]
arch/arm/mach-ks8695/board-dsm320.c [deleted file]
arch/arm/mach-ks8695/board-micrel.c [deleted file]
arch/arm/mach-ks8695/board-og.c [deleted file]
arch/arm/mach-ks8695/board-sg.c [deleted file]
arch/arm/mach-ks8695/cpu.c [deleted file]
arch/arm/mach-ks8695/devices.c [deleted file]
arch/arm/mach-ks8695/devices.h [deleted file]
arch/arm/mach-ks8695/generic.h [deleted file]
arch/arm/mach-ks8695/include/mach/entry-macro.S [deleted file]
arch/arm/mach-ks8695/include/mach/gpio-ks8695.h [deleted file]
arch/arm/mach-ks8695/include/mach/hardware.h [deleted file]
arch/arm/mach-ks8695/include/mach/irqs.h [deleted file]
arch/arm/mach-ks8695/include/mach/memory.h [deleted file]
arch/arm/mach-ks8695/include/mach/regs-gpio.h [deleted file]
arch/arm/mach-ks8695/include/mach/regs-irq.h [deleted file]
arch/arm/mach-ks8695/include/mach/regs-misc.h [deleted file]
arch/arm/mach-ks8695/include/mach/regs-switch.h [deleted file]
arch/arm/mach-ks8695/include/mach/regs-uart.h [deleted file]
arch/arm/mach-ks8695/include/mach/uncompress.h [deleted file]
arch/arm/mach-ks8695/irq.c [deleted file]
arch/arm/mach-ks8695/pci.c [deleted file]
arch/arm/mach-ks8695/regs-hpna.h [deleted file]
arch/arm/mach-ks8695/regs-lan.h [deleted file]
arch/arm/mach-ks8695/regs-mem.h [deleted file]
arch/arm/mach-ks8695/regs-pci.h [deleted file]
arch/arm/mach-ks8695/regs-sys.h [deleted file]
arch/arm/mach-ks8695/regs-wan.h [deleted file]
arch/arm/mach-ks8695/time.c [deleted file]
arch/arm/mach-lpc32xx/Kconfig [new file with mode: 0644]
arch/arm/mach-lpc32xx/common.c
arch/arm/mach-lpc32xx/common.h
arch/arm/mach-lpc32xx/include/mach/board.h [deleted file]
arch/arm/mach-lpc32xx/include/mach/entry-macro.S [deleted file]
arch/arm/mach-lpc32xx/include/mach/hardware.h [deleted file]
arch/arm/mach-lpc32xx/include/mach/uncompress.h [deleted file]
arch/arm/mach-lpc32xx/lpc32xx.h [moved from arch/arm/mach-lpc32xx/include/mach/platform.h with 98% similarity]
arch/arm/mach-lpc32xx/pm.c
arch/arm/mach-lpc32xx/serial.c
arch/arm/mach-lpc32xx/suspend.S
arch/arm/mach-mv78xx0/mv78xx0.h
arch/arm/mach-nspire/Makefile
arch/arm/mach-nspire/clcd.c [deleted file]
arch/arm/mach-nspire/clcd.h [deleted file]
arch/arm/mach-nspire/nspire.c
arch/arm/mach-omap1/ams-delta-fiq-handler.S
arch/arm/mach-omap1/ams-delta-fiq.c
arch/arm/mach-omap2/.gitignore [new file with mode: 0644]
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/hsmmc.c
arch/arm/mach-omap2/omap-iommu.c [new file with mode: 0644]
arch/arm/mach-omap2/omap4-common.c
arch/arm/mach-omap2/omap_hwmod_7xx_data.c
arch/arm/mach-omap2/sleep33xx.S
arch/arm/mach-omap2/sleep43xx.S
arch/arm/mach-orion5x/orion5x.h
arch/arm/mach-s3c64xx/setup-usb-phy.c
arch/arm/mach-ux500/cpu-db8500.c
arch/arm/mach-vexpress/spc.c
arch/arm/mach-w90x900/Kconfig [deleted file]
arch/arm/mach-w90x900/Makefile [deleted file]
arch/arm/mach-w90x900/Makefile.boot [deleted file]
arch/arm/mach-w90x900/clksel.c [deleted file]
arch/arm/mach-w90x900/clock.c [deleted file]
arch/arm/mach-w90x900/clock.h [deleted file]
arch/arm/mach-w90x900/cpu.c [deleted file]
arch/arm/mach-w90x900/cpu.h [deleted file]
arch/arm/mach-w90x900/dev.c [deleted file]
arch/arm/mach-w90x900/gpio.c [deleted file]
arch/arm/mach-w90x900/include/mach/entry-macro.S [deleted file]
arch/arm/mach-w90x900/include/mach/hardware.h [deleted file]
arch/arm/mach-w90x900/include/mach/irqs.h [deleted file]
arch/arm/mach-w90x900/include/mach/map.h [deleted file]
arch/arm/mach-w90x900/include/mach/mfp.h [deleted file]
arch/arm/mach-w90x900/include/mach/regs-clock.h [deleted file]
arch/arm/mach-w90x900/include/mach/regs-irq.h [deleted file]
arch/arm/mach-w90x900/include/mach/regs-ldm.h [deleted file]
arch/arm/mach-w90x900/include/mach/regs-serial.h [deleted file]
arch/arm/mach-w90x900/include/mach/uncompress.h [deleted file]
arch/arm/mach-w90x900/irq.c [deleted file]
arch/arm/mach-w90x900/mach-nuc910evb.c [deleted file]
arch/arm/mach-w90x900/mach-nuc950evb.c [deleted file]
arch/arm/mach-w90x900/mach-nuc960evb.c [deleted file]
arch/arm/mach-w90x900/mfp.c [deleted file]
arch/arm/mach-w90x900/nuc910.c [deleted file]
arch/arm/mach-w90x900/nuc910.h [deleted file]
arch/arm/mach-w90x900/nuc950.c [deleted file]
arch/arm/mach-w90x900/nuc950.h [deleted file]
arch/arm/mach-w90x900/nuc960.c [deleted file]
arch/arm/mach-w90x900/nuc960.h [deleted file]
arch/arm/mach-w90x900/nuc9xx.h [deleted file]
arch/arm/mach-w90x900/regs-ebi.h [deleted file]
arch/arm/mach-w90x900/regs-gcr.h [deleted file]
arch/arm/mach-w90x900/regs-timer.h [deleted file]
arch/arm/mach-w90x900/regs-usb.h [deleted file]
arch/arm/mach-w90x900/time.c [deleted file]
arch/arm/mach-zynq/headsmp.S
arch/arm/mach-zynq/platsmp.c
arch/arm/mm/Kconfig
arch/arm/mm/copypage-xscale.c
arch/arm/mm/init.c
arch/arm/plat-iop/Makefile [deleted file]
arch/arm/plat-samsung/include/plat/gpio-core.h
arch/arm/plat-samsung/include/plat/usb-phy.h
arch/arm64/Kbuild [new file with mode: 0644]
arch/arm64/Kconfig
arch/arm64/Kconfig.platforms
arch/arm64/Makefile
arch/arm64/boot/dts/allwinner/Makefile
arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino-emmc.dts [new file with mode: 0644]
arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-3.dts
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64.dts
arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts [new file with mode: 0644]
arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi
arch/arm64/boot/dts/amlogic/Makefile
arch/arm64/boot/dts/amlogic/meson-axg.dtsi
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
arch/arm64/boot/dts/amlogic/meson-gx.dtsi
arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
arch/arm64/boot/dts/amlogic/meson-gxbb-p201.dts
arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-hub.dts
arch/arm64/boot/dts/amlogic/meson-gxbb-wetek-play2.dts
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
arch/arm64/boot/dts/amlogic/meson-gxl-s905w-tx3-mini.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-hwacom-amazetv.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
arch/arm64/boot/dts/amlogic/meson-gxm.dtsi
arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-sm1.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/arm/fvp-base-revc.dts
arch/arm64/boot/dts/arm/rtsm_ve-motherboard.dtsi
arch/arm64/boot/dts/bitmain/bm1880.dtsi
arch/arm64/boot/dts/freescale/Makefile
arch/arm64/boot/dts/freescale/fsl-ls1012a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts
arch/arm64/boot/dts/freescale/fsl-ls1028a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts
arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
arch/arm64/boot/dts/freescale/imx8mm-evk.dts
arch/arm64/boot/dts/freescale/imx8mm.dtsi
arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mn.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mq-evk.dts
arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts
arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mq-sr-som.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi
arch/arm64/boot/dts/freescale/imx8mq.dtsi
arch/arm64/boot/dts/freescale/imx8qxp-ai_ml.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
arch/arm64/boot/dts/freescale/imx8qxp.dtsi
arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
arch/arm64/boot/dts/marvell/armada-37xx.dtsi
arch/arm64/boot/dts/marvell/armada-7040-db.dts
arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
arch/arm64/boot/dts/marvell/armada-8040-db.dts
arch/arm64/boot/dts/marvell/armada-8040-mcbin.dtsi
arch/arm64/boot/dts/marvell/armada-ap806-quad.dtsi
arch/arm64/boot/dts/marvell/armada-ap806.dtsi
arch/arm64/boot/dts/marvell/armada-cp110.dtsi
arch/arm64/boot/dts/mediatek/mt8183-evb.dts
arch/arm64/boot/dts/mediatek/mt8183.dtsi
arch/arm64/boot/dts/qcom/Makefile
arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts [new file with mode: 0644]
arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts [new file with mode: 0644]
arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts [new file with mode: 0644]
arch/arm64/boot/dts/qcom/msm8996.dtsi
arch/arm64/boot/dts/qcom/msm8998-asus-novago-tp370ql.dts [new file with mode: 0644]
arch/arm64/boot/dts/qcom/msm8998-clamshell.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/msm8998-hp-envy-x2.dts [new file with mode: 0644]
arch/arm64/boot/dts/qcom/msm8998-lenovo-miix-630.dts [new file with mode: 0644]
arch/arm64/boot/dts/qcom/msm8998.dtsi
arch/arm64/boot/dts/qcom/pm8150.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/pm8150b.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/pm8150l.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/pm8998.dtsi
arch/arm64/boot/dts/qcom/pms405.dtsi
arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
arch/arm64/boot/dts/qcom/qcs404.dtsi
arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
arch/arm64/boot/dts/qcom/sdm845.dtsi
arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts [new file with mode: 0644]
arch/arm64/boot/dts/qcom/sm8150-mtp.dts [new file with mode: 0644]
arch/arm64/boot/dts/qcom/sm8150.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/renesas/hihope-common.dtsi
arch/arm64/boot/dts/renesas/hihope-rzg2-ex.dtsi
arch/arm64/boot/dts/renesas/r8a774a1.dtsi
arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts
arch/arm64/boot/dts/renesas/r8a774c0.dtsi
arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts
arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts
arch/arm64/boot/dts/renesas/r8a7795-salvator-xs.dts
arch/arm64/boot/dts/renesas/r8a7795.dtsi
arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts
arch/arm64/boot/dts/renesas/r8a7796-salvator-xs.dts
arch/arm64/boot/dts/renesas/r8a7796.dtsi
arch/arm64/boot/dts/renesas/r8a77965-salvator-x.dts
arch/arm64/boot/dts/renesas/r8a77965-salvator-xs.dts
arch/arm64/boot/dts/renesas/r8a77965.dtsi
arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
arch/arm64/boot/dts/renesas/r8a77970.dtsi
arch/arm64/boot/dts/renesas/r8a77980-condor.dts
arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
arch/arm64/boot/dts/renesas/r8a77980.dtsi
arch/arm64/boot/dts/renesas/r8a77990-ebisu.dts
arch/arm64/boot/dts/renesas/r8a77990.dtsi
arch/arm64/boot/dts/renesas/r8a77995-draak.dts
arch/arm64/boot/dts/renesas/r8a77995.dtsi
arch/arm64/boot/dts/renesas/salvator-common.dtsi
arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
arch/arm64/boot/dts/renesas/ulcb.dtsi
arch/arm64/boot/dts/rockchip/Makefile
arch/arm64/boot/dts/rockchip/rk3328-rock64.dts
arch/arm64/boot/dts/rockchip/rk3328.dtsi
arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts
arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts
arch/arm64/configs/defconfig
arch/arm64/include/asm/assembler.h
arch/arm64/include/asm/atomic.h
arch/arm64/include/asm/atomic_ll_sc.h
arch/arm64/include/asm/atomic_lse.h
arch/arm64/include/asm/cache.h
arch/arm64/include/asm/cmpxchg.h
arch/arm64/include/asm/compat.h
arch/arm64/include/asm/cpu_ops.h
arch/arm64/include/asm/cpufeature.h
arch/arm64/include/asm/cputype.h
arch/arm64/include/asm/debug-monitors.h
arch/arm64/include/asm/dma-mapping.h
arch/arm64/include/asm/efi.h
arch/arm64/include/asm/esr.h
arch/arm64/include/asm/exception.h
arch/arm64/include/asm/fpsimd.h
arch/arm64/include/asm/futex.h
arch/arm64/include/asm/hw_breakpoint.h
arch/arm64/include/asm/io.h
arch/arm64/include/asm/irqflags.h
arch/arm64/include/asm/kasan.h
arch/arm64/include/asm/lse.h
arch/arm64/include/asm/memory.h
arch/arm64/include/asm/mmu.h
arch/arm64/include/asm/mmu_context.h
arch/arm64/include/asm/pci.h
arch/arm64/include/asm/pgtable-hwdef.h
arch/arm64/include/asm/pgtable.h
arch/arm64/include/asm/pointer_auth.h
arch/arm64/include/asm/proc-fns.h
arch/arm64/include/asm/processor.h
arch/arm64/include/asm/ptrace.h
arch/arm64/include/asm/signal32.h
arch/arm64/include/asm/sysreg.h
arch/arm64/include/asm/thread_info.h
arch/arm64/include/asm/tlbflush.h
arch/arm64/include/asm/topology.h
arch/arm64/include/asm/uaccess.h
arch/arm64/include/asm/vdso.h
arch/arm64/include/asm/vdso_datapage.h
arch/arm64/include/uapi/asm/stat.h [deleted file]
arch/arm64/kernel/cpufeature.c
arch/arm64/kernel/cpuidle.c
arch/arm64/kernel/cpuinfo.c
arch/arm64/kernel/entry.S
arch/arm64/kernel/head.S
arch/arm64/kernel/hibernate-asm.S
arch/arm64/kernel/hibernate.c
arch/arm64/kernel/image-vars.h [new file with mode: 0644]
arch/arm64/kernel/image.h
arch/arm64/kernel/insn.c
arch/arm64/kernel/kaslr.c
arch/arm64/kernel/kexec_image.c
arch/arm64/kernel/machine_kexec_file.c
arch/arm64/kernel/module-plts.c
arch/arm64/kernel/perf_event.c
arch/arm64/kernel/process.c
arch/arm64/kernel/psci.c
arch/arm64/kernel/ptrace.c
arch/arm64/kernel/setup.c
arch/arm64/kernel/smp.c
arch/arm64/kernel/smp_spin_table.c
arch/arm64/kernel/topology.c
arch/arm64/kernel/traps.c
arch/arm64/kernel/vmlinux.lds.S
arch/arm64/kvm/hyp/switch.c
arch/arm64/kvm/va_layout.c
arch/arm64/lib/Makefile
arch/arm64/lib/atomic_ll_sc.c [deleted file]
arch/arm64/lib/error-inject.c [new file with mode: 0644]
arch/arm64/mm/dump.c
arch/arm64/mm/fault.c
arch/arm64/mm/init.c
arch/arm64/mm/ioremap.c
arch/arm64/mm/kasan_init.c
arch/arm64/mm/mmu.c
arch/arm64/mm/numa.c
arch/arm64/mm/pageattr.c
arch/arm64/mm/proc.S
arch/ia64/Kconfig
arch/ia64/Kconfig.debug
arch/ia64/Makefile
arch/ia64/configs/bigsur_defconfig
arch/ia64/configs/generic_defconfig
arch/ia64/configs/gensparse_defconfig
arch/ia64/configs/sim_defconfig [deleted file]
arch/ia64/configs/tiger_defconfig
arch/ia64/configs/zx1_defconfig
arch/ia64/dig/Makefile [deleted file]
arch/ia64/dig/machvec.c [deleted file]
arch/ia64/dig/machvec_vtd.c [deleted file]
arch/ia64/dig/setup.c [deleted file]
arch/ia64/hp/common/Makefile
arch/ia64/hp/common/hwsw_iommu.c [deleted file]
arch/ia64/hp/common/sba_iommu.c
arch/ia64/hp/sim/Kconfig [deleted file]
arch/ia64/hp/sim/Makefile [deleted file]
arch/ia64/hp/sim/boot/Makefile [deleted file]
arch/ia64/hp/sim/boot/boot_head.S [deleted file]
arch/ia64/hp/sim/boot/bootloader.c [deleted file]
arch/ia64/hp/sim/boot/bootloader.lds [deleted file]
arch/ia64/hp/sim/boot/fw-emu.c [deleted file]
arch/ia64/hp/sim/boot/ssc.h [deleted file]
arch/ia64/hp/sim/hpsim.S [deleted file]
arch/ia64/hp/sim/hpsim_console.c [deleted file]
arch/ia64/hp/sim/hpsim_irq.c [deleted file]
arch/ia64/hp/sim/hpsim_machvec.c [deleted file]
arch/ia64/hp/sim/hpsim_setup.c [deleted file]
arch/ia64/hp/sim/hpsim_ssc.h [deleted file]
arch/ia64/hp/sim/simeth.c [deleted file]
arch/ia64/hp/sim/simscsi.c [deleted file]
arch/ia64/hp/sim/simserial.c [deleted file]
arch/ia64/hp/zx1/Makefile [deleted file]
arch/ia64/hp/zx1/hpzx1_machvec.c [deleted file]
arch/ia64/hp/zx1/hpzx1_swiotlb_machvec.c [deleted file]
arch/ia64/include/asm/acpi.h
arch/ia64/include/asm/dma-mapping.h
arch/ia64/include/asm/dma.h
arch/ia64/include/asm/hpsim.h [deleted file]
arch/ia64/include/asm/hw_irq.h
arch/ia64/include/asm/io.h
arch/ia64/include/asm/iommu.h
arch/ia64/include/asm/iosapic.h
arch/ia64/include/asm/irq.h
arch/ia64/include/asm/machvec.h [deleted file]
arch/ia64/include/asm/machvec_dig.h [deleted file]
arch/ia64/include/asm/machvec_dig_vtd.h [deleted file]
arch/ia64/include/asm/machvec_hpsim.h [deleted file]
arch/ia64/include/asm/machvec_hpzx1.h [deleted file]
arch/ia64/include/asm/machvec_hpzx1_swiotlb.h [deleted file]
arch/ia64/include/asm/machvec_init.h [deleted file]
arch/ia64/include/asm/machvec_sn2.h [deleted file]
arch/ia64/include/asm/machvec_uv.h [deleted file]
arch/ia64/include/asm/mmiowb.h
arch/ia64/include/asm/mmzone.h
arch/ia64/include/asm/pci.h
arch/ia64/include/asm/processor.h
arch/ia64/include/asm/sn/acpi.h [deleted file]
arch/ia64/include/asm/sn/addrs.h [deleted file]
arch/ia64/include/asm/sn/arch.h [deleted file]
arch/ia64/include/asm/sn/bte.h [deleted file]
arch/ia64/include/asm/sn/clksupport.h [deleted file]
arch/ia64/include/asm/sn/geo.h [deleted file]
arch/ia64/include/asm/sn/intr.h
arch/ia64/include/asm/sn/io.h [deleted file]
arch/ia64/include/asm/sn/ioc3.h [deleted file]
arch/ia64/include/asm/sn/klconfig.h [deleted file]
arch/ia64/include/asm/sn/l1.h [deleted file]
arch/ia64/include/asm/sn/leds.h [deleted file]
arch/ia64/include/asm/sn/module.h [deleted file]
arch/ia64/include/asm/sn/mspec.h [deleted file]
arch/ia64/include/asm/sn/nodepda.h [deleted file]
arch/ia64/include/asm/sn/pcibr_provider.h [deleted file]
arch/ia64/include/asm/sn/pcibus_provider_defs.h [deleted file]
arch/ia64/include/asm/sn/pcidev.h [deleted file]
arch/ia64/include/asm/sn/pda.h [deleted file]
arch/ia64/include/asm/sn/pic.h [deleted file]
arch/ia64/include/asm/sn/rw_mmr.h [deleted file]
arch/ia64/include/asm/sn/shub_mmr.h [deleted file]
arch/ia64/include/asm/sn/shubio.h [deleted file]
arch/ia64/include/asm/sn/simulator.h [deleted file]
arch/ia64/include/asm/sn/sn2/sn_hwperf.h [deleted file]
arch/ia64/include/asm/sn/sn_cpuid.h [deleted file]
arch/ia64/include/asm/sn/sn_feature_sets.h [deleted file]
arch/ia64/include/asm/sn/sn_sal.h
arch/ia64/include/asm/sn/tioca.h [deleted file]
arch/ia64/include/asm/sn/tioca_provider.h [deleted file]
arch/ia64/include/asm/sn/tioce.h [deleted file]
arch/ia64/include/asm/sn/tioce_provider.h [deleted file]
arch/ia64/include/asm/sn/tiocp.h [deleted file]
arch/ia64/include/asm/sn/tiocx.h [deleted file]
arch/ia64/include/asm/sn/types.h [deleted file]
arch/ia64/include/asm/switch_to.h
arch/ia64/include/asm/tlb.h
arch/ia64/include/asm/uv/uv.h
arch/ia64/kernel/Makefile
arch/ia64/kernel/acpi.c
arch/ia64/kernel/dma-mapping.c
arch/ia64/kernel/iosapic.c
arch/ia64/kernel/irq.c
arch/ia64/kernel/irq_ia64.c
arch/ia64/kernel/kprobes.c
arch/ia64/kernel/machine_kexec.c
arch/ia64/kernel/machvec.c [deleted file]
arch/ia64/kernel/mca.c
arch/ia64/kernel/mca_drv.c
arch/ia64/kernel/module.c
arch/ia64/kernel/msi_ia64.c
arch/ia64/kernel/pci-dma.c
arch/ia64/kernel/sal.c
arch/ia64/kernel/setup.c
arch/ia64/kernel/signal.c
arch/ia64/kernel/smp.c
arch/ia64/kernel/smpboot.c
arch/ia64/kernel/sys_ia64.c
arch/ia64/kernel/time.c
arch/ia64/kernel/topology.c
arch/ia64/kernel/unaligned.c
arch/ia64/kernel/uncached.c
arch/ia64/kernel/vmlinux.lds.S
arch/ia64/lib/io.c
arch/ia64/mm/discontig.c
arch/ia64/mm/init.c
arch/ia64/mm/tlb.c
arch/ia64/pci/fixup.c
arch/ia64/pci/pci.c
arch/ia64/sn/Makefile [deleted file]
arch/ia64/sn/include/ioerror.h [deleted file]
arch/ia64/sn/include/tio.h [deleted file]
arch/ia64/sn/include/xtalk/hubdev.h [deleted file]
arch/ia64/sn/include/xtalk/xbow.h [deleted file]
arch/ia64/sn/include/xtalk/xwidgetdev.h [deleted file]
arch/ia64/sn/kernel/Makefile [deleted file]
arch/ia64/sn/kernel/bte.c [deleted file]
arch/ia64/sn/kernel/bte_error.c [deleted file]
arch/ia64/sn/kernel/huberror.c [deleted file]
arch/ia64/sn/kernel/idle.c [deleted file]
arch/ia64/sn/kernel/io_acpi_init.c [deleted file]
arch/ia64/sn/kernel/io_common.c [deleted file]
arch/ia64/sn/kernel/io_init.c [deleted file]
arch/ia64/sn/kernel/iomv.c [deleted file]
arch/ia64/sn/kernel/irq.c [deleted file]
arch/ia64/sn/kernel/klconflib.c [deleted file]
arch/ia64/sn/kernel/machvec.c [deleted file]
arch/ia64/sn/kernel/mca.c [deleted file]
arch/ia64/sn/kernel/msi_sn.c [deleted file]
arch/ia64/sn/kernel/pio_phys.S [deleted file]
arch/ia64/sn/kernel/setup.c [deleted file]
arch/ia64/sn/kernel/sn2/Makefile [deleted file]
arch/ia64/sn/kernel/sn2/cache.c [deleted file]
arch/ia64/sn/kernel/sn2/io.c [deleted file]
arch/ia64/sn/kernel/sn2/prominfo_proc.c [deleted file]
arch/ia64/sn/kernel/sn2/ptc_deadlock.S [deleted file]
arch/ia64/sn/kernel/sn2/sn2_smp.c [deleted file]
arch/ia64/sn/kernel/sn2/sn_hwperf.c [deleted file]
arch/ia64/sn/kernel/sn2/sn_proc_fs.c [deleted file]
arch/ia64/sn/kernel/sn2/timer.c [deleted file]
arch/ia64/sn/kernel/sn2/timer_interrupt.c [deleted file]
arch/ia64/sn/kernel/tiocx.c [deleted file]
arch/ia64/sn/pci/Makefile [deleted file]
arch/ia64/sn/pci/pci_dma.c [deleted file]
arch/ia64/sn/pci/pcibr/Makefile [deleted file]
arch/ia64/sn/pci/pcibr/pcibr_ate.c [deleted file]
arch/ia64/sn/pci/pcibr/pcibr_dma.c [deleted file]
arch/ia64/sn/pci/pcibr/pcibr_provider.c [deleted file]
arch/ia64/sn/pci/pcibr/pcibr_reg.c [deleted file]
arch/ia64/sn/pci/tioca_provider.c [deleted file]
arch/ia64/sn/pci/tioce_provider.c [deleted file]
arch/ia64/uv/kernel/Makefile
arch/ia64/uv/kernel/machvec.c [deleted file]
arch/ia64/uv/kernel/setup.c
arch/m68k/atari/config.c
arch/m68k/configs/amiga_defconfig
arch/m68k/configs/apollo_defconfig
arch/m68k/configs/atari_defconfig
arch/m68k/configs/bvme6000_defconfig
arch/m68k/configs/hp300_defconfig
arch/m68k/configs/mac_defconfig
arch/m68k/configs/multi_defconfig
arch/m68k/configs/mvme147_defconfig
arch/m68k/configs/mvme16x_defconfig
arch/m68k/configs/q40_defconfig
arch/m68k/configs/sun3_defconfig
arch/m68k/configs/sun3x_defconfig
arch/m68k/include/asm/atarihw.h
arch/m68k/include/asm/io_mm.h
arch/m68k/include/asm/kmap.h
arch/m68k/include/asm/macintosh.h
arch/m68k/mac/config.c
arch/mips/configs/bigsur_defconfig
arch/mips/configs/ip32_defconfig
arch/mips/configs/markeins_defconfig
arch/mips/configs/rm200_defconfig
arch/mips/configs/sb1250_swarm_defconfig
arch/nds32/kernel/signal.c
arch/parisc/Kconfig
arch/parisc/boot/compressed/.gitignore
arch/parisc/include/asm/alternative.h
arch/parisc/include/asm/fixmap.h
arch/parisc/include/asm/ftrace.h
arch/parisc/include/asm/kexec.h [new file with mode: 0644]
arch/parisc/include/asm/pdc.h
arch/parisc/include/asm/string.h
arch/parisc/kernel/Makefile
arch/parisc/kernel/alternative.c
arch/parisc/kernel/entry.S
arch/parisc/kernel/firmware.c
arch/parisc/kernel/ftrace.c
arch/parisc/kernel/kexec.c [new file with mode: 0644]
arch/parisc/kernel/kexec_file.c [new file with mode: 0644]
arch/parisc/kernel/kprobes.c
arch/parisc/kernel/pacache.S
arch/parisc/kernel/parisc_ksyms.c
arch/parisc/kernel/pci.c
arch/parisc/kernel/relocate_kernel.S [new file with mode: 0644]
arch/parisc/kernel/smp.c
arch/parisc/kernel/syscalls/syscall.tbl
arch/parisc/kernel/traps.c
arch/parisc/lib/Makefile
arch/parisc/lib/memset.c [deleted file]
arch/parisc/lib/string.S [new file with mode: 0644]
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/include/asm/error-injection.h [deleted file]
arch/powerpc/kernel/kexec_elf_64.c
arch/powerpc/kernel/process.c
arch/powerpc/kvm/book3s_64_vio.c
arch/powerpc/kvm/book3s_64_vio_hv.c
arch/powerpc/mm/nohash/tlb.c
arch/riscv/Kbuild [new file with mode: 0644]
arch/riscv/Kconfig
arch/riscv/Makefile
arch/riscv/include/asm/fixmap.h
arch/riscv/include/asm/image.h
arch/riscv/include/asm/page.h
arch/riscv/include/asm/pgtable.h
arch/riscv/include/asm/smp.h
arch/riscv/include/asm/sparsemem.h [new file with mode: 0644]
arch/riscv/include/asm/timex.h
arch/riscv/include/asm/tlbflush.h
arch/riscv/include/uapi/asm/perf_regs.h [new file with mode: 0644]
arch/riscv/kernel/Makefile
arch/riscv/kernel/entry.S
arch/riscv/kernel/fpu.S
arch/riscv/kernel/head.S
arch/riscv/kernel/perf_callchain.c [new file with mode: 0644]
arch/riscv/kernel/perf_regs.c [new file with mode: 0644]
arch/riscv/kernel/smp.c
arch/riscv/kernel/smpboot.c
arch/riscv/kernel/stacktrace.c
arch/riscv/lib/uaccess.S
arch/riscv/mm/Makefile
arch/riscv/mm/cacheflush.c
arch/riscv/mm/context.c
arch/riscv/mm/init.c
arch/riscv/mm/tlbflush.c [new file with mode: 0644]
arch/s390/kvm/interrupt.c
arch/s390/kvm/kvm-s390.c
arch/s390/net/bpf_jit_comp.c
arch/sparc/kernel/sys_sparc_64.c
arch/unicore32/kernel/irq.c
arch/x86/Makefile
arch/x86/boot/compressed/pgtable_64.c
arch/x86/events/amd/ibs.c
arch/x86/events/intel/core.c
arch/x86/hyperv/mmu.c
arch/x86/include/asm/bootparam_utils.h
arch/x86/include/asm/error-injection.h [deleted file]
arch/x86/include/asm/ftrace.h
arch/x86/include/asm/iommu.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/perf_event.h
arch/x86/include/asm/uaccess.h
arch/x86/kernel/amd_nb.c
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/bigsmp_32.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/cpu/mce/severity.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/uprobes.c
arch/x86/kvm/hyperv.c
arch/x86/kvm/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c
arch/x86/mm/pageattr.c
arch/x86/purgatory/Makefile
drivers/Kconfig
drivers/Makefile
drivers/acpi/Kconfig
drivers/acpi/arm64/iort.c
drivers/acpi/pptt.c
drivers/atm/Kconfig
drivers/base/Kconfig
drivers/base/arch_topology.c
drivers/base/regmap/regmap-debugfs.c
drivers/base/regmap/regmap-irq.c
drivers/base/soc.c
drivers/block/rbd.c
drivers/bluetooth/bpa10x.c
drivers/bluetooth/btusb.c
drivers/bluetooth/hci_qca.c
drivers/bus/Kconfig
drivers/bus/Makefile
drivers/bus/fsl-mc/fsl-mc-allocator.c
drivers/bus/fsl-mc/mc-io.c
drivers/bus/hisi_lpc.c
drivers/bus/imx-weim.c
drivers/bus/moxtet.c [new file with mode: 0644]
drivers/bus/sunxi-rsb.c
drivers/bus/ti-sysc.c
drivers/bus/uniphier-system-bus.c
drivers/char/Kconfig
drivers/char/Makefile
drivers/char/agp/Kconfig
drivers/char/agp/Makefile
drivers/char/agp/sgi-agp.c [deleted file]
drivers/char/mbcs.c [deleted file]
drivers/char/mbcs.h [deleted file]
drivers/char/mspec.c
drivers/char/random.c
drivers/char/snsc.c [deleted file]
drivers/char/snsc.h [deleted file]
drivers/char/snsc_event.c [deleted file]
drivers/char/tpm/Kconfig
drivers/char/tpm/Makefile
drivers/char/tpm/tpm-chip.c
drivers/char/tpm/tpm-sysfs.c
drivers/char/tpm/tpm_ftpm_tee.c [new file with mode: 0644]
drivers/char/tpm/tpm_ftpm_tee.h [new file with mode: 0644]
drivers/char/tpm/tpm_tis_core.c
drivers/clk/clk-scmi.c
drivers/clk/clk.c
drivers/clk/imx/Kconfig
drivers/clk/imx/Makefile
drivers/clk/imx/clk-imx8mm.c
drivers/clk/imx/clk-imx8mn.c [new file with mode: 0644]
drivers/clk/imx/clk-imx8qxp-lpcg.c
drivers/clk/imx/clk.c
drivers/clk/imx/clk.h
drivers/clk/meson/Kconfig
drivers/clk/meson/Makefile
drivers/clk/meson/axg-aoclk.c
drivers/clk/meson/axg-audio.c
drivers/clk/meson/axg.c
drivers/clk/meson/clk-cpu-dyndiv.c [new file with mode: 0644]
drivers/clk/meson/clk-cpu-dyndiv.h [new file with mode: 0644]
drivers/clk/meson/clk-input.c [deleted file]
drivers/clk/meson/clk-input.h [deleted file]
drivers/clk/meson/clk-regmap.h
drivers/clk/meson/g12a-aoclk.c
drivers/clk/meson/g12a.c
drivers/clk/meson/g12a.h
drivers/clk/meson/gxbb-aoclk.c
drivers/clk/meson/gxbb.c
drivers/clk/meson/meson-aoclk.c
drivers/clk/meson/meson-aoclk.h
drivers/clk/meson/meson-eeclk.c
drivers/clk/meson/meson-eeclk.h
drivers/clk/meson/meson8b.c
drivers/clocksource/timer-riscv.c
drivers/cpuidle/Kconfig.arm
drivers/cpuidle/Makefile
drivers/cpuidle/cpuidle-arm.c
drivers/cpuidle/cpuidle-psci.c [new file with mode: 0644]
drivers/crypto/ccp/ccp-dev.c
drivers/dma/Kconfig
drivers/dma/bcm2835-dma.c
drivers/dma/iop-adma.c
drivers/dma/iop-adma.h [moved from arch/arm/include/asm/hardware/iop3xx-adma.h with 99% similarity]
drivers/dma/sh/rcar-dmac.c
drivers/dma/sprd-dma.c
drivers/dma/ti/dma-crossbar.c
drivers/dma/ti/omap-dma.c
drivers/edac/Kconfig
drivers/edac/Makefile
drivers/edac/altera_edac.c
drivers/edac/altera_edac.h
drivers/edac/amd64_edac.c
drivers/edac/amd64_edac.h
drivers/edac/bluefield_edac.c [new file with mode: 0644]
drivers/edac/edac_mc.c
drivers/edac/edac_mc.h
drivers/edac/edac_mc_sysfs.c
drivers/edac/ghes_edac.c
drivers/edac/i5100_edac.c
drivers/edac/pnd2_edac.c
drivers/firmware/Kconfig
drivers/firmware/Makefile
drivers/firmware/arm_scmi/Makefile
drivers/firmware/arm_scmi/base.c
drivers/firmware/arm_scmi/clock.c
drivers/firmware/arm_scmi/common.h
drivers/firmware/arm_scmi/driver.c
drivers/firmware/arm_scmi/perf.c
drivers/firmware/arm_scmi/power.c
drivers/firmware/arm_scmi/reset.c [new file with mode: 0644]
drivers/firmware/arm_scmi/sensors.c
drivers/firmware/imx/Kconfig
drivers/firmware/imx/Makefile
drivers/firmware/imx/imx-dsp.c [new file with mode: 0644]
drivers/firmware/imx/scu-pd.c
drivers/firmware/psci/psci.c
drivers/firmware/psci/psci_checker.c
drivers/firmware/qcom_scm.c
drivers/firmware/ti_sci.c
drivers/firmware/turris-mox-rwtm.c [new file with mode: 0644]
drivers/fpga/altera-ps-spi.c
drivers/fsi/fsi-scom.c
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-arizona.c
drivers/gpio/gpio-aspeed.c
drivers/gpio/gpio-bd70528.c
drivers/gpio/gpio-brcmstb.c
drivers/gpio/gpio-cadence.c
drivers/gpio/gpio-creg-snps.c
drivers/gpio/gpio-dwapb.c
drivers/gpio/gpio-eic-sprd.c
drivers/gpio/gpio-em.c
drivers/gpio/gpio-ep93xx.c
drivers/gpio/gpio-ftgpio010.c
drivers/gpio/gpio-grgpio.c
drivers/gpio/gpio-hlwd.c
drivers/gpio/gpio-htc-egpio.c
drivers/gpio/gpio-intel-mid.c
drivers/gpio/gpio-ixp4xx.c
drivers/gpio/gpio-ks8695.c [deleted file]
drivers/gpio/gpio-lpc32xx.c
drivers/gpio/gpio-lynxpoint.c
drivers/gpio/gpio-madera.c
drivers/gpio/gpio-max77620.c
drivers/gpio/gpio-max77650.c
drivers/gpio/gpio-mb86s7x.c
drivers/gpio/gpio-merrifield.c
drivers/gpio/gpio-mockup.c
drivers/gpio/gpio-moxtet.c [new file with mode: 0644]
drivers/gpio/gpio-mpc8xxx.c
drivers/gpio/gpio-mt7621.c
drivers/gpio/gpio-mxc.c
drivers/gpio/gpio-pca953x.c
drivers/gpio/gpio-pch.c
drivers/gpio/gpio-pmic-eic-sprd.c
drivers/gpio/gpio-sprd.c
drivers/gpio/gpio-stmpe.c
drivers/gpio/gpio-tb10x.c
drivers/gpio/gpio-tegra.c
drivers/gpio/gpio-thunderx.c
drivers/gpio/gpio-tqmx86.c
drivers/gpio/gpio-vf610.c
drivers/gpio/gpio-viperboard.c
drivers/gpio/gpio-xgene-sb.c
drivers/gpio/gpio-xlp.c
drivers/gpio/gpio-zx.c
drivers/gpio/gpio-zynq.c
drivers/gpio/gpiolib-acpi.c
drivers/gpio/gpiolib-acpi.h [new file with mode: 0644]
drivers/gpio/gpiolib-devres.c
drivers/gpio/gpiolib-of.c
drivers/gpio/gpiolib-of.h [new file with mode: 0644]
drivers/gpio/gpiolib.c
drivers/gpio/gpiolib.h
drivers/gpio/sgpio-aspeed.c [new file with mode: 0644]
drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/powerplay/hwmgr/vega20_hwmgr.c
drivers/gpu/drm/amd/powerplay/vega20_ppt.c
drivers/gpu/drm/arm/display/komeda/komeda_dev.c
drivers/gpu/drm/arm/display/komeda/komeda_kms.c
drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c
drivers/gpu/drm/drm_modes.c
drivers/gpu/drm/i915/display/intel_dp_mst.c
drivers/gpu/drm/i915/display/intel_vdsc.c
drivers/gpu/drm/i915/gem/i915_gem_userptr.c
drivers/gpu/drm/i915/gt/intel_workarounds.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_vgpu.c
drivers/gpu/drm/ingenic/ingenic-drm.c
drivers/gpu/drm/lima/lima_gem.c
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp102.c
drivers/gpu/drm/omapdrm/dss/output.c
drivers/gpu/drm/panfrost/panfrost_mmu.c
drivers/gpu/drm/qxl/qxl_drv.c
drivers/gpu/drm/selftests/drm_cmdline_selftests.h
drivers/gpu/drm/selftests/test-drm_cmdline_parser.c
drivers/gpu/drm/virtio/virtgpu_object.c
drivers/gpu/drm/vmwgfx/vmwgfx_msg.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/acpi_power_meter.c
drivers/hwmon/ads1015.c [deleted file]
drivers/hwmon/adt7475.c
drivers/hwmon/as370-hwmon.c [new file with mode: 0644]
drivers/hwmon/asb100.c
drivers/hwmon/coretemp.c
drivers/hwmon/iio_hwmon.c
drivers/hwmon/k10temp.c
drivers/hwmon/k8temp.c
drivers/hwmon/lm75.c
drivers/hwmon/ltc2990.c
drivers/hwmon/nct6775.c
drivers/hwmon/nct7904.c
drivers/hwmon/npcm750-pwm-fan.c
drivers/hwmon/pmbus/Kconfig
drivers/hwmon/pmbus/Makefile
drivers/hwmon/pmbus/ibm-cffps.c
drivers/hwmon/pmbus/inspur-ipsps.c [new file with mode: 0644]
drivers/hwmon/pmbus/max31785.c
drivers/hwmon/pmbus/ucd9000.c
drivers/hwmon/raspberrypi-hwmon.c
drivers/hwmon/scmi-hwmon.c
drivers/hwmon/shtc1.c
drivers/hwmon/smm665.c
drivers/hwmon/w83781d.c
drivers/hwmon/w83791d.c
drivers/hwmon/w83792d.c
drivers/hwmon/w83793.c
drivers/hwtracing/intel_th/pci.c
drivers/hwtracing/stm/core.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-bcm-iproc.c
drivers/i2c/busses/i2c-designware-slave.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-mt65xx.c
drivers/i2c/busses/i2c-piix4.c
drivers/i2c/i2c-core-base.c
drivers/i3c/device.c
drivers/i3c/master.c
drivers/i3c/master/dw-i3c-master.c
drivers/i3c/master/i3c-master-cdns.c
drivers/ide/Kconfig
drivers/ide/Makefile
drivers/ide/sgiioc4.c [deleted file]
drivers/iio/adc/Kconfig
drivers/infiniband/sw/siw/siw_cm.c
drivers/iommu/Kconfig
drivers/iommu/Makefile
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu.h [new file with mode: 0644]
drivers/iommu/amd_iommu_init.c
drivers/iommu/amd_iommu_quirks.c [new file with mode: 0644]
drivers/iommu/amd_iommu_types.h
drivers/iommu/arm-smmu-impl.c [new file with mode: 0644]
drivers/iommu/arm-smmu-regs.h [deleted file]
drivers/iommu/arm-smmu-v3.c
drivers/iommu/arm-smmu.c
drivers/iommu/arm-smmu.h [new file with mode: 0644]
drivers/iommu/dma-iommu.c
drivers/iommu/dmar.c
drivers/iommu/exynos-iommu.c
drivers/iommu/intel-iommu.c
drivers/iommu/intel-svm.c
drivers/iommu/intel-trace.c [new file with mode: 0644]
drivers/iommu/intel_irq_remapping.c
drivers/iommu/io-pgtable-arm-v7s.c
drivers/iommu/io-pgtable-arm.c
drivers/iommu/iommu.c
drivers/iommu/iova.c
drivers/iommu/ipmmu-vmsa.c
drivers/iommu/msm_iommu.c
drivers/iommu/mtk_iommu.c
drivers/iommu/mtk_iommu.h
drivers/iommu/mtk_iommu_v1.c
drivers/iommu/omap-iommu.c
drivers/iommu/omap-iommu.h
drivers/iommu/qcom_iommu.c
drivers/iommu/rockchip-iommu.c
drivers/iommu/s390-iommu.c
drivers/iommu/tegra-gart.c
drivers/iommu/tegra-smmu.c
drivers/iommu/virtio-iommu.c
drivers/irqchip/irq-sifive-plic.c
drivers/isdn/capi/capi.c
drivers/memory/mtk-smi.c
drivers/mfd/rk808.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/ioc4.c [deleted file]
drivers/misc/lkdtm/bugs.c
drivers/misc/mei/hw-me-regs.h
drivers/misc/mei/pci-me.c
drivers/misc/sgi-xp/Makefile
drivers/misc/sgi-xp/xp.h
drivers/misc/sgi-xp/xp_main.c
drivers/misc/sgi-xp/xp_nofault.S [deleted file]
drivers/misc/sgi-xp/xp_sn2.c [deleted file]
drivers/misc/sgi-xp/xp_uv.c
drivers/misc/sgi-xp/xpc.h
drivers/misc/sgi-xp/xpc_main.c
drivers/misc/sgi-xp/xpc_partition.c
drivers/misc/sgi-xp/xpc_sn2.c [deleted file]
drivers/misc/sgi-xp/xpc_uv.c
drivers/misc/sgi-xp/xpnet.c
drivers/misc/vmw_balloon.c
drivers/misc/vmw_vmci/vmci_doorbell.c
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/sd.c
drivers/mmc/host/bcm2835.c
drivers/mmc/host/renesas_sdhi_core.c
drivers/mmc/host/sdhci-cadence.c
drivers/mmc/host/sdhci-of-at91.c
drivers/mmc/host/sdhci-pci-o2micro.c
drivers/mmc/host/sdhci-sprd.c
drivers/mmc/host/sdhci-tegra.c
drivers/mmc/host/tmio_mmc.c
drivers/mmc/host/tmio_mmc.h
drivers/mmc/host/tmio_mmc_core.c
drivers/mmc/host/uniphier-sd.c
drivers/mtd/hyperbus/Kconfig
drivers/net/dsa/bcm_sf2.c
drivers/net/dsa/microchip/ksz9477_spi.c
drivers/net/dsa/microchip/ksz_common.h
drivers/net/ethernet/Kconfig
drivers/net/ethernet/Makefile
drivers/net/ethernet/amd/xgbe/xgbe-main.c
drivers/net/ethernet/aquantia/atlantic/aq_filters.c
drivers/net/ethernet/aquantia/atlantic/aq_main.c
drivers/net/ethernet/aquantia/atlantic/aq_nic.c
drivers/net/ethernet/aquantia/atlantic/aq_vec.c
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/freescale/enetc/enetc_ptp.c
drivers/net/ethernet/google/gve/gve_main.c
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_err.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_xsk.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/marvell/sky2.c
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_tx.c
drivers/net/ethernet/mellanox/mlx5/core/health.c
drivers/net/ethernet/micrel/Kconfig
drivers/net/ethernet/micrel/Makefile
drivers/net/ethernet/micrel/ks8695net.c [deleted file]
drivers/net/ethernet/micrel/ks8695net.h [deleted file]
drivers/net/ethernet/mscc/ocelot_ace.c
drivers/net/ethernet/natsemi/sonic.c
drivers/net/ethernet/netronome/nfp/bpf/jit.c
drivers/net/ethernet/netronome/nfp/flower/cmsg.c
drivers/net/ethernet/netronome/nfp/flower/offload.c
drivers/net/ethernet/netronome/nfp/flower/tunnel_conf.c
drivers/net/ethernet/nuvoton/Kconfig [deleted file]
drivers/net/ethernet/nuvoton/Makefile [deleted file]
drivers/net/ethernet/nuvoton/w90p910_ether.c [deleted file]
drivers/net/ethernet/nvidia/forcedeth.c
drivers/net/ethernet/nxp/Kconfig
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/qlogic/qed/qed_main.c
drivers/net/ethernet/realtek/r8169_main.c
drivers/net/ethernet/seeq/sgiseeq.c
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/hamradio/6pack.c
drivers/net/ieee802154/mac802154_hwsim.c
drivers/net/phy/phy-c45.c
drivers/net/phy/phy.c
drivers/net/phy/phylink.c
drivers/net/tun.c
drivers/net/usb/cdc_ether.c
drivers/net/usb/r8152.c
drivers/net/virtio_net.c
drivers/net/wan/lmc/lmc_main.c
drivers/net/wimax/i2400m/op-rfkill.c
drivers/net/wireless/intel/iwlwifi/cfg/22000.c
drivers/net/wireless/intel/iwlwifi/iwl-config.h
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
drivers/net/wireless/marvell/mwifiex/ie.c
drivers/net/wireless/marvell/mwifiex/uap_cmd.c
drivers/net/wireless/mediatek/mt76/mt76x0/eeprom.c
drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
drivers/net/wireless/ralink/rt2x00/rt2800lib.c
drivers/net/wireless/ralink/rt2x00/rt2x00.h
drivers/net/wireless/ralink/rt2x00/rt2x00dev.c
drivers/net/wireless/rsi/rsi_91x_usb.c
drivers/nfc/st95hf/core.c
drivers/nvdimm/pfn_devs.c
drivers/of/fdt.c
drivers/parisc/dino.c
drivers/parisc/eisa_enumerator.c
drivers/parisc/hppb.c
drivers/pci/hotplug/Kconfig
drivers/pci/hotplug/Makefile
drivers/pci/hotplug/sgi_hotplug.c [deleted file]
drivers/perf/arm_smmuv3_pmu.c
drivers/perf/fsl_imx8_ddr_perf.c
drivers/perf/hisilicon/hisi_uncore_ddrc_pmu.c
drivers/perf/hisilicon/hisi_uncore_hha_pmu.c
drivers/perf/hisilicon/hisi_uncore_l3c_pmu.c
drivers/perf/qcom_l2_pmu.c
drivers/perf/xgene_pmu.c
drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c
drivers/pinctrl/aspeed/pinmux-aspeed.c
drivers/pinctrl/aspeed/pinmux-aspeed.h
drivers/pinctrl/intel/pinctrl-baytrail.c
drivers/pinctrl/intel/pinctrl-cherryview.c
drivers/pinctrl/pinctrl-stmfx.c
drivers/pinctrl/qcom/Kconfig
drivers/pinctrl/qcom/pinctrl-msm.c
drivers/pinctrl/qcom/pinctrl-spmi-gpio.c
drivers/platform/chrome/cros_ec_spi.c
drivers/platform/x86/intel_int0002_vgpio.c
drivers/ras/Makefile
drivers/ras/cec.c
drivers/ras/debugfs.c
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/act8865-regulator.c
drivers/regulator/act8945a-regulator.c
drivers/regulator/core.c
drivers/regulator/da9062-regulator.c
drivers/regulator/da9063-regulator.c
drivers/regulator/da9211-regulator.c
drivers/regulator/fixed.c
drivers/regulator/helpers.c
drivers/regulator/lm363x-regulator.c
drivers/regulator/lp87565-regulator.c
drivers/regulator/lp8788-ldo.c
drivers/regulator/max77686-regulator.c
drivers/regulator/max8660.c
drivers/regulator/mt6358-regulator.c [new file with mode: 0644]
drivers/regulator/qcom-rpmh-regulator.c
drivers/regulator/rk808-regulator.c
drivers/regulator/s2mps11.c
drivers/regulator/slg51000-regulator.c
drivers/regulator/stm32-booster.c
drivers/regulator/sy8824x.c [new file with mode: 0644]
drivers/regulator/tps65132-regulator.c
drivers/regulator/twl-regulator.c
drivers/regulator/twl6030-regulator.c
drivers/regulator/uniphier-regulator.c
drivers/reset/Kconfig
drivers/reset/Makefile
drivers/reset/reset-imx7.c
drivers/reset/reset-meson.c
drivers/reset/reset-scmi.c [new file with mode: 0644]
drivers/reset/reset-simple.c
drivers/s390/net/qeth_core_main.c
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_sli4.h
drivers/scsi/qla1280.c
drivers/scsi/qla1280.h
drivers/scsi/qla2xxx/qla_init.c
drivers/sn/Kconfig [deleted file]
drivers/sn/Makefile [deleted file]
drivers/sn/ioc3.c [deleted file]
drivers/soc/amlogic/Kconfig
drivers/soc/amlogic/Makefile
drivers/soc/amlogic/meson-clk-measure.c
drivers/soc/amlogic/meson-ee-pwrc.c [new file with mode: 0644]
drivers/soc/amlogic/meson-gx-socinfo.c
drivers/soc/fsl/dpaa2-console.c
drivers/soc/fsl/dpio/dpio-service.c
drivers/soc/fsl/guts.c
drivers/soc/fsl/qbman/bman.c
drivers/soc/fsl/qbman/bman_ccsr.c
drivers/soc/fsl/qbman/bman_portal.c
drivers/soc/fsl/qbman/bman_priv.h
drivers/soc/fsl/qbman/dpaa_sys.c
drivers/soc/fsl/qbman/qman.c
drivers/soc/fsl/qbman/qman_ccsr.c
drivers/soc/fsl/qbman/qman_portal.c
drivers/soc/fsl/qbman/qman_priv.h
drivers/soc/fsl/qe/qe.c
drivers/soc/imx/gpcv2.c
drivers/soc/imx/soc-imx-scu.c
drivers/soc/imx/soc-imx8.c
drivers/soc/ixp4xx/Kconfig
drivers/soc/mediatek/mtk-cmdq-helper.c
drivers/soc/qcom/Kconfig
drivers/soc/qcom/Makefile
drivers/soc/qcom/qcom-geni-se.c
drivers/soc/qcom/qcom_aoss.c
drivers/soc/qcom/smem.c
drivers/soc/qcom/socinfo.c [new file with mode: 0644]
drivers/soc/renesas/Kconfig
drivers/soc/renesas/rcar-sysc.c
drivers/soc/renesas/rmobile-sysc.c
drivers/soc/samsung/Kconfig
drivers/soc/samsung/Makefile
drivers/soc/samsung/exynos-chipid.c [new file with mode: 0644]
drivers/soc/ti/pm33xx.c
drivers/soc/ti/ti_sci_pm_domains.c
drivers/soc/ux500/ux500-soc-id.c
drivers/spi/Kconfig
drivers/spi/Makefile
drivers/spi/atmel-quadspi.c
drivers/spi/spi-altera.c
drivers/spi/spi-armada-3700.c
drivers/spi/spi-ath79.c
drivers/spi/spi-atmel.c
drivers/spi/spi-axi-spi-engine.c
drivers/spi/spi-bcm-qspi.c
drivers/spi/spi-bcm2835.c
drivers/spi/spi-bcm2835aux.c
drivers/spi/spi-bcm63xx-hsspi.c
drivers/spi/spi-bcm63xx.c
drivers/spi/spi-cadence.c
drivers/spi/spi-cavium-octeon.c
drivers/spi/spi-clps711x.c
drivers/spi/spi-coldfire-qspi.c
drivers/spi/spi-dw-mmio.c
drivers/spi/spi-dw-pci.c
drivers/spi/spi-efm32.c
drivers/spi/spi-ep93xx.c
drivers/spi/spi-fsl-cpm.c
drivers/spi/spi-fsl-dspi.c
drivers/spi/spi-fsl-lib.h
drivers/spi/spi-fsl-qspi.c
drivers/spi/spi-fsl-spi.c
drivers/spi/spi-geni-qcom.c
drivers/spi/spi-gpio.c
drivers/spi/spi-lantiq-ssc.c
drivers/spi/spi-lp8841-rtc.c
drivers/spi/spi-meson-spicc.c
drivers/spi/spi-meson-spifc.c
drivers/spi/spi-mt65xx.c
drivers/spi/spi-mt7621.c
drivers/spi/spi-mxs.c
drivers/spi/spi-npcm-fiu.c [new file with mode: 0644]
drivers/spi/spi-npcm-pspi.c
drivers/spi/spi-nuc900.c [deleted file]
drivers/spi/spi-nxp-fspi.c
drivers/spi/spi-oc-tiny.c
drivers/spi/spi-pic32-sqi.c
drivers/spi/spi-pic32.c
drivers/spi/spi-qcom-qspi.c
drivers/spi/spi-rb4xx.c
drivers/spi/spi-s3c24xx.c
drivers/spi/spi-sh-msiof.c
drivers/spi/spi-sh.c
drivers/spi/spi-sifive.c
drivers/spi/spi-sirf.c
drivers/spi/spi-slave-mt27xx.c
drivers/spi/spi-sprd-adi.c
drivers/spi/spi-sprd.c
drivers/spi/spi-st-ssc4.c
drivers/spi/spi-stm32-qspi.c
drivers/spi/spi-sun4i.c
drivers/spi/spi-sun6i.c
drivers/spi/spi-synquacer.c
drivers/spi/spi-tegra20-sflash.c
drivers/spi/spi-ti-qspi.c
drivers/spi/spi-uniphier.c
drivers/spi/spi-xlp.c
drivers/spi/spi-zynq-qspi.c
drivers/spi/spi-zynqmp-gqspi.c
drivers/spi/spi.c
drivers/tee/optee/call.c
drivers/tty/serial/Kconfig
drivers/tty/serial/Makefile
drivers/tty/serial/ioc3_serial.c [deleted file]
drivers/tty/serial/ioc4_serial.c [deleted file]
drivers/tty/serial/lpc32xx_hs.c
drivers/tty/serial/sn_console.c [deleted file]
drivers/usb/chipidea/udc.c
drivers/usb/class/cdc-wdm.c
drivers/usb/class/usbtmc.c
drivers/usb/core/hcd-pci.c
drivers/usb/gadget/udc/Kconfig
drivers/usb/gadget/udc/lpc32xx_udc.c
drivers/usb/host/Kconfig
drivers/usb/host/ohci-hcd.c
drivers/usb/host/ohci-nxp.c
drivers/usb/host/xhci-rcar.c
drivers/usb/host/xhci-tegra.c
drivers/usb/storage/realtek_cr.c
drivers/usb/storage/unusual_devs.h
drivers/usb/typec/tcpm/tcpm.c
drivers/vfio/vfio_iommu_type1.c
drivers/vhost/test.c
drivers/vhost/vhost.c
drivers/vhost/vhost.h
drivers/video/fbdev/Kconfig
drivers/video/fbdev/Makefile
drivers/video/fbdev/atafb.c
drivers/video/fbdev/da8xx-fb.c
drivers/video/fbdev/nuc900fb.c [deleted file]
drivers/video/fbdev/nuc900fb.h [deleted file]
drivers/virtio/virtio_ring.c
drivers/watchdog/Kconfig
drivers/watchdog/pnx4008_wdt.c
drivers/xen/swiotlb-xen.c
fs/btrfs/extent_io.c
fs/btrfs/tree-log.c
fs/cifs/cifsfs.h
fs/cifs/cifsproto.h
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/misc.c
fs/cifs/sess.c
fs/configfs/configfs_internal.h
fs/configfs/dir.c
fs/configfs/file.c
fs/ext4/inode.c
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/flexfilelayout/flexfilelayout.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/nfs4file.c
fs/nfs/pagelist.c
fs/nfs/pnfs_nfs.c
fs/nfs/proc.c
fs/nfs/read.c
fs/nfs/write.c
include/Kbuild
include/asm-generic/error-injection.h
include/dt-bindings/bus/moxtet.h [new file with mode: 0644]
include/dt-bindings/clock/g12a-clkc.h
include/dt-bindings/clock/imx8-clock.h
include/dt-bindings/clock/imx8mn-clock.h [new file with mode: 0644]
include/dt-bindings/memory/mt8183-larb-port.h [new file with mode: 0644]
include/dt-bindings/power/meson-g12a-power.h [new file with mode: 0644]
include/dt-bindings/power/meson-sm1-power.h [new file with mode: 0644]
include/dt-bindings/regulator/active-semi,8865-regulator.h [new file with mode: 0644]
include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h [new file with mode: 0644]
include/dt-bindings/reset/amlogic,meson-gxbb-reset.h
include/dt-bindings/reset/amlogic,meson8b-reset.h
include/dt-bindings/reset/imx8mq-reset.h
include/dt-bindings/reset/mt7629-resets.h [new file with mode: 0644]
include/dt-bindings/soc/ti,sci_pm_domain.h [new file with mode: 0644]
include/linux/acpi.h
include/linux/amd-iommu.h
include/linux/arch_topology.h
include/linux/blk_types.h
include/linux/clk-provider.h
include/linux/compiler.h
include/linux/cpuidle.h
include/linux/edac.h
include/linux/error-injection.h
include/linux/firmware/imx/dsp.h [new file with mode: 0644]
include/linux/gpio.h
include/linux/gpio/consumer.h
include/linux/gpio/driver.h
include/linux/i3c/device.h
include/linux/i3c/master.h
include/linux/input/elan-i2c-ids.h
include/linux/intel-iommu.h
include/linux/io-pgtable.h
include/linux/ioc4.h [deleted file]
include/linux/iommu.h
include/linux/kexec.h
include/linux/logic_pio.h
include/linux/mmzone.h
include/linux/moxtet.h [new file with mode: 0644]
include/linux/netfilter/nf_conntrack_h323_types.h
include/linux/of_gpio.h
include/linux/omap-iommu.h
include/linux/pci_ids.h
include/linux/phy.h
include/linux/phy_fixed.h
include/linux/pid.h
include/linux/platform_data/dma-iop32x.h [moved from arch/arm/include/asm/hardware/iop_adma.h with 98% similarity]
include/linux/platform_data/gpio-htc-egpio.h
include/linux/platform_data/iommu-omap.h
include/linux/platform_data/spi-nuc900.h [deleted file]
include/linux/platform_data/video-nuc900fb.h [deleted file]
include/linux/psci.h
include/linux/qcom_scm.h
include/linux/random.h
include/linux/regulator/consumer.h
include/linux/regulator/mt6358-regulator.h [new file with mode: 0644]
include/linux/scmi_protocol.h
include/linux/soc/mediatek/mtk-cmdq.h
include/linux/soc/nxp/lpc32xx-misc.h [new file with mode: 0644]
include/linux/soc/samsung/exynos-chipid.h [new file with mode: 0644]
include/linux/soc/ti/ti_sci_protocol.h
include/linux/sunrpc/sched.h
include/linux/swiotlb.h
include/linux/sys_soc.h
include/linux/syscalls.h
include/linux/topology.h
include/linux/trace_events.h
include/linux/usb/samsung_usb_phy.h [deleted file]
include/math-emu/op-common.h
include/net/act_api.h
include/net/addrconf.h
include/net/ip_fib.h
include/net/net_namespace.h
include/net/nexthop.h
include/net/psample.h
include/net/route.h
include/net/xfrm.h
include/soc/arc/mcip.h
include/soc/mediatek/smi.h
include/trace/events/intel_iommu.h [new file with mode: 0644]
include/trace/events/rxrpc.h
include/uapi/asm-generic/unistd.h
include/uapi/linux/isdn/capicmd.h
include/uapi/linux/kexec.h
include/uapi/linux/netfilter/xt_nfacct.h
include/uapi/linux/prctl.h
include/uapi/linux/rds.h
include/uapi/linux/wait.h
include/video/da8xx-fb.h
init/Kconfig
ipc/util.h
kernel/Makefile
kernel/bpf/core.c
kernel/bpf/syscall.c
kernel/bpf/verifier.c
kernel/cgroup/cgroup.c
kernel/dma/direct.c
kernel/dma/swiotlb.c
kernel/events/hw_breakpoint.c
kernel/exit.c
kernel/fork.c
kernel/irq/proc.c
kernel/irq/resend.c
kernel/jump_label.c
kernel/kallsyms.c
kernel/kexec_elf.c [new file with mode: 0644]
kernel/sched/core.c
kernel/sched/fair.c
kernel/signal.c
kernel/sys.c
kernel/trace/ftrace.c
kernel/trace/trace.c
kernel/trace/trace_events.c
kernel/trace/trace_probe.c
lib/Kconfig
lib/kfifo.c
lib/logic_pio.c
mm/balloon_compaction.c
mm/memcontrol.c
mm/vmscan.c
mm/z3fold.c
mm/zsmalloc.c
net/batman-adv/bat_iv_ogm.c
net/batman-adv/bat_v_ogm.c
net/batman-adv/netlink.c
net/bluetooth/hci_event.c
net/bluetooth/l2cap_core.c
net/bridge/br_mdb.c
net/bridge/br_netfilter_hooks.c
net/bridge/netfilter/ebtables.c
net/bridge/netfilter/nft_meta_bridge.c
net/ceph/crypto.c
net/core/dev.c
net/core/filter.c
net/core/flow_dissector.c
net/core/netpoll.c
net/core/skbuff.c
net/core/sock.c
net/core/sock_map.c
net/core/stream.c
net/dsa/tag_8021q.c
net/ieee802154/socket.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv6/addrconf.c
net/ipv6/mcast.c
net/ipv6/ping.c
net/ipv6/route.c
net/mac80211/cfg.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mpls/mpls_iptunnel.c
net/ncsi/ncsi-cmd.c
net/ncsi/ncsi-rsp.c
net/netfilter/nf_conntrack_ftp.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_standalone.c
net/netfilter/nf_flow_table_core.c
net/netfilter/nf_flow_table_ip.c
net/netfilter/nft_fib_netdev.c
net/netfilter/nft_flow_offload.c
net/netfilter/nft_socket.c
net/netfilter/xt_nfacct.c
net/netfilter/xt_physdev.c
net/openvswitch/conntrack.c
net/openvswitch/flow.c
net/openvswitch/flow.h
net/psample/psample.c
net/qrtr/tun.c
net/rds/bind.c
net/rds/ib.c
net/rds/ib.h
net/rds/ib_cm.c
net/rds/rdma_transport.c
net/rds/recv.c
net/rxrpc/af_rxrpc.c
net/rxrpc/ar-internal.h
net/rxrpc/call_event.c
net/rxrpc/call_object.c
net/rxrpc/conn_client.c
net/rxrpc/conn_event.c
net/rxrpc/conn_object.c
net/rxrpc/input.c
net/rxrpc/local_event.c
net/rxrpc/local_object.c
net/rxrpc/output.c
net/rxrpc/peer_event.c
net/rxrpc/protocol.h
net/rxrpc/recvmsg.c
net/rxrpc/rxkad.c
net/rxrpc/sendmsg.c
net/rxrpc/skbuff.c
net/sched/act_bpf.c
net/sched/act_connmark.c
net/sched/act_csum.c
net/sched/act_ct.c
net/sched/act_ctinfo.c
net/sched/act_gact.c
net/sched/act_ife.c
net/sched/act_ipt.c
net/sched/act_mirred.c
net/sched/act_mpls.c
net/sched/act_nat.c
net/sched/act_pedit.c
net/sched/act_police.c
net/sched/act_sample.c
net/sched/act_simple.c
net/sched/act_skbedit.c
net/sched/act_skbmod.c
net/sched/act_tunnel_key.c
net/sched/act_vlan.c
net/sched/sch_api.c
net/sched/sch_cbs.c
net/sched/sch_generic.c
net/sched/sch_hhf.c
net/sched/sch_taprio.c
net/sctp/protocol.c
net/sctp/sm_sideeffect.c
net/sctp/socket.c
net/smc/smc_tx.c
net/sunrpc/clnt.c
net/sunrpc/xprt.c
net/tipc/name_distr.c
net/wireless/reg.c
net/wireless/util.c
net/xdp/xdp_umem.c
net/xfrm/xfrm_interface.c
net/xfrm/xfrm_policy.c
scripts/Makefile.kasan
scripts/tools-support-relr.sh [new file with mode: 0755]
security/keys/request_key.c
security/keys/request_key_auth.c
sound/core/seq/seq_clientmgr.c
sound/core/seq/seq_fifo.c
sound/core/seq/seq_fifo.h
sound/firewire/oxfw/oxfw-pcm.c
sound/pci/hda/hda_auto_parser.c
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_generic.h
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_realtek.c
sound/soc/intel/boards/bytcht_cx2072x.c
sound/soc/intel/boards/cht_bsw_max98090_ti.c
sound/soc/intel/boards/cht_bsw_rt5672.c
sound/usb/line6/pcm.c
sound/usb/mixer.c
sound/usb/mixer_quirks.c
sound/usb/pcm.c
tools/arch/riscv/include/uapi/asm/perf_regs.h [new file with mode: 0644]
tools/bpf/bpftool/prog.c
tools/perf/Makefile.config
tools/perf/arch/riscv/Build [new file with mode: 0644]
tools/perf/arch/riscv/Makefile [new file with mode: 0644]
tools/perf/arch/riscv/include/perf_regs.h [new file with mode: 0644]
tools/perf/arch/riscv/util/Build [new file with mode: 0644]
tools/perf/arch/riscv/util/dwarf-regs.c [new file with mode: 0644]
tools/perf/arch/riscv/util/unwind-libdw.c [new file with mode: 0644]
tools/power/x86/turbostat/Makefile
tools/power/x86/turbostat/turbostat.c
tools/power/x86/x86_energy_perf_policy/Makefile
tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8
tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c
tools/testing/selftests/arm64/.gitignore [new file with mode: 0644]
tools/testing/selftests/arm64/Makefile [new file with mode: 0644]
tools/testing/selftests/arm64/run_tags_test.sh [new file with mode: 0755]
tools/testing/selftests/arm64/tags_test.c [new file with mode: 0644]
tools/testing/selftests/bpf/Makefile
tools/testing/selftests/bpf/config
tools/testing/selftests/bpf/test_btf_dump.c
tools/testing/selftests/bpf/test_cgroup_storage.c
tools/testing/selftests/bpf/test_sock.c
tools/testing/selftests/cgroup/test_freezer.c
tools/testing/selftests/net/fib_nexthops.sh
tools/testing/selftests/net/xfrm_policy.sh
tools/testing/selftests/pidfd/.gitignore
tools/testing/selftests/pidfd/Makefile
tools/testing/selftests/pidfd/pidfd.h
tools/testing/selftests/pidfd/pidfd_open_test.c
tools/testing/selftests/pidfd/pidfd_poll_test.c [new file with mode: 0644]
tools/testing/selftests/pidfd/pidfd_test.c
tools/testing/selftests/pidfd/pidfd_wait.c [new file with mode: 0644]
tools/testing/selftests/tc-testing/plugin-lib/nsPlugin.py
virt/kvm/arm/vgic/vgic-mmio.c
virt/kvm/arm/vgic/vgic-v2.c
virt/kvm/arm/vgic/vgic-v3.c
virt/kvm/arm/vgic/vgic.c

index 2ffd69a..196ca31 100644 (file)
@@ -107,10 +107,13 @@ ForEachMacros:
   - 'css_for_each_descendant_post'
   - 'css_for_each_descendant_pre'
   - 'device_for_each_child_node'
+  - 'dma_fence_chain_for_each'
   - 'drm_atomic_crtc_for_each_plane'
   - 'drm_atomic_crtc_state_for_each_plane'
   - 'drm_atomic_crtc_state_for_each_plane_state'
   - 'drm_atomic_for_each_plane_damage'
+  - 'drm_client_for_each_connector_iter'
+  - 'drm_client_for_each_modeset'
   - 'drm_connector_for_each_possible_encoder'
   - 'drm_for_each_connector_iter'
   - 'drm_for_each_crtc'
@@ -126,6 +129,7 @@ ForEachMacros:
   - 'drm_mm_for_each_node_in_range'
   - 'drm_mm_for_each_node_safe'
   - 'flow_action_for_each'
+  - 'for_each_active_dev_scope'
   - 'for_each_active_drhd_unit'
   - 'for_each_active_iommu'
   - 'for_each_available_child_of_node'
@@ -153,6 +157,8 @@ ForEachMacros:
   - 'for_each_cpu_not'
   - 'for_each_cpu_wrap'
   - 'for_each_dev_addr'
+  - 'for_each_dev_scope'
+  - 'for_each_displayid_db'
   - 'for_each_dma_cap_mask'
   - 'for_each_dpcm_be'
   - 'for_each_dpcm_be_rollback'
@@ -169,6 +175,8 @@ ForEachMacros:
   - 'for_each_evictable_lru'
   - 'for_each_fib6_node_rt_rcu'
   - 'for_each_fib6_walker_rt'
+  - 'for_each_free_mem_pfn_range_in_zone'
+  - 'for_each_free_mem_pfn_range_in_zone_from'
   - 'for_each_free_mem_range'
   - 'for_each_free_mem_range_reverse'
   - 'for_each_func_rsrc'
@@ -178,6 +186,7 @@ ForEachMacros:
   - 'for_each_ip_tunnel_rcu'
   - 'for_each_irq_nr'
   - 'for_each_link_codecs'
+  - 'for_each_link_platforms'
   - 'for_each_lru'
   - 'for_each_matching_node'
   - 'for_each_matching_node_and_match'
@@ -302,7 +311,10 @@ ForEachMacros:
   - 'ide_port_for_each_present_dev'
   - 'idr_for_each_entry'
   - 'idr_for_each_entry_continue'
+  - 'idr_for_each_entry_continue_ul'
   - 'idr_for_each_entry_ul'
+  - 'in_dev_for_each_ifa_rcu'
+  - 'in_dev_for_each_ifa_rtnl'
   - 'inet_bind_bucket_for_each'
   - 'inet_lhash2_for_each_icsk_rcu'
   - 'key_for_each'
@@ -343,8 +355,6 @@ ForEachMacros:
   - 'media_device_for_each_intf'
   - 'media_device_for_each_link'
   - 'media_device_for_each_pad'
-  - 'mp_bvec_for_each_page'
-  - 'mp_bvec_for_each_segment'
   - 'nanddev_io_for_each_page'
   - 'netdev_for_each_lower_dev'
   - 'netdev_for_each_lower_private'
@@ -381,18 +391,19 @@ ForEachMacros:
   - 'radix_tree_for_each_slot'
   - 'radix_tree_for_each_tagged'
   - 'rbtree_postorder_for_each_entry_safe'
+  - 'rdma_for_each_block'
   - 'rdma_for_each_port'
   - 'resource_list_for_each_entry'
   - 'resource_list_for_each_entry_safe'
   - 'rhl_for_each_entry_rcu'
   - 'rhl_for_each_rcu'
   - 'rht_for_each'
-  - 'rht_for_each_from'
   - 'rht_for_each_entry'
   - 'rht_for_each_entry_from'
   - 'rht_for_each_entry_rcu'
   - 'rht_for_each_entry_rcu_from'
   - 'rht_for_each_entry_safe'
+  - 'rht_for_each_from'
   - 'rht_for_each_rcu'
   - 'rht_for_each_rcu_from'
   - '__rq_for_each_bio'
index acba1a6..1ad4fd6 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -64,6 +64,9 @@ Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@imgtec.com>
 Dengcheng Zhu <dzhu@wavecomp.com> <dczhu@mips.com>
 Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@gmail.com>
 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+Dmitry Safonov <0x7f454c46@gmail.com> <dsafonov@virtuozzo.com>
+Dmitry Safonov <0x7f454c46@gmail.com> <d.safonov@partner.samsung.com>
+Dmitry Safonov <0x7f454c46@gmail.com> <dima@arista.com>
 Domen Puncer <domen@coderock.org>
 Douglas Gilbert <dougg@torque.net>
 Ed L. Cashin <ecashin@coraid.com>
@@ -160,6 +163,8 @@ Matt Ranostay <mranostay@gmail.com> Matthew Ranostay <mranostay@embeddedalley.co
 Matt Ranostay <mranostay@gmail.com> <matt.ranostay@intel.com>
 Matt Ranostay <matt.ranostay@konsulko.com> <matt@ranostay.consulting>
 Matt Redfearn <matt.redfearn@mips.com> <matt.redfearn@imgtec.com>
+Maxime Ripard <mripard@kernel.org> <maxime.ripard@bootlin.com>
+Maxime Ripard <mripard@kernel.org> <maxime.ripard@free-electrons.com>
 Mayuresh Janorkar <mayur@ti.com>
 Michael Buesch <m@bues.ch>
 Michel Dänzer <michel@tungstengraphics.com>
@@ -173,6 +178,7 @@ Morten Welinder <welinder@darter.rentec.com>
 Morten Welinder <welinder@troll.com>
 Mythri P K <mythripk@ti.com>
 Nguyen Anh Quynh <aquynh@gmail.com>
+Nicolas Ferre <nicolas.ferre@microchip.com> <nicolas.ferre@atmel.com>
 Nicolas Pitre <nico@fluxnic.net> <nicolas.pitre@linaro.org>
 Nicolas Pitre <nico@fluxnic.net> <nico@linaro.org>
 Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
diff --git a/Documentation/ABI/testing/debugfs-moxtet b/Documentation/ABI/testing/debugfs-moxtet
new file mode 100644 (file)
index 0000000..67b1717
--- /dev/null
@@ -0,0 +1,23 @@
+What:          /sys/kernel/debug/moxtet/input
+Date:          March 2019
+KernelVersion: 5.3
+Contact:       Marek Behún <marek.behun@nic.cz>
+Description:   (R) Read input from the shift registers, in hexadecimal.
+               Returns N+1 bytes, where N is the number of Moxtet connected
+               modules. The first byte is from the CPU board itself.
+               Example: 101214
+                        10: CPU board with SD card
+                        12: 2 = PCIe module, 1 = IRQ not active
+                        14: 4 = Peridot module, 1 = IRQ not active
+
+What:          /sys/kernel/debug/moxtet/output
+Date:          March 2019
+KernelVersion: 5.3
+Contact:       Marek Behún <marek.behun@nic.cz>
+Description:   (RW) Read last written value to the shift registers, in
+               hexadecimal, or write values to the shift registers, also
+               in hexadecimal.
+               Example: 0102
+                        01: 01 was last written, or is to be written, to the
+                            first module's shift register
+                        02: the same for second module
diff --git a/Documentation/ABI/testing/sysfs-bus-moxtet-devices b/Documentation/ABI/testing/sysfs-bus-moxtet-devices
new file mode 100644 (file)
index 0000000..3559585
--- /dev/null
@@ -0,0 +1,17 @@
+What:          /sys/bus/moxtet/devices/moxtet-<name>.<addr>/module_description
+Date:          March 2019
+KernelVersion: 5.3
+Contact:       Marek Behún <marek.behun@nic.cz>
+Description:   (R) Moxtet module description. Format: string
+
+What:          /sys/bus/moxtet/devices/moxtet-<name>.<addr>/module_id
+Date:          March 2019
+KernelVersion: 5.3
+Contact:       Marek Behún <marek.behun@nic.cz>
+Description:   (R) Moxtet module ID. Format: %x
+
+What:          /sys/bus/moxtet/devices/moxtet-<name>.<addr>/module_name
+Date:          March 2019
+KernelVersion: 5.3
+Contact:       Marek Behún <marek.behun@nic.cz>
+Description:   (R) Moxtet module name. Format: string
index 6d9cc25..ba3a3fa 100644 (file)
@@ -26,6 +26,13 @@ Description:
                Read-only attribute common to all SoCs. Contains SoC family name
                (e.g. DB8500).
 
+What:          /sys/devices/socX/serial_number
+Date:          January 2019
+contact:       Bjorn Andersson <bjorn.andersson@linaro.org>
+Description:
+               Read-only attribute supported by most SoCs. Contains the SoC's
+               serial number, if available.
+
 What:          /sys/devices/socX/soc_id
 Date:          January 2012
 contact:       Lee Jones <lee.jones@linaro.org>
diff --git a/Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm b/Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm
new file mode 100644 (file)
index 0000000..15595fa
--- /dev/null
@@ -0,0 +1,37 @@
+What:          /sys/firmware/turris-mox-rwtm/board_version
+Date:          August 2019
+KernelVersion: 5.4
+Contact:       Marek Behún <marek.behun@nic.cz>
+Description:   (R) Board version burned into eFuses of this Turris Mox board.
+               Format: %i
+
+What:          /sys/firmware/turris-mox-rwtm/mac_address*
+Date:          August 2019
+KernelVersion: 5.4
+Contact:       Marek Behún <marek.behun@nic.cz>
+Description:   (R) MAC addresses burned into eFuses of this Turris Mox board.
+               Format: %pM
+
+What:          /sys/firmware/turris-mox-rwtm/pubkey
+Date:          August 2019
+KernelVersion: 5.4
+Contact:       Marek Behún <marek.behun@nic.cz>
+Description:   (R) ECDSA public key (in pubkey hex compressed form) computed
+               as pair to the ECDSA private key burned into eFuses of this
+               Turris Mox Board.
+               Format: string
+
+What:          /sys/firmware/turris-mox-rwtm/ram_size
+Date:          August 2019
+KernelVersion: 5.4
+Contact:       Marek Behún <marek.behun@nic.cz>
+Description:   (R) RAM size in MiB of this Turris Mox board as was detected
+               during manufacturing and burned into eFuses. Can be 512 or 1024.
+               Format: %i
+
+What:          /sys/firmware/turris-mox-rwtm/serial_number
+Date:          August 2019
+KernelVersion: 5.4
+Contact:       Marek Behún <marek.behun@nic.cz>
+Description:   (R) Serial number burned into eFuses of this Turris Mox device.
+               Format: %016X
index 4c19719..0d2a67e 100644 (file)
                        Note that using this option lowers the security
                        provided by tboot because it makes the system
                        vulnerable to DMA attacks.
+               nobounce [Default off]
+                       Disable bounce buffer for unstrusted devices such as
+                       the Thunderbolt devices. This will treat the untrusted
+                       devices as the trusted ones, hence might expose security
+                       risks of DMA attacks.
 
        intel_idle.max_cstate=  [KNL,HW,ACPI,X86]
                        0       disables intel_idle and fall back on acpi_idle.
                          synchronously.
 
        iommu.passthrough=
-                       [ARM64] Configure DMA to bypass the IOMMU by default.
+                       [ARM64, X86] Configure DMA to bypass the IOMMU by default.
                        Format: { "0" | "1" }
                        0 - Use IOMMU translation for DMA.
                        1 - Bypass the IOMMU for DMA.
 
        machvec=        [IA-64] Force the use of a particular machine-vector
                        (machvec) in a generic kernel.
-                       Example: machvec=hpzx1_swiotlb
+                       Example: machvec=hpzx1
 
        machtype=       [Loongson] Share the same kernel image file between different
                         yeeloong laptop.
diff --git a/Documentation/admin-guide/perf/imx-ddr.rst b/Documentation/admin-guide/perf/imx-ddr.rst
new file mode 100644 (file)
index 0000000..517a205
--- /dev/null
@@ -0,0 +1,52 @@
+=====================================================
+Freescale i.MX8 DDR Performance Monitoring Unit (PMU)
+=====================================================
+
+There are no performance counters inside the DRAM controller, so performance
+signals are brought out to the edge of the controller where a set of 4 x 32 bit
+counters is implemented. This is controlled by the CSV modes programed in counter
+control register which causes a large number of PERF signals to be generated.
+
+Selection of the value for each counter is done via the config registers. There
+is one register for each counter. Counter 0 is special in that it always counts
+“time” and when expired causes a lock on itself and the other counters and an
+interrupt is raised. If any other counter overflows, it continues counting, and
+no interrupt is raised.
+
+The "format" directory describes format of the config (event ID) and config1
+(AXI filtering) fields of the perf_event_attr structure, see /sys/bus/event_source/
+devices/imx8_ddr0/format/. The "events" directory describes the events types
+hardware supported that can be used with perf tool, see /sys/bus/event_source/
+devices/imx8_ddr0/events/.
+  e.g.::
+        perf stat -a -e imx8_ddr0/cycles/ cmd
+        perf stat -a -e imx8_ddr0/read/,imx8_ddr0/write/ cmd
+
+AXI filtering is only used by CSV modes 0x41 (axid-read) and 0x42 (axid-write)
+to count reading or writing matches filter setting. Filter setting is various
+from different DRAM controller implementations, which is distinguished by quirks
+in the driver.
+
+* With DDR_CAP_AXI_ID_FILTER quirk.
+  Filter is defined with two configuration parts:
+  --AXI_ID defines AxID matching value.
+  --AXI_MASKING defines which bits of AxID are meaningful for the matching.
+        0:corresponding bit is masked.
+        1: corresponding bit is not masked, i.e. used to do the matching.
+
+  AXI_ID and AXI_MASKING are mapped on DPCR1 register in performance counter.
+  When non-masked bits are matching corresponding AXI_ID bits then counter is
+  incremented. Perf counter is incremented if
+          AxID && AXI_MASKING == AXI_ID && AXI_MASKING
+
+  This filter doesn't support filter different AXI ID for axid-read and axid-write
+  event at the same time as this filter is shared between counters.
+  e.g.::
+        perf stat -a -e imx8_ddr0/axid-read,axi_mask=0xMMMM,axi_id=0xDDDD/ cmd
+        perf stat -a -e imx8_ddr0/axid-write,axi_mask=0xMMMM,axi_id=0xDDDD/ cmd
+
+  NOTE: axi_mask is inverted in userspace(i.e. set bits are bits to mask), and
+  it will be reverted in driver automatically. so that the user can just specify
+  axi_id to monitor a specific id, rather than having to specify axi_mask.
+  e.g.::
+        perf stat -a -e imx8_ddr0/axid-read,axi_id=0x12/ cmd, which will monitor ARID=0x12
index 96b696b..5c0c69d 100644 (file)
@@ -16,6 +16,7 @@ ARM64 Architecture
     pointer-authentication
     silicon-errata
     sve
+    tagged-address-abi
     tagged-pointers
 
 .. only::  subproject and html
diff --git a/Documentation/arm64/kasan-offsets.sh b/Documentation/arm64/kasan-offsets.sh
new file mode 100644 (file)
index 0000000..2b7a021
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# Print out the KASAN_SHADOW_OFFSETS required to place the KASAN SHADOW
+# start address at the mid-point of the kernel VA space
+
+print_kasan_offset () {
+       printf "%02d\t" $1
+       printf "0x%08x00000000\n" $(( (0xffffffff & (-1 << ($1 - 1 - 32))) \
+                       + (1 << ($1 - 32 - $2)) \
+                       - (1 << (64 - 32 - $2)) ))
+}
+
+echo KASAN_SHADOW_SCALE_SHIFT = 3
+printf "VABITS\tKASAN_SHADOW_OFFSET\n"
+print_kasan_offset 48 3
+print_kasan_offset 47 3
+print_kasan_offset 42 3
+print_kasan_offset 39 3
+print_kasan_offset 36 3
+echo
+echo KASAN_SHADOW_SCALE_SHIFT = 4
+printf "VABITS\tKASAN_SHADOW_OFFSET\n"
+print_kasan_offset 48 4
+print_kasan_offset 47 4
+print_kasan_offset 42 4
+print_kasan_offset 39 4
+print_kasan_offset 36 4
index 464b880..b040909 100644 (file)
@@ -14,6 +14,10 @@ with the 4KB page configuration, allowing 39-bit (512GB) or 48-bit
 64KB pages, only 2 levels of translation tables, allowing 42-bit (4TB)
 virtual address, are used but the memory layout is the same.
 
+ARMv8.2 adds optional support for Large Virtual Address space. This is
+only available when running with a 64KB page size and expands the
+number of descriptors in the first level of translation.
+
 User addresses have bits 63:48 set to 0 while the kernel addresses have
 the same bits set to 1. TTBRx selection is given by bit 63 of the
 virtual address. The swapper_pg_dir contains only kernel (global)
@@ -22,40 +26,43 @@ The swapper_pg_dir address is written to TTBR1 and never written to
 TTBR0.
 
 
-AArch64 Linux memory layout with 4KB pages + 3 levels::
-
-  Start                        End                     Size            Use
-  -----------------------------------------------------------------------
-  0000000000000000     0000007fffffffff         512GB          user
-  ffffff8000000000     ffffffffffffffff         512GB          kernel
-
-
-AArch64 Linux memory layout with 4KB pages + 4 levels::
+AArch64 Linux memory layout with 4KB pages + 4 levels (48-bit)::
 
   Start                        End                     Size            Use
   -----------------------------------------------------------------------
   0000000000000000     0000ffffffffffff         256TB          user
-  ffff000000000000     ffffffffffffffff         256TB          kernel
-
-
-AArch64 Linux memory layout with 64KB pages + 2 levels::
+  ffff000000000000     ffff7fffffffffff         128TB          kernel logical memory map
+  ffff800000000000     ffff9fffffffffff          32TB          kasan shadow region
+  ffffa00000000000     ffffa00007ffffff         128MB          bpf jit region
+  ffffa00008000000     ffffa0000fffffff         128MB          modules
+  ffffa00010000000     fffffdffbffeffff         ~93TB          vmalloc
+  fffffdffbfff0000     fffffdfffe5f8fff        ~998MB          [guard region]
+  fffffdfffe5f9000     fffffdfffe9fffff        4124KB          fixed mappings
+  fffffdfffea00000     fffffdfffebfffff           2MB          [guard region]
+  fffffdfffec00000     fffffdffffbfffff          16MB          PCI I/O space
+  fffffdffffc00000     fffffdffffdfffff           2MB          [guard region]
+  fffffdffffe00000     ffffffffffdfffff           2TB          vmemmap
+  ffffffffffe00000     ffffffffffffffff           2MB          [guard region]
+
+
+AArch64 Linux memory layout with 64KB pages + 3 levels (52-bit with HW support)::
 
   Start                        End                     Size            Use
   -----------------------------------------------------------------------
-  0000000000000000     000003ffffffffff           4TB          user
-  fffffc0000000000     ffffffffffffffff           4TB          kernel
-
-
-AArch64 Linux memory layout with 64KB pages + 3 levels::
-
-  Start                        End                     Size            Use
-  -----------------------------------------------------------------------
-  0000000000000000     0000ffffffffffff         256TB          user
-  ffff000000000000     ffffffffffffffff         256TB          kernel
-
-
-For details of the virtual kernel memory layout please see the kernel
-booting log.
+  0000000000000000     000fffffffffffff           4PB          user
+  fff0000000000000     fff7ffffffffffff           2PB          kernel logical memory map
+  fff8000000000000     fffd9fffffffffff        1440TB          [gap]
+  fffda00000000000     ffff9fffffffffff         512TB          kasan shadow region
+  ffffa00000000000     ffffa00007ffffff         128MB          bpf jit region
+  ffffa00008000000     ffffa0000fffffff         128MB          modules
+  ffffa00010000000     fffff81ffffeffff         ~88TB          vmalloc
+  fffff81fffff0000     fffffc1ffe58ffff          ~3TB          [guard region]
+  fffffc1ffe590000     fffffc1ffe9fffff        4544KB          fixed mappings
+  fffffc1ffea00000     fffffc1ffebfffff           2MB          [guard region]
+  fffffc1ffec00000     fffffc1fffbfffff          16MB          PCI I/O space
+  fffffc1fffc00000     fffffc1fffdfffff           2MB          [guard region]
+  fffffc1fffe00000     ffffffffffdfffff        3968GB          vmemmap
+  ffffffffffe00000     ffffffffffffffff           2MB          [guard region]
 
 
 Translation table lookup with 4KB pages::
@@ -83,7 +90,8 @@ Translation table lookup with 64KB pages::
    |                 |    |               |            [15:0]  in-page offset
    |                 |    |               +----------> [28:16] L3 index
    |                 |    +--------------------------> [41:29] L2 index
-   |                 +-------------------------------> [47:42] L1 index
+   |                 +-------------------------------> [47:42] L1 index (48-bit)
+   |                                                   [51:42] L1 index (52-bit)
    +-------------------------------------------------> [63] TTBR0/1
 
 
@@ -96,3 +104,62 @@ ARM64_HARDEN_EL2_VECTORS is selected for particular CPUs.
 
 When using KVM with the Virtualization Host Extensions, no additional
 mappings are created, since the host kernel runs directly in EL2.
+
+52-bit VA support in the kernel
+-------------------------------
+If the ARMv8.2-LVA optional feature is present, and we are running
+with a 64KB page size; then it is possible to use 52-bits of address
+space for both userspace and kernel addresses. However, any kernel
+binary that supports 52-bit must also be able to fall back to 48-bit
+at early boot time if the hardware feature is not present.
+
+This fallback mechanism necessitates the kernel .text to be in the
+higher addresses such that they are invariant to 48/52-bit VAs. Due
+to the kasan shadow being a fraction of the entire kernel VA space,
+the end of the kasan shadow must also be in the higher half of the
+kernel VA space for both 48/52-bit. (Switching from 48-bit to 52-bit,
+the end of the kasan shadow is invariant and dependent on ~0UL,
+whilst the start address will "grow" towards the lower addresses).
+
+In order to optimise phys_to_virt and virt_to_phys, the PAGE_OFFSET
+is kept constant at 0xFFF0000000000000 (corresponding to 52-bit),
+this obviates the need for an extra variable read. The physvirt
+offset and vmemmap offsets are computed at early boot to enable
+this logic.
+
+As a single binary will need to support both 48-bit and 52-bit VA
+spaces, the VMEMMAP must be sized large enough for 52-bit VAs and
+also must be sized large enought to accommodate a fixed PAGE_OFFSET.
+
+Most code in the kernel should not need to consider the VA_BITS, for
+code that does need to know the VA size the variables are
+defined as follows:
+
+VA_BITS                constant        the *maximum* VA space size
+
+VA_BITS_MIN    constant        the *minimum* VA space size
+
+vabits_actual  variable        the *actual* VA space size
+
+
+Maximum and minimum sizes can be useful to ensure that buffers are
+sized large enough or that addresses are positioned close enough for
+the "worst" case.
+
+52-bit userspace VAs
+--------------------
+To maintain compatibility with software that relies on the ARMv8.0
+VA space maximum size of 48-bits, the kernel will, by default,
+return virtual addresses to userspace from a 48-bit range.
+
+Software can "opt-in" to receiving VAs from a 52-bit space by
+specifying an mmap hint parameter that is larger than 48-bit.
+For example:
+    maybe_high_address = mmap(~0UL, size, prot, flags,...);
+
+It is also possible to build a debug kernel that returns addresses
+from a 52-bit space by enabling the following kernel config options:
+   CONFIG_EXPERT=y && CONFIG_ARM64_FORCE_52BIT=y
+
+Note that this option is only intended for debugging applications
+and should not be used in production.
diff --git a/Documentation/arm64/tagged-address-abi.rst b/Documentation/arm64/tagged-address-abi.rst
new file mode 100644 (file)
index 0000000..d4a85d5
--- /dev/null
@@ -0,0 +1,156 @@
+==========================
+AArch64 TAGGED ADDRESS ABI
+==========================
+
+Authors: Vincenzo Frascino <vincenzo.frascino@arm.com>
+         Catalin Marinas <catalin.marinas@arm.com>
+
+Date: 21 August 2019
+
+This document describes the usage and semantics of the Tagged Address
+ABI on AArch64 Linux.
+
+1. Introduction
+---------------
+
+On AArch64 the ``TCR_EL1.TBI0`` bit is set by default, allowing
+userspace (EL0) to perform memory accesses through 64-bit pointers with
+a non-zero top byte. This document describes the relaxation of the
+syscall ABI that allows userspace to pass certain tagged pointers to
+kernel syscalls.
+
+2. AArch64 Tagged Address ABI
+-----------------------------
+
+From the kernel syscall interface perspective and for the purposes of
+this document, a "valid tagged pointer" is a pointer with a potentially
+non-zero top-byte that references an address in the user process address
+space obtained in one of the following ways:
+
+- ``mmap()`` syscall where either:
+
+  - flags have the ``MAP_ANONYMOUS`` bit set or
+  - the file descriptor refers to a regular file (including those
+    returned by ``memfd_create()``) or ``/dev/zero``
+
+- ``brk()`` syscall (i.e. the heap area between the initial location of
+  the program break at process creation and its current location).
+
+- any memory mapped by the kernel in the address space of the process
+  during creation and with the same restrictions as for ``mmap()`` above
+  (e.g. data, bss, stack).
+
+The AArch64 Tagged Address ABI has two stages of relaxation depending
+how the user addresses are used by the kernel:
+
+1. User addresses not accessed by the kernel but used for address space
+   management (e.g. ``mmap()``, ``mprotect()``, ``madvise()``). The use
+   of valid tagged pointers in this context is always allowed.
+
+2. User addresses accessed by the kernel (e.g. ``write()``). This ABI
+   relaxation is disabled by default and the application thread needs to
+   explicitly enable it via ``prctl()`` as follows:
+
+   - ``PR_SET_TAGGED_ADDR_CTRL``: enable or disable the AArch64 Tagged
+     Address ABI for the calling thread.
+
+     The ``(unsigned int) arg2`` argument is a bit mask describing the
+     control mode used:
+
+     - ``PR_TAGGED_ADDR_ENABLE``: enable AArch64 Tagged Address ABI.
+       Default status is disabled.
+
+     Arguments ``arg3``, ``arg4``, and ``arg5`` must be 0.
+
+   - ``PR_GET_TAGGED_ADDR_CTRL``: get the status of the AArch64 Tagged
+     Address ABI for the calling thread.
+
+     Arguments ``arg2``, ``arg3``, ``arg4``, and ``arg5`` must be 0.
+
+   The ABI properties described above are thread-scoped, inherited on
+   clone() and fork() and cleared on exec().
+
+   Calling ``prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0)``
+   returns ``-EINVAL`` if the AArch64 Tagged Address ABI is globally
+   disabled by ``sysctl abi.tagged_addr_disabled=1``. The default
+   ``sysctl abi.tagged_addr_disabled`` configuration is 0.
+
+When the AArch64 Tagged Address ABI is enabled for a thread, the
+following behaviours are guaranteed:
+
+- All syscalls except the cases mentioned in section 3 can accept any
+  valid tagged pointer.
+
+- The syscall behaviour is undefined for invalid tagged pointers: it may
+  result in an error code being returned, a (fatal) signal being raised,
+  or other modes of failure.
+
+- The syscall behaviour for a valid tagged pointer is the same as for
+  the corresponding untagged pointer.
+
+
+A definition of the meaning of tagged pointers on AArch64 can be found
+in Documentation/arm64/tagged-pointers.rst.
+
+3. AArch64 Tagged Address ABI Exceptions
+-----------------------------------------
+
+The following system call parameters must be untagged regardless of the
+ABI relaxation:
+
+- ``prctl()`` other than pointers to user data either passed directly or
+  indirectly as arguments to be accessed by the kernel.
+
+- ``ioctl()`` other than pointers to user data either passed directly or
+  indirectly as arguments to be accessed by the kernel.
+
+- ``shmat()`` and ``shmdt()``.
+
+Any attempt to use non-zero tagged pointers may result in an error code
+being returned, a (fatal) signal being raised, or other modes of
+failure.
+
+4. Example of correct usage
+---------------------------
+.. code-block:: c
+
+   #include <stdlib.h>
+   #include <string.h>
+   #include <unistd.h>
+   #include <sys/mman.h>
+   #include <sys/prctl.h>
+   
+   #define PR_SET_TAGGED_ADDR_CTRL     55
+   #define PR_TAGGED_ADDR_ENABLE       (1UL << 0)
+   
+   #define TAG_SHIFT           56
+   
+   int main(void)
+   {
+       int tbi_enabled = 0;
+       unsigned long tag = 0;
+       char *ptr;
+   
+       /* check/enable the tagged address ABI */
+       if (!prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0))
+               tbi_enabled = 1;
+   
+       /* memory allocation */
+       ptr = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE,
+                  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+       if (ptr == MAP_FAILED)
+               return 1;
+   
+       /* set a non-zero tag if the ABI is available */
+       if (tbi_enabled)
+               tag = rand() & 0xff;
+       ptr = (char *)((unsigned long)ptr | (tag << TAG_SHIFT));
+   
+       /* memory access to a tagged address */
+       strcpy(ptr, "tagged pointer\n");
+   
+       /* syscall with a tagged pointer */
+       write(1, ptr, strlen(ptr));
+   
+       return 0;
+   }
index 2acdec3..eab4323 100644 (file)
@@ -20,7 +20,9 @@ Passing tagged addresses to the kernel
 --------------------------------------
 
 All interpretation of userspace memory addresses by the kernel assumes
-an address tag of 0x00.
+an address tag of 0x00, unless the application enables the AArch64
+Tagged Address ABI explicitly
+(Documentation/arm64/tagged-address-abi.rst).
 
 This includes, but is not limited to, addresses found in:
 
@@ -33,13 +35,15 @@ This includes, but is not limited to, addresses found in:
  - the frame pointer (x29) and frame records, e.g. when interpreting
    them to generate a backtrace or call graph.
 
-Using non-zero address tags in any of these locations may result in an
-error code being returned, a (fatal) signal being raised, or other modes
-of failure.
+Using non-zero address tags in any of these locations when the
+userspace application did not enable the AArch64 Tagged Address ABI may
+result in an error code being returned, a (fatal) signal being raised,
+or other modes of failure.
 
-For these reasons, passing non-zero address tags to the kernel via
-system calls is forbidden, and using a non-zero address tag for sp is
-strongly discouraged.
+For these reasons, when the AArch64 Tagged Address ABI is disabled,
+passing non-zero address tags to the kernel via system calls is
+forbidden, and using a non-zero address tag for sp is strongly
+discouraged.
 
 Programs maintaining a frame pointer and frame records that use non-zero
 address tags may suffer impaired or inaccurate debug and profiling
@@ -59,6 +63,9 @@ be preserved.
 The architecture prevents the use of a tagged PC, so the upper byte will
 be set to a sign-extension of bit 55 on exception return.
 
+This behaviour is maintained when the AArch64 Tagged Address ABI is
+enabled.
+
 
 Other considerations
 --------------------
index 325c6fd..99015ce 100644 (file)
@@ -91,13 +91,11 @@ properties:
       - description: Boards with the Amlogic Meson GXL S905X SoC
         items:
           - enum:
-              - amediatech,x96-max
               - amlogic,p212
               - hwacom,amazetv
               - khadas,vim
               - libretech,cc
               - nexbox,a95x
-              - seirobotics,sei510
           - const: amlogic,s905x
           - const: amlogic,meson-gxl
 
@@ -129,16 +127,33 @@ properties:
           - const: amlogic,a113d
           - const: amlogic,meson-axg
 
-      - description: Boards with the Amlogic Meson G12A S905D2 SoC
+      - description: Boards with the Amlogic Meson G12A S905D2/X2/Y2 SoC
         items:
           - enum:
+              - amediatech,x96-max
               - amlogic,u200
+              - seirobotics,sei510
           - const: amlogic,g12a
 
+      - description: Boards with the Amlogic Meson G12B A311D SoC
+        items:
+          - enum:
+              - khadas,vim3
+          - const: amlogic,a311d
+          - const: amlogic,g12b
+
       - description: Boards with the Amlogic Meson G12B S922X SoC
         items:
           - enum:
               - hardkernel,odroid-n2
+              - khadas,vim3
+          - const: amlogic,s922x
           - const: amlogic,g12b
 
+      - description: Boards with the Amlogic Meson SM1 S905X3/D3/Y3 SoC
+        items:
+          - enum:
+              - seirobotics,sei610
+              - khadas,vim3l
+          - const: amlogic,sm1
 ...
index 317a2fc..083dbf9 100644 (file)
@@ -73,6 +73,16 @@ Required properties:
                         as used by the firmware. Refer to  platform details
                         for your implementation for the IDs to use.
 
+Reset signal bindings for the reset domains based on SCMI Message Protocol
+------------------------------------------------------------
+
+This binding for the SCMI reset domain providers uses the generic reset
+signal binding[5].
+
+Required properties:
+ - #reset-cells : Should be 1. Contains the reset domain ID value used
+                 by SCMI commands.
+
 SRAM and Shared Memory for SCMI
 -------------------------------
 
@@ -93,6 +103,7 @@ Required sub-node properties:
 [2] Documentation/devicetree/bindings/power/power_domain.txt
 [3] Documentation/devicetree/bindings/thermal/thermal.txt
 [4] Documentation/devicetree/bindings/sram/sram.txt
+[5] Documentation/devicetree/bindings/reset/reset.txt
 
 Example:
 
@@ -152,6 +163,11 @@ firmware {
                        reg = <0x15>;
                        #thermal-sensor-cells = <1>;
                };
+
+               scmi_reset: protocol@16 {
+                       reg = <0x16>;
+                       #reset-cells = <1>;
+               };
        };
 };
 
@@ -166,6 +182,7 @@ hdlcd@7ff60000 {
        reg = <0 0x7ff60000 0 0x1000>;
        clocks = <&scmi_clk 4>;
        power-domains = <&scmi_devpd 1>;
+       resets = <&scmi_reset 10>;
 };
 
 thermal-zones {
index aa40b07..727e0ff 100644 (file)
@@ -175,6 +175,7 @@ properties:
               - amlogic,meson8-smp
               - amlogic,meson8b-smp
               - arm,realview-smp
+              - aspeed,ast2600-smp
               - brcm,bcm11351-cpu-method
               - brcm,bcm23550
               - brcm,bcm2836-smp
index 7294ac3..1b4b4e6 100644 (file)
@@ -161,6 +161,20 @@ properties:
         items:
           - enum:
               - fsl,imx6ul-14x14-evk      # i.MX6 UltraLite 14x14 EVK Board
+              - kontron,imx6ul-n6310-som  # Kontron N6310 SOM
+          - const: fsl,imx6ul
+
+      - description: Kontron N6310 S Board
+        items:
+          - const: kontron,imx6ul-n6310-s
+          - const: kontron,imx6ul-n6310-som
+          - const: fsl,imx6ul
+
+      - description: Kontron N6310 S 43 Board
+        items:
+          - const: kontron,imx6ul-n6310-s-43
+          - const: kontron,imx6ul-n6310-s
+          - const: kontron,imx6ul-n6310-som
           - const: fsl,imx6ul
 
       - description: i.MX6ULL based Boards
@@ -188,6 +202,7 @@ properties:
               - fsl,imx7d-sdb             # i.MX7 SabreSD Board
               - novtech,imx7d-meerkat96   # i.MX7 Meerkat96 Board
               - tq,imx7d-mba7             # i.MX7D TQ MBa7 with TQMa7D SoM
+              - zii,imx7d-rmu2            # ZII RMU2 Board
               - zii,imx7d-rpu2            # ZII RPU2 Board
           - const: fsl,imx7d
 
@@ -214,16 +229,26 @@ properties:
               - fsl,imx8mm-evk            # i.MX8MM EVK Board
           - const: fsl,imx8mm
 
+      - description: i.MX8MN based Boards
+        items:
+          - enum:
+              - fsl,imx8mn-ddr4-evk       # i.MX8MN DDR4 EVK Board
+          - const: fsl,imx8mn
+
       - description: i.MX8MQ based Boards
         items:
           - enum:
+              - boundary,imx8mq-nitrogen8m # i.MX8MQ NITROGEN Board
               - fsl,imx8mq-evk            # i.MX8MQ EVK Board
               - purism,librem5-devkit     # Purism Librem5 devkit
+              - solidrun,hummingboard-pulse # SolidRun Hummingboard Pulse
+              - technexion,pico-pi-imx8m  # TechNexion PICO-PI-8M evk
           - const: fsl,imx8mq
 
       - description: i.MX8QXP based Boards
         items:
           - enum:
+              - einfochips,imx8qxp-ai_ml  # i.MX8QXP AI_ML Board
               - fsl,imx8qxp-mek           # i.MX8QXP MEK Board
           - const: fsl,imx8qxp
 
@@ -283,6 +308,7 @@ properties:
       - description: LS1046A based Boards
         items:
           - enum:
+              - fsl,ls1046a-frwy
               - fsl,ls1046a-qds
               - fsl,ls1046a-rdb
           - const: fsl,ls1046a
index a4ad2eb..4043c50 100644 (file)
@@ -48,6 +48,10 @@ properties:
           - const: mediatek,mt6765
       - items:
           - enum:
+              - mediatek,mt6779-evb
+          - const: mediatek,mt6779
+      - items:
+          - enum:
               - mediatek,mt6795-evb
           - const: mediatek,mt6795
       - items:
index 54ef6b6..e39d8f0 100644 (file)
@@ -45,6 +45,7 @@ description: |
        mtp
        sbc
        hk01
+       qrd
 
   The 'soc_version' and 'board_version' elements take the form of v<Major>.<Minor>
   where the minor number may be omitted when it's zero, i.e.  v1.0 is the same
@@ -116,6 +117,13 @@ properties:
           - const: qcom,msm8916
 
       - items:
+          - enum:
+              - longcheer,l8150
+              - samsung,a3u-eur
+              - samsung,a5u-eur
+          - const: qcom,msm8916
+
+      - items:
           - const: qcom,msm8996-mtp
 
       - items:
index 3486504..c82c5e5 100644 (file)
@@ -128,6 +128,21 @@ properties:
           - const: google,veyron
           - const: rockchip,rk3288
 
+      - description: Google Fievel (AOPEN Chromebox Mini)
+        items:
+          - const: google,veyron-fievel-rev8
+          - const: google,veyron-fievel-rev7
+          - const: google,veyron-fievel-rev6
+          - const: google,veyron-fievel-rev5
+          - const: google,veyron-fievel-rev4
+          - const: google,veyron-fievel-rev3
+          - const: google,veyron-fievel-rev2
+          - const: google,veyron-fievel-rev1
+          - const: google,veyron-fievel-rev0
+          - const: google,veyron-fievel
+          - const: google,veyron
+          - const: rockchip,rk3288
+
       - description: Google Gru (dev-board)
         items:
           - const: google,gru-rev15
@@ -311,6 +326,21 @@ properties:
           - const: google,veyron
           - const: rockchip,rk3288
 
+      - description: Google Tiger (AOpen Chromebase Mini)
+        items:
+          - const: google,veyron-tiger-rev8
+          - const: google,veyron-tiger-rev7
+          - const: google,veyron-tiger-rev6
+          - const: google,veyron-tiger-rev5
+          - const: google,veyron-tiger-rev4
+          - const: google,veyron-tiger-rev3
+          - const: google,veyron-tiger-rev2
+          - const: google,veyron-tiger-rev1
+          - const: google,veyron-tiger-rev0
+          - const: google,veyron-tiger
+          - const: google,veyron
+          - const: rockchip,rk3288
+
       - description: Haoyu MarsBoard RK3066
         items:
           - const: haoyu,marsboard-rk3066
@@ -329,6 +359,16 @@ properties:
               - khadas,edge-v
           - const: rockchip,rk3399
 
+      - description: Mecer Xtreme Mini S6
+        items:
+          - const: mecer,xms6
+          - const: rockchip,rk3229
+
+      - description: Leez RK3399 P710
+        items:
+          - const: leez,p710
+          - const: rockchip,rk3399
+
       - description: mqmaker MiQi
         items:
           - const: mqmaker,miqi
@@ -424,11 +464,6 @@ properties:
               - rockchip,rk3288-evb-rk808
           - const: rockchip,rk3288
 
-      - description: Rockchip RK3288 Fennec
-        items:
-          - const: rockchip,rk3288-fennec
-          - const: rockchip,rk3288
-
       - description: Rockchip RK3328 Evaluation board
         items:
           - const: rockchip,rk3328-evb
index 000a00d..972b1e9 100644 (file)
@@ -353,6 +353,12 @@ properties:
           - const: licheepi,licheepi-zero
           - const: allwinner,sun8i-v3s
 
+      - description: Lichee Zero Plus (with S3, without eMMC/SPI Flash)
+        items:
+          - const: sipeed,lichee-zero-plus
+          - const: sochip,s3
+          - const: allwinner,sun8i-v3
+
       - description: Linksprite PCDuino
         items:
           - const: linksprite,a10-pcduino
@@ -568,6 +574,11 @@ properties:
           - const: olimex,a64-olinuxino
           - const: allwinner,sun50i-a64
 
+      - description: Olimex A64-OlinuXino (with eMMC)
+        items:
+          - const: olimex,a64-olinuxino-emmc
+          - const: allwinner,sun50i-a64
+
       - description: Olimex A64 Teres-I
         items:
           - const: olimex,a64-teres-i
@@ -671,6 +682,11 @@ properties:
           - const: sinlinx,sina33
           - const: allwinner,sun8i-a33
 
+      - description: Tanix TX6
+        items:
+          - const: oranth,tanix-tx6
+          - const: allwinner,sun50i-h6
+
       - description: TBS A711 Tablet
         items:
           - const: tbs-biometrics,a711
index dda7d6d..1b1d1c5 100644 (file)
@@ -44,6 +44,10 @@ Optional properties:
                        what bootloader sets up in IOMUXC_GPR1[11:0] will be
                        used.
 
+ - fsl,burst-clk-enable        For "fsl,imx50-weim" and "fsl,imx6q-weim" type of
+                       devices, the presence of this property indicates that
+                       the weim bus should operate in Burst Clock Mode.
+
 Timing property for child nodes. It is mandatory, not optional.
 
  - fsl,weim-cs-timing: The timing array, contains timing values for the
diff --git a/Documentation/devicetree/bindings/bus/moxtet.txt b/Documentation/devicetree/bindings/bus/moxtet.txt
new file mode 100644 (file)
index 0000000..fb50fc8
--- /dev/null
@@ -0,0 +1,46 @@
+Turris Mox module status and configuration bus (over SPI)
+
+Required properties:
+ - compatible          : Should be "cznic,moxtet"
+ - #address-cells      : Has to be 1
+ - #size-cells         : Has to be 0
+ - spi-cpol            : Required inverted clock polarity
+ - spi-cpha            : Required shifted clock phase
+ - interrupts          : Must contain reference to the shared interrupt line
+ - interrupt-controller        : Required
+ - #interrupt-cells    : Has to be 1
+
+For other required and optional properties of SPI slave nodes please refer to
+../spi/spi-bus.txt.
+
+Required properties of subnodes:
+ - reg                 : Should be position on the Moxtet bus (how many Moxtet
+                         modules are between this module and CPU module, so
+                         either 0 or a positive integer)
+
+The driver finds the devices connected to the bus by itself, but it may be
+needed to reference some of them from other parts of the device tree. In that
+case the devices can be defined as subnodes of the moxtet node.
+
+Example:
+
+       moxtet@1 {
+               compatible = "cznic,moxtet";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <1>;
+               spi-max-frequency = <10000000>;
+               spi-cpol;
+               spi-cpha;
+               interrupt-controller;
+               #interrupt-cells = <1>;
+               interrupt-parent = <&gpiosb>;
+               interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+
+               moxtet_sfp: gpio@0 {
+                       compatible = "cznic,moxtet-gpio";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       reg = <0>;
+               }
+       };
index 0f77774..b3957d1 100644 (file)
@@ -22,6 +22,7 @@ Required Properties:
                                       components.
 - resets       : phandle of the internal reset line
 - #clock-cells : should be 1.
+- #reset-cells  : should be 1 on the g12a (and following) soc family
 
 Each clock is assigned an identifier and client nodes can use this identifier
 to specify the clock which they consume. All available clocks are defined as
index 6eaa520..7ccecd5 100644 (file)
@@ -11,6 +11,7 @@ Required Properties:
                "amlogic,axg-clkc" for AXG SoC.
                "amlogic,g12a-clkc" for G12A SoC.
                "amlogic,g12b-clkc" for G12B SoC.
+               "amlogic,sm1-clkc" for SM1 SoC.
 - clocks : list of clock phandle, one for each entry clock-names.
 - clock-names : should contain the following:
   * "xtal": the platform xtal
diff --git a/Documentation/devicetree/bindings/clock/imx8mn-clock.yaml b/Documentation/devicetree/bindings/clock/imx8mn-clock.yaml
new file mode 100644 (file)
index 0000000..622f365
--- /dev/null
@@ -0,0 +1,112 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bindings/clock/imx8mn-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX8M Nano Clock Control Module Binding
+
+maintainers:
+  - Anson Huang <Anson.Huang@nxp.com>
+
+description: |
+  NXP i.MX8M Nano clock control module is an integrated clock controller, which
+  generates and supplies to all modules.
+
+properties:
+  compatible:
+    const: fsl,imx8mn-ccm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: 32k osc
+      - description: 24m osc
+      - description: ext1 clock input
+      - description: ext2 clock input
+      - description: ext3 clock input
+      - description: ext4 clock input
+
+  clock-names:
+    items:
+      - const: osc_32k
+      - const: osc_24m
+      - const: clk_ext1
+      - const: clk_ext2
+      - const: clk_ext3
+      - const: clk_ext4
+
+  '#clock-cells':
+    const: 1
+    description: |
+      The clock consumer should specify the desired clock by having the clock
+      ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8mn-clock.h
+      for the full list of i.MX8M Nano clock IDs.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+
+examples:
+  # Clock Control Module node:
+  - |
+    clk: clock-controller@30380000 {
+        compatible = "fsl,imx8mn-ccm";
+        reg = <0x0 0x30380000 0x0 0x10000>;
+        #clock-cells = <1>;
+        clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>,
+                 <&clk_ext2>, <&clk_ext3>, <&clk_ext4>;
+        clock-names = "osc_32k", "osc_24m", "clk_ext1",
+                      "clk_ext2", "clk_ext3", "clk_ext4";
+    };
+
+  # Required external clocks for Clock Control Module node:
+  - |
+    osc_32k: clock-osc-32k {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <32768>;
+        clock-output-names = "osc_32k";
+    };
+
+    osc_24m: clock-osc-24m {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <24000000>;
+        clock-output-names = "osc_24m";
+    };
+
+    clk_ext1: clock-ext1 {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <133000000>;
+        clock-output-names = "clk_ext1";
+    };
+
+    clk_ext2: clock-ext2 {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <133000000>;
+        clock-output-names = "clk_ext2";
+    };
+
+    clk_ext3: clock-ext3 {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency = <133000000>;
+        clock-output-names = "clk_ext3";
+    };
+
+    clk_ext4: clock-ext4 {
+        compatible = "fixed-clock";
+        #clock-cells = <0>;
+        clock-frequency= <133000000>;
+        clock-output-names = "clk_ext4";
+    };
+
+...
@@ -1,21 +1,19 @@
 ===========================================
-ARM topology binding description
+CPU topology binding description
 ===========================================
 
 ===========================================
 1 - Introduction
 ===========================================
 
-In an ARM system, the hierarchy of CPUs is defined through three entities that
+In a SMP system, the hierarchy of CPUs is defined through three entities that
 are used to describe the layout of physical CPUs in the system:
 
+- socket
 - cluster
 - core
 - thread
 
-The cpu nodes (bindings defined in [1]) represent the devices that
-correspond to physical CPUs and are to be mapped to the hierarchy levels.
-
 The bottom hierarchy level sits at core or thread level depending on whether
 symmetric multi-threading (SMT) is supported or not.
 
@@ -24,33 +22,31 @@ threads existing in the system and map to the hierarchy level "thread" above.
 In systems where SMT is not supported "cpu" nodes represent all cores present
 in the system and map to the hierarchy level "core" above.
 
-ARM topology bindings allow one to associate cpu nodes with hierarchical groups
+CPU topology bindings allow one to associate cpu nodes with hierarchical groups
 corresponding to the system hierarchy; syntactically they are defined as device
 tree nodes.
 
-The remainder of this document provides the topology bindings for ARM, based
-on the Devicetree Specification, available from:
+Currently, only ARM/RISC-V intend to use this cpu topology binding but it may be
+used for any other architecture as well.
 
-https://www.devicetree.org/specifications/
+The cpu nodes, as per bindings defined in [4], represent the devices that
+correspond to physical CPUs and are to be mapped to the hierarchy levels.
 
-If not stated otherwise, whenever a reference to a cpu node phandle is made its
-value must point to a cpu node compliant with the cpu node bindings as
-documented in [1].
 A topology description containing phandles to cpu nodes that are not compliant
-with bindings standardized in [1] is therefore considered invalid.
+with bindings standardized in [4] is therefore considered invalid.
 
 ===========================================
 2 - cpu-map node
 ===========================================
 
-The ARM CPU topology is defined within the cpu-map node, which is a direct
+The ARM/RISC-V CPU topology is defined within the cpu-map node, which is a direct
 child of the cpus node and provides a container where the actual topology
 nodes are listed.
 
 - cpu-map node
 
-       Usage: Optional - On ARM SMP systems provide CPUs topology to the OS.
-                         ARM uniprocessor systems do not require a topology
+       Usage: Optional - On SMP systems provide CPUs topology to the OS.
+                         Uniprocessor systems do not require a topology
                          description and therefore should not define a
                          cpu-map node.
 
@@ -63,21 +59,23 @@ nodes are listed.
 
        The cpu-map node's child nodes can be:
 
-       - one or more cluster nodes
+       - one or more cluster nodes or
+       - one or more socket nodes in a multi-socket system
 
        Any other configuration is considered invalid.
 
-The cpu-map node can only contain three types of child nodes:
+The cpu-map node can only contain 4 types of child nodes:
 
+- socket node
 - cluster node
 - core node
 - thread node
 
 whose bindings are described in paragraph 3.
 
-The nodes describing the CPU topology (cluster/core/thread) can only
-be defined within the cpu-map node and every core/thread in the system
-must be defined within the topology.  Any other configuration is
+The nodes describing the CPU topology (socket/cluster/core/thread) can
+only be defined within the cpu-map node and every core/thread in the
+system must be defined within the topology.  Any other configuration is
 invalid and therefore must be ignored.
 
 ===========================================
@@ -85,26 +83,44 @@ invalid and therefore must be ignored.
 ===========================================
 
 cpu-map child nodes must follow a naming convention where the node name
-must be "clusterN", "coreN", "threadN" depending on the node type (ie
-cluster/core/thread) (where N = {0, 1, ...} is the node number; nodes which
-are siblings within a single common parent node must be given a unique and
+must be "socketN", "clusterN", "coreN", "threadN" depending on the node type
+(ie socket/cluster/core/thread) (where N = {0, 1, ...} is the node number; nodes
+which are siblings within a single common parent node must be given a unique and
 sequential N value, starting from 0).
 cpu-map child nodes which do not share a common parent node can have the same
 name (ie same number N as other cpu-map child nodes at different device tree
 levels) since name uniqueness will be guaranteed by the device tree hierarchy.
 
 ===========================================
-3 - cluster/core/thread node bindings
+3 - socket/cluster/core/thread node bindings
 ===========================================
 
-Bindings for cluster/cpu/thread nodes are defined as follows:
+Bindings for socket/cluster/cpu/thread nodes are defined as follows:
+
+- socket node
+
+        Description: must be declared within a cpu-map node, one node
+                     per physical socket in the system. A system can
+                     contain single or multiple physical socket.
+                     The association of sockets and NUMA nodes is beyond
+                     the scope of this bindings, please refer [2] for
+                     NUMA bindings.
+
+       This node is optional for a single socket system.
+
+       The socket node name must be "socketN" as described in 2.1 above.
+       A socket node can not be a leaf node.
+
+       A socket node's child nodes must be one or more cluster nodes.
+
+       Any other configuration is considered invalid.
 
 - cluster node
 
         Description: must be declared within a cpu-map node, one node
                      per cluster. A system can contain several layers of
-                     clustering and cluster nodes can be contained in parent
-                     cluster nodes.
+                     clustering within a single physical socket and cluster
+                     nodes can be contained in parent cluster nodes.
 
        The cluster node name must be "clusterN" as described in 2.1 above.
        A cluster node can not be a leaf node.
@@ -164,90 +180,93 @@ Bindings for cluster/cpu/thread nodes are defined as follows:
 4 - Example dts
 ===========================================
 
-Example 1 (ARM 64-bit, 16-cpu system, two clusters of clusters):
+Example 1 (ARM 64-bit, 16-cpu system, two clusters of clusters in a single
+physical socket):
 
 cpus {
        #size-cells = <0>;
        #address-cells = <2>;
 
        cpu-map {
-               cluster0 {
+               socket0 {
                        cluster0 {
-                               core0 {
-                                       thread0 {
-                                               cpu = <&CPU0>;
+                               cluster0 {
+                                       core0 {
+                                               thread0 {
+                                                       cpu = <&CPU0>;
+                                               };
+                                               thread1 {
+                                                       cpu = <&CPU1>;
+                                               };
                                        };
-                                       thread1 {
-                                               cpu = <&CPU1>;
-                                       };
-                               };
 
-                               core1 {
-                                       thread0 {
-                                               cpu = <&CPU2>;
-                                       };
-                                       thread1 {
-                                               cpu = <&CPU3>;
+                                       core1 {
+                                               thread0 {
+                                                       cpu = <&CPU2>;
+                                               };
+                                               thread1 {
+                                                       cpu = <&CPU3>;
+                                               };
                                        };
                                };
-                       };
 
-                       cluster1 {
-                               core0 {
-                                       thread0 {
-                                               cpu = <&CPU4>;
-                                       };
-                                       thread1 {
-                                               cpu = <&CPU5>;
+                               cluster1 {
+                                       core0 {
+                                               thread0 {
+                                                       cpu = <&CPU4>;
+                                               };
+                                               thread1 {
+                                                       cpu = <&CPU5>;
+                                               };
                                        };
-                               };
 
-                               core1 {
-                                       thread0 {
-                                               cpu = <&CPU6>;
-                                       };
-                                       thread1 {
-                                               cpu = <&CPU7>;
-                                       };
-                               };
-                       };
-               };
-
-               cluster1 {
-                       cluster0 {
-                               core0 {
-                                       thread0 {
-                                               cpu = <&CPU8>;
-                                       };
-                                       thread1 {
-                                               cpu = <&CPU9>;
-                                       };
-                               };
-                               core1 {
-                                       thread0 {
-                                               cpu = <&CPU10>;
-                                       };
-                                       thread1 {
-                                               cpu = <&CPU11>;
+                                       core1 {
+                                               thread0 {
+                                                       cpu = <&CPU6>;
+                                               };
+                                               thread1 {
+                                                       cpu = <&CPU7>;
+                                               };
                                        };
                                };
                        };
 
                        cluster1 {
-                               core0 {
-                                       thread0 {
-                                               cpu = <&CPU12>;
+                               cluster0 {
+                                       core0 {
+                                               thread0 {
+                                                       cpu = <&CPU8>;
+                                               };
+                                               thread1 {
+                                                       cpu = <&CPU9>;
+                                               };
                                        };
-                                       thread1 {
-                                               cpu = <&CPU13>;
+                                       core1 {
+                                               thread0 {
+                                                       cpu = <&CPU10>;
+                                               };
+                                               thread1 {
+                                                       cpu = <&CPU11>;
+                                               };
                                        };
                                };
-                               core1 {
-                                       thread0 {
-                                               cpu = <&CPU14>;
+
+                               cluster1 {
+                                       core0 {
+                                               thread0 {
+                                                       cpu = <&CPU12>;
+                                               };
+                                               thread1 {
+                                                       cpu = <&CPU13>;
+                                               };
                                        };
-                                       thread1 {
-                                               cpu = <&CPU15>;
+                                       core1 {
+                                               thread0 {
+                                                       cpu = <&CPU14>;
+                                               };
+                                               thread1 {
+                                                       cpu = <&CPU15>;
+                                               };
                                        };
                                };
                        };
@@ -470,6 +489,65 @@ cpus {
        };
 };
 
+Example 3: HiFive Unleashed (RISC-V 64 bit, 4 core system)
+
+{
+       #address-cells = <2>;
+       #size-cells = <2>;
+       compatible = "sifive,fu540g", "sifive,fu500";
+       model = "sifive,hifive-unleashed-a00";
+
+       ...
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               cpu-map {
+                       socket0 {
+                               cluster0 {
+                                       core0 {
+                                               cpu = <&CPU1>;
+                                       };
+                                       core1 {
+                                               cpu = <&CPU2>;
+                                       };
+                                       core2 {
+                                               cpu0 = <&CPU2>;
+                                       };
+                                       core3 {
+                                               cpu0 = <&CPU3>;
+                                       };
+                               };
+                       };
+               };
+
+               CPU1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "sifive,rocket0", "riscv";
+                       reg = <0x1>;
+               }
+
+               CPU2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "sifive,rocket0", "riscv";
+                       reg = <0x2>;
+               }
+               CPU3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "sifive,rocket0", "riscv";
+                       reg = <0x3>;
+               }
+               CPU4: cpu@4 {
+                       device_type = "cpu";
+                       compatible = "sifive,rocket0", "riscv";
+                       reg = <0x4>;
+               }
+       }
+};
 ===============================================================================
 [1] ARM Linux kernel documentation
     Documentation/devicetree/bindings/arm/cpus.yaml
+[2] Devicetree NUMA binding description
+    Documentation/devicetree/bindings/numa.txt
+[3] RISC-V Linux kernel documentation
+    Documentation/devicetree/bindings/riscv/cpus.txt
+[4] https://www.devicetree.org/specifications/
index b3bde97..42577dd 100644 (file)
@@ -3,6 +3,7 @@ EEPROMs (SPI) compatible with Atmel at25.
 Required properties:
 - compatible : Should be "<vendor>,<type>", and generic value "atmel,at25".
   Example "<vendor>,<type>" values:
+    "anvo,anv32e61w"
     "microchip,25lc040"
     "st,m95m02"
     "st,m95256"
diff --git a/Documentation/devicetree/bindings/firmware/cznic,turris-mox-rwtm.txt b/Documentation/devicetree/bindings/firmware/cznic,turris-mox-rwtm.txt
new file mode 100644 (file)
index 0000000..338169d
--- /dev/null
@@ -0,0 +1,19 @@
+Turris Mox rWTM firmware driver
+
+Required properties:
+ - compatible          : Should be "cznic,turris-mox-rwtm"
+ - mboxes              : Must contain a reference to associated mailbox
+
+This device tree node should be used on Turris Mox, or potentially another A3700
+compatible device running the Mox's rWTM firmware in the secure processor (for
+example it is possible to flash this firmware into EspressoBin).
+
+Example:
+
+       firmware {
+               turris-mox-rwtm {
+                       compatible = "cznic,turris-mox-rwtm";
+                       mboxes = <&rwtm 0>;
+                       status = "okay";
+               };
+       };
index 41f133a..3f29ea0 100644 (file)
@@ -9,14 +9,16 @@ Required properties:
 - compatible: must contain one of the following:
  * "qcom,scm-apq8064"
  * "qcom,scm-apq8084"
+ * "qcom,scm-ipq4019"
  * "qcom,scm-msm8660"
  * "qcom,scm-msm8916"
  * "qcom,scm-msm8960"
  * "qcom,scm-msm8974"
  * "qcom,scm-msm8996"
  * "qcom,scm-msm8998"
- * "qcom,scm-ipq4019"
+ * "qcom,scm-sc7180"
  * "qcom,scm-sdm845"
+ * "qcom,scm-sm8150"
  and:
  * "qcom,scm"
 - clocks: Specifies clocks needed by the SCM interface, if any:
index 7e9b586..b2033fc 100644 (file)
@@ -2,7 +2,8 @@ Aspeed GPIO controller Device Tree Bindings
 -------------------------------------------
 
 Required properties:
-- compatible           : Either "aspeed,ast2400-gpio" or "aspeed,ast2500-gpio"
+- compatible           : Either "aspeed,ast2400-gpio", "aspeed,ast2500-gpio",
+                                       or "aspeed,ast2600-gpio".
 
 - #gpio-cells          : Should be two
                          - First cell is the GPIO line number
@@ -17,7 +18,9 @@ Required properties:
 
 Optional properties:
 
-- clocks                : A phandle to the clock to use for debounce timings
+- clocks               : A phandle to the clock to use for debounce timings
+- ngpios               : Number of GPIOs controlled by this controller. Should be set
+                                 when there are multiple GPIO controllers on a SoC (ast2600).
 
 The gpio and interrupt properties are further described in their respective
 bindings documentation:
index bc6b4b6..cd91d61 100644 (file)
@@ -6,6 +6,7 @@ Required Properties:
                                                66AK2E SoCs
                        "ti,k2g-gpio", "ti,keystone-gpio": for 66AK2G
                        "ti,am654-gpio", "ti,keystone-gpio": for TI K3 AM654
+                       "ti,j721e-gpio", "ti,keystone-gpio": for J721E SoCs
 
 - reg: Physical base address of the controller and the size of memory mapped
        registers.
diff --git a/Documentation/devicetree/bindings/gpio/gpio-moxtet.txt b/Documentation/devicetree/bindings/gpio/gpio-moxtet.txt
new file mode 100644 (file)
index 0000000..410759d
--- /dev/null
@@ -0,0 +1,18 @@
+Turris Mox Moxtet GPIO expander via Moxtet bus
+
+Required properties:
+ - compatible          : Should be "cznic,moxtet-gpio".
+ - gpio-controller     : Marks the device node as a GPIO controller.
+ - #gpio-cells         : Should be two. For consumer use see gpio.txt.
+
+Other properties are required for a Moxtet bus device, please refer to
+Documentation/devicetree/bindings/bus/moxtet.txt.
+
+Example:
+
+       moxtet_sfp: gpio@0 {
+               compatible = "cznic,moxtet-gpio";
+               gpio-controller;
+               #gpio-cells = <2>;
+               reg = <0>;
+       }
index 69d4616..cd28e93 100644 (file)
@@ -4,7 +4,7 @@ Required properties:
 - compatible : Should be "fsl,<soc>-gpio"
   The following <soc>s are known to be supported:
        mpc5121, mpc5125, mpc8349, mpc8572, mpc8610, pq3, qoriq,
-       ls1021a, ls1043a, ls2080a.
+       ls1021a, ls1043a, ls2080a, ls1028a, ls1088a.
 - reg : Address and length of the register set for the device
 - interrupts : Should be the port interrupt shared by all 32 pins.
 - #gpio-cells : Should be two.  The first cell is the pin number and
@@ -37,3 +37,17 @@ gpio0: gpio@2300000 {
        interrupt-controller;
        #interrupt-cells = <2>;
 };
+
+
+Example of gpio-controller node for a ls1028a/ls1088a SoC:
+
+gpio1: gpio@2300000 {
+       compatible = "fsl,ls1028a-gpio", "fsl,ls1088a-gpio", "fsl,qoriq-gpio";
+       reg = <0x0 0x2300000 0x0 0x10000>;
+       interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+       gpio-controller;
+       #gpio-cells = <2>;
+       interrupt-controller;
+       #interrupt-cells = <2>;
+       little-endian;
+};
diff --git a/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt b/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
new file mode 100644 (file)
index 0000000..d4d8391
--- /dev/null
@@ -0,0 +1,45 @@
+Aspeed SGPIO controller Device Tree Bindings
+--------------------------------------------
+
+This SGPIO controller is for ASPEED AST2500 SoC, it supports up to 80 full
+featured Serial GPIOs. Each of the Serial GPIO pins can be programmed to
+support the following options:
+- Support interrupt option for each input port and various interrupt
+  sensitivity option (level-high, level-low, edge-high, edge-low)
+- Support reset tolerance option for each output port
+- Directly connected to APB bus and its shift clock is from APB bus clock
+  divided by a programmable value.
+- Co-work with external signal-chained TTL components (74LV165/74LV595)
+
+Required properties:
+
+- compatible : Should be one of
+  "aspeed,ast2400-sgpio", "aspeed,ast2500-sgpio"
+- #gpio-cells : Should be 2, see gpio.txt
+- reg : Address and length of the register set for the device
+- gpio-controller : Marks the device node as a GPIO controller
+- interrupts : Interrupt specifier, see interrupt-controller/interrupts.txt
+- interrupt-controller : Mark the GPIO controller as an interrupt-controller
+- ngpios : number of GPIO lines, see gpio.txt
+  (should be multiple of 8, up to 80 pins)
+- clocks : A phandle to the APB clock for SGPM clock division
+- bus-frequency : SGPM CLK frequency
+
+The sgpio and interrupt properties are further described in their respective
+bindings documentation:
+
+- Documentation/devicetree/bindings/gpio/gpio.txt
+- Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+  Example:
+       sgpio: sgpio@1e780200 {
+               #gpio-cells = <2>;
+               compatible = "aspeed,ast2500-sgpio";
+               gpio-controller;
+               interrupts = <40>;
+               reg = <0x1e780200 0x0100>;
+               clocks = <&syscon ASPEED_CLK_APB>;
+               interrupt-controller;
+               ngpios = <8>;
+               bus-frequency = <12000000>;
+       };
diff --git a/Documentation/devicetree/bindings/hwmon/as370.txt b/Documentation/devicetree/bindings/hwmon/as370.txt
new file mode 100644 (file)
index 0000000..d102fe7
--- /dev/null
@@ -0,0 +1,11 @@
+Bindings for Synaptics AS370 PVT sensors
+
+Required properties:
+- compatible : "syna,as370-hwmon"
+- reg        : address and length of the register set.
+
+Example:
+       hwmon@ea0810 {
+               compatible = "syna,as370-hwmon";
+               reg = <0xea0810 0xc>;
+       };
index f68a0a6..1036f65 100644 (file)
@@ -1,8 +1,10 @@
-Device-tree bindings for IBM Common Form Factor Power Supply Version 1
-----------------------------------------------------------------------
+Device-tree bindings for IBM Common Form Factor Power Supply Versions 1 and 2
+-----------------------------------------------------------------------------
 
 Required properties:
- - compatible = "ibm,cffps1";
+ - compatible                          : Must be one of the following:
+                                               "ibm,cffps1"
+                                               "ibm,cffps2"
  - reg = < I2C bus address >;          : Address of the power supply on the
                                          I2C bus.
 
index 586b5ed..2736167 100644 (file)
@@ -15,6 +15,7 @@ Required properties:
                "maxim,max31725",
                "maxim,max31726",
                "maxim,mcp980x",
+               "nxp,pct2075",
                "st,stds75",
                "st,stlm75",
                "microchip,tcn75",
index 001f2b7..c779000 100644 (file)
@@ -26,6 +26,9 @@ properties:
       - items:
           - const: allwinner,sun50i-a64-i2c
           - const: allwinner,sun6i-a31-i2c
+      - items:
+          - const: allwinner,sun50i-h6-i2c
+          - const: allwinner,sun6i-a31-i2c
 
       - const: marvell,mv64xxx-i2c
       - const: marvell,mv78230-i2c
diff --git a/Documentation/devicetree/bindings/iio/adc/allwinner,sun8i-a33-ths.yaml b/Documentation/devicetree/bindings/iio/adc/allwinner,sun8i-a33-ths.yaml
new file mode 100644 (file)
index 0000000..d74962c
--- /dev/null
@@ -0,0 +1,43 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/iio/adc/allwinner,sun8i-a33-ths.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A33 Thermal Sensor Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <maxime.ripard@bootlin.com>
+
+properties:
+  "#io-channel-cells":
+    const: 0
+
+  "#thermal-sensor-cells":
+    const: 0
+
+  compatible:
+    const: allwinner,sun8i-a33-ths
+
+  reg:
+    maxItems: 1
+
+required:
+  - "#io-channel-cells"
+  - "#thermal-sensor-cells"
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    ths: ths@1c25000 {
+        compatible = "allwinner,sun8i-a33-ths";
+        reg = <0x01c25000 0x100>;
+        #thermal-sensor-cells = <0>;
+        #io-channel-cells = <0>;
+    };
+
+...
index 0e312fe..84ced3f 100644 (file)
@@ -15,6 +15,7 @@ Required properties:
        "mediatek,mt7629-sysirq", "mediatek,mt6577-sysirq": for MT7629
        "mediatek,mt6795-sysirq", "mediatek,mt6577-sysirq": for MT6795
        "mediatek,mt6797-sysirq", "mediatek,mt6577-sysirq": for MT6797
+       "mediatek,mt6779-sysirq", "mediatek,mt6577-sysirq": for MT6779
        "mediatek,mt6765-sysirq", "mediatek,mt6577-sysirq": for MT6765
        "mediatek,mt6755-sysirq", "mediatek,mt6577-sysirq": for MT6755
        "mediatek,mt6592-sysirq", "mediatek,mt6577-sysirq": for MT6592
index 09fc02b..a5c1db9 100644 (file)
@@ -1,20 +1,30 @@
 * ARC-HS Interrupt Distribution Unit
 
-  This optional 2nd level interrupt controller can be used in SMP configurations for
-  dynamic IRQ routing, load balancing of common/external IRQs towards core intc.
+  This optional 2nd level interrupt controller can be used in SMP configurations
+  for dynamic IRQ routing, load balancing of common/external IRQs towards core
+  intc.
 
 Properties:
 
 - compatible: "snps,archs-idu-intc"
 - interrupt-controller: This is an interrupt controller.
-- #interrupt-cells: Must be <1>.
-
-  Value of the cell specifies the "common" IRQ from peripheral to IDU. Number N
-  of the particular interrupt line of IDU corresponds to the line N+24 of the
-  core interrupt controller.
-
-  intc accessed via the special ARC AUX register interface, hence "reg" property
-  is not specified.
+- #interrupt-cells: Must be <1> or <2>.
+
+  Value of the first cell specifies the "common" IRQ from peripheral to IDU.
+  Number N of the particular interrupt line of IDU corresponds to the line N+24
+  of the core interrupt controller.
+
+  The (optional) second cell specifies any of the following flags:
+    - bits[3:0] trigger type and level flags
+        1 = low-to-high edge triggered
+        2 = NOT SUPPORTED (high-to-low edge triggered)
+        4 = active high level-sensitive <<< DEFAULT
+        8 = NOT SUPPORTED (active low level-sensitive)
+  When no second cell is specified, the interrupt is assumed to be level
+  sensitive.
+
+  The interrupt controller is accessed via the special ARC AUX register
+  interface, hence "reg" property is not specified.
 
 Example:
        core_intc: core-interrupt-controller {
index 6922db5..ce59a50 100644 (file)
@@ -11,10 +11,23 @@ ARM Short-Descriptor translation table format for address translation.
                |
               m4u (Multimedia Memory Management Unit)
                |
+          +--------+
+          |        |
+      gals0-rx   gals1-rx    (Global Async Local Sync rx)
+          |        |
+          |        |
+      gals0-tx   gals1-tx    (Global Async Local Sync tx)
+          |        |          Some SoCs may have GALS.
+          +--------+
+               |
            SMI Common(Smart Multimedia Interface Common)
                |
        +----------------+-------
        |                |
+       |             gals-rx        There may be GALS in some larbs.
+       |                |
+       |                |
+       |             gals-tx
        |                |
    SMI larb0        SMI larb1   ... SoCs have several SMI local arbiter(larb).
    (display)         (vdec)
@@ -36,6 +49,10 @@ each local arbiter.
 like display, video decode, and camera. And there are different ports
 in each larb. Take a example, There are many ports like MC, PP, VLD in the
 video decode local arbiter, all these ports are according to the video HW.
+  In some SoCs, there may be a GALS(Global Async Local Sync) module between
+smi-common and m4u, and additional GALS module between smi-larb and
+smi-common. GALS can been seen as a "asynchronous fifo" which could help
+synchronize for the modules in different clock frequency.
 
 Required properties:
 - compatible : must be one of the following string:
@@ -44,18 +61,25 @@ Required properties:
        "mediatek,mt7623-m4u", "mediatek,mt2701-m4u" for mt7623 which uses
                                                     generation one m4u HW.
        "mediatek,mt8173-m4u" for mt8173 which uses generation two m4u HW.
+       "mediatek,mt8183-m4u" for mt8183 which uses generation two m4u HW.
 - reg : m4u register base and size.
 - interrupts : the interrupt of m4u.
 - clocks : must contain one entry for each clock-names.
-- clock-names : must be "bclk", It is the block clock of m4u.
+- clock-names : Only 1 optional clock:
+  - "bclk": the block clock of m4u.
+  Here is the list which require this "bclk":
+  - mt2701, mt2712, mt7623 and mt8173.
+  Note that m4u use the EMI clock which always has been enabled before kernel
+  if there is no this "bclk".
 - mediatek,larbs : List of phandle to the local arbiters in the current Socs.
        Refer to bindings/memory-controllers/mediatek,smi-larb.txt. It must sort
        according to the local arbiter index, like larb0, larb1, larb2...
 - iommu-cells : must be 1. This is the mtk_m4u_id according to the HW.
        Specifies the mtk_m4u_id as defined in
        dt-binding/memory/mt2701-larb-port.h for mt2701, mt7623
-       dt-binding/memory/mt2712-larb-port.h for mt2712, and
-       dt-binding/memory/mt8173-larb-port.h for mt8173.
+       dt-binding/memory/mt2712-larb-port.h for mt2712,
+       dt-binding/memory/mt8173-larb-port.h for mt8173, and
+       dt-binding/memory/mt8183-larb-port.h for mt8183.
 
 Example:
        iommu: iommu@10205000 {
index aabdd01..9b6aace 100644 (file)
@@ -26,6 +26,7 @@ Required properties:
        - GXBB (S905) : "amlogic,gxbb-vdec"
        - GXL (S905X, S905D) : "amlogic,gxl-vdec"
        - GXM (S912) : "amlogic,gxm-vdec"
+       followed by the common "amlogic,gx-vdec"
 - reg: base address and size of he following memory-mapped regions :
        - dos
        - esparser
@@ -47,8 +48,8 @@ Required properties:
 
 Example:
 
-vdec: video-decoder@c8820000 {
-       compatible = "amlogic,gxbb-vdec";
+vdec: video-codec@c8820000 {
+       compatible = "amlogic,gxbb-vdec", "amlogic,gx-vdec";
        reg = <0x0 0xc8820000 0x0 0x10000>,
              <0x0 0xc110a580 0x0 0xe4>;
        reg-names = "dos", "esparser";
index e937ddd..b478ade 100644 (file)
@@ -2,9 +2,10 @@ SMI (Smart Multimedia Interface) Common
 
 The hardware block diagram please check bindings/iommu/mediatek,iommu.txt
 
-Mediatek SMI have two generations of HW architecture, mt2712 and mt8173 use
-the second generation of SMI HW while mt2701 uses the first generation HW of
-SMI.
+Mediatek SMI have two generations of HW architecture, here is the list
+which generation the SoCs use:
+generation 1: mt2701 and mt7623.
+generation 2: mt2712, mt8173 and mt8183.
 
 There's slight differences between the two SMI, for generation 2, the
 register which control the iommu port is at each larb's register base. But
@@ -19,6 +20,7 @@ Required properties:
        "mediatek,mt2712-smi-common"
        "mediatek,mt7623-smi-common", "mediatek,mt2701-smi-common"
        "mediatek,mt8173-smi-common"
+       "mediatek,mt8183-smi-common"
 - reg : the register and size of the SMI block.
 - power-domains : a phandle to the power domain of this local arbiter.
 - clocks : Must contain an entry for each entry in clock-names.
@@ -30,6 +32,10 @@ Required properties:
            They may be the same if both source clocks are the same.
   - "async" : asynchronous clock, it help transform the smi clock into the emi
              clock domain, this clock is only needed by generation 1 smi HW.
+  and these 2 option clocks for generation 2 smi HW:
+  - "gals0": the path0 clock of GALS(Global Async Local Sync).
+  - "gals1": the path1 clock of GALS(Global Async Local Sync).
+  Here is the list which has this GALS: mt8183.
 
 Example:
        smi_common: smi@14022000 {
index 94eddca..4b369b3 100644 (file)
@@ -8,6 +8,7 @@ Required properties:
                "mediatek,mt2712-smi-larb"
                "mediatek,mt7623-smi-larb", "mediatek,mt2701-smi-larb"
                "mediatek,mt8173-smi-larb"
+               "mediatek,mt8183-smi-larb"
 - reg : the register and size of this local arbiter.
 - mediatek,smi : a phandle to the smi_common node.
 - power-domains : a phandle to the power domain of this local arbiter.
@@ -16,6 +17,9 @@ Required properties:
   - "apb" : Advanced Peripheral Bus clock, It's the clock for setting
            the register.
   - "smi" : It's the clock for transfer data and command.
+  and this optional clock name:
+  - "gals": the clock for GALS(Global Async Local Sync).
+  Here is the list which has this GALS: mt8183.
 
 Required property for mt2701, mt2712 and mt7623:
 - mediatek,larb-id :the hardware id of this larb.
diff --git a/Documentation/devicetree/bindings/mfd/allwinner,sun4i-a10-ts.yaml b/Documentation/devicetree/bindings/mfd/allwinner,sun4i-a10-ts.yaml
new file mode 100644 (file)
index 0000000..4b1a09a
--- /dev/null
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/allwinner,sun4i-a10-ts.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A10 Resistive Touchscreen Controller Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <maxime.ripard@bootlin.com>
+
+properties:
+  "#thermal-sensor-cells":
+    const: 0
+
+  compatible:
+    enum:
+      - allwinner,sun4i-a10-ts
+      - allwinner,sun5i-a13-ts
+      - allwinner,sun6i-a31-ts
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  allwinner,ts-attached:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description: A touchscreen is attached to the controller
+
+  allwinner,tp-sensitive-adjust:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - minimum: 0
+        maximum: 15
+        default: 15
+    description: Sensitivity of pen down detection
+
+  allwinner,filter-type:
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - minimum: 0
+        maximum: 3
+        default: 1
+    description: |
+      Select median and averaging filter. Sample used for median /
+      averaging filter:
+        0: 4/2
+        1: 5/3
+        2: 8/4
+        3: 16/8
+
+required:
+  - "#thermal-sensor-cells"
+  - compatible
+  - reg
+  - interrupts
+
+additionalProperties: false
+
+examples:
+  - |
+    rtp: rtp@1c25000 {
+        compatible = "allwinner,sun4i-a10-ts";
+        reg = <0x01c25000 0x100>;
+        interrupts = <29>;
+        allwinner,ts-attached;
+        #thermal-sensor-cells = <0>;
+        /* sensitive/noisy touch panel */
+        allwinner,tp-sensitive-adjust = <0>;
+        allwinner,filter-type = <3>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
deleted file mode 100644 (file)
index 86dd819..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-Allwinner SoCs' GPADC Device Tree bindings
-------------------------------------------
-The Allwinner SoCs all have an ADC that can also act as a thermal sensor
-and sometimes as a touchscreen controller.
-
-Required properties:
-  - compatible: "allwinner,sun8i-a33-ths",
-  - reg: mmio address range of the chip,
-  - #thermal-sensor-cells: shall be 0,
-  - #io-channel-cells: shall be 0,
-
-Example:
-       ths: ths@1c25000 {
-               compatible = "allwinner,sun8i-a33-ths";
-               reg = <0x01c25000 0x100>;
-               #thermal-sensor-cells = <0>;
-               #io-channel-cells = <0>;
-       };
-
-sun4i, sun5i and sun6i SoCs are also supported via the older binding:
-
-sun4i resistive touchscreen controller
---------------------------------------
-
-Required properties:
- - compatible: "allwinner,sun4i-a10-ts", "allwinner,sun5i-a13-ts" or
-   "allwinner,sun6i-a31-ts"
- - reg: mmio address range of the chip
- - interrupts: interrupt to which the chip is connected
- - #thermal-sensor-cells: shall be 0
-
-Optional properties:
- - allwinner,ts-attached        : boolean indicating that an actual touchscreen
-                                  is attached to the controller
- - allwinner,tp-sensitive-adjust : integer (4 bits)
-                                  adjust sensitivity of pen down detection
-                                  between 0 (least sensitive) and 15
-                                  (defaults to 15)
- - allwinner,filter-type        : integer (2 bits)
-                                  select median and averaging filter
-                                  samples used for median / averaging filter
-                                  0: 4/2
-                                  1: 5/3
-                                  2: 8/4
-                                  3: 16/8
-                                  (defaults to 1)
-
-Example:
-
-       rtp: rtp@1c25000 {
-               compatible = "allwinner,sun4i-a10-ts";
-               reg = <0x01c25000 0x100>;
-               interrupts = <29>;
-               allwinner,ts-attached;
-               #thermal-sensor-cells = <0>;
-               /* sensitive/noisy touch panel */
-               allwinner,tp-sensitive-adjust = <0>;
-               allwinner,filter-type = <3>;
-       };
index b463e12..19e4a7d 100644 (file)
@@ -5,6 +5,7 @@ Required properties:
 - compatible: "renesas,can-r8a7743" if CAN controller is a part of R8A7743 SoC.
              "renesas,can-r8a7744" if CAN controller is a part of R8A7744 SoC.
              "renesas,can-r8a7745" if CAN controller is a part of R8A7745 SoC.
+             "renesas,can-r8a77470" if CAN controller is a part of R8A77470 SoC.
              "renesas,can-r8a774a1" if CAN controller is a part of R8A774A1 SoC.
              "renesas,can-r8a774c0" if CAN controller is a part of R8A774C0 SoC.
              "renesas,can-r8a7778" if CAN controller is a part of R8A7778 SoC.
@@ -17,6 +18,8 @@ Required properties:
              "renesas,can-r8a7795" if CAN controller is a part of R8A7795 SoC.
              "renesas,can-r8a7796" if CAN controller is a part of R8A7796 SoC.
              "renesas,can-r8a77965" if CAN controller is a part of R8A77965 SoC.
+             "renesas,can-r8a77990" if CAN controller is a part of R8A77990 SoC.
+             "renesas,can-r8a77995" if CAN controller is a part of R8A77995 SoC.
              "renesas,rcar-gen1-can" for a generic R-Car Gen1 compatible device.
              "renesas,rcar-gen2-can" for a generic R-Car Gen2 or RZ/G1
              compatible device.
@@ -33,7 +36,8 @@ Required properties:
 - pinctrl-0: pin control group to be used for this controller.
 - pinctrl-names: must be "default".
 
-Required properties for R8A7795, R8A7796 and R8A77965:
+Required properties for R8A774A1, R8A774C0, R8A7795, R8A7796, R8A77965,
+R8A77990, and R8A77995:
 For the denoted SoCs, "clkp2" can be CANFD clock. This is a div6 clock and can
 be used by both CAN and CAN FD controller at the same time. It needs to be
 scaled to maximum frequency if any of these controllers use it. This is done
index 32f051f..a901cd9 100644 (file)
@@ -4,6 +4,7 @@ Renesas R-Car CAN FD controller Device Tree Bindings
 Required properties:
 - compatible: Must contain one or more of the following:
   - "renesas,rcar-gen3-canfd" for R-Car Gen3 and RZ/G2 compatible controllers.
+  - "renesas,r8a774a1-canfd" for R8A774A1 (RZ/G2M) compatible controller.
   - "renesas,r8a774c0-canfd" for R8A774C0 (RZ/G2E) compatible controller.
   - "renesas,r8a7795-canfd" for R8A7795 (R-Car H3) compatible controller.
   - "renesas,r8a7796-canfd" for R8A7796 (R-Car M3-W) compatible controller.
@@ -11,6 +12,7 @@ Required properties:
   - "renesas,r8a77970-canfd" for R8A77970 (R-Car V3M) compatible controller.
   - "renesas,r8a77980-canfd" for R8A77980 (R-Car V3H) compatible controller.
   - "renesas,r8a77990-canfd" for R8A77990 (R-Car E3) compatible controller.
+  - "renesas,r8a77995-canfd" for R8A77995 (R-Car D3) compatible controller.
 
   When compatible with the generic version, nodes must list the
   SoC-specific version corresponding to the platform first, followed by the
@@ -29,13 +31,12 @@ The name of the child nodes are "channel0" and "channel1" respectively. Each
 child node supports the "status" property only, which is used to
 enable/disable the respective channel.
 
-Required properties for "renesas,r8a774c0-canfd", "renesas,r8a7795-canfd",
-"renesas,r8a7796-canfd", "renesas,r8a77965-canfd", and "renesas,r8a77990-canfd"
-compatible:
-In R8A774C0, R8A7795, R8A7796, R8A77965, and R8A77990 SoCs, canfd clock is a
-div6 clock and can be used by both CAN and CAN FD controller at the same time.
-It needs to be scaled to maximum frequency if any of these controllers use it.
-This is done using the below properties:
+Required properties for R8A774A1, R8A774C0, R8A7795, R8A7796, R8A77965,
+R8A77990, and R8A77995:
+In the denoted SoCs, canfd clock is a div6 clock and can be used by both CAN
+and CAN FD controller at the same time. It needs to be scaled to maximum
+frequency if any of these controllers use it. This is done using the below
+properties:
 
 - assigned-clocks: phandle of canfd clock.
 - assigned-clock-rates: maximum frequency of this clock.
index 4ac21ce..113e7ac 100644 (file)
@@ -12,6 +12,7 @@ Required properties:
   - "microchip,ksz8565"
   - "microchip,ksz9893"
   - "microchip,ksz9563"
+  - "microchip,ksz8563"
 
 Optional properties:
 
index 63c73fa..0b61a90 100644 (file)
@@ -15,10 +15,10 @@ Required properties:
   Use "atmel,sama5d4-gem" for the GEM IP (10/100) available on Atmel sama5d4 SoCs.
   Use "cdns,zynq-gem" Xilinx Zynq-7xxx SoC.
   Use "cdns,zynqmp-gem" for Zynq Ultrascale+ MPSoC.
-  Use "sifive,fu540-macb" for SiFive FU540-C000 SoC.
+  Use "sifive,fu540-c000-gem" for SiFive FU540-C000 SoC.
   Or the generic form: "cdns,emac".
 - reg: Address and length of the register set for the device
-       For "sifive,fu540-macb", second range is required to specify the
+       For "sifive,fu540-c000-gem", second range is required to specify the
        address and length of the registers for GEMGXL Management block.
 - interrupts: Should contain macb interrupt
 - phy-mode: See ethernet.txt file in the same directory.
diff --git a/Documentation/devicetree/bindings/power/amlogic,meson-ee-pwrc.yaml b/Documentation/devicetree/bindings/power/amlogic,meson-ee-pwrc.yaml
new file mode 100644 (file)
index 0000000..aab70e8
--- /dev/null
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2019 BayLibre, SAS
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/power/amlogic,meson-ee-pwrc.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Amlogic Meson Everything-Else Power Domains
+
+maintainers:
+  - Neil Armstrong <narmstrong@baylibre.com>
+
+description: |+
+  The Everything-Else Power Domains node should be the child of a syscon
+  node with the required property:
+
+  - compatible: Should be the following:
+                "amlogic,meson-gx-hhi-sysctrl", "simple-mfd", "syscon"
+
+  Refer to the the bindings described in
+  Documentation/devicetree/bindings/mfd/syscon.txt
+
+properties:
+  compatible:
+    enum:
+      - amlogic,meson-g12a-pwrc
+      - amlogic,meson-sm1-pwrc
+
+  clocks:
+    minItems: 2
+
+  clock-names:
+    items:
+      - const: vpu
+      - const: vapb
+
+  resets:
+    minItems: 11
+
+  reset-names:
+    items:
+      - const: viu
+      - const: venc
+      - const: vcbus
+      - const: bt656
+      - const: rdma
+      - const: venci
+      - const: vencp
+      - const: vdac
+      - const: vdi6
+      - const: vencl
+      - const: vid_lock
+
+  "#power-domain-cells":
+    const: 1
+
+  amlogic,ao-sysctrl:
+    description: phandle to the AO sysctrl node
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/phandle
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - resets
+  - reset-names
+  - "#power-domain-cells"
+  - amlogic,ao-sysctrl
+
+examples:
+  - |
+    pwrc: power-controller {
+          compatible = "amlogic,meson-sm1-pwrc";
+          #power-domain-cells = <1>;
+          amlogic,ao-sysctrl = <&rti>;
+          resets = <&reset_viu>,
+                   <&reset_venc>,
+                   <&reset_vcbus>,
+                   <&reset_bt656>,
+                   <&reset_rdma>,
+                   <&reset_venci>,
+                   <&reset_vencp>,
+                   <&reset_vdac>,
+                   <&reset_vdi6>,
+                   <&reset_vencl>,
+                   <&reset_vid_lock>;
+          reset-names = "viu", "venc", "vcbus", "bt656",
+                        "rdma", "venci", "vencp", "vdac",
+                        "vdi6", "vencl", "vid_lock";
+          clocks = <&clk_vpu>, <&clk_vapb>;
+          clock-names = "vpu", "vapb";
+    };
index 3ae9f10..b9f58e4 100644 (file)
@@ -34,6 +34,9 @@ Optional input supply properties:
   - inl67-supply: The input supply for LDO_REG3 and LDO_REG4
 
 Any standard regulator properties can be used to configure the single regulator.
+regulator-initial-mode, regulator-allowed-modes and regulator-mode could be specified
+for act8865 using mode values from dt-bindings/regulator/active-semi,8865-regulator.h
+file.
 
 The valid names for regulators are:
        - for act8846:
@@ -47,6 +50,8 @@ The valid names for regulators are:
 Example:
 --------
 
+#include <dt-bindings/regulator/active-semi,8865-regulator.h>
+
                i2c1: i2c@f0018000 {
                        pmic: act8865@5b {
                                compatible = "active-semi,act8865";
@@ -65,9 +70,19 @@ Example:
                                                regulator-name = "VCC_1V2";
                                                regulator-min-microvolt = <1100000>;
                                                regulator-max-microvolt = <1300000>;
-                                               regulator-suspend-mem-microvolt = <1150000>;
-                                               regulator-suspend-standby-microvolt = <1150000>;
                                                regulator-always-on;
+
+                                               regulator-allowed-modes = <ACT8865_REGULATOR_MODE_FIXED>,
+                                                                         <ACT8865_REGULATOR_MODE_LOWPOWER>;
+                                               regulator-initial-mode = <ACT8865_REGULATOR_MODE_FIXED>;
+
+                                               regulator-state-mem {
+                                                       regulator-on-in-suspend;
+                                                       regulator-suspend-min-microvolt = <1150000>;
+                                                       regulator-suspend-max-microvolt = <1150000>;
+                                                       regulator-changeable-in-suspend;
+                                                       regulator-mode = <ACT8865_REGULATOR_MODE_LOWPOWER>;
+                                               };
                                        };
 
                                        vcc_3v3_reg: DCDC_REG3 {
@@ -82,6 +97,14 @@ Example:
                                                regulator-min-microvolt = <3300000>;
                                                regulator-max-microvolt = <3300000>;
                                                regulator-always-on;
+
+                                               regulator-allowed-modes = <ACT8865_REGULATOR_MODE_NORMAL>,
+                                                                         <ACT8865_REGULATOR_MODE_LOWPOWER>;
+                                               regulator-initial-mode = <ACT8865_REGULATOR_MODE_NORMAL>;
+
+                                               regulator-state-mem {
+                                                       regulator-off-in-suspend;
+                                               };
                                        };
 
                                        vddfuse_reg: LDO_REG2 {
index a650b45..a78150c 100644 (file)
@@ -19,9 +19,19 @@ description:
 allOf:
   - $ref: "regulator.yaml#"
 
+if:
+  properties:
+    compatible:
+      contains:
+        const: regulator-fixed-clock
+  required:
+    - clocks
+
 properties:
   compatible:
-    const: regulator-fixed
+    enum:
+      - const: regulator-fixed
+      - const: regulator-fixed-clock
 
   regulator-name: true
 
@@ -29,6 +39,13 @@ properties:
     description: gpio to use for enable control
     maxItems: 1
 
+  clocks:
+    description:
+      clock to use for enable control. This binding is only available if
+      the compatible is chosen to regulator-fixed-clock. The clock binding
+      is mandatory if compatible is chosen to regulator-fixed-clock.
+    maxItems: 1
+
   startup-delay-us:
     description: startup time in microseconds
     $ref: /schemas/types.yaml#/definitions/uint32
diff --git a/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6358-regulator.txt
new file mode 100644 (file)
index 0000000..9a90a92
--- /dev/null
@@ -0,0 +1,358 @@
+MediaTek MT6358 Regulator
+
+All voltage regulators provided by the MT6358 PMIC are described as the
+subnodes of the MT6358 regulators node. Each regulator is named according
+to its regulator type, buck_<name> and ldo_<name>. The definition for each
+of these nodes is defined using the standard binding for regulators at
+Documentation/devicetree/bindings/regulator/regulator.txt.
+
+The valid names for regulators are::
+BUCK:
+  buck_vdram1, buck_vcore, buck_vpa, buck_vproc11, buck_vproc12, buck_vgpu,
+  buck_vs2, buck_vmodem, buck_vs1
+LDO:
+  ldo_vdram2, ldo_vsim1, ldo_vibr, ldo_vrf12, ldo_vio18, ldo_vusb, ldo_vcamio,
+  ldo_vcamd, ldo_vcn18, ldo_vfe28, ldo_vsram_proc11, ldo_vcn28, ldo_vsram_others,
+  ldo_vsram_gpu, ldo_vxo22, ldo_vefuse, ldo_vaux18, ldo_vmch, ldo_vbif28,
+  ldo_vsram_proc12, ldo_vcama1, ldo_vemc, ldo_vio28, ldo_va12, ldo_vrf18,
+  ldo_vcn33_bt, ldo_vcn33_wifi, ldo_vcama2, ldo_vmc, ldo_vldo28, ldo_vaud28,
+  ldo_vsim2
+
+Example:
+
+       pmic {
+               compatible = "mediatek,mt6358";
+
+               mt6358regulator: mt6358regulator {
+                       compatible = "mediatek,mt6358-regulator";
+
+                       mt6358_vdram1_reg: buck_vdram1 {
+                               regulator-compatible = "buck_vdram1";
+                               regulator-name = "vdram1";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <2087500>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-enable-ramp-delay = <0>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vcore_reg: buck_vcore {
+                               regulator-name = "vcore";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <200>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vpa_reg: buck_vpa {
+                               regulator-name = "vpa";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <3650000>;
+                               regulator-ramp-delay = <50000>;
+                               regulator-enable-ramp-delay = <250>;
+                       };
+
+                       mt6358_vproc11_reg: buck_vproc11 {
+                               regulator-name = "vproc11";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <200>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vproc12_reg: buck_vproc12 {
+                               regulator-name = "vproc12";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <200>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vgpu_reg: buck_vgpu {
+                               regulator-name = "vgpu";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <200>;
+                       };
+
+                       mt6358_vs2_reg: buck_vs2 {
+                               regulator-name = "vs2";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <2087500>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-enable-ramp-delay = <0>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vmodem_reg: buck_vmodem {
+                               regulator-name = "vmodem";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <900>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vs1_reg: buck_vs1 {
+                               regulator-name = "vs1";
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <2587500>;
+                               regulator-ramp-delay = <12500>;
+                               regulator-enable-ramp-delay = <0>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vdram2_reg: ldo_vdram2 {
+                               regulator-name = "vdram2";
+                               regulator-min-microvolt = <600000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <3300>;
+                       };
+
+                       mt6358_vsim1_reg: ldo_vsim1 {
+                               regulator-name = "vsim1";
+                               regulator-min-microvolt = <1700000>;
+                               regulator-max-microvolt = <3100000>;
+                               regulator-enable-ramp-delay = <540>;
+                       };
+
+                       mt6358_vibr_reg: ldo_vibr {
+                               regulator-name = "vibr";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-enable-ramp-delay = <60>;
+                       };
+
+                       mt6358_vrf12_reg: ldo_vrf12 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vrf12";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-enable-ramp-delay = <120>;
+                       };
+
+                       mt6358_vio18_reg: ldo_vio18 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vio18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <2700>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vusb_reg: ldo_vusb {
+                               regulator-name = "vusb";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3100000>;
+                               regulator-enable-ramp-delay = <270>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vcamio_reg: ldo_vcamio {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vcamio";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vcamd_reg: ldo_vcamd {
+                               regulator-name = "vcamd";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vcn18_reg: ldo_vcn18 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vcn18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vfe28_reg: ldo_vfe28 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vfe28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vsram_proc11_reg: ldo_vsram_proc11 {
+                               regulator-name = "vsram_proc11";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <240>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vcn28_reg: ldo_vcn28 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vcn28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vsram_others_reg: ldo_vsram_others {
+                               regulator-name = "vsram_others";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <240>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vsram_gpu_reg: ldo_vsram_gpu {
+                               regulator-name = "vsram_gpu";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <240>;
+                       };
+
+                       mt6358_vxo22_reg: ldo_vxo22 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vxo22";
+                               regulator-min-microvolt = <2200000>;
+                               regulator-max-microvolt = <2200000>;
+                               regulator-enable-ramp-delay = <120>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vefuse_reg: ldo_vefuse {
+                               regulator-name = "vefuse";
+                               regulator-min-microvolt = <1700000>;
+                               regulator-max-microvolt = <1900000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vaux18_reg: ldo_vaux18 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vaux18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vmch_reg: ldo_vmch {
+                               regulator-name = "vmch";
+                               regulator-min-microvolt = <2900000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-enable-ramp-delay = <60>;
+                       };
+
+                       mt6358_vbif28_reg: ldo_vbif28 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vbif28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vsram_proc12_reg: ldo_vsram_proc12 {
+                               regulator-name = "vsram_proc12";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <1293750>;
+                               regulator-ramp-delay = <6250>;
+                               regulator-enable-ramp-delay = <240>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vcama1_reg: ldo_vcama1 {
+                               regulator-name = "vcama1";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vemc_reg: ldo_vemc {
+                               regulator-name = "vemc";
+                               regulator-min-microvolt = <2900000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-enable-ramp-delay = <60>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vio28_reg: ldo_vio28 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vio28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_va12_reg: ldo_va12 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "va12";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-enable-ramp-delay = <270>;
+                               regulator-always-on;
+                       };
+
+                       mt6358_vrf18_reg: ldo_vrf18 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vrf18";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-enable-ramp-delay = <120>;
+                       };
+
+                       mt6358_vcn33_bt_reg: ldo_vcn33_bt {
+                               regulator-name = "vcn33_bt";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3500000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vcn33_wifi_reg: ldo_vcn33_wifi {
+                               regulator-name = "vcn33_wifi";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3500000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vcama2_reg: ldo_vcama2 {
+                               regulator-name = "vcama2";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vmc_reg: ldo_vmc {
+                               regulator-name = "vmc";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-enable-ramp-delay = <60>;
+                       };
+
+                       mt6358_vldo28_reg: ldo_vldo28 {
+                               regulator-name = "vldo28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vaud28_reg: ldo_vaud28 {
+                               compatible = "regulator-fixed";
+                               regulator-name = "vaud28";
+                               regulator-min-microvolt = <2800000>;
+                               regulator-max-microvolt = <2800000>;
+                               regulator-enable-ramp-delay = <270>;
+                       };
+
+                       mt6358_vsim2_reg: ldo_vsim2 {
+                               regulator-name = "vsim2";
+                               regulator-min-microvolt = <1700000>;
+                               regulator-max-microvolt = <3100000>;
+                               regulator-enable-ramp-delay = <540>;
+                       };
+               };
+       };
index 14d2eee..bab9f71 100644 (file)
@@ -22,9 +22,12 @@ RPMh resource.
 
 The names used for regulator nodes must match those supported by a given PMIC.
 Supported regulator node names:
+       PM8005:         smps1 - smps4
+       PM8009:         smps1 - smps2, ldo1 - ldo7
+       PM8150:         smps1 - smps10, ldo1 - ldo18
+       PM8150L:        smps1 - smps8, ldo1 - ldo11, bob, flash, rgb
        PM8998:         smps1 - smps13, ldo1 - ldo28, lvs1 - lvs2
        PMI8998:        bob
-       PM8005:         smps1 - smps4
 
 ========================
 First Level Nodes - PMIC
@@ -33,9 +36,13 @@ First Level Nodes - PMIC
 - compatible
        Usage:      required
        Value type: <string>
-       Definition: Must be one of: "qcom,pm8998-rpmh-regulators",
-                   "qcom,pmi8998-rpmh-regulators" or
-                   "qcom,pm8005-rpmh-regulators".
+       Definition: Must be one of below:
+                   "qcom,pm8005-rpmh-regulators"
+                   "qcom,pm8009-rpmh-regulators"
+                   "qcom,pm8150-rpmh-regulators"
+                   "qcom,pm8150l-rpmh-regulators"
+                   "qcom,pm8998-rpmh-regulators"
+                   "qcom,pmi8998-rpmh-regulators"
 
 - qcom,pmic-id
        Usage:      required
diff --git a/Documentation/devicetree/bindings/regulator/sy8824x.txt b/Documentation/devicetree/bindings/regulator/sy8824x.txt
new file mode 100644 (file)
index 0000000..c5e9585
--- /dev/null
@@ -0,0 +1,24 @@
+SY8824C/SY8824E/SY20276 Voltage regulator
+
+Required properties:
+- compatible: Must be one of the following.
+       "silergy,sy8824c"
+       "silergy,sy8824e"
+       "silergy,sy20276"
+       "silergy,sy20278"
+- reg: I2C slave address
+
+Any property defined as part of the core regulator binding, defined in
+./regulator.txt, can also be used.
+
+Example:
+
+       vcore: regulator@00 {
+               compatible = "silergy,sy8824c";
+               reg = <0x66>;
+               regulator-name = "vcore";
+               regulator-min-microvolt = <800000>;
+               regulator-max-microvolt = <1150000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
index 74a91c4..549f804 100644 (file)
@@ -71,3 +71,10 @@ Example:
                regulator-min-microvolt  = <1000000>;
                regulator-max-microvolt  = <3000000>;
        };
+
+For twl6030 regulators/LDOs:
+
+ - ti,retain-on-reset: Does not turn off the supplies during warm
+                       reset. Could be needed for VMMC, as TWL6030
+                       reset sequence for this signal does not comply
+                       with the SD specification.
index c9919f4..94fd38b 100644 (file)
@@ -13,6 +13,7 @@ this layer. These clocks and resets should be described in each property.
 Required properties:
 - compatible: Should be
     "socionext,uniphier-pro4-usb3-regulator" - for Pro4 SoC
+    "socionext,uniphier-pro5-usb3-regulator" - for Pro5 SoC
     "socionext,uniphier-pxs2-usb3-regulator" - for PXs2 SoC
     "socionext,uniphier-ld20-usb3-regulator" - for LD20 SoC
     "socionext,uniphier-pxs3-usb3-regulator" - for PXs3 SoC
@@ -20,12 +21,12 @@ Required properties:
 - clocks: A list of phandles to the clock gate for USB3 glue layer.
        According to the clock-names, appropriate clocks are required.
 - clock-names: Should contain
-    "gio", "link" - for Pro4 SoC
+    "gio", "link" - for Pro4 and Pro5 SoCs
     "link"        - for others
 - resets: A list of phandles to the reset control for USB3 glue layer.
        According to the reset-names, appropriate resets are required.
 - reset-names: Should contain
-    "gio", "link" - for Pro4 SoC
+    "gio", "link" - for Pro4 and Pro5 SoCs
     "link"        - for others
 
 See Documentation/devicetree/bindings/regulator/regulator.txt
index 13e0951..c2489e4 100644 (file)
@@ -8,6 +8,7 @@ Required properties:
 - compatible:
        - For i.MX7 SoCs should be "fsl,imx7d-src", "syscon"
        - For i.MX8MQ SoCs should be "fsl,imx8mq-src", "syscon"
+       - For i.MX8MM SoCs should be "fsl,imx8mm-src", "fsl,imx8mq-src", "syscon"
 - reg: should be register base and length as documented in the
   datasheet
 - interrupts: Should contain SRC interrupt
@@ -46,5 +47,6 @@ Example:
 
 
 For list of all valid reset indices see
-<dt-bindings/reset/imx7-reset.h> for i.MX7 and
-<dt-bindings/reset/imx8mq-reset.h> for i.MX8MQ
+<dt-bindings/reset/imx7-reset.h> for i.MX7,
+<dt-bindings/reset/imx8mq-reset.h> for i.MX8MQ and
+<dt-bindings/reset/imx8mq-reset.h> for i.MX8MM
diff --git a/Documentation/devicetree/bindings/reset/snps,dw-reset.txt b/Documentation/devicetree/bindings/reset/snps,dw-reset.txt
new file mode 100644 (file)
index 0000000..f94f911
--- /dev/null
@@ -0,0 +1,30 @@
+Synopsys DesignWare Reset controller
+=======================================
+
+Please also refer to reset.txt in this directory for common reset
+controller binding usage.
+
+Required properties:
+
+- compatible: should be one of the following.
+       "snps,dw-high-reset" - for active high configuration
+       "snps,dw-low-reset" - for active low configuration
+
+- reg: physical base address of the controller and length of memory mapped
+       region.
+
+- #reset-cells: must be 1.
+
+example:
+
+       dw_rst_1: reset-controller@0000 {
+               compatible = "snps,dw-high-reset";
+               reg = <0x0000 0x4>;
+               #reset-cells = <1>;
+       };
+
+       dw_rst_2: reset-controller@1000 {i
+               compatible = "snps,dw-low-reset";
+               reg = <0x1000 0x8>;
+               #reset-cells = <1>;
+       };
index 21483ba..3495eee 100644 (file)
@@ -13,7 +13,10 @@ Required properties:
 - reg : Address and length of the register set for the device
 - interrupts : Should contain uart interrupt
 - clocks : phandle + clock specifier pairs, one for each entry in clock-names
-- clock-names : should contain: "ipg" - the uart clock
+- clock-names : For vf610/ls1021a/imx7ulp, "ipg" clock is for uart bus/baud
+  clock. For imx8qxp lpuart, "ipg" clock is bus clock that is used to access
+  lpuart controller registers, it also requires "baud" clock for module to
+  receive/transmit data.
 
 Optional properties:
 - dmas: A list of two dma specifiers, one for each entry in dma-names.
index 6fdffb7..3a3b570 100644 (file)
@@ -9,6 +9,7 @@ Required properties:
   * "mediatek,mt6589-uart" for MT6589 compatible UARTS
   * "mediatek,mt6755-uart" for MT6755 compatible UARTS
   * "mediatek,mt6765-uart" for MT6765 compatible UARTS
+  * "mediatek,mt6779-uart" for MT6779 compatible UARTS
   * "mediatek,mt6795-uart" for MT6795 compatible UARTS
   * "mediatek,mt6797-uart" for MT6797 compatible UARTS
   * "mediatek,mt7622-uart" for MT7622 compatible UARTS
index 6bf6b43..3dd563c 100644 (file)
@@ -11,6 +11,7 @@ Required properties:
                        "amlogic,meson8b-clk-measure" for Meson8b SoCs
                        "amlogic,meson-axg-clk-measure" for AXG SoCs
                        "amlogic,meson-g12a-clk-measure" for G12a SoCs
+                       "amlogic,meson-sm1-clk-measure" for SM1 SoCs
 - reg: base address and size of the Clock Measurer register space.
 
 Example:
index d7afaff..05ec2a8 100644 (file)
@@ -18,7 +18,8 @@ Required properties:
 - reg : offset and length of the device registers.
 - bus-frequency : the clock frequency for QUICC Engine.
 - fsl,qe-num-riscs: define how many RISC engines the QE has.
-- fsl,qe-num-snums: define how many serial number(SNUM) the QE can use for the
+- fsl,qe-snums: This property has to be specified as '/bits/ 8' value,
+  defining the array of serial number (SNUM) values for the virtual
   threads.
 
 Optional properties:
@@ -34,6 +35,11 @@ Recommended properties
 - brg-frequency : the internal clock source frequency for baud-rate
   generators in Hz.
 
+Deprecated properties
+- fsl,qe-num-snums: define how many serial number(SNUM) the QE can use
+  for the threads. Use fsl,qe-snums instead to not only specify the
+  number of snums, but also their values.
+
 Example:
      qe@e0100000 {
        #address-cells = <1>;
@@ -44,6 +50,11 @@ Example:
        reg = <e0100000 480>;
        brg-frequency = <0>;
        bus-frequency = <179A7B00>;
+       fsl,qe-snums = /bits/ 8 <
+               0x04 0x05 0x0C 0x0D 0x14 0x15 0x1C 0x1D
+               0x24 0x25 0x2C 0x2D 0x34 0x35 0x88 0x89
+               0x98 0x99 0xA8 0xA9 0xB8 0xB9 0xC8 0xC9
+               0xD8 0xD9 0xE8 0xE9>;
      }
 
 * Multi-User RAM (MURAM)
index 954ffee..4fc571e 100644 (file)
@@ -15,7 +15,10 @@ power-domains.
 - compatible:
        Usage: required
        Value type: <string>
-       Definition: must be "qcom,sdm845-aoss-qmp"
+       Definition: must be one of:
+                   "qcom,sc7180-aoss-qmp"
+                   "qcom,sdm845-aoss-qmp"
+                   "qcom,sm8150-aoss-qmp"
 
 - reg:
        Usage: required
index f7b00a7..f541d1f 100644 (file)
@@ -19,8 +19,15 @@ child of the pmmc node.
 Required Properties:
 --------------------
 - compatible: should be "ti,sci-pm-domain"
-- #power-domain-cells: Must be 1 so that an id can be provided in each
-                      device node.
+- #power-domain-cells: Can be one of the following:
+                       1: Containing the device id of each node
+                       2: First entry should be device id
+                          Second entry should be one of the floowing:
+                          TI_SCI_PD_EXCLUSIVE: To allow device to be
+                                               exclusively controlled by
+                                               the requesting hosts.
+                          TI_SCI_PD_SHARED: To allow device to be shared
+                                            by multiple hosts.
 
 Example (K2G):
 -------------
diff --git a/Documentation/devicetree/bindings/spi/nuvoton,npcm-fiu.txt b/Documentation/devicetree/bindings/spi/nuvoton,npcm-fiu.txt
new file mode 100644 (file)
index 0000000..a388005
--- /dev/null
@@ -0,0 +1,47 @@
+* Nuvoton FLASH Interface Unit (FIU) SPI Controller
+
+NPCM FIU supports single, dual and quad communication interface.
+
+The NPCM7XX supports three FIU modules,
+FIU0 and FIUx supports two chip selects,
+FIU3 support four chip select.
+
+Required properties:
+  - compatible : "nuvoton,npcm750-fiu" for the NPCM7XX BMC
+  - #address-cells : should be 1.
+  - #size-cells : should be 0.
+  - reg : the first contains the register location and length,
+          the second contains the memory mapping address and length
+  - reg-names: Should contain the reg names "control" and "memory"
+  - clocks : phandle of FIU reference clock.
+
+Required properties in case the pins can be muxed:
+  - pinctrl-names : a pinctrl state named "default" must be defined.
+  - pinctrl-0 : phandle referencing pin configuration of the device.
+
+Optional property:
+  - nuvoton,spix-mode: enable spix-mode for an expansion bus to an ASIC or CPLD.
+
+Aliases:
+- All the FIU controller nodes should be represented in the aliases node using
+  the following format 'fiu{n}' where n is a unique number for the alias.
+  In the NPCM7XX BMC:
+               fiu0 represent fiu 0 controller
+               fiu1 represent fiu 3 controller
+               fiu2 represent fiu x controller
+
+Example:
+fiu3: spi@c00000000 {
+       compatible = "nuvoton,npcm750-fiu";
+       #address-cells = <1>;
+       #size-cells = <0>;
+       reg = <0xfb000000 0x1000>, <0x80000000 0x10000000>;
+       reg-names = "control", "memory";
+       clocks = <&clk NPCM7XX_CLK_AHB>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi3_pins>;
+       spi-nor@0 {
+                       ...
+       };
+};
+
index a02e2fe..7323392 100644 (file)
@@ -31,7 +31,7 @@ properties:
       If that property is used, the number of chip selects will be
       increased automatically with max(cs-gpios, hardware chip selects).
 
-      So if, for example, the controller has 2 CS lines, and the
+      So if, for example, the controller has 4 CS lines, and the
       cs-gpios looks like this
         cs-gpios = <&gpio1 0 0>, <0>, <&gpio1 1 0>, <&gpio1 2 0>;
 
index dcc7eaa..162e024 100644 (file)
@@ -6,6 +6,7 @@ Required properties:
                or
                "fsl,ls2080a-dspi" followed by "fsl,ls2085a-dspi"
                "fsl,ls1012a-dspi" followed by "fsl,ls1021a-v1.0-dspi"
+               "fsl,ls1088a-dspi" followed by "fsl,ls1021a-v1.0-dspi"
 - reg : Offset and length of the register set for the device
 - interrupts : Should contain SPI controller interrupt
 - clocks: from common clock binding: handle to dspi clock.
index e8f1d62..69dc5d5 100644 (file)
@@ -3,9 +3,8 @@
 Required properties:
   - compatible : Should be "fsl,vf610-qspi", "fsl,imx6sx-qspi",
                 "fsl,imx7d-qspi", "fsl,imx6ul-qspi",
-                "fsl,ls1021a-qspi"
+                "fsl,ls1021a-qspi", "fsl,ls2080a-qspi"
                 or
-                "fsl,ls2080a-qspi" followed by "fsl,ls1021a-qspi",
                 "fsl,ls1043a-qspi" followed by "fsl,ls1021a-qspi"
   - reg : the first contains the register location and length,
           the second contains the memory mapping address and length
@@ -34,7 +33,11 @@ qspi0: quadspi@40044000 {
        clock-names = "qspi_en", "qspi";
 
        flash0: s25fl128s@0 {
-               ....
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spansion,s25fl128s", "jedec,spi-nor";
+               spi-max-frequency = <50000000>;
+               reg = <0>;
        };
 };
 
index c0f6c8e..3a8079e 100644 (file)
@@ -5,6 +5,7 @@ Required properties:
     - mediatek,mt2701-spi: for mt2701 platforms
     - mediatek,mt2712-spi: for mt2712 platforms
     - mediatek,mt6589-spi: for mt6589 platforms
+    - mediatek,mt6765-spi: for mt6765 platforms
     - mediatek,mt7622-spi: for mt7622 platforms
     - "mediatek,mt7629-spi", "mediatek,mt7622-spi": for mt7629 platforms
     - mediatek,mt8135-spi: for mt8135 platforms
index 8de589b..2567c82 100644 (file)
@@ -25,18 +25,23 @@ data by ADI software channels at the same time, or two parallel routine of setti
 ADI registers will make ADI controller registers chaos to lead incorrect results.
 Then we need one hardware spinlock to synchronize between the multiple subsystems.
 
+The new version ADI controller supplies multiple master channels for different
+subsystem accessing, that means no need to add hardware spinlock to synchronize,
+thus change the hardware spinlock support to be optional to keep backward
+compatibility.
+
 Required properties:
 - compatible: Should be "sprd,sc9860-adi".
 - reg: Offset and length of ADI-SPI controller register space.
-- hwlocks: Reference to a phandle of a hwlock provider node.
-- hwlock-names: Reference to hwlock name strings defined in the same order
-       as the hwlocks, should be "adi".
 - #address-cells: Number of cells required to define a chip select address
        on the ADI-SPI bus. Should be set to 1.
 - #size-cells: Size of cells required to define a chip select address size
        on the ADI-SPI bus. Should be set to 0.
 
 Optional properties:
+- hwlocks: Reference to a phandle of a hwlock provider node.
+- hwlock-names: Reference to hwlock name strings defined in the same order
+       as the hwlocks, should be "adi".
 - sprd,hw-channels: This is an array of channel values up to 49 channels.
        The first value specifies the hardware channel id which is used to
        transfer data triggered by hardware automatically, and the second
index 2e742d3..870ac52 100644 (file)
@@ -104,6 +104,8 @@ properties:
           - infineon,slb9645tt
             # Infineon TLV493D-A1B6 I2C 3D Magnetic Sensor
           - infineon,tlv493d-a1b6
+            # Inspur Power System power supply unit version 1
+          - inspur,ipsps1
             # Intersil ISL29028 Ambient Light and Proximity Sensor
           - isil,isl29028
             # Intersil ISL29030 Ambient Light and Proximity Sensor
index 6992bbb..de4240e 100644 (file)
@@ -27,6 +27,8 @@ patternProperties:
     description: Abilis Systems
   "^abracon,.*":
     description: Abracon Corporation
+  "^acme,.*":
+    description: Acme Systems srl
   "^actions,.*":
     description: Actions Semiconductor Co., Ltd.
   "^active-semi,.*":
@@ -81,6 +83,8 @@ patternProperties:
     description: Analogix Semiconductor, Inc.
   "^andestech,.*":
     description: Andes Technology Corporation
+  "^anvo,.*":
+    description: Anvo-Systems Dresden GmbH
   "^apm,.*":
     description: Applied Micro Circuits Corporation (APM)
   "^aptina,.*":
@@ -269,6 +273,8 @@ patternProperties:
     description: Emerging Display Technologies
   "^eeti,.*":
     description: eGalax_eMPIA Technology Inc
+  "^einfochips,.*":
+    description: Einfochips
   "^elan,.*":
     description: Elan Microelectronic Corp.
   "^elgin,.*":
@@ -503,6 +509,8 @@ patternProperties:
     description: Lantiq Semiconductor
   "^lattice,.*":
     description: Lattice Semiconductor
+  "^leez,.*":
+    description: Leez
   "^lego,.*":
     description: LEGO Systems A/S
   "^lemaker,.*":
@@ -529,6 +537,8 @@ patternProperties:
     description: Linear Technology Corporation
   "^logicpd,.*":
     description: Logic PD, Inc.
+  "^longcheer,.*":
+    description: Longcheer Technology (Shanghai) Co., Ltd.
   "^lsi,.*":
     description: LSI Corp. (LSI Logic)
   "^lwn,.*":
@@ -549,6 +559,8 @@ patternProperties:
     description: mCube
   "^meas,.*":
     description: Measurement Specialties
+  "^mecer,.*":
+    description: Mustek Limited
   "^mediatek,.*":
     description: MediaTek Inc.
   "^megachips,.*":
@@ -575,6 +587,8 @@ patternProperties:
     description: Micro Crystal AG
   "^micron,.*":
     description: Micron Technology Inc.
+  "^microsoft,.*":
+    description: Microsoft Corporation
   "^mikroe,.*":
     description: MikroElektronika d.o.o.
   "^miniand,.*":
index 921c71a..3fdb324 100644 (file)
@@ -69,9 +69,9 @@ driver code:
 
 The code implementing a gpio_chip should support multiple instances of the
 controller, preferably using the driver model. That code will configure each
-gpio_chip and issue ``gpiochip_add[_data]()`` or ``devm_gpiochip_add_data()``.
-Removing a GPIO controller should be rare; use ``[devm_]gpiochip_remove()``
-when it is unavoidable.
+gpio_chip and issue gpiochip_add(), gpiochip_add_data(), or
+devm_gpiochip_add_data().  Removing a GPIO controller should be rare; use
+gpiochip_remove() when it is unavoidable.
 
 Often a gpio_chip is part of an instance-specific structure with states not
 exposed by the GPIO interfaces, such as addressing, power management, and more.
@@ -259,7 +259,7 @@ most often cascaded off a parent interrupt controller, and in some special
 cases the GPIO logic is melded with a SoC's primary interrupt controller.
 
 The IRQ portions of the GPIO block are implemented using an irq_chip, using
-the header <linux/irq.h>. So basically such a driver is utilizing two sub-
+the header <linux/irq.h>. So this combined driver is utilizing two sub-
 systems simultaneously: gpio and irq.
 
 It is legal for any IRQ consumer to request an IRQ from any irqchip even if it
@@ -391,25 +391,119 @@ Infrastructure helpers for GPIO irqchips
 ----------------------------------------
 
 To help out in handling the set-up and management of GPIO irqchips and the
-associated irqdomain and resource allocation callbacks, the gpiolib has
-some helpers that can be enabled by selecting the GPIOLIB_IRQCHIP Kconfig
-symbol:
-
-- gpiochip_irqchip_add(): adds a chained cascaded irqchip to a gpiochip. It
-  will pass the struct gpio_chip* for the chip to all IRQ callbacks, so the
-  callbacks need to embed the gpio_chip in its state container and obtain a
-  pointer to the container using container_of().
-  (See Documentation/driver-api/driver-model/design-patterns.rst)
+associated irqdomain and resource allocation callbacks. These are activated
+by selecting the Kconfig symbol GPIOLIB_IRQCHIP. If the symbol
+IRQ_DOMAIN_HIERARCHY is also selected, hierarchical helpers will also be
+provided. A big portion of overhead code will be managed by gpiolib,
+under the assumption that your interrupts are 1-to-1-mapped to the
+GPIO line index:
+
+  GPIO line offset   Hardware IRQ
+  0                  0
+  1                  1
+  2                  2
+  ...                ...
+  ngpio-1            ngpio-1
+
+If some GPIO lines do not have corresponding IRQs, the bitmask valid_mask
+and the flag need_valid_mask in gpio_irq_chip can be used to mask off some
+lines as invalid for associating with IRQs.
+
+The preferred way to set up the helpers is to fill in the
+struct gpio_irq_chip inside struct gpio_chip before adding the gpio_chip.
+If you do this, the additional irq_chip will be set up by gpiolib at the
+same time as setting up the rest of the GPIO functionality. The following
+is a typical example of a cascaded interrupt handler using gpio_irq_chip:
+
+  /* Typical state container with dynamic irqchip */
+  struct my_gpio {
+      struct gpio_chip gc;
+      struct irq_chip irq;
+  };
+
+  int irq; /* from platform etc */
+  struct my_gpio *g;
+  struct gpio_irq_chip *girq;
+
+  /* Set up the irqchip dynamically */
+  g->irq.name = "my_gpio_irq";
+  g->irq.irq_ack = my_gpio_ack_irq;
+  g->irq.irq_mask = my_gpio_mask_irq;
+  g->irq.irq_unmask = my_gpio_unmask_irq;
+  g->irq.irq_set_type = my_gpio_set_irq_type;
+
+  /* Get a pointer to the gpio_irq_chip */
+  girq = &g->gc.irq;
+  girq->chip = &g->irq;
+  girq->parent_handler = ftgpio_gpio_irq_handler;
+  girq->num_parents = 1;
+  girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
+                               GFP_KERNEL);
+  if (!girq->parents)
+      return -ENOMEM;
+  girq->default_type = IRQ_TYPE_NONE;
+  girq->handler = handle_bad_irq;
+  girq->parents[0] = irq;
+
+  return devm_gpiochip_add_data(dev, &g->gc, g);
+
+The helper support using hierarchical interrupt controllers as well.
+In this case the typical set-up will look like this:
+
+  /* Typical state container with dynamic irqchip */
+  struct my_gpio {
+      struct gpio_chip gc;
+      struct irq_chip irq;
+      struct fwnode_handle *fwnode;
+  };
+
+  int irq; /* from platform etc */
+  struct my_gpio *g;
+  struct gpio_irq_chip *girq;
+
+  /* Set up the irqchip dynamically */
+  g->irq.name = "my_gpio_irq";
+  g->irq.irq_ack = my_gpio_ack_irq;
+  g->irq.irq_mask = my_gpio_mask_irq;
+  g->irq.irq_unmask = my_gpio_unmask_irq;
+  g->irq.irq_set_type = my_gpio_set_irq_type;
+
+  /* Get a pointer to the gpio_irq_chip */
+  girq = &g->gc.irq;
+  girq->chip = &g->irq;
+  girq->default_type = IRQ_TYPE_NONE;
+  girq->handler = handle_bad_irq;
+  girq->fwnode = g->fwnode;
+  girq->parent_domain = parent;
+  girq->child_to_parent_hwirq = my_gpio_child_to_parent_hwirq;
+
+  return devm_gpiochip_add_data(dev, &g->gc, g);
+
+As you can see pretty similar, but you do not supply a parent handler for
+the IRQ, instead a parent irqdomain, an fwnode for the hardware and
+a funcion .child_to_parent_hwirq() that has the purpose of looking up
+the parent hardware irq from a child (i.e. this gpio chip) hardware irq.
+As always it is good to look at examples in the kernel tree for advice
+on how to find the required pieces.
+
+The old way of adding irqchips to gpiochips after registration is also still
+available but we try to move away from this:
+
+- DEPRECATED: gpiochip_irqchip_add(): adds a chained cascaded irqchip to a
+  gpiochip. It will pass the struct gpio_chip* for the chip to all IRQ
+  callbacks, so the callbacks need to embed the gpio_chip in its state
+  container and obtain a pointer to the container using container_of().
+  (See Documentation/driver-model/design-patterns.txt)
 
 - gpiochip_irqchip_add_nested(): adds a nested cascaded irqchip to a gpiochip,
   as discussed above regarding different types of cascaded irqchips. The
   cascaded irq has to be handled by a threaded interrupt handler.
   Apart from that it works exactly like the chained irqchip.
 
-- gpiochip_set_chained_irqchip(): sets up a chained cascaded irq handler for a
-  gpio_chip from a parent IRQ and passes the struct gpio_chip* as handler
-  data. Notice that we pass is as the handler data, since the irqchip data is
-  likely used by the parent irqchip.
+- DEPRECATED: gpiochip_set_chained_irqchip(): sets up a chained cascaded irq
+  handler for a gpio_chip from a parent IRQ and passes the struct gpio_chip*
+  as handler data. Notice that we pass is as the handler data, since the
+  irqchip data is likely used by the parent irqchip.
 
 - gpiochip_set_nested_irqchip(): sets up a nested cascaded irq handler for a
   gpio_chip from a parent IRQ. As the parent IRQ has usually been
@@ -418,11 +512,11 @@ symbol:
 
 If there is a need to exclude certain GPIO lines from the IRQ domain handled by
 these helpers, we can set .irq.need_valid_mask of the gpiochip before
-``[devm_]gpiochip_add_data()`` is called. This allocates an .irq.valid_mask with as
-many bits set as there are GPIO lines in the chip, each bit representing line
-0..n-1. Drivers can exclude GPIO lines by clearing bits from this mask. The mask
-must be filled in before gpiochip_irqchip_add() or gpiochip_irqchip_add_nested()
-is called.
+devm_gpiochip_add_data() or gpiochip_add_data() is called. This allocates an
+.irq.valid_mask with as many bits set as there are GPIO lines in the chip, each
+bit representing line 0..n-1. Drivers can exclude GPIO lines by clearing bits
+from this mask. The mask must be filled in before gpiochip_irqchip_add() or
+gpiochip_irqchip_add_nested() is called.
 
 To use the helpers please keep the following in mind:
 
diff --git a/Documentation/driver-api/sgi-ioc4.rst b/Documentation/driver-api/sgi-ioc4.rst
deleted file mode 100644 (file)
index 7270922..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-====================================
-SGI IOC4 PCI (multi function) device
-====================================
-
-The SGI IOC4 PCI device is a bit of a strange beast, so some notes on
-it are in order.
-
-First, even though the IOC4 performs multiple functions, such as an
-IDE controller, a serial controller, a PS/2 keyboard/mouse controller,
-and an external interrupt mechanism, it's not implemented as a
-multifunction device.  The consequence of this from a software
-standpoint is that all these functions share a single IRQ, and
-they can't all register to own the same PCI device ID.  To make
-matters a bit worse, some of the register blocks (and even registers
-themselves) present in IOC4 are mixed-purpose between these several
-functions, meaning that there's no clear "owning" device driver.
-
-The solution is to organize the IOC4 driver into several independent
-drivers, "ioc4", "sgiioc4", and "ioc4_serial".  Note that there is no
-PS/2 controller driver as this functionality has never been wired up
-on a shipping IO card.
-
-ioc4
-====
-This is the core (or shim) driver for IOC4.  It is responsible for
-initializing the basic functionality of the chip, and allocating
-the PCI resources that are shared between the IOC4 functions.
-
-This driver also provides registration functions that the other
-IOC4 drivers can call to make their presence known.  Each driver
-needs to provide a probe and remove function, which are invoked
-by the core driver at appropriate times.  The interface of these
-IOC4 function probe and remove operations isn't precisely the same
-as PCI device probe and remove operations, but is logically the
-same operation.
-
-sgiioc4
-=======
-This is the IDE driver for IOC4.  Its name isn't very descriptive
-simply for historical reasons (it used to be the only IOC4 driver
-component).  There's not much to say about it other than it hooks
-up to the ioc4 driver via the appropriate registration, probe, and
-remove functions.
-
-ioc4_serial
-===========
-This is the serial driver for IOC4.  There's not much to say about it
-other than it hooks up to the ioc4 driver via the appropriate registration,
-probe, and remove functions.
index 7fc2e24..cae7be2 100644 (file)
@@ -21,7 +21,7 @@
     |       nds32: | TODO |
     |       nios2: | TODO |
     |    openrisc: | TODO |
-    |      parisc: | TODO |
+    |      parisc: |  ok  |
     |     powerpc: |  ok  |
     |       riscv: | TODO |
     |        s390: |  ok  |
index 68f2669..4fae046 100644 (file)
@@ -21,7 +21,7 @@
     |       nds32: | TODO |
     |       nios2: | TODO |
     |    openrisc: | TODO |
-    |      parisc: | TODO |
+    |      parisc: |  ok  |
     |     powerpc: |  ok  |
     |       riscv: | TODO |
     |        s390: | TODO |
diff --git a/Documentation/hwmon/ads1015.rst b/Documentation/hwmon/ads1015.rst
deleted file mode 100644 (file)
index e0951c4..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-Kernel driver ads1015
-=====================
-
-Supported chips:
-
-  * Texas Instruments ADS1015
-
-    Prefix: 'ads1015'
-
-    Datasheet: Publicly available at the Texas Instruments website:
-
-              http://focus.ti.com/lit/ds/symlink/ads1015.pdf
-
-  * Texas Instruments ADS1115
-
-    Prefix: 'ads1115'
-
-    Datasheet: Publicly available at the Texas Instruments website:
-
-              http://focus.ti.com/lit/ds/symlink/ads1115.pdf
-
-Authors:
-       Dirk Eibach, Guntermann & Drunck GmbH <eibach@gdsys.de>
-
-Description
------------
-
-This driver implements support for the Texas Instruments ADS1015/ADS1115.
-
-This device is a 12/16-bit A-D converter with 4 inputs.
-
-The inputs can be used single ended or in certain differential combinations.
-
-The inputs can be made available by 8 sysfs input files in0_input - in7_input:
-
-  - in0: Voltage over AIN0 and AIN1.
-  - in1: Voltage over AIN0 and AIN3.
-  - in2: Voltage over AIN1 and AIN3.
-  - in3: Voltage over AIN2 and AIN3.
-  - in4: Voltage over AIN0 and GND.
-  - in5: Voltage over AIN1 and GND.
-  - in6: Voltage over AIN2 and GND.
-  - in7: Voltage over AIN3 and GND.
-
-Which inputs are available can be configured using platform data or devicetree.
-
-By default all inputs are exported.
-
-Platform Data
--------------
-
-In linux/platform_data/ads1015.h platform data is defined, channel_data contains
-configuration data for the used input combinations:
-
-- pga is the programmable gain amplifier (values are full scale)
-
-    - 0: +/- 6.144 V
-    - 1: +/- 4.096 V
-    - 2: +/- 2.048 V
-    - 3: +/- 1.024 V
-    - 4: +/- 0.512 V
-    - 5: +/- 0.256 V
-
-- data_rate in samples per second
-
-    - 0: 128
-    - 1: 250
-    - 2: 490
-    - 3: 920
-    - 4: 1600
-    - 5: 2400
-    - 6: 3300
-
-Example::
-
-  struct ads1015_platform_data data = {
-       .channel_data = {
-               [2] = { .enabled = true, .pga = 1, .data_rate = 0 },
-               [4] = { .enabled = true, .pga = 4, .data_rate = 5 },
-       }
-  };
-
-In this case only in2_input (FS +/- 4.096 V, 128 SPS) and in4_input
-(FS +/- 0.512 V, 2400 SPS) would be created.
-
-Devicetree
-----------
-
-Configuration is also possible via devicetree:
-Documentation/devicetree/bindings/hwmon/ads1015.txt
index ee090e5..8147c3f 100644 (file)
@@ -30,7 +30,6 @@ Hardware Monitoring Kernel Drivers
    adm1031
    adm1275
    adm9240
-   ads1015
    ads7828
    adt7410
    adt7411
@@ -130,6 +129,7 @@ Hardware Monitoring Kernel Drivers
    pcf8591
    pmbus
    powr1220
+   pxe1610
    pwm-fan
    raspberrypi-hwmon
    sch5627
diff --git a/Documentation/hwmon/inspur-ipsps1.rst b/Documentation/hwmon/inspur-ipsps1.rst
new file mode 100644 (file)
index 0000000..2b871ae
--- /dev/null
@@ -0,0 +1,79 @@
+Kernel driver inspur-ipsps1
+=======================
+
+Supported chips:
+
+  * Inspur Power System power supply unit
+
+Author: John Wang <wangzqbj@inspur.com>
+
+Description
+-----------
+
+This driver supports Inspur Power System power supplies. This driver
+is a client to the core PMBus driver.
+
+Usage Notes
+-----------
+
+This driver does not auto-detect devices. You will have to instantiate the
+devices explicitly. Please see Documentation/i2c/instantiating-devices for
+details.
+
+Sysfs entries
+-------------
+
+The following attributes are supported:
+
+======================= ======================================================
+curr1_input            Measured input current
+curr1_label            "iin"
+curr1_max              Maximum current
+curr1_max_alarm                Current high alarm
+curr2_input            Measured output current in mA.
+curr2_label            "iout1"
+curr2_crit             Critical maximum current
+curr2_crit_alarm       Current critical high alarm
+curr2_max              Maximum current
+curr2_max_alarm                Current high alarm
+
+fan1_alarm             Fan 1 warning.
+fan1_fault             Fan 1 fault.
+fan1_input             Fan 1 speed in RPM.
+
+in1_alarm              Input voltage under-voltage alarm.
+in1_input              Measured input voltage in mV.
+in1_label              "vin"
+in2_input              Measured output voltage in mV.
+in2_label              "vout1"
+in2_lcrit              Critical minimum output voltage
+in2_lcrit_alarm                Output voltage critical low alarm
+in2_max                        Maximum output voltage
+in2_max_alarm          Output voltage high alarm
+in2_min                        Minimum output voltage
+in2_min_alarm          Output voltage low alarm
+
+power1_alarm           Input fault or alarm.
+power1_input           Measured input power in uW.
+power1_label           "pin"
+power1_max             Input power limit
+power2_max_alarm       Output power high alarm
+power2_max             Output power limit
+power2_input           Measured output power in uW.
+power2_label           "pout"
+
+temp[1-3]_input                Measured temperature
+temp[1-2]_max          Maximum temperature
+temp[1-3]_max_alarm    Temperature high alarm
+
+vendor                 Manufacturer name
+model                  Product model
+part_number            Product part number
+serial_number          Product serial number
+fw_version             Firmware version
+hw_version             Hardware version
+mode                   Work mode. Can be set to active or
+                       standby, when set to standby, PSU will
+                       automatically switch between standby
+                       and redundancy mode.
+======================= ======================================================
index ba8acbd..e749f82 100644 (file)
@@ -119,9 +119,9 @@ Supported chips:
 
               http://www.ti.com/product/tmp275
 
-  * NXP LM75B
+  * NXP LM75B, PCT2075
 
-    Prefix: 'lm75b'
+    Prefix: 'lm75b', 'pct2075'
 
     Addresses scanned: none
 
@@ -129,6 +129,8 @@ Supported chips:
 
               http://www.nxp.com/documents/data_sheet/LM75B.pdf
 
+               http://www.nxp.com/docs/en/data-sheet/PCT2075.pdf
+
 Author: Frodo Looijaard <frodol@dds.nl>
 
 Description
similarity index 82%
rename from Documentation/hwmon/pxe1610
rename to Documentation/hwmon/pxe1610.rst
index 211cede..4f23888 100644 (file)
@@ -2,19 +2,29 @@ Kernel driver pxe1610
 =====================
 
 Supported chips:
+
   * Infineon PXE1610
+
     Prefix: 'pxe1610'
+
     Addresses scanned: -
+
     Datasheet: Datasheet is not publicly available.
 
   * Infineon PXE1110
+
     Prefix: 'pxe1110'
+
     Addresses scanned: -
+
     Datasheet: Datasheet is not publicly available.
 
   * Infineon PXM1310
+
     Prefix: 'pxm1310'
+
     Addresses scanned: -
+
     Datasheet: Datasheet is not publicly available.
 
 Author: Vijay Khemka <vijaykhemka@fb.com>
@@ -25,14 +35,19 @@ Description
 
 PXE1610/PXE1110 are Multi-rail/Multiphase Digital Controllers
 and compliant to
-       -- Intel VR13 DC-DC converter specifications.
-       -- Intel SVID protocol.
+
+       - Intel VR13 DC-DC converter specifications.
+       - Intel SVID protocol.
+
 Used for Vcore power regulation for Intel VR13 based microprocessors
-       -- Servers, Workstations, and High-end desktops
+
+       - Servers, Workstations, and High-end desktops
 
 PXM1310 is a Multi-rail Controller and it is compliant to
-       -- Intel VR13 DC-DC converter specifications.
-       -- Intel SVID protocol.
+
+       - Intel VR13 DC-DC converter specifications.
+       - Intel SVID protocol.
+
 Used for DDR3/DDR4 Memory power regulation for Intel VR13 and
 IMVP8 based systems
 
@@ -44,10 +59,10 @@ This driver does not probe for PMBus devices. You will have
 to instantiate devices explicitly.
 
 Example: the following commands will load the driver for an PXE1610
-at address 0x70 on I2C bus #4:
+at address 0x70 on I2C bus #4::
 
-# modprobe pxe1610
-# echo pxe1610 0x70 > /sys/bus/i2c/devices/i2c-4/new_device
+    # modprobe pxe1610
+    # echo pxe1610 0x70 > /sys/bus/i2c/devices/i2c-4/new_device
 
 It can also be instantiated by declaring in device tree
 
@@ -55,6 +70,7 @@ It can also be instantiated by declaring in device tree
 Sysfs attributes
 ----------------
 
+======================  ====================================
 curr1_label            "iin"
 curr1_input            Measured input current
 curr1_alarm            Current high alarm
@@ -88,3 +104,4 @@ temp[1-3]_crit               Critical high temperature
 temp[1-3]_crit_alarm   Chip temperature critical high alarm
 temp[1-3]_max          Maximum temperature
 temp[1-3]_max_alarm    Chip temperature high alarm
+======================  ====================================
index aa11633..9b0f1ee 100644 (file)
@@ -19,7 +19,17 @@ Supported chips:
 
     Addresses scanned: none
 
-    Datasheet: Not publicly available
+    Datasheet: http://www.sensirion.com/file/datasheet_shtw1
+
+
+
+  * Sensirion SHTC3
+
+    Prefix: 'shtc3'
+
+    Addresses scanned: none
+
+    Datasheet: http://www.sensirion.com/file/datasheet_shtc3
 
 
 
@@ -30,10 +40,9 @@ Author:
 Description
 -----------
 
-This driver implements support for the Sensirion SHTC1 chip, a humidity and
-temperature sensor. Temperature is measured in degrees celsius, relative
-humidity is expressed as a percentage. Driver can be used as well for SHTW1
-chip, which has the same electrical interface.
+This driver implements support for the Sensirion SHTC1, SHTW1, and SHTC3
+chips, a humidity and temperature sensor. Temperature is measured in degrees
+celsius, relative humidity is expressed as a percentage.
 
 The device communicates with the I2C protocol. All sensors are set to I2C
 address 0x70. See Documentation/i2c/instantiating-devices for methods to
index 452fc28..9a218ea 100644 (file)
@@ -20,6 +20,10 @@ increase the chances of your change being accepted.
   errors, no warnings, and few if any check messages. If there are any
   messages, please be prepared to explain.
 
+* Please use the standard multi-line comment style. Do not mix C and C++
+  style comments in a single driver (with the exception of the SPDX license
+  identifier).
+
 * If your patch generates checkpatch errors, warnings, or check messages,
   please refrain from explanations such as "I prefer that coding style".
   Keep in mind that each unnecessary message helps hiding a real problem,
@@ -120,8 +124,8 @@ increase the chances of your change being accepted.
   completely initialize your chip and your driver first, then register with
   the hwmon subsystem.
 
-* Use devm_hwmon_device_register_with_groups() or, if your driver needs a remove
-  function, hwmon_device_register_with_groups() to register your driver with the
+* Use devm_hwmon_device_register_with_info() or, if your driver needs a remove
+  function, hwmon_device_register_with_info() to register your driver with the
   hwmon subsystem. Try using devm_add_action() instead of a remove function if
   possible. Do not use hwmon_device_register().
 
diff --git a/Documentation/process/embargoed-hardware-issues.rst b/Documentation/process/embargoed-hardware-issues.rst
new file mode 100644 (file)
index 0000000..4026363
--- /dev/null
@@ -0,0 +1,279 @@
+Embargoed hardware issues
+=========================
+
+Scope
+-----
+
+Hardware issues which result in security problems are a different category
+of security bugs than pure software bugs which only affect the Linux
+kernel.
+
+Hardware issues like Meltdown, Spectre, L1TF etc. must be treated
+differently because they usually affect all Operating Systems ("OS") and
+therefore need coordination across different OS vendors, distributions,
+hardware vendors and other parties. For some of the issues, software
+mitigations can depend on microcode or firmware updates, which need further
+coordination.
+
+.. _Contact:
+
+Contact
+-------
+
+The Linux kernel hardware security team is separate from the regular Linux
+kernel security team.
+
+The team only handles the coordination of embargoed hardware security
+issues.  Reports of pure software security bugs in the Linux kernel are not
+handled by this team and the reporter will be guided to contact the regular
+Linux kernel security team (:ref:`Documentation/admin-guide/
+<securitybugs>`) instead.
+
+The team can be contacted by email at <hardware-security@kernel.org>. This
+is a private list of security officers who will help you to coordinate an
+issue according to our documented process.
+
+The list is encrypted and email to the list can be sent by either PGP or
+S/MIME encrypted and must be signed with the reporter's PGP key or S/MIME
+certificate. The list's PGP key and S/MIME certificate are available from
+https://www.kernel.org/....
+
+While hardware security issues are often handled by the affected hardware
+vendor, we welcome contact from researchers or individuals who have
+identified a potential hardware flaw.
+
+Hardware security officers
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The current team of hardware security officers:
+
+  - Linus Torvalds (Linux Foundation Fellow)
+  - Greg Kroah-Hartman (Linux Foundation Fellow)
+  - Thomas Gleixner (Linux Foundation Fellow)
+
+Operation of mailing-lists
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The encrypted mailing-lists which are used in our process are hosted on
+Linux Foundation's IT infrastructure. By providing this service Linux
+Foundation's director of IT Infrastructure security technically has the
+ability to access the embargoed information, but is obliged to
+confidentiality by his employment contract. Linux Foundation's director of
+IT Infrastructure security is also responsible for the kernel.org
+infrastructure.
+
+The Linux Foundation's current director of IT Infrastructure security is
+Konstantin Ryabitsev.
+
+
+Non-disclosure agreements
+-------------------------
+
+The Linux kernel hardware security team is not a formal body and therefore
+unable to enter into any non-disclosure agreements.  The kernel community
+is aware of the sensitive nature of such issues and offers a Memorandum of
+Understanding instead.
+
+
+Memorandum of Understanding
+---------------------------
+
+The Linux kernel community has a deep understanding of the requirement to
+keep hardware security issues under embargo for coordination between
+different OS vendors, distributors, hardware vendors and other parties.
+
+The Linux kernel community has successfully handled hardware security
+issues in the past and has the necessary mechanisms in place to allow
+community compliant development under embargo restrictions.
+
+The Linux kernel community has a dedicated hardware security team for
+initial contact, which oversees the process of handling such issues under
+embargo rules.
+
+The hardware security team identifies the developers (domain experts) who
+will form the initial response team for a particular issue. The initial
+response team can bring in further developers (domain experts) to address
+the issue in the best technical way.
+
+All involved developers pledge to adhere to the embargo rules and to keep
+the received information confidential. Violation of the pledge will lead to
+immediate exclusion from the current issue and removal from all related
+mailing-lists. In addition, the hardware security team will also exclude
+the offender from future issues. The impact of this consequence is a highly
+effective deterrent in our community. In case a violation happens the
+hardware security team will inform the involved parties immediately. If you
+or anyone becomes aware of a potential violation, please report it
+immediately to the Hardware security officers.
+
+
+Process
+^^^^^^^
+
+Due to the globally distributed nature of Linux kernel development,
+face-to-face meetings are almost impossible to address hardware security
+issues.  Phone conferences are hard to coordinate due to time zones and
+other factors and should be only used when absolutely necessary. Encrypted
+email has been proven to be the most effective and secure communication
+method for these types of issues.
+
+Start of Disclosure
+"""""""""""""""""""
+
+Disclosure starts by contacting the Linux kernel hardware security team by
+email. This initial contact should contain a description of the problem and
+a list of any known affected hardware. If your organization builds or
+distributes the affected hardware, we encourage you to also consider what
+other hardware could be affected.
+
+The hardware security team will provide an incident-specific encrypted
+mailing-list which will be used for initial discussion with the reporter,
+further disclosure and coordination.
+
+The hardware security team will provide the disclosing party a list of
+developers (domain experts) who should be informed initially about the
+issue after confirming with the developers  that they will adhere to this
+Memorandum of Understanding and the documented process. These developers
+form the initial response team and will be responsible for handling the
+issue after initial contact. The hardware security team is supporting the
+response team, but is not necessarily involved in the mitigation
+development process.
+
+While individual developers might be covered by a non-disclosure agreement
+via their employer, they cannot enter individual non-disclosure agreements
+in their role as Linux kernel developers. They will, however, agree to
+adhere to this documented process and the Memorandum of Understanding.
+
+
+Disclosure
+""""""""""
+
+The disclosing party provides detailed information to the initial response
+team via the specific encrypted mailing-list.
+
+From our experience the technical documentation of these issues is usually
+a sufficient starting point and further technical clarification is best
+done via email.
+
+Mitigation development
+""""""""""""""""""""""
+
+The initial response team sets up an encrypted mailing-list or repurposes
+an existing one if appropriate. The disclosing party should provide a list
+of contacts for all other parties who have already been, or should be,
+informed about the issue. The response team contacts these parties so they
+can name experts who should be subscribed to the mailing-list.
+
+Using a mailing-list is close to the normal Linux development process and
+has been successfully used in developing mitigations for various hardware
+security issues in the past.
+
+The mailing-list operates in the same way as normal Linux development.
+Patches are posted, discussed and reviewed and if agreed on applied to a
+non-public git repository which is only accessible to the participating
+developers via a secure connection. The repository contains the main
+development branch against the mainline kernel and backport branches for
+stable kernel versions as necessary.
+
+The initial response team will identify further experts from the Linux
+kernel developer community as needed and inform the disclosing party about
+their participation. Bringing in experts can happen at any time of the
+development process and often needs to be handled in a timely manner.
+
+Coordinated release
+"""""""""""""""""""
+
+The involved parties will negotiate the date and time where the embargo
+ends. At that point the prepared mitigations are integrated into the
+relevant kernel trees and published.
+
+While we understand that hardware security issues need coordinated embargo
+time, the embargo time should be constrained to the minimum time which is
+required for all involved parties to develop, test and prepare the
+mitigations. Extending embargo time artificially to meet conference talk
+dates or other non-technical reasons is creating more work and burden for
+the involved developers and response teams as the patches need to be kept
+up to date in order to follow the ongoing upstream kernel development,
+which might create conflicting changes.
+
+CVE assignment
+""""""""""""""
+
+Neither the hardware security team nor the initial response team assign
+CVEs, nor are CVEs required for the development process. If CVEs are
+provided by the disclosing party they can be used for documentation
+purposes.
+
+Process ambassadors
+-------------------
+
+For assistance with this process we have established ambassadors in various
+organizations, who can answer questions about or provide guidance on the
+reporting process and further handling. Ambassadors are not involved in the
+disclosure of a particular issue, unless requested by a response team or by
+an involved disclosed party. The current ambassadors list:
+
+  ============= ========================================================
+  ARM
+  AMD
+  IBM
+  Intel
+  Qualcomm     Trilok Soni <tsoni@codeaurora.org>
+
+  Microsoft    Sasha Levin <sashal@kernel.org>
+  VMware
+  Xen          Andrew Cooper <andrew.cooper3@citrix.com>
+
+  Canonical    Tyler Hicks <tyhicks@canonical.com>
+  Debian       Ben Hutchings <ben@decadent.org.uk>
+  Oracle       Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
+  Red Hat      Josh Poimboeuf <jpoimboe@redhat.com>
+  SUSE         Jiri Kosina <jkosina@suse.cz>
+
+  Amazon
+  Google       Kees Cook <keescook@chromium.org>
+  ============= ========================================================
+
+If you want your organization to be added to the ambassadors list, please
+contact the hardware security team. The nominated ambassador has to
+understand and support our process fully and is ideally well connected in
+the Linux kernel community.
+
+Encrypted mailing-lists
+-----------------------
+
+We use encrypted mailing-lists for communication. The operating principle
+of these lists is that email sent to the list is encrypted either with the
+list's PGP key or with the list's S/MIME certificate. The mailing-list
+software decrypts the email and re-encrypts it individually for each
+subscriber with the subscriber's PGP key or S/MIME certificate. Details
+about the mailing-list software and the setup which is used to ensure the
+security of the lists and protection of the data can be found here:
+https://www.kernel.org/....
+
+List keys
+^^^^^^^^^
+
+For initial contact see :ref:`Contact`. For incident specific mailing-lists
+the key and S/MIME certificate are conveyed to the subscribers by email
+sent from the specific list.
+
+Subscription to incident specific lists
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Subscription is handled by the response teams. Disclosed parties who want
+to participate in the communication send a list of potential subscribers to
+the response team so the response team can validate subscription requests.
+
+Each subscriber needs to send a subscription request to the response team
+by email. The email must be signed with the subscriber's PGP key or S/MIME
+certificate. If a PGP key is used, it must be available from a public key
+server and is ideally connected to the Linux kernel's PGP web of trust. See
+also: https://www.kernel.org/signature.html.
+
+The response team verifies that the subscriber request is valid and adds
+the subscriber to the list. After subscription the subscriber will receive
+email from the mailing-list which is signed either with the list's PGP key
+or the list's S/MIME certificate. The subscriber's email client can extract
+the PGP key or the S/MIME certificate from the signature so the subscriber
+can send encrypted email to the list.
+
index 878ebfd..e2c9ffc 100644 (file)
@@ -45,6 +45,7 @@ Other guides to the community that are of interest to most developers are:
    submit-checklist
    kernel-docs
    deprecated
+   embargoed-hardware-issues
 
 These are some overall technical guides that have been put here for now for
 lack of a better place.
index 1b73fea..14b1492 100644 (file)
@@ -18,7 +18,7 @@ The following 64-byte header is present in decompressed Linux kernel image.
        u32 res1  = 0;            /* Reserved */
        u64 res2  = 0;            /* Reserved */
        u64 magic = 0x5643534952; /* Magic number, little endian, "RISCV" */
-       u32 res3;                 /* Reserved for additional RISC-V specific header */
+       u32 magic2 = 0x56534905;  /* Magic number 2, little endian, "RSC\x05" */
        u32 res4;                 /* Reserved for PE COFF offset */
 
 This header format is compliant with PE/COFF header and largely inspired from
@@ -37,13 +37,14 @@ Notes:
        Bits 16:31 - Major version
 
   This preserves compatibility across newer and older version of the header.
-  The current version is defined as 0.1.
+  The current version is defined as 0.2.
 
-- res3 is reserved for offset to any other additional fields. This makes the
-  header extendible in future. One example would be to accommodate ISA
-  extension for RISC-V in future. For current version, it is set to be zero.
+- The "magic" field is deprecated as of version 0.2.  In a future
+  release, it may be removed.  This originally should have matched up
+  with the ARM64 header "magic" field, but unfortunately does not.
+  The "magic2" field replaces it, matching up with the ARM64 header.
 
-- In current header, the flag field has only one field.
+- In current header, the flags field has only one field.
        Bit 0: Kernel endianness. 1 if BE, 0 if LE.
 
 - Image size is mandatory for boot loader to load kernel image. Booting will
index 3296533..487852f 100644 (file)
@@ -6,3 +6,4 @@ Trusted Platform Module documentation
 
    tpm_vtpm_proxy
    xen-tpmfront
+   tpm_ftpm_tee
diff --git a/Documentation/security/tpm/tpm_ftpm_tee.rst b/Documentation/security/tpm/tpm_ftpm_tee.rst
new file mode 100644 (file)
index 0000000..8c2bae1
--- /dev/null
@@ -0,0 +1,27 @@
+=============================================
+Firmware TPM Driver
+=============================================
+
+This document describes the firmware Trusted Platform Module (fTPM)
+device driver.
+
+Introduction
+============
+
+This driver is a shim for firmware implemented in ARM's TrustZone
+environment. The driver allows programs to interact with the TPM in the same
+way they would interact with a hardware TPM.
+
+Design
+======
+
+The driver acts as a thin layer that passes commands to and from a TPM
+implemented in firmware. The driver itself doesn't contain much logic and is
+used more like a dumb pipe between firmware and kernel/userspace.
+
+The firmware itself is based on the following paper:
+https://www.microsoft.com/en-us/research/wp-content/uploads/2017/06/ftpm1.pdf
+
+When the driver is loaded it will expose ``/dev/tpmX`` character devices to
+userspace which will enable userspace to communicate with the firmware TPM
+through this device.
index 9cbcf16..9f1bc29 100644 (file)
@@ -517,14 +517,6 @@ W: http://ez.analog.com/community/linux-device-drivers
 S:     Supported
 F:     drivers/video/backlight/adp8860_bl.c
 
-ADS1015 HARDWARE MONITOR DRIVER
-M:     Dirk Eibach <eibach@gdsys.de>
-L:     linux-hwmon@vger.kernel.org
-S:     Maintained
-F:     Documentation/hwmon/ads1015.rst
-F:     drivers/hwmon/ads1015.c
-F:     include/linux/platform_data/ads1015.h
-
 ADT746X FAN DRIVER
 M:     Colin Leroy <colin@colino.net>
 S:     Maintained
@@ -683,7 +675,7 @@ S:  Maintained
 F:     drivers/crypto/sunxi-ss/
 
 ALLWINNER VPU DRIVER
-M:     Maxime Ripard <maxime.ripard@bootlin.com>
+M:     Maxime Ripard <mripard@kernel.org>
 M:     Paul Kocialkowski <paul.kocialkowski@bootlin.com>
 L:     linux-media@vger.kernel.org
 S:     Maintained
@@ -1350,8 +1342,7 @@ M:        Will Deacon <will@kernel.org>
 R:     Robin Murphy <robin.murphy@arm.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
-F:     drivers/iommu/arm-smmu.c
-F:     drivers/iommu/arm-smmu-v3.c
+F:     drivers/iommu/arm-smmu*
 F:     drivers/iommu/io-pgtable-arm.c
 F:     drivers/iommu/io-pgtable-arm-v7s.c
 
@@ -1408,7 +1399,7 @@ S:        Maintained
 F:     drivers/clk/sunxi/
 
 ARM/Allwinner sunXi SoC support
-M:     Maxime Ripard <maxime.ripard@bootlin.com>
+M:     Maxime Ripard <mripard@kernel.org>
 M:     Chen-Yu Tsai <wens@csie.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
@@ -1626,6 +1617,21 @@ F:       drivers/clocksource/timer-atlas7.c
 N:     [^a-z]sirf
 X:     drivers/gnss
 
+ARM/CZ.NIC TURRIS MOX SUPPORT
+M:     Marek Behun <marek.behun@nic.cz>
+W:     http://mox.turris.cz
+S:     Maintained
+F:     Documentation/ABI/testing/debugfs-moxtet
+F:     Documentation/ABI/testing/sysfs-bus-moxtet-devices
+F:     Documentation/ABI/testing/sysfs-firmware-turris-mox-rwtm
+F:     Documentation/devicetree/bindings/bus/moxtet.txt
+F:     Documentation/devicetree/bindings/firmware/cznic,turris-mox-rwtm.txt
+F:     Documentation/devicetree/bindings/gpio/gpio-moxtet.txt
+F:     include/linux/moxtet.h
+F:     drivers/bus/moxtet.c
+F:     drivers/firmware/turris-mox-rwtm.c
+F:     drivers/gpio/gpio-moxtet.c
+
 ARM/EBSA110 MACHINE SUPPORT
 M:     Russell King <linux@armlinux.org.uk>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1749,20 +1755,11 @@ L:      linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 F:     arch/arm/mach-pxa/colibri-pxa270-income.c
 
-ARM/INTEL IOP13XX ARM ARCHITECTURE
-M:     Lennert Buytenhek <kernel@wantstofly.org>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Maintained
-
 ARM/INTEL IOP32X ARM ARCHITECTURE
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
 
-ARM/INTEL IOP33X ARM ARCHITECTURE
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Orphan
-
 ARM/INTEL IQ81342EX MACHINE SUPPORT
 M:     Lennert Buytenhek <kernel@wantstofly.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -1921,12 +1918,6 @@ S:       Maintained
 F:     drivers/phy/mediatek/
 F:     Documentation/devicetree/bindings/phy/phy-mtk-*
 
-ARM/MICREL KS8695 ARCHITECTURE
-M:     Greg Ungerer <gerg@uclinux.org>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-F:     arch/arm/mach-ks8695/
-S:     Odd Fixes
-
 ARM/Microchip (AT91) SoC support
 M:     Nicolas Ferre <nicolas.ferre@microchip.com>
 M:     Alexandre Belloni <alexandre.belloni@bootlin.com>
@@ -1968,6 +1959,7 @@ F:        Documentation/devicetree/bindings/i2c/i2c-stu300.txt
 F:     arch/arm/mach-nomadik/
 F:     arch/arm/mach-u300/
 F:     arch/arm/mach-ux500/
+F:     drivers/soc/ux500/
 F:     arch/arm/boot/dts/ste-*
 F:     drivers/clk/clk-nomadik.c
 F:     drivers/clk/clk-u300.c
@@ -2011,22 +2003,6 @@ F:       drivers/*/*npcm*
 F:     Documentation/devicetree/bindings/*/*npcm*
 F:     Documentation/devicetree/bindings/*/*/*npcm*
 
-ARM/NUVOTON W90X900 ARM ARCHITECTURE
-M:     Wan ZongShun <mcuos.com@gmail.com>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-W:     http://www.mcuos.com
-S:     Maintained
-F:     arch/arm/mach-w90x900/
-F:     drivers/input/keyboard/w90p910_keypad.c
-F:     drivers/input/touchscreen/w90p910_ts.c
-F:     drivers/watchdog/nuc900_wdt.c
-F:     drivers/net/ethernet/nuvoton/w90p910_ether.c
-F:     drivers/mtd/nand/raw/nuc900_nand.c
-F:     drivers/rtc/rtc-nuc900.c
-F:     drivers/spi/spi-nuc900.c
-F:     drivers/usb/host/ehci-w90x900.c
-F:     drivers/video/fbdev/nuc900fb.c
-
 ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT
 L:     openmoko-kernel@lists.openmoko.org (subscribers-only)
 W:     http://wiki.openmoko.org/wiki/Neo_FreeRunner
@@ -2219,8 +2195,9 @@ F:        drivers/*/*s3c24*
 F:     drivers/*/*/*s3c24*
 F:     drivers/*/*s3c64xx*
 F:     drivers/*/*s5pv210*
-F:     drivers/memory/samsung/*
-F:     drivers/soc/samsung/*
+F:     drivers/memory/samsung/
+F:     drivers/soc/samsung/
+F:     include/linux/soc/samsung/
 F:     Documentation/arm/samsung/
 F:     Documentation/devicetree/bindings/arm/samsung/
 F:     Documentation/devicetree/bindings/sram/samsung-sram.txt
@@ -3577,7 +3554,7 @@ F:        Documentation/filesystems/caching/cachefiles.txt
 F:     fs/cachefiles/
 
 CADENCE MIPI-CSI2 BRIDGES
-M:     Maxime Ripard <maxime.ripard@bootlin.com>
+M:     Maxime Ripard <mripard@kernel.org>
 L:     linux-media@vger.kernel.org
 S:     Maintained
 F:     Documentation/devicetree/bindings/media/cdns,*.txt
@@ -4290,6 +4267,14 @@ S:       Supported
 F:     drivers/cpuidle/cpuidle-exynos.c
 F:     arch/arm/mach-exynos/pm.c
 
+CPUIDLE DRIVER - ARM PSCI
+M:     Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+M:     Sudeep Holla <sudeep.holla@arm.com>
+L:     linux-pm@vger.kernel.org
+L:     linux-arm-kernel@lists.infradead.org
+S:     Supported
+F:     drivers/cpuidle/cpuidle-psci.c
+
 CPU IDLE TIME MANAGEMENT FRAMEWORK
 M:     "Rafael J. Wysocki" <rjw@rjwysocki.net>
 M:     Daniel Lezcano <daniel.lezcano@linaro.org>
@@ -5295,7 +5280,7 @@ F:        include/linux/vga*
 
 DRM DRIVERS AND MISC GPU PATCHES
 M:     Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
-M:     Maxime Ripard <maxime.ripard@bootlin.com>
+M:     Maxime Ripard <mripard@kernel.org>
 M:     Sean Paul <sean@poorly.run>
 W:     https://01.org/linuxgraphics/gfx-docs/maintainer-tools/drm-misc.html
 S:     Maintained
@@ -5308,7 +5293,7 @@ F:        include/uapi/drm/drm*
 F:     include/linux/vga*
 
 DRM DRIVERS FOR ALLWINNER A10
-M:     Maxime Ripard  <maxime.ripard@bootlin.com>
+M:     Maxime Ripard <mripard@kernel.org>
 L:     dri-devel@lists.freedesktop.org
 S:     Supported
 F:     drivers/gpu/drm/sun4i/
@@ -5761,6 +5746,11 @@ S:       Supported
 F:     drivers/edac/aspeed_edac.c
 F:     Documentation/devicetree/bindings/edac/aspeed-sdram-edac.txt
 
+EDAC-BLUEFIELD
+M:     Shravan Kumar Ramani <sramani@mellanox.com>
+S:     Supported
+F:     drivers/edac/bluefield_edac.c
+
 EDAC-CALXEDA
 M:     Robert Richter <rric@kernel.org>
 L:     linux-edac@vger.kernel.org
@@ -5785,10 +5775,11 @@ F:      drivers/edac/thunderx_edac*
 EDAC-CORE
 M:     Borislav Petkov <bp@alien8.de>
 M:     Mauro Carvalho Chehab <mchehab@kernel.org>
+M:     Tony Luck <tony.luck@intel.com>
 R:     James Morse <james.morse@arm.com>
+R:     Robert Richter <rrichter@marvell.com>
 L:     linux-edac@vger.kernel.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git for-next
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-edac.git linux_next
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras.git edac-for-next
 S:     Supported
 F:     Documentation/admin-guide/ras.rst
 F:     Documentation/driver-api/edac.rst
@@ -6331,15 +6322,6 @@ S:       Odd Fixes
 L:     linux-block@vger.kernel.org
 F:     drivers/block/floppy.c
 
-FMC SUBSYSTEM
-M:     Alessandro Rubini <rubini@gnudd.com>
-W:     http://www.ohwr.org/projects/fmc-bus
-S:     Supported
-F:     drivers/fmc/
-F:     include/linux/fmc*.h
-F:     include/linux/ipmi-fru.h
-K:     fmc_d.*register
-
 FPGA MANAGER FRAMEWORK
 M:     Moritz Fischer <mdf@kernel.org>
 L:     linux-fpga@vger.kernel.org
@@ -6439,6 +6421,7 @@ M:        Frank Li <Frank.li@nxp.com>
 L:     linux-arm-kernel@lists.infradead.org
 S:     Maintained
 F:     drivers/perf/fsl_imx8_ddr_perf.c
+F:     Documentation/admin-guide/perf/imx-ddr.rst
 F:     Documentation/devicetree/bindings/perf/fsl-imx-ddr.txt
 
 FREESCALE IMX I2C DRIVER
@@ -6732,6 +6715,13 @@ W:       https://linuxtv.org
 S:     Maintained
 F:     drivers/media/radio/radio-gemtek*
 
+GENERIC ARCHITECTURE TOPOLOGY
+M:     Sudeep Holla <sudeep.holla@arm.com>
+L:     linux-kernel@vger.kernel.org
+S:     Maintained
+F:     drivers/base/arch_topology.c
+F:     include/linux/arch_topology.h
+
 GENERIC GPIO I2C DRIVER
 M:     Wolfram Sang <wsa+renesas@sang-engineering.com>
 S:     Supported
@@ -7513,7 +7503,7 @@ I2C MV64XXX MARVELL AND ALLWINNER DRIVER
 M:     Gregory CLEMENT <gregory.clement@bootlin.com>
 L:     linux-i2c@vger.kernel.org
 S:     Maintained
-F:     Documentation/devicetree/bindings/i2c/i2c-mv64xxx.txt
+F:     Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml
 F:     drivers/i2c/busses/i2c-mv64xxx.c
 
 I2C OVER PARALLEL PORT
@@ -8385,12 +8375,6 @@ F:       Documentation/x86/intel_txt.rst
 F:     include/linux/tboot.h
 F:     arch/x86/kernel/tboot.c
 
-INTEL-MID GPIO DRIVER
-M:     David Cohen <david.a.cohen@linux.intel.com>
-L:     linux-gpio@vger.kernel.org
-S:     Maintained
-F:     drivers/gpio/gpio-intel-mid.c
-
 INTERCONNECT API
 M:     Georgi Djakov <georgi.djakov@linaro.org>
 L:     linux-pm@vger.kernel.org
@@ -8415,12 +8399,6 @@ L:       linux-mips@vger.kernel.org
 S:     Maintained
 F:     drivers/net/ethernet/sgi/ioc3-eth.c
 
-IOC3 SERIAL DRIVER
-M:     Pat Gefre <pfg@sgi.com>
-L:     linux-serial@vger.kernel.org
-S:     Maintained
-F:     drivers/tty/serial/ioc3_serial.c
-
 IOMAP FILESYSTEM LIBRARY
 M:     Christoph Hellwig <hch@infradead.org>
 M:     Darrick J. Wong <darrick.wong@oracle.com>
@@ -8454,11 +8432,6 @@ S:       Maintained
 F:     fs/io_uring.c
 F:     include/uapi/linux/io_uring.h
 
-IP MASQUERADING
-M:     Juanjo Ciarlante <jjciarla@raiz.uncu.edu.ar>
-S:     Maintained
-F:     net/ipv4/netfilter/ipt_MASQUERADE.c
-
 IPMI SUBSYSTEM
 M:     Corey Minyard <minyard@acm.org>
 L:     openipmi-developer@lists.sourceforge.net (moderated for non-subscribers)
@@ -8938,7 +8911,7 @@ F:        security/keys/encrypted-keys/
 
 KEYS-TRUSTED
 M:     James Bottomley <jejb@linux.ibm.com>
-M:      Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+M:     Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
 M:     Mimi Zohar <zohar@linux.ibm.com>
 L:     linux-integrity@vger.kernel.org
 L:     keyrings@vger.kernel.org
@@ -9234,6 +9207,18 @@ F:       include/linux/nd.h
 F:     include/linux/libnvdimm.h
 F:     include/uapi/linux/ndctl.h
 
+LICENSES and SPDX stuff
+M:     Thomas Gleixner <tglx@linutronix.de>
+M:     Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+L:     linux-spdx@vger.kernel.org
+S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/spdx.git
+F:     COPYING
+F:     Documentation/process/license-rules.rst
+F:     LICENSES/
+F:     scripts/spdxcheck-test.sh
+F:     scripts/spdxcheck.py
+
 LIGHTNVM PLATFORM SUPPORT
 M:     Matias Bjorling <mb@lightnvm.io>
 W:     http://github/OpenChannelSSD
@@ -10031,8 +10016,8 @@ L:      linux-media@vger.kernel.org
 L:     linux-renesas-soc@vger.kernel.org
 T:     git git://linuxtv.org/media_tree.git
 S:     Supported
-F:     Documentation/devicetree/bindings/media/renesas,rcar-csi2.txt
-F:     Documentation/devicetree/bindings/media/rcar_vin.txt
+F:     Documentation/devicetree/bindings/media/renesas,csi2.txt
+F:     Documentation/devicetree/bindings/media/renesas,vin.txt
 F:     drivers/media/platform/rcar-vin/
 
 MEDIA DRIVERS FOR RENESAS - VSP1
@@ -10629,12 +10614,6 @@ M:     Nicolas Ferre <nicolas.ferre@microchip.com>
 S:     Supported
 F:     drivers/power/reset/at91-sama5d2_shdwc.c
 
-MICROCHIP SAMA5D2-COMPATIBLE PIOBU GPIO
-M:     Andrei Stefanescu <andrei.stefanescu@microchip.com>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-L:     linux-gpio@vger.kernel.org
-F:     drivers/gpio/gpio-sama5d2-piobu.c
-
 MICROCHIP SPI DRIVER
 M:     Nicolas Ferre <nicolas.ferre@microchip.com>
 S:     Supported
@@ -10647,13 +10626,6 @@ S:     Supported
 F:     drivers/misc/atmel-ssc.c
 F:     include/linux/atmel-ssc.h
 
-MICROCHIP TIMER COUNTER (TC) AND CLOCKSOURCE DRIVERS
-M:     Nicolas Ferre <nicolas.ferre@microchip.com>
-L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S:     Supported
-F:     drivers/misc/atmel_tclib.c
-F:     drivers/clocksource/tcb_clksrc.c
-
 MICROCHIP USBA UDC DRIVER
 M:     Cristian Birsan <cristian.birsan@microchip.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
@@ -11086,7 +11058,7 @@ NET_FAILOVER MODULE
 M:     Sridhar Samudrala <sridhar.samudrala@intel.com>
 L:     netdev@vger.kernel.org
 S:     Supported
-F:     driver/net/net_failover.c
+F:     drivers/net/net_failover.c
 F:     include/net/net_failover.h
 F:     Documentation/networking/net_failover.rst
 
@@ -12695,6 +12667,7 @@ L:      linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-gpio@vger.kernel.org
 S:     Supported
 F:     drivers/pinctrl/pinctrl-at91*
+F:     drivers/gpio/gpio-sama5d2-piobu.c
 
 PIN CONTROLLER - FREESCALE
 M:     Dong Aisheng <aisheng.dong@nxp.com>
@@ -14128,6 +14101,8 @@ M:      Kamil Konieczny <k.konieczny@partner.samsung.com>
 L:     linux-crypto@vger.kernel.org
 L:     linux-samsung-soc@vger.kernel.org
 S:     Maintained
+F:     Documentation/devicetree/bindings/crypto/samsung-slimsss.txt
+F:     Documentation/devicetree/bindings/crypto/samsung-sss.txt
 F:     drivers/crypto/s5p-sss.c
 
 SAMSUNG S5P/EXYNOS4 SOC SERIES CAMERA SUBSYSTEM DRIVERS
@@ -14148,6 +14123,8 @@ T:      git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
 F:     drivers/clk/samsung/
 F:     include/dt-bindings/clock/exynos*.h
 F:     Documentation/devicetree/bindings/clock/exynos*.txt
+F:     Documentation/devicetree/bindings/clock/samsung,s3c*
+F:     Documentation/devicetree/bindings/clock/samsung,s5p*
 
 SAMSUNG SPI DRIVERS
 M:     Kukjin Kim <kgene@kernel.org>
@@ -14478,6 +14455,7 @@ F:      drivers/net/phy/phylink.c
 F:     drivers/net/phy/sfp*
 F:     include/linux/phylink.h
 F:     include/linux/sfp.h
+K:     phylink
 
 SGI GRU DRIVER
 M:     Dimitri Sivanich <sivanich@sgi.com>
@@ -15567,6 +15545,7 @@ F:      drivers/clk/clk-sc[mp]i.c
 F:     drivers/cpufreq/sc[mp]i-cpufreq.c
 F:     drivers/firmware/arm_scpi.c
 F:     drivers/firmware/arm_scmi/
+F:     drivers/reset/reset-scmi.c
 F:     include/linux/sc[mp]i_protocol.h
 
 SYSTEM RESET/SHUTDOWN DRIVERS
@@ -15875,6 +15854,7 @@ F:      drivers/firmware/ti_sci*
 F:     include/linux/soc/ti/ti_sci_protocol.h
 F:     Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
 F:     drivers/soc/ti/ti_sci_pm_domains.c
+F:     include/dt-bindings/soc/ti,sci_pm_domain.h
 F:     Documentation/devicetree/bindings/reset/ti,sci-reset.txt
 F:     Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 F:     drivers/clk/keystone/sci-clk.c
@@ -17255,6 +17235,7 @@ F:      Documentation/power/regulator/
 F:     drivers/regulator/
 F:     include/dt-bindings/regulator/
 F:     include/linux/regulator/
+K:     regulator_get_optional
 
 VRF
 M:     David Ahern <dsa@cumulusnetworks.com>
@@ -17691,8 +17672,7 @@ F:      include/uapi/linux/dqblk_xfs.h
 F:     include/uapi/linux/fsmap.h
 
 XILINX AXI ETHERNET DRIVER
-M:     Anirudha Sarangi <anirudh@xilinx.com>
-M:     John Linn <John.Linn@xilinx.com>
+M:     Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
 S:     Maintained
 F:     drivers/net/ethernet/xilinx/xilinx_axienet*
 
index f125625..4262ef9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 5
 PATCHLEVEL = 3
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
+EXTRAVERSION =
 NAME = Bobtail Squid
 
 # *DOCUMENTATION*
@@ -913,6 +913,10 @@ ifeq ($(CONFIG_STRIP_ASM_SYMS),y)
 LDFLAGS_vmlinux        += $(call ld-option, -X,)
 endif
 
+ifeq ($(CONFIG_RELR),y)
+LDFLAGS_vmlinux        += --pack-dyn-relocs=relr
+endif
+
 # insure the checker run with the right endianness
 CHECKFLAGS += $(if $(CONFIG_CPU_BIG_ENDIAN),-mbig-endian,-mlittle-endian)
 
index a7b57dd..71d9ae0 100644 (file)
@@ -18,6 +18,9 @@ config KEXEC_CORE
        select CRASH_CORE
        bool
 
+config KEXEC_ELF
+       bool
+
 config HAVE_IMA_KEXEC
        bool
 
@@ -925,6 +928,20 @@ config LOCK_EVENT_COUNTS
          the chance of application behavior change because of timing
          differences. The counts are reported via debugfs.
 
+# Select if the architecture has support for applying RELR relocations.
+config ARCH_HAS_RELR
+       bool
+
+config RELR
+       bool "Use RELR relocation packing"
+       depends on ARCH_HAS_RELR && TOOLS_SUPPORT_RELR
+       default y
+       help
+         Store the kernel's dynamic relocations in the RELR relocation packing
+         format. Requires a compatible linker (LLD supports this feature), as
+         well as compatible NM and OBJCOPY utilities (llvm-nm and llvm-objcopy
+         are compatible).
+
 source "kernel/gcov/Kconfig"
 
 source "scripts/gcc-plugins/Kconfig"
index a83c4f5..8483a86 100644 (file)
@@ -12,3 +12,6 @@ dtb-y := $(builtindtb-y).dtb
 # for CONFIG_OF_ALL_DTBS test
 dtstree        := $(srctree)/$(src)
 dtb-   := $(patsubst $(dtstree)/%.dts,%.dtb, $(wildcard $(dtstree)/*.dts))
+
+# board-specific dtc flags
+DTC_FLAGS_hsdk += --pad 20
index f5ae394..41b16f2 100644 (file)
 
 .macro FAKE_RET_FROM_EXCPN
        lr      r9, [status32]
-       bic     r9, r9, (STATUS_U_MASK|STATUS_DE_MASK|STATUS_AE_MASK)
+       bic     r9, r9, STATUS_AE_MASK
        or      r9, r9, STATUS_IE_MASK
        kflag   r9
 .endm
index a0eeb9f..d9ee43c 100644 (file)
 #else  /* !__ASSEMBLY__ */
 
 #ifdef CONFIG_ARC_HAS_ICCM
-#define __arcfp_code __attribute__((__section__(".text.arcfp")))
+#define __arcfp_code __section(.text.arcfp)
 #else
-#define __arcfp_code __attribute__((__section__(".text")))
+#define __arcfp_code __section(.text)
 #endif
 
 #ifdef CONFIG_ARC_HAS_DCCM
-#define __arcfp_data __attribute__((__section__(".data.arcfp")))
+#define __arcfp_data __section(.data.arcfp)
 #else
-#define __arcfp_data __attribute__((__section__(".data")))
+#define __arcfp_data __section(.data)
 #endif
 
 #endif /* __ASSEMBLY__ */
index 8ac0e2a..73746ed 100644 (file)
@@ -53,8 +53,7 @@ extern const struct machine_desc __arch_info_begin[], __arch_info_end[];
  */
 #define MACHINE_START(_type, _name)                    \
 static const struct machine_desc __mach_desc_##_type   \
-__used                                                 \
-__attribute__((__section__(".arch.info.init"))) = {    \
+__used __section(.arch.info.init) = {                  \
        .name           = _name,
 
 #define MACHINE_END                            \
index 18b493d..abf9398 100644 (file)
@@ -202,8 +202,8 @@ static void idu_set_dest(unsigned int cmn_irq, unsigned int cpu_mask)
        __mcip_cmd_data(CMD_IDU_SET_DEST, cmn_irq, cpu_mask);
 }
 
-static void idu_set_mode(unsigned int cmn_irq, unsigned int lvl,
-                          unsigned int distr)
+static void idu_set_mode(unsigned int cmn_irq, bool set_lvl, unsigned int lvl,
+                        bool set_distr, unsigned int distr)
 {
        union {
                unsigned int word;
@@ -212,8 +212,11 @@ static void idu_set_mode(unsigned int cmn_irq, unsigned int lvl,
                };
        } data;
 
-       data.distr = distr;
-       data.lvl = lvl;
+       data.word = __mcip_cmd_read(CMD_IDU_READ_MODE, cmn_irq);
+       if (set_distr)
+               data.distr = distr;
+       if (set_lvl)
+               data.lvl = lvl;
        __mcip_cmd_data(CMD_IDU_SET_MODE, cmn_irq, data.word);
 }
 
@@ -240,6 +243,25 @@ static void idu_irq_unmask(struct irq_data *data)
        raw_spin_unlock_irqrestore(&mcip_lock, flags);
 }
 
+static void idu_irq_ack(struct irq_data *data)
+{
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&mcip_lock, flags);
+       __mcip_cmd(CMD_IDU_ACK_CIRQ, data->hwirq);
+       raw_spin_unlock_irqrestore(&mcip_lock, flags);
+}
+
+static void idu_irq_mask_ack(struct irq_data *data)
+{
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&mcip_lock, flags);
+       __mcip_cmd_data(CMD_IDU_SET_MASK, data->hwirq, 1);
+       __mcip_cmd(CMD_IDU_ACK_CIRQ, data->hwirq);
+       raw_spin_unlock_irqrestore(&mcip_lock, flags);
+}
+
 static int
 idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask,
                     bool force)
@@ -263,13 +285,36 @@ idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask,
        else
                distribution_mode = IDU_M_DISTRI_RR;
 
-       idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, distribution_mode);
+       idu_set_mode(data->hwirq, false, 0, true, distribution_mode);
 
        raw_spin_unlock_irqrestore(&mcip_lock, flags);
 
        return IRQ_SET_MASK_OK;
 }
 
+static int idu_irq_set_type(struct irq_data *data, u32 type)
+{
+       unsigned long flags;
+
+       /*
+        * ARCv2 IDU HW does not support inverse polarity, so these are the
+        * only interrupt types supported.
+        */
+       if (type & ~(IRQ_TYPE_EDGE_RISING | IRQ_TYPE_LEVEL_HIGH))
+               return -EINVAL;
+
+       raw_spin_lock_irqsave(&mcip_lock, flags);
+
+       idu_set_mode(data->hwirq, true,
+                    type & IRQ_TYPE_EDGE_RISING ? IDU_M_TRIG_EDGE :
+                                                  IDU_M_TRIG_LEVEL,
+                    false, 0);
+
+       raw_spin_unlock_irqrestore(&mcip_lock, flags);
+
+       return 0;
+}
+
 static void idu_irq_enable(struct irq_data *data)
 {
        /*
@@ -289,7 +334,10 @@ static struct irq_chip idu_irq_chip = {
        .name                   = "MCIP IDU Intc",
        .irq_mask               = idu_irq_mask,
        .irq_unmask             = idu_irq_unmask,
+       .irq_ack                = idu_irq_ack,
+       .irq_mask_ack           = idu_irq_mask_ack,
        .irq_enable             = idu_irq_enable,
+       .irq_set_type           = idu_irq_set_type,
 #ifdef CONFIG_SMP
        .irq_set_affinity       = idu_irq_set_affinity,
 #endif
@@ -317,7 +365,7 @@ static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t
 }
 
 static const struct irq_domain_ops idu_irq_ops = {
-       .xlate  = irq_domain_xlate_onecell,
+       .xlate  = irq_domain_xlate_onetwocell,
        .map    = idu_irq_map,
 };
 
index c2663fc..dc05a63 100644 (file)
@@ -572,6 +572,7 @@ static unsigned long read_pointer(const u8 **pLoc, const void *end,
 #else
                BUILD_BUG_ON(sizeof(u32) != sizeof(value));
 #endif
+               /* Fall through */
        case DW_EH_PE_native:
                if (end < (const void *)(ptr.pul + 1))
                        return 0;
@@ -826,7 +827,7 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
                        case DW_CFA_def_cfa:
                                state->cfa.reg = get_uleb128(&ptr.p8, end);
                                unw_debug("cfa_def_cfa: r%lu ", state->cfa.reg);
-                               /*nobreak*/
+                               /* fall through */
                        case DW_CFA_def_cfa_offset:
                                state->cfa.offs = get_uleb128(&ptr.p8, end);
                                unw_debug("cfa_def_cfa_offset: 0x%lx ",
@@ -834,7 +835,7 @@ static int processCFI(const u8 *start, const u8 *end, unsigned long targetLoc,
                                break;
                        case DW_CFA_def_cfa_sf:
                                state->cfa.reg = get_uleb128(&ptr.p8, end);
-                               /*nobreak */
+                               /* fall through */
                        case DW_CFA_def_cfa_offset_sf:
                                state->cfa.offs = get_sleb128(&ptr.p8, end)
                                    * state->dataAlign;
index 62c210e..70a3fbe 100644 (file)
@@ -101,7 +101,7 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
        if (is_isa_arcv2() && ioc_enable && coherent)
                dev->dma_coherent = true;
 
-       dev_info(dev, "use %sncoherent DMA ops\n",
+       dev_info(dev, "use %scoherent DMA ops\n",
                 dev->dma_coherent ? "" : "non");
 }
 
index 7dd2dd3..0b961a2 100644 (file)
@@ -6,11 +6,15 @@
  */
 
 #include <linux/init.h>
+#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
 #include <linux/smp.h>
 #include <asm/arcregs.h>
 #include <asm/io.h>
 #include <asm/mach_desc.h>
 
+int arc_hsdk_axi_dmac_coherent __section(.data) = 0;
+
 #define ARC_CCM_UNUSED_ADDR    0x60000000
 
 static void __init hsdk_init_per_cpu(unsigned int cpu)
@@ -97,6 +101,42 @@ static void __init hsdk_enable_gpio_intc_wire(void)
        iowrite32(GPIO_INT_CONNECTED_MASK, (void __iomem *) GPIO_INTEN);
 }
 
+static int __init hsdk_tweak_node_coherency(const char *path, bool coherent)
+{
+       void *fdt = initial_boot_params;
+       const void *prop;
+       int node, ret;
+       bool dt_coh_set;
+
+       node = fdt_path_offset(fdt, path);
+       if (node < 0)
+               goto tweak_fail;
+
+       prop = fdt_getprop(fdt, node, "dma-coherent", &ret);
+       if (!prop && ret != -FDT_ERR_NOTFOUND)
+               goto tweak_fail;
+
+       dt_coh_set = ret != -FDT_ERR_NOTFOUND;
+       ret = 0;
+
+       /* need to remove "dma-coherent" property */
+       if (dt_coh_set && !coherent)
+               ret = fdt_delprop(fdt, node, "dma-coherent");
+
+       /* need to set "dma-coherent" property */
+       if (!dt_coh_set && coherent)
+               ret = fdt_setprop(fdt, node, "dma-coherent", NULL, 0);
+
+       if (ret < 0)
+               goto tweak_fail;
+
+       return 0;
+
+tweak_fail:
+       pr_err("failed to tweak %s to %scoherent\n", path, coherent ? "" : "non");
+       return -EFAULT;
+}
+
 enum hsdk_axi_masters {
        M_HS_CORE = 0,
        M_HS_RTT,
@@ -162,6 +202,39 @@ enum hsdk_axi_masters {
 #define CREG_PAE               ((void __iomem *)(CREG_BASE + 0x180))
 #define CREG_PAE_UPDT          ((void __iomem *)(CREG_BASE + 0x194))
 
+static void __init hsdk_init_memory_bridge_axi_dmac(void)
+{
+       bool coherent = !!arc_hsdk_axi_dmac_coherent;
+       u32 axi_m_slv1, axi_m_oft1;
+
+       /*
+        * Don't tweak memory bridge configuration if we failed to tweak DTB
+        * as we will end up in a inconsistent state.
+        */
+       if (hsdk_tweak_node_coherency("/soc/dmac@80000", coherent))
+               return;
+
+       if (coherent) {
+               axi_m_slv1 = 0x77999999;
+               axi_m_oft1 = 0x76DCBA98;
+       } else {
+               axi_m_slv1 = 0x77777777;
+               axi_m_oft1 = 0x76543210;
+       }
+
+       writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_0));
+       writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_0));
+       writel(axi_m_slv1, CREG_AXI_M_SLV1(M_DMAC_0));
+       writel(axi_m_oft1, CREG_AXI_M_OFT1(M_DMAC_0));
+       writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_0));
+
+       writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_1));
+       writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_1));
+       writel(axi_m_slv1, CREG_AXI_M_SLV1(M_DMAC_1));
+       writel(axi_m_oft1, CREG_AXI_M_OFT1(M_DMAC_1));
+       writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_1));
+}
+
 static void __init hsdk_init_memory_bridge(void)
 {
        u32 reg;
@@ -227,24 +300,14 @@ static void __init hsdk_init_memory_bridge(void)
        writel(0x76543210, CREG_AXI_M_OFT1(M_GPU));
        writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_GPU));
 
-       writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_0));
-       writel(0x77777777, CREG_AXI_M_SLV1(M_DMAC_0));
-       writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_0));
-       writel(0x76543210, CREG_AXI_M_OFT1(M_DMAC_0));
-       writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_0));
-
-       writel(0x77777777, CREG_AXI_M_SLV0(M_DMAC_1));
-       writel(0x77777777, CREG_AXI_M_SLV1(M_DMAC_1));
-       writel(0xFEDCBA98, CREG_AXI_M_OFT0(M_DMAC_1));
-       writel(0x76543210, CREG_AXI_M_OFT1(M_DMAC_1));
-       writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DMAC_1));
-
        writel(0x00000000, CREG_AXI_M_SLV0(M_DVFS));
        writel(0x60000000, CREG_AXI_M_SLV1(M_DVFS));
        writel(0x00000000, CREG_AXI_M_OFT0(M_DVFS));
        writel(0x00000000, CREG_AXI_M_OFT1(M_DVFS));
        writel(UPDATE_VAL, CREG_AXI_M_UPDT(M_DVFS));
 
+       hsdk_init_memory_bridge_axi_dmac();
+
        /*
         * PAE remapping for DMA clients does not work due to an RTL bug, so
         * CREG_PAE register must be programmed to all zeroes, otherwise it
index 2436021..2ae7f8a 100644 (file)
@@ -267,8 +267,6 @@ config PHYS_OFFSET
        default 0x00000000 if ARCH_EBSA110 || \
                        ARCH_FOOTBRIDGE || \
                        ARCH_INTEGRATOR || \
-                       ARCH_IOP13XX || \
-                       ARCH_KS8695 || \
                        ARCH_REALVIEW
        default 0x10000000 if ARCH_OMAP1 || ARCH_RPC
        default 0x20000000 if ARCH_S5PV210
@@ -381,19 +379,6 @@ config ARCH_FOOTBRIDGE
          Support for systems based on the DC21285 companion chip
          ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder.
 
-config ARCH_IOP13XX
-       bool "IOP13xx-based"
-       depends on MMU
-       select CPU_XSC3
-       select NEED_MACH_MEMORY_H
-       select NEED_RET_TO_USER
-       select FORCE_PCI
-       select PLAT_IOP
-       select VMSPLIT_1G
-       select SPARSE_IRQ
-       help
-         Support for Intel's IOP13XX (XScale) family of processors.
-
 config ARCH_IOP32X
        bool "IOP32x-based"
        depends on MMU
@@ -407,18 +392,6 @@ config ARCH_IOP32X
          Support for Intel's 80219 and IOP32X (XScale) family of
          processors.
 
-config ARCH_IOP33X
-       bool "IOP33x-based"
-       depends on MMU
-       select CPU_XSCALE
-       select GPIO_IOP
-       select GPIOLIB
-       select NEED_RET_TO_USER
-       select FORCE_PCI
-       select PLAT_IOP
-       help
-         Support for Intel's IOP33X (XScale) family of processors.
-
 config ARCH_IXP4XX
        bool "IXP4xx-based"
        depends on MMU
@@ -455,48 +428,6 @@ config ARCH_DOVE
        help
          Support for the Marvell Dove SoC 88AP510
 
-config ARCH_KS8695
-       bool "Micrel/Kendin KS8695"
-       select CLKSRC_MMIO
-       select CPU_ARM922T
-       select GENERIC_CLOCKEVENTS
-       select GPIOLIB
-       select NEED_MACH_MEMORY_H
-       help
-         Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
-         System-on-Chip devices.
-
-config ARCH_W90X900
-       bool "Nuvoton W90X900 CPU"
-       select CLKDEV_LOOKUP
-       select CLKSRC_MMIO
-       select CPU_ARM926T
-       select GENERIC_CLOCKEVENTS
-       select GPIOLIB
-       help
-         Support for Nuvoton (Winbond logic dept.) ARM9 processor,
-         At present, the w90x900 has been renamed nuc900, regarding
-         the ARM series product line, you can login the following
-         link address to know more.
-
-         <http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/
-               ConsumerElectronicsIC/ARMMicrocontroller/ARMMicrocontroller>
-
-config ARCH_LPC32XX
-       bool "NXP LPC32XX"
-       select ARM_AMBA
-       select CLKDEV_LOOKUP
-       select CLKSRC_LPC32XX
-       select COMMON_CLK
-       select CPU_ARM926T
-       select GENERIC_CLOCKEVENTS
-       select GENERIC_IRQ_MULTI_HANDLER
-       select GPIOLIB
-       select SPARSE_IRQ
-       select USE_OF
-       help
-         Support for the NXP LPC32XX family of processors
-
 config ARCH_PXA
        bool "PXA2xx/PXA3xx-based"
        depends on MMU
@@ -582,27 +513,6 @@ config ARCH_S3C24XX
          (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or the
          Samsung SMDK2410 development board (and derivatives).
 
-config ARCH_DAVINCI
-       bool "TI DaVinci"
-       select ARCH_HAS_HOLES_MEMORYMODEL
-       select COMMON_CLK
-       select CPU_ARM926T
-       select GENERIC_ALLOCATOR
-       select GENERIC_CLOCKEVENTS
-       select GENERIC_IRQ_CHIP
-       select GENERIC_IRQ_MULTI_HANDLER
-       select GPIOLIB
-       select HAVE_IDE
-       select PM_GENERIC_DOMAINS if PM
-       select PM_GENERIC_DOMAINS_OF if PM && OF
-       select REGMAP_MMIO
-       select RESET_CONTROLLER
-       select SPARSE_IRQ
-       select USE_OF
-       select ZONE_DMA
-       help
-         Support for TI's DaVinci platform.
-
 config ARCH_OMAP1
        bool "TI OMAP1"
        depends on MMU
@@ -738,17 +648,13 @@ source "arch/arm/mach-imx/Kconfig"
 
 source "arch/arm/mach-integrator/Kconfig"
 
-source "arch/arm/mach-iop13xx/Kconfig"
-
 source "arch/arm/mach-iop32x/Kconfig"
 
-source "arch/arm/mach-iop33x/Kconfig"
-
 source "arch/arm/mach-ixp4xx/Kconfig"
 
 source "arch/arm/mach-keystone/Kconfig"
 
-source "arch/arm/mach-ks8695/Kconfig"
+source "arch/arm/mach-lpc32xx/Kconfig"
 
 source "arch/arm/mach-mediatek/Kconfig"
 
@@ -834,8 +740,6 @@ source "arch/arm/plat-versatile/Kconfig"
 
 source "arch/arm/mach-vt8500/Kconfig"
 
-source "arch/arm/mach-w90x900/Kconfig"
-
 source "arch/arm/mach-zx/Kconfig"
 
 source "arch/arm/mach-zynq/Kconfig"
index 85710e0..fe7e9b5 100644 (file)
@@ -509,13 +509,6 @@ choice
                  Say Y here if you want the debug print routines to direct
                  their output to UART1 serial port on KEYSTONE2 devices.
 
-       config DEBUG_KS8695_UART
-               bool "KS8695 Debug UART"
-               depends on ARCH_KS8695
-               help
-                 Say Y here if you want kernel low-level debugging support
-                 on KS8695.
-
        config DEBUG_LPC18XX_UART0
                bool "Kernel low-level debugging via LPC18xx/43xx UART0"
                depends on ARCH_LPC18XX
@@ -924,6 +917,20 @@ choice
                  Say Y here if you want kernel low-level debugging support
                  via SCIF2 on Renesas RZ/A1H (R7S72100).
 
+       config DEBUG_R7S9210_SCIF2
+               bool "Kernel low-level debugging messages via SCIF2 on R7S9210"
+               depends on ARCH_R7S9210
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 via SCIF2 on Renesas RZ/A2M (R7S9210).
+
+       config DEBUG_R7S9210_SCIF4
+               bool "Kernel low-level debugging messages via SCIF4 on R7S9210"
+               depends on ARCH_R7S9210
+               help
+                 Say Y here if you want kernel low-level debugging support
+                 via SCIF4 on Renesas RZ/A2M (R7S9210).
+
        config DEBUG_RCAR_GEN1_SCIF0
                bool "Kernel low-level debugging messages via SCIF0 on R8A7778"
                depends on ARCH_R8A7778
@@ -1533,10 +1540,11 @@ config DEBUG_LL_INCLUDE
                                 DEBUG_IMX6SX_UART || \
                                 DEBUG_IMX6UL_UART || \
                                 DEBUG_IMX7D_UART
-       default "debug/ks8695.S" if DEBUG_KS8695_UART
        default "debug/msm.S" if DEBUG_QCOM_UARTDM
        default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
        default "debug/renesas-scif.S" if DEBUG_R7S72100_SCIF2
+       default "debug/renesas-scif.S" if DEBUG_R7S9210_SCIF2
+       default "debug/renesas-scif.S" if DEBUG_R7S9210_SCIF4
        default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF0
        default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF2
        default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF0
@@ -1568,9 +1576,7 @@ config DEBUG_UART_PL01X
 
 # Compatibility options for 8250
 config DEBUG_UART_8250
-       def_bool ARCH_EBSA110 || \
-               ARCH_IOP13XX || ARCH_IOP32X || ARCH_IOP33X || ARCH_IXP4XX || \
-               ARCH_RPC
+       def_bool ARCH_EBSA110 || ARCH_IOP32X || ARCH_IXP4XX || ARCH_RPC
 
 config DEBUG_UART_PHYS
        hex "Physical base address of debug UART"
@@ -1666,7 +1672,8 @@ config DEBUG_UART_PHYS
        default 0xe6e60000 if DEBUG_RCAR_GEN2_SCIF0
        default 0xe6e68000 if DEBUG_RCAR_GEN2_SCIF1
        default 0xe6ee0000 if DEBUG_RCAR_GEN2_SCIF4
-       default 0xe8008000 if DEBUG_R7S72100_SCIF2
+       default 0xe8008000 if DEBUG_R7S72100_SCIF2 || DEBUG_R7S9210_SCIF2
+       default 0xe8009000 if DEBUG_R7S9210_SCIF4
        default 0xf0000000 if DEBUG_DIGICOLOR_UA0
        default 0xf0000be0 if ARCH_EBSA110
        default 0xf1012000 if DEBUG_MVEBU_UART0_ALTERNATE
@@ -1683,7 +1690,6 @@ config DEBUG_UART_PHYS
        default 0xffc02000 if DEBUG_SOCFPGA_UART0
        default 0xffc02100 if DEBUG_SOCFPGA_ARRIA10_UART1
        default 0xffc03000 if DEBUG_SOCFPGA_CYCLONE5_UART1
-       default 0xffd82340 if ARCH_IOP13XX
        default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0
        default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2
        default 0xfff36000 if DEBUG_HIGHBANK_UART
@@ -1693,12 +1699,12 @@ config DEBUG_UART_PHYS
        default 0xfffe8600 if DEBUG_BCM63XX_UART
        default 0xffffee00 if DEBUG_AT91_SAM9263_DBGU
        default 0xfffff200 if DEBUG_AT91_RM9200_DBGU
-       default 0xfffff700 if ARCH_IOP33X
        depends on ARCH_EP93XX || \
                DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
                DEBUG_LL_UART_EFM32 || \
                DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
                DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \
+               DEBUG_R7S9210_SCIF2 || DEBUG_R7S9210_SCIF4 || \
                DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \
                DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF1 || \
                DEBUG_RCAR_GEN2_SCIF2 || DEBUG_RCAR_GEN2_SCIF4 || \
@@ -1772,10 +1778,7 @@ config DEBUG_UART_VIRT
        default 0xfc705000 if DEBUG_ZTE_ZX
        default 0xfcfe8600 if DEBUG_BCM63XX_UART
        default 0xfd000000 if DEBUG_SPEAR3XX || DEBUG_SPEAR13XX
-       default 0xfd012000 if DEBUG_MVEBU_UART0_ALTERNATE && ARCH_MV78XX0
        default 0xfd883000 if DEBUG_ALPINE_UART0
-       default 0xfde12000 if DEBUG_MVEBU_UART0_ALTERNATE && ARCH_DOVE
-       default 0xfe012000 if DEBUG_MVEBU_UART0_ALTERNATE && ARCH_ORION5X
        default 0xfe017000 if DEBUG_MMP_UART2
        default 0xfe018000 if DEBUG_MMP_UART3
        default 0xfe100000 if DEBUG_IMX23_UART || DEBUG_IMX28_UART
@@ -1790,7 +1793,7 @@ config DEBUG_UART_VIRT
        default 0xfec02000 if DEBUG_SOCFPGA_UART0
        default 0xfec02100 if DEBUG_SOCFPGA_ARRIA10_UART1
        default 0xfec03000 if DEBUG_SOCFPGA_CYCLONE5_UART1
-       default 0xfec12000 if (DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE) && ARCH_MVEBU
+       default 0xfec12000 if DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE
        default 0xfec12100 if DEBUG_MVEBU_UART1_ALTERNATE
        default 0xfec10000 if DEBUG_SIRFATLAS7_UART0
        default 0xfec20000 if DEBUG_DAVINCI_DMx_UART0
@@ -1805,14 +1808,12 @@ config DEBUG_UART_VIRT
        default 0xfedc0000 if DEBUG_EP93XX
        default 0xfee003f8 if DEBUG_FOOTBRIDGE_COM1
        default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
-       default 0xfee82340 if ARCH_IOP13XX
        default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
        default 0xfef00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN
        default 0xfef36000 if DEBUG_HIGHBANK_UART
        default 0xfefb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1
        default 0xfefb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2
        default 0xfefb9800 if DEBUG_OMAP1UART3 || DEBUG_OMAP7XXUART3
-       default 0xfefff700 if ARCH_IOP33X
        default 0xff003000 if DEBUG_U300_UART
        default 0xffd01000 if DEBUG_HIP01_UART
        default DEBUG_UART_PHYS if !MMU
index c3624ca..f9002e4 100644 (file)
@@ -155,6 +155,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
 machine-$(CONFIG_ARCH_ACTIONS)         += actions
 machine-$(CONFIG_ARCH_ALPINE)          += alpine
 machine-$(CONFIG_ARCH_ARTPEC)          += artpec
+machine-$(CONFIG_ARCH_ASPEED)           += aspeed
 machine-$(CONFIG_ARCH_AT91)            += at91
 machine-$(CONFIG_ARCH_AXXIA)           += axxia
 machine-$(CONFIG_ARCH_BCM)             += bcm
@@ -173,12 +174,9 @@ machine-$(CONFIG_ARCH_GEMINI)              += gemini
 machine-$(CONFIG_ARCH_HIGHBANK)                += highbank
 machine-$(CONFIG_ARCH_HISI)            += hisi
 machine-$(CONFIG_ARCH_INTEGRATOR)      += integrator
-machine-$(CONFIG_ARCH_IOP13XX)         += iop13xx
 machine-$(CONFIG_ARCH_IOP32X)          += iop32x
-machine-$(CONFIG_ARCH_IOP33X)          += iop33x
 machine-$(CONFIG_ARCH_IXP4XX)          += ixp4xx
 machine-$(CONFIG_ARCH_KEYSTONE)                += keystone
-machine-$(CONFIG_ARCH_KS8695)          += ks8695
 machine-$(CONFIG_ARCH_LPC18XX)         += lpc18xx
 machine-$(CONFIG_ARCH_LPC32XX)         += lpc32xx
 machine-$(CONFIG_ARCH_MESON)           += meson
@@ -222,7 +220,6 @@ machine-$(CONFIG_ARCH_U8500)                += ux500
 machine-$(CONFIG_ARCH_VERSATILE)       += versatile
 machine-$(CONFIG_ARCH_VEXPRESS)                += vexpress
 machine-$(CONFIG_ARCH_VT8500)          += vt8500
-machine-$(CONFIG_ARCH_W90X900)         += w90x900
 machine-$(CONFIG_ARCH_ZX)              += zx
 machine-$(CONFIG_ARCH_ZYNQ)            += zynq
 machine-$(CONFIG_PLAT_SPEAR)           += spear
@@ -233,7 +230,6 @@ plat-$(CONFIG_ARCH_EXYNOS)  += samsung
 plat-$(CONFIG_ARCH_OMAP)       += omap
 plat-$(CONFIG_ARCH_S3C64XX)    += samsung
 plat-$(CONFIG_ARCH_S5PV210)    += samsung
-plat-$(CONFIG_PLAT_IOP)                += iop
 plat-$(CONFIG_PLAT_ORION)      += orion
 plat-$(CONFIG_PLAT_PXA)                += pxa
 plat-$(CONFIG_PLAT_S3C24XX)    += samsung
index 9159fa2..a24a6a1 100644 (file)
@@ -569,17 +569,22 @@ dtb-$(CONFIG_SOC_IMX6UL) += \
        imx6ul-geam.dtb \
        imx6ul-isiot-emmc.dtb \
        imx6ul-isiot-nand.dtb \
+       imx6ul-kontron-n6310-s.dtb \
+       imx6ul-kontron-n6310-s-43.dtb \
        imx6ul-liteboard.dtb \
        imx6ul-opos6uldev.dtb \
        imx6ul-pico-hobbit.dtb \
        imx6ul-pico-pi.dtb \
-       imx6ul-phytec-phyboard-segin-full.dtb \
+       imx6ul-phytec-segin-ff-rdk-nand.dtb \
        imx6ul-tx6ul-0010.dtb \
        imx6ul-tx6ul-0011.dtb \
        imx6ul-tx6ul-mainboard.dtb \
        imx6ull-14x14-evk.dtb \
        imx6ull-colibri-eval-v3.dtb \
        imx6ull-colibri-wifi-eval-v3.dtb \
+       imx6ull-phytec-segin-ff-rdk-nand.dtb \
+       imx6ull-phytec-segin-ff-rdk-emmc.dtb \
+       imx6ull-phytec-segin-lc-rdk-nand.dtb \
        imx6ulz-14x14-evk.dtb
 dtb-$(CONFIG_SOC_IMX7D) += \
        imx7d-cl-som-imx7.dtb \
@@ -594,6 +599,7 @@ dtb-$(CONFIG_SOC_IMX7D) += \
        imx7d-sdb.dtb \
        imx7d-sdb-reva.dtb \
        imx7d-sdb-sht11.dtb \
+       imx7d-zii-rmu2.dtb \
        imx7d-zii-rpu2.dtb \
        imx7s-colibri-eval-v3.dtb \
        imx7s-mba7.dtb \
@@ -905,9 +911,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
        rk3188-radxarock.dtb \
        rk3228-evb.dtb \
        rk3229-evb.dtb \
+       rk3229-xms6.dtb \
        rk3288-evb-act8846.dtb \
        rk3288-evb-rk808.dtb \
-       rk3288-fennec.dtb \
        rk3288-firefly-beta.dtb \
        rk3288-firefly.dtb \
        rk3288-firefly-reload.dtb \
@@ -919,6 +925,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
        rk3288-tinker.dtb \
        rk3288-tinker-s.dtb \
        rk3288-veyron-brain.dtb \
+       rk3288-veyron-fievel.dtb \
        rk3288-veyron-jaq.dtb \
        rk3288-veyron-jerry.dtb \
        rk3288-veyron-mickey.dtb \
@@ -926,6 +933,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += \
        rk3288-veyron-minnie.dtb \
        rk3288-veyron-pinky.dtb \
        rk3288-veyron-speedy.dtb \
+       rk3288-veyron-tiger.dtb \
        rk3288-vyasa.dtb
 dtb-$(CONFIG_ARCH_S3C24XX) += \
        s3c2416-smdk2416.dtb
@@ -1114,6 +1122,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
        sun8i-r16-nintendo-super-nes-classic.dtb \
        sun8i-r16-parrot.dtb \
        sun8i-r40-bananapi-m2-ultra.dtb \
+       sun8i-s3-lichee-zero-plus.dtb \
        sun8i-t3-cqa3t-bv3.dtb \
        sun8i-v3s-licheepi-zero.dtb \
        sun8i-v3s-licheepi-zero-dock.dtb \
@@ -1262,6 +1271,7 @@ dtb-$(CONFIG_ARCH_MEDIATEK) += \
        mt7623a-rfb-nand.dtb \
        mt7623n-rfb-emmc.dtb \
        mt7623n-bananapi-bpi-r2.dtb \
+       mt7629-rfb.dtb \
        mt8127-moose.dtb \
        mt8135-evbp1.dtb
 dtb-$(CONFIG_ARCH_MILBEAUT) += milbeaut-m10v-evb.dtb
@@ -1271,13 +1281,18 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
        aspeed-bmc-arm-centriq2400-rep.dtb \
        aspeed-bmc-arm-stardragon4800-rep2.dtb \
        aspeed-bmc-facebook-cmm.dtb \
+       aspeed-bmc-facebook-minipack.dtb \
        aspeed-bmc-facebook-tiogapass.dtb \
+       aspeed-bmc-facebook-wedge40.dtb \
+       aspeed-bmc-facebook-wedge100.dtb \
        aspeed-bmc-facebook-yamp.dtb \
        aspeed-bmc-intel-s2600wf.dtb \
        aspeed-bmc-inspur-fp5280g2.dtb \
        aspeed-bmc-lenovo-hr630.dtb \
+       aspeed-bmc-lenovo-hr855xg2.dtb \
        aspeed-bmc-microsoft-olympus.dtb \
        aspeed-bmc-opp-lanyang.dtb \
+       aspeed-bmc-opp-mihawk.dtb \
        aspeed-bmc-opp-palmetto.dtb \
        aspeed-bmc-opp-romulus.dtb \
        aspeed-bmc-opp-swift.dtb \
index 0257576..2f6652e 100644 (file)
@@ -5,23 +5,13 @@
 /dts-v1/;
 
 #include "am33xx.dtsi"
+#include "am335x-osd335x-common.dtsi"
 #include <dt-bindings/interrupt-controller/irq.h>
 
 / {
        model = "TI AM335x BeagleBone Blue";
        compatible = "ti,am335x-bone-blue", "ti,am33xx";
 
-       cpus {
-               cpu@0 {
-                       cpu0-supply = <&dcdc2_reg>;
-               };
-       };
-
-       memory@80000000 {
-               device_type = "memory";
-               reg = <0x80000000 0x20000000>; /* 512 MB */
-       };
-
        chosen {
                stdout-path = &uart0;
        };
                >;
        };
 
-       i2c0_pins: pinmux_i2c0_pins {
-               pinctrl-single,pins = <
-                       AM33XX_PADCONF(AM335X_PIN_I2C0_SDA, PIN_INPUT_PULLUP, MUX_MODE0)        /* (C17) I2C0_SDA.I2C0_SDA */
-                       AM33XX_PADCONF(AM335X_PIN_I2C0_SCL, PIN_INPUT_PULLUP, MUX_MODE0)        /* (C16) I2C0_SCL.I2C0_SCL */
-               >;
-       };
-
        i2c2_pins: pinmux_i2c2_pins {
                pinctrl-single,pins = <
                        AM33XX_PADCONF(AM335X_PIN_UART1_CTSN, PIN_INPUT_PULLUP, MUX_MODE3)      /* (D18) uart1_ctsn.I2C2_SDA */
 };
 
 &i2c0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&i2c0_pins>;
-
-       status = "okay";
-       clock-frequency = <400000>;
-
-       tps: tps@24 {
-               reg = <0x24>;
-       };
-
        baseboard_eeprom: baseboard_eeprom@50 {
                compatible = "atmel,24c256";
                reg = <0x50>;
 /include/ "tps65217.dtsi"
 
 &tps {
-       interrupts = <7>; /* NMI */
-       interrupt-parent = <&intc>;
+       /delete-property/ ti,pmic-shutdown-controller;
 
        charger {
                interrupts = <0>, <1>;
                interrupt-names = "USB", "AC";
                status = "okay";
        };
-
-       pwrbutton {
-               interrupts = <2>;
-               status = "okay";
-       };
-
-       regulators {
-               dcdc1_reg: regulator@0 {
-                       regulator-name = "vdds_dpr";
-                       regulator-always-on;
-               };
-
-               dcdc2_reg: regulator@1 {
-                       /* VDD_MPU voltage limits 0.95V - 1.26V with +/-4% tolerance */
-                       regulator-name = "vdd_mpu";
-                       regulator-min-microvolt = <925000>;
-                       regulator-max-microvolt = <1351500>;
-                       regulator-boot-on;
-                       regulator-always-on;
-               };
-
-               dcdc3_reg: regulator@2 {
-                       /* VDD_CORE voltage limits 0.95V - 1.1V with +/-4% tolerance */
-                       regulator-name = "vdd_core";
-                       regulator-min-microvolt = <925000>;
-                       regulator-max-microvolt = <1150000>;
-                       regulator-boot-on;
-                       regulator-always-on;
-               };
-
-               ldo1_reg: regulator@3 {
-                       regulator-name = "vio,vrtc,vdds";
-                       regulator-always-on;
-               };
-
-               ldo2_reg: regulator@4 {
-                       regulator-name = "vdd_3v3aux";
-                       regulator-always-on;
-               };
-
-               ldo3_reg: regulator@5 {
-                       regulator-name = "vdd_1v8";
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
-                       regulator-always-on;
-               };
-
-               ldo4_reg: regulator@6 {
-                       regulator-name = "vdd_3v3a";
-                       regulator-always-on;
-               };
-       };
 };
 
 &mmc1 {
        };
 };
 
-&aes {
-       status = "okay";
-};
-
-&sham {
-       status = "okay";
-};
-
 &rtc {
        system-power-controller;
        clocks = <&clk_32768_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>;
index ceecbfd..1fe3b56 100644 (file)
@@ -44,7 +44,6 @@
                regulator-name = "vwlan_fixed";
                gpio = <&gpio0 20 GPIO_ACTIVE_HIGH>; /* gpio0_20 */
                enable-active-high;
-               regulator-boot-off;
        };
 
        backlight {
index ced1a19..46849d6 100644 (file)
                        uart0: serial@0 {
                                compatible = "ti,am3352-uart", "ti,omap3-uart";
                                clock-frequency = <48000000>;
-                               reg = <0x0 0x2000>;
+                               reg = <0x0 0x1000>;
                                interrupts = <72>;
                                status = "disabled";
                                dmas = <&edma 26 0>, <&edma 27 0>;
                        uart1: serial@0 {
                                compatible = "ti,am3352-uart", "ti,omap3-uart";
                                clock-frequency = <48000000>;
-                               reg = <0x0 0x2000>;
+                               reg = <0x0 0x1000>;
                                interrupts = <73>;
                                status = "disabled";
                                dmas = <&edma 28 0>, <&edma 29 0>;
                        uart2: serial@0 {
                                compatible = "ti,am3352-uart", "ti,omap3-uart";
                                clock-frequency = <48000000>;
-                               reg = <0x0 0x2000>;
+                               reg = <0x0 0x1000>;
                                interrupts = <74>;
                                status = "disabled";
                                dmas = <&edma 30 0>, <&edma 31 0>;
                        uart3: serial@0 {
                                compatible = "ti,am3352-uart", "ti,omap3-uart";
                                clock-frequency = <48000000>;
-                               reg = <0x0 0x2000>;
+                               reg = <0x0 0x1000>;
                                interrupts = <44>;
                                status = "disabled";
                        };
                        uart4: serial@0 {
                                compatible = "ti,am3352-uart", "ti,omap3-uart";
                                clock-frequency = <48000000>;
-                               reg = <0x0 0x2000>;
+                               reg = <0x0 0x1000>;
                                interrupts = <45>;
                                status = "disabled";
                        };
                        uart5: serial@0 {
                                compatible = "ti,am3352-uart", "ti,omap3-uart";
                                clock-frequency = <48000000>;
-                               reg = <0x0 0x2000>;
+                               reg = <0x0 0x1000>;
                                interrupts = <46>;
                                status = "disabled";
                        };
 
                target-module@cc000 {                   /* 0x481cc000, ap 60 46.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0xcc020 0x4>;
+                       reg-names = "rev";
                        ti,hwmods = "d_can0";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
                        clocks = <&l4ls_clkctrl AM3_L4LS_D_CAN0_CLKCTRL 0>,
 
                target-module@d0000 {                   /* 0x481d0000, ap 62 42.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0xd0020 0x4>;
+                       reg-names = "rev";
                        ti,hwmods = "d_can1";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
                        clocks = <&l4ls_clkctrl AM3_L4LS_D_CAN1_CLKCTRL 0>,
index e5c2f71..fb6b8aa 100644 (file)
                        interrupt-names = "edma3_tcerrint";
                };
 
-               mmc3: mmc@47810000 {
-                       compatible = "ti,omap4-hsmmc";
+               target-module@47810000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
                        ti,hwmods = "mmc3";
-                       ti,needs-special-reset;
-                       interrupts = <29>;
-                       reg = <0x47810000 0x1000>;
-                       status = "disabled";
+                       reg = <0x478102fc 0x4>,
+                             <0x47810110 0x4>,
+                             <0x47810114 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       clocks = <&l3s_clkctrl AM3_L3S_MMC3_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x47810000 0x1000>;
+
+                       mmc3: mmc@0 {
+                               compatible = "ti,omap4-hsmmc";
+                               ti,needs-special-reset;
+                               interrupts = <29>;
+                               reg = <0x0 0x1000>;
+                       };
                };
 
                usb: usb@47400000 {
index 55aff4d..848e2a8 100644 (file)
                        interrupt-names = "edma3_tcerrint";
                };
 
-               mmc3: mmc@47810000 {
-                       compatible = "ti,omap4-hsmmc";
-                       reg = <0x47810000 0x1000>;
+               target-module@47810000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
                        ti,hwmods = "mmc3";
-                       ti,needs-special-reset;
-                       interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
-                       status = "disabled";
+                       reg = <0x478102fc 0x4>,
+                             <0x47810110 0x4>,
+                             <0x47810114 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_ENAWAKEUP |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       clocks = <&l3s_clkctrl AM4_L3S_MMC3_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x47810000 0x1000>;
+
+                       mmc3: mmc@0 {
+                               compatible = "ti,omap4-hsmmc";
+                               ti,needs-special-reset;
+                               interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x0 0x1000>;
+                       };
                };
 
                sham: sham@53100000 {
index 989cb60..04bee4f 100644 (file)
 
                target-module@cc000 {                   /* 0x481cc000, ap 50 46.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0xcc020 0x4>;
+                       reg-names = "rev";
                        ti,hwmods = "d_can0";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
                        clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN0_CLKCTRL 0>;
 
                target-module@d0000 {                   /* 0x481d0000, ap 52 3a.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0xd0020 0x4>;
+                       reg-names = "rev";
                        ti,hwmods = "d_can1";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
                        clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN1_CLKCTRL 0>;
index 1d5e999..0aaacea 100644 (file)
 };
 
 &mmc1 {
-       pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104";
+       pinctrl-names = "default", "hs";
        pinctrl-0 = <&mmc1_pins_default_no_clk_pu>;
        pinctrl-1 = <&mmc1_pins_hs>;
-       pinctrl-2 = <&mmc1_pins_sdr12>;
-       pinctrl-3 = <&mmc1_pins_sdr25>;
-       pinctrl-4 = <&mmc1_pins_sdr50>;
-       pinctrl-5 = <&mmc1_pins_ddr50_rev20 &mmc1_iodelay_ddr50_conf>;
-       pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>;
 };
 
 &mmc2 {
index c65d7f6..ea1c119 100644 (file)
 };
 
 &mmc1 {
-       pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104";
+       pinctrl-names = "default", "hs";
        pinctrl-0 = <&mmc1_pins_default_no_clk_pu>;
        pinctrl-1 = <&mmc1_pins_hs>;
-       pinctrl-2 = <&mmc1_pins_sdr12>;
-       pinctrl-3 = <&mmc1_pins_sdr25>;
-       pinctrl-4 = <&mmc1_pins_sdr50>;
-       pinctrl-5 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev20_conf>;
-       pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>;
 };
 
 &mmc2 {
index dc5141c..7935d70 100644 (file)
 };
 
 &mmc1 {
-       pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104";
+       pinctrl-names = "default", "hs";
        pinctrl-0 = <&mmc1_pins_default_no_clk_pu>;
        pinctrl-1 = <&mmc1_pins_hs>;
-       pinctrl-2 = <&mmc1_pins_default>;
-       pinctrl-3 = <&mmc1_pins_hs>;
-       pinctrl-4 = <&mmc1_pins_sdr50>;
-       pinctrl-5 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_conf>;
-       pinctrl-6 = <&mmc1_pins_ddr50 &mmc1_iodelay_sdr104_conf>;
 };
 
 &mmc2 {
index d02f5fa..bc76f17 100644 (file)
        };
 };
 
-&gpio7 {
+&gpio7_target {
        ti,no-reset-on-init;
        ti,no-idle-on-init;
 };
 
        bus-width = <4>;
        cd-gpios = <&gpio6 27 GPIO_ACTIVE_LOW>; /* gpio 219 */
+       no-1-8-v;
 };
 
 &mmc2 {
index a374b5c..7b113b5 100644 (file)
 };
 
 &mmc1 {
-       pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104";
+       pinctrl-names = "default", "hs";
        pinctrl-0 = <&mmc1_pins_default>;
        pinctrl-1 = <&mmc1_pins_hs>;
-       pinctrl-2 = <&mmc1_pins_sdr12>;
-       pinctrl-3 = <&mmc1_pins_sdr25>;
-       pinctrl-4 = <&mmc1_pins_sdr50>;
-       pinctrl-5 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev11_conf>;
-       pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev11_conf>;
        vmmc-supply = <&vdd_3v3>;
        vqmmc-supply = <&ldo1_reg>;
 };
index 4badd21..30c500b 100644 (file)
 };
 
 &mmc1 {
-       pinctrl-names = "default", "hs", "sdr12", "sdr25", "sdr50", "ddr50", "sdr104";
+       pinctrl-names = "default", "hs";
        pinctrl-0 = <&mmc1_pins_default>;
        pinctrl-1 = <&mmc1_pins_hs>;
-       pinctrl-2 = <&mmc1_pins_sdr12>;
-       pinctrl-3 = <&mmc1_pins_sdr25>;
-       pinctrl-4 = <&mmc1_pins_sdr50>;
-       pinctrl-5 = <&mmc1_pins_ddr50 &mmc1_iodelay_ddr_rev20_conf>;
-       pinctrl-6 = <&mmc1_pins_sdr104 &mmc1_iodelay_sdr104_rev20_conf>;
        vmmc-supply = <&vdd_3v3>;
        vqmmc-supply = <&ldo1_reg>;
 };
index 556ed46..c9d88c9 100644 (file)
        };
 };
 
+&sdmmc {
+       status = "okay";
+};
+
+&sdhci0 {
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sd1_default>;
+};
+
 /*
  * Enable port A as device (via the virtual hub) and port B as
  * host by default on the eval board. This can be easily changed
diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-minipack.dts
new file mode 100644 (file)
index 0000000..c054782
--- /dev/null
@@ -0,0 +1,429 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2018 Facebook Inc.
+/dts-v1/;
+
+#include "aspeed-g5.dtsi"
+
+/ {
+       model = "Facebook Minipack 100 BMC";
+       compatible = "facebook,minipack-bmc", "aspeed,ast2500";
+
+       aliases {
+               /*
+                * Override the default serial aliases to avoid breaking
+                * the legacy applications.
+                */
+               serial0 = &uart5;
+               serial1 = &uart1;
+               serial2 = &uart2;
+               serial3 = &uart3;
+               serial4 = &uart4;
+
+               /*
+                * i2c switch 2-0070, pca9548, 8 child channels assigned
+                * with bus number 16-23.
+                */
+               i2c16 = &imux16;
+               i2c17 = &imux17;
+               i2c18 = &imux18;
+               i2c19 = &imux19;
+               i2c20 = &imux20;
+               i2c21 = &imux21;
+               i2c22 = &imux22;
+               i2c23 = &imux23;
+
+               /*
+                * i2c switch 8-0070, pca9548, 8 child channels assigned
+                * with bus number 24-31.
+                */
+               i2c24 = &imux24;
+               i2c25 = &imux25;
+               i2c26 = &imux26;
+               i2c27 = &imux27;
+               i2c28 = &imux28;
+               i2c29 = &imux29;
+               i2c30 = &imux30;
+               i2c31 = &imux31;
+
+               /*
+                * i2c switch 9-0070, pca9548, 8 child channels assigned
+                * with bus number 32-39.
+                */
+               i2c32 = &imux32;
+               i2c33 = &imux33;
+               i2c34 = &imux34;
+               i2c35 = &imux35;
+               i2c36 = &imux36;
+               i2c37 = &imux37;
+               i2c38 = &imux38;
+               i2c39 = &imux39;
+
+               /*
+                * i2c switch 11-0070, pca9548, 8 child channels assigned
+                * with bus number 40-47.
+                */
+               i2c40 = &imux40;
+               i2c41 = &imux41;
+               i2c42 = &imux42;
+               i2c43 = &imux43;
+               i2c44 = &imux44;
+               i2c45 = &imux45;
+               i2c46 = &imux46;
+               i2c47 = &imux47;
+       };
+
+       chosen {
+               stdout-path = &uart1;
+               bootargs = "debug console=ttyS1,9600n8 root=/dev/ram rw";
+       };
+
+       memory@80000000 {
+               reg = <0x80000000 0x20000000>;
+       };
+};
+
+&wdt1 {
+       status = "okay";
+       aspeed,reset-type = "system";
+};
+
+&wdt2 {
+       status = "okay";
+       aspeed,reset-type = "system";
+};
+
+&fmc {
+       status = "okay";
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "bmc";
+#include "facebook-bmc-flash-layout.dtsi"
+       };
+};
+
+&uart1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd1_default
+                    &pinctrl_rxd1_default
+                    &pinctrl_ncts1_default
+                    &pinctrl_ndsr1_default
+                    &pinctrl_ndtr1_default
+                    &pinctrl_nrts1_default>;
+};
+
+&uart2 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd2_default
+                    &pinctrl_rxd2_default>;
+};
+
+&uart3 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd3_default
+                    &pinctrl_rxd3_default>;
+};
+
+&uart4 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd4_default
+                    &pinctrl_rxd4_default>;
+};
+
+&uart5 {
+       status = "okay";
+};
+
+&mac1 {
+       status = "okay";
+       no-hw-checksum;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
+};
+
+&i2c0 {
+       status = "okay";
+       bus-frequency = <400000>;
+       multi-master;
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+
+       i2c-switch@70 {
+               compatible = "nxp,pca9548";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x70>;
+
+               imux16: i2c@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0>;
+               };
+
+               imux17: i2c@1 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+               };
+
+               imux18: i2c@2 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <2>;
+               };
+
+               imux19: i2c@3 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <3>;
+               };
+
+               imux20: i2c@4 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <4>;
+               };
+
+               imux21: i2c@5 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <5>;
+               };
+
+               imux22: i2c@6 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <6>;
+               };
+
+               imux23: i2c@7 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <7>;
+               };
+       };
+};
+
+&i2c3 {
+       status = "okay";
+};
+
+&i2c4 {
+       status = "okay";
+       multi-master;
+};
+
+&i2c5 {
+       status = "okay";
+};
+
+&i2c6 {
+       status = "okay";
+};
+
+&i2c7 {
+       status = "okay";
+};
+
+&i2c8 {
+       status = "okay";
+
+       i2c-switch@70 {
+               compatible = "nxp,pca9548";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x70>;
+
+               imux24: i2c@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0>;
+               };
+
+               imux25: i2c@1 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+               };
+
+               imux26: i2c@2 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <2>;
+               };
+
+               imux27: i2c@3 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <3>;
+               };
+
+               imux28: i2c@4 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <4>;
+               };
+
+               imux29: i2c@5 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <5>;
+               };
+
+               imux30: i2c@6 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <6>;
+               };
+
+               imux31: i2c@7 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <7>;
+               };
+       };
+};
+
+&i2c9 {
+       status = "okay";
+
+       i2c-switch@70 {
+               compatible = "nxp,pca9548";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x70>;
+
+               imux32: i2c@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0>;
+               };
+
+               imux33: i2c@1 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+               };
+
+               imux34: i2c@2 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <2>;
+               };
+
+               imux35: i2c@3 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <3>;
+               };
+
+               imux36: i2c@4 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <4>;
+               };
+
+               imux37: i2c@5 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <5>;
+               };
+
+               imux38: i2c@6 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <6>;
+               };
+
+               imux39: i2c@7 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <7>;
+               };
+       };
+};
+
+&i2c10 {
+       status = "okay";
+};
+
+&i2c11 {
+       status = "okay";
+
+       i2c-switch@70 {
+               compatible = "nxp,pca9548";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x70>;
+
+               imux40: i2c@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0>;
+               };
+
+               imux41: i2c@1 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+               };
+
+               imux42: i2c@2 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <2>;
+               };
+
+               imux43: i2c@3 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <3>;
+               };
+
+               imux44: i2c@4 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <4>;
+               };
+
+               imux45: i2c@5 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <5>;
+               };
+
+               imux46: i2c@6 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <6>;
+               };
+
+               imux47: i2c@7 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <7>;
+               };
+       };
+};
+
+&i2c12 {
+       status = "okay";
+};
+
+&i2c13 {
+       status = "okay";
+};
+
+&vhub {
+       status = "okay";
+};
index c4521ed..682f729 100644 (file)
        aliases {
                serial0 = &uart1;
                serial4 = &uart5;
+
+               /*
+                * Hardcode the bus number of i2c switches' channels to
+                * avoid breaking the legacy applications.
+                */
+               i2c16 = &imux16;
+               i2c17 = &imux17;
+               i2c18 = &imux18;
+               i2c19 = &imux19;
+               i2c20 = &imux20;
+               i2c21 = &imux21;
+               i2c22 = &imux22;
+               i2c23 = &imux23;
+               i2c24 = &imux24;
+               i2c25 = &imux25;
+               i2c26 = &imux26;
+               i2c27 = &imux27;
+               i2c28 = &imux28;
+               i2c29 = &imux29;
+               i2c30 = &imux30;
+               i2c31 = &imux31;
        };
        chosen {
                stdout-path = &uart5;
        iio-hwmon {
                compatible = "iio-hwmon";
                io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>,
-                                       <&adc 4>, <&adc 5>, <&adc 6>;
+                             <&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>;
        };
 
-       iio-hwmon-battery {
-               compatible = "iio-hwmon";
-               io-channels = <&adc 7>;
-       };
 };
 
 &fmc {
 &i2c1 {
        status = "okay";
        //X24 Riser
+       i2c-switch@71 {
+               compatible = "nxp,pca9544";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x71>;
+
+               imux16: i2c@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0>;
+
+                       ina230@45 {
+                               compatible = "ti,ina230";
+                               reg = <0x45>;
+                       };
+
+                       tmp75@48 {
+                               compatible = "ti,tmp75";
+                               reg = <0x48>;
+                       };
+
+                       tmp421@49 {
+                               compatible = "ti,tmp75";
+                               reg = <0x49>;
+                       };
+
+                       eeprom@50 {
+                               compatible = "atmel,24c64";
+                               reg = <0x50>;
+                               pagesize = <32>;
+                       };
+
+                       i2c-switch@73 {
+                               compatible = "nxp,pca9546";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x73>;
+
+                               imux20: i2c@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0>;
+                               };
+
+                               imux21: i2c@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <1>;
+                               };
+
+                               imux22: i2c@2 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <2>;
+                               };
+
+                               imux23: i2c@3 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <3>;
+                               };
+
+                       };
+
+               };
+
+               imux17: i2c@1 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+
+                       ina230@45 {
+                               compatible = "ti,ina230";
+                               reg = <0x45>;
+                       };
+
+                       tmp421@48 {
+                               compatible = "ti,tmp75";
+                               reg = <0x48>;
+                       };
+
+                       tmp421@49 {
+                               compatible = "ti,tmp75";
+                               reg = <0x49>;
+                       };
+
+                       eeprom@50 {
+                               compatible = "atmel,24c64";
+                               reg = <0x50>;
+                               pagesize = <32>;
+                       };
+
+                       i2c-switch@73 {
+                               compatible = "nxp,pca9546";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x73>;
+
+                               imux24: i2c@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0>;
+                               };
+
+                               imux25: i2c@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <1>;
+                               };
+
+                               imux26: i2c@2 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <2>;
+                               };
+
+                               imux27: i2c@3 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <3>;
+                               };
+
+                       };
+
+               };
+
+               imux18: i2c@2 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <2>;
+
+                       ina230@45 {
+                               compatible = "ti,ina230";
+                               reg = <0x45>;
+                       };
+
+                       tmp421@48 {
+                               compatible = "ti,tmp75";
+                               reg = <0x48>;
+                       };
+
+                       tmp421@49 {
+                               compatible = "ti,tmp75";
+                               reg = <0x49>;
+                       };
+
+                       eeprom@50 {
+                               compatible = "atmel,24c64";
+                               reg = <0x50>;
+                               pagesize = <32>;
+                       };
+
+                       i2c-switch@73 {
+                               compatible = "nxp,pca9546";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x73>;
+
+                               imux28: i2c@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0>;
+                               };
+
+                               imux29: i2c@1 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <1>;
+                               };
+
+                               imux30: i2c@2 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <2>;
+                               };
+
+                               imux31: i2c@3 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <3>;
+                               };
+
+                       };
+
+               };
+
+               imux19: i2c@3 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <3>;
+
+                       i2c-switch@40 {
+                               compatible = "ti,ina230";
+                               reg = <0x40>;
+                       };
+
+                       i2c-switch@41 {
+                               compatible = "ti,ina230";
+                               reg = <0x41>;
+                       };
+
+                       i2c-switch@45 {
+                               compatible = "ti,ina230";
+                               reg = <0x45>;
+                       };
+
+               };
+
+       };
 };
 
 &i2c2 {
 &i2c5 {
        status = "okay";
        // CPU Voltage regulators
+       regulator@48 {
+               compatible = "infineon,pxe1610";
+               reg = <0x48>;
+       };
+       regulator@4a {
+               compatible = "infineon,pxe1610";
+               reg = <0x4a>;
+       };
+       regulator@50 {
+               compatible = "infineon,pxe1610";
+               reg = <0x50>;
+       };
+       regulator@52 {
+               compatible = "infineon,pxe1610";
+               reg = <0x52>;
+       };
+       regulator@58 {
+               compatible = "infineon,pxe1610";
+               reg = <0x58>;
+       };
+       regulator@5a {
+               compatible = "infineon,pxe1610";
+               reg = <0x5a>;
+       };
+       regulator@68 {
+               compatible = "infineon,pxe1610";
+               reg = <0x68>;
+       };
+       regulator@70 {
+               compatible = "infineon,pxe1610";
+               reg = <0x70>;
+       };
+       regulator@72 {
+               compatible = "infineon,pxe1610";
+               reg = <0x72>;
+       };
 };
 
 &i2c6 {
diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge100.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge100.dts
new file mode 100644 (file)
index 0000000..b1e10f0
--- /dev/null
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2018 Facebook Inc.
+/dts-v1/;
+
+#include "aspeed-g4.dtsi"
+
+/ {
+       model = "Facebook Wedge 100 BMC";
+       compatible = "facebook,wedge100-bmc", "aspeed,ast2400";
+
+       aliases {
+               /*
+                * Override the default uart aliases to avoid breaking
+                * the legacy applications.
+                */
+               serial0 = &uart5;
+               serial1 = &uart1;
+               serial2 = &uart3;
+               serial3 = &uart4;
+       };
+
+       chosen {
+               stdout-path = &uart3;
+               bootargs = "console=ttyS2,9600n8 root=/dev/ram rw";
+       };
+
+       memory@40000000 {
+               reg = <0x40000000 0x20000000>;
+       };
+};
+
+&wdt1 {
+       status = "okay";
+       aspeed,reset-type = "system";
+};
+
+&wdt2 {
+       status = "okay";
+       aspeed,reset-type = "system";
+};
+
+&fmc {
+       status = "okay";
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "fmc0";
+#include "facebook-bmc-flash-layout.dtsi"
+       };
+};
+
+&uart1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd1_default
+                    &pinctrl_rxd1_default>;
+};
+
+&uart3 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd3_default
+                    &pinctrl_rxd3_default>;
+};
+
+&uart4 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd4_default
+                    &pinctrl_rxd4_default>;
+};
+
+&uart5 {
+       status = "okay";
+};
+
+&mac1 {
+       status = "okay";
+       no-hw-checksum;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
+};
+
+&i2c0 {
+       status = "okay";
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c3 {
+       status = "okay";
+};
+
+&i2c4 {
+       status = "okay";
+};
+
+&i2c5 {
+       status = "okay";
+};
+
+&i2c6 {
+       status = "okay";
+};
+
+&i2c7 {
+       status = "okay";
+
+       i2c-switch@70 {
+               compatible = "nxp,pca9548";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x70>;
+       };
+};
+
+&i2c8 {
+       status = "okay";
+};
+
+&i2c9 {
+       status = "okay";
+};
+
+&i2c10 {
+       status = "okay";
+};
+
+&i2c11 {
+       status = "okay";
+};
+
+&i2c12 {
+       status = "okay";
+};
+
+&i2c13 {
+       status = "okay";
+};
+
+&vhub {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts b/arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts
new file mode 100644 (file)
index 0000000..aaa77a5
--- /dev/null
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2018 Facebook Inc.
+/dts-v1/;
+
+#include "aspeed-g4.dtsi"
+
+/ {
+       model = "Facebook Wedge 40 BMC";
+       compatible = "facebook,wedge40-bmc", "aspeed,ast2400";
+
+       aliases {
+               /*
+                * Override the default uart aliases to avoid breaking
+                * the legacy applications.
+                */
+               serial0 = &uart5;
+               serial1 = &uart1;
+               serial2 = &uart3;
+               serial3 = &uart4;
+       };
+
+       chosen {
+               stdout-path = &uart3;
+               bootargs = "console=ttyS2,9600n8 root=/dev/ram rw";
+       };
+
+       memory@40000000 {
+               reg = <0x40000000 0x20000000>;
+       };
+};
+
+&wdt1 {
+       status = "okay";
+       aspeed,reset-type = "system";
+};
+
+&wdt2 {
+       status = "disabled";
+};
+
+&fmc {
+       status = "okay";
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "fmc0";
+#include "facebook-bmc-flash-layout.dtsi"
+       };
+};
+
+&uart1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd1_default
+                    &pinctrl_rxd1_default>;
+};
+
+&uart3 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd3_default
+                    &pinctrl_rxd3_default>;
+};
+
+&uart4 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd4_default
+                    &pinctrl_rxd4_default>;
+};
+
+&uart5 {
+       status = "okay";
+};
+
+&mac1 {
+       status = "okay";
+       no-hw-checksum;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
+};
+
+&i2c0 {
+       status = "okay";
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c3 {
+       status = "okay";
+};
+
+&i2c4 {
+       status = "okay";
+};
+
+&i2c5 {
+       status = "okay";
+};
+
+&i2c6 {
+       status = "okay";
+};
+
+&i2c7 {
+       status = "okay";
+};
+
+&i2c8 {
+       status = "okay";
+};
+
+&i2c9 {
+       status = "okay";
+};
+
+&i2c10 {
+       status = "okay";
+};
+
+&i2c11 {
+       status = "okay";
+};
+
+&i2c12 {
+       status = "okay";
+};
+
+&i2c13 {
+       status = "okay";
+};
+
+&vhub {
+       status = "okay";
+};
index 628195b..e9d714a 100644 (file)
                reg = <0x58>;
        };
 
-       power-supply@5a {
+       power-supply@59 {
                compatible = "pmbus";
-               reg = <0x5a>;
+               reg = <0x59>;
        };
 };
 
diff --git a/arch/arm/boot/dts/aspeed-bmc-lenovo-hr855xg2.dts b/arch/arm/boot/dts/aspeed-bmc-lenovo-hr855xg2.dts
new file mode 100644 (file)
index 0000000..118eb8b
--- /dev/null
@@ -0,0 +1,663 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Device Tree file for Lenovo Hr855xg2 platform
+ *
+ * Copyright (C) 2019-present Lenovo
+ */
+
+/dts-v1/;
+
+#include "aspeed-g5.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+
+/ {
+       model = "HR855XG2 BMC";
+       compatible = "lenovo,hr855xg2-bmc", "aspeed,ast2500";
+
+       aliases {
+               i2c14 = &i2c_riser1;
+               i2c15 = &i2c_riser2;
+               i2c16 = &i2c_riser3;
+               i2c17 = &i2c_M2;
+               i2c18 = &channel_0;
+               i2c19 = &channel_1;
+               i2c20 = &channel_2;
+               i2c21 = &channel_3;
+       };
+
+       chosen {
+               stdout-path = &uart5;
+               bootargs = "console=tty0 console=ttyS4,115200 earlyprintk";
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0x20000000>;
+       };
+
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               flash_memory: region@98000000 {
+                       no-map;
+                       reg = <0x98000000 0x00100000>; /* 1M */
+               };
+
+               gfx_memory: framebuffer {
+                       size = <0x01000000>;
+                       alignment = <0x01000000>;
+                       compatible = "shared-dma-pool";
+                       reusable;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               heartbeat {
+                       gpios = <&gpio ASPEED_GPIO(C, 7) GPIO_ACTIVE_LOW>;
+               };
+
+               fault {
+                       gpios = <&gpio ASPEED_GPIO(G, 3) GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       iio-hwmon {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 0>, <&adc 1>, <&adc 2>, <&adc 3>,
+               <&adc 4>, <&adc 5>, <&adc 6>, <&adc 7>,
+               <&adc 8>, <&adc 9>, <&adc 10>,<&adc 11>,
+               <&adc 12>,<&adc 13>,<&adc 14>;
+       };
+
+       iio-hwmon-battery {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 15>;
+       };
+
+};
+
+&fmc {
+       status = "okay";
+       flash@0 {
+               status = "okay";
+               m25p,fast-read;
+               label = "bmc";
+               spi-max-frequency = <50000000>;
+#include "openbmc-flash-layout.dtsi"
+       };
+};
+
+&lpc_ctrl {
+       status = "okay";
+       memory-region = <&flash_memory>;
+       flash = <&spi1>;
+};
+
+&lpc_snoop {
+       status = "okay";
+       snoop-ports = <0x80>;
+};
+
+&uart1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd1_default
+                       &pinctrl_rxd1_default>;
+};
+
+&uart2 {
+       /* Rear RS-232 connector */
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd2_default
+                       &pinctrl_rxd2_default
+                       &pinctrl_nrts2_default
+                       &pinctrl_ndtr2_default
+                       &pinctrl_ndsr2_default
+                       &pinctrl_ncts2_default
+                       &pinctrl_ndcd2_default
+                       &pinctrl_nri2_default>;
+};
+
+&uart3 {
+       status = "okay";
+};
+
+&uart5 {
+       status = "okay";
+};
+
+&ibt {
+       status = "okay";
+};
+
+&mac0 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rmii1_default>;
+       use-ncsi;
+};
+
+&mac1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
+};
+
+&adc{
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_adc0_default
+                       &pinctrl_adc1_default
+                       &pinctrl_adc2_default
+                       &pinctrl_adc3_default
+                       &pinctrl_adc4_default
+                       &pinctrl_adc5_default
+                       &pinctrl_adc6_default
+                       &pinctrl_adc7_default
+                       &pinctrl_adc8_default
+                       &pinctrl_adc9_default
+                       &pinctrl_adc10_default
+                       &pinctrl_adc11_default
+                       &pinctrl_adc12_default
+                       &pinctrl_adc13_default
+                       &pinctrl_adc14_default
+                       &pinctrl_adc15_default>;
+};
+
+&i2c0 {
+       status = "okay";
+
+       i2c-switch@70 {
+               compatible = "nxp,pca9545";
+               reg = <0x70>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               i2c_riser1: i2c@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0>;
+               };
+
+               i2c_riser2: i2c@1 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+               };
+
+               i2c_riser3: i2c@2 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <2>;
+               };
+
+               i2c_M2: i2c@3 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <3>;
+               };
+       };
+};
+
+&i2c1 {
+       status = "okay";
+       bus-frequency = <90000>;
+       HotSwap@10 {
+               compatible = "adm1272";
+               reg = <0x10>;
+       };
+
+       VR@45 {
+               compatible = "pmbus";
+               reg = <0x45>;
+       };
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c3 {
+       status = "okay";
+       i2c-switch@70 {
+               compatible = "nxp,pca9546";
+               reg = <0x70>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               channel_0: i2c@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0>;
+               };
+
+               channel_1: i2c@1 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+               };
+
+               channel_2: i2c@2 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <2>;
+               };
+
+               channel_3: i2c@3 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <3>;
+               };
+       };
+};
+
+&i2c4 {
+       status = "okay";
+};
+
+&i2c5 {
+       status = "okay";
+};
+
+&i2c6 {
+       status = "okay";
+       /* temp1 */
+       tmp75@49 {
+               compatible = "national,lm75";
+               reg = <0x49>;
+       };
+
+       /* temp2 */
+       tmp75@4d {
+               compatible = "national,lm75";
+               reg = <0x4d>;
+       };
+
+       eeprom@54 {
+               compatible = "atmel,24c256";
+               reg = <0x54>;
+               pagesize = <16>;
+       };
+};
+
+&i2c7 {
+       status = "okay";
+};
+
+&i2c8 {
+       status = "okay";
+};
+
+&i2c9 {
+       status = "okay";
+};
+
+&i2c10 {
+       status = "okay";
+};
+
+&i2c11 {
+       status = "okay";
+};
+
+&i2c13 {
+       status = "okay";
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&uhci {
+       status = "okay";
+};
+
+&gfx {
+       status = "okay";
+       memory-region = <&gfx_memory>;
+};
+
+&pwm_tacho {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm0_default
+       &pinctrl_pwm1_default
+       &pinctrl_pwm2_default
+       &pinctrl_pwm3_default
+       &pinctrl_pwm4_default
+       &pinctrl_pwm5_default
+       &pinctrl_pwm6_default
+       &pinctrl_pwm7_default>;
+
+       fan@0 {
+               reg = <0x00>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x00>;
+       };
+
+       fan@1 {
+               reg = <0x00>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x01>;
+       };
+
+       fan@2 {
+               reg = <0x01>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x02>;
+       };
+
+       fan@3 {
+               reg = <0x01>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x03>;
+       };
+
+       fan@4 {
+               reg = <0x02>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x04>;
+       };
+
+       fan@5 {
+               reg = <0x02>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x05>;
+       };
+
+       fan@6 {
+               reg = <0x03>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x06>;
+       };
+
+       fan@7 {
+               reg = <0x03>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x07>;
+       };
+
+       fan@8 {
+               reg = <0x04>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x08>;
+       };
+
+       fan@9 {
+               reg = <0x04>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x09>;
+       };
+
+       fan@10 {
+               reg = <0x05>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x0a>;
+       };
+
+       fan@11 {
+               reg = <0x05>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x0b>;
+       };
+
+       fan@12 {
+               reg = <0x06>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x0c>;
+       };
+
+       fan@13 {
+               reg = <0x06>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x0d>;
+       };
+
+       fan@14 {
+               reg = <0x07>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x0e>;
+       };
+
+       fan@15 {
+               reg = <0x07>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x0f>;
+       };
+
+       fan@16 {
+               reg = <0x07>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x0f>;
+       };
+};
+
+&gpio {
+
+       pin_gpio_a1 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(A, 1) GPIO_ACTIVE_LOW>;
+               output-high;
+               line-name = "BMC_EMMC_RST_N";
+       };
+
+       pin_gpio_a3 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(A, 3) GPIO_ACTIVE_LOW>;
+               output-high;
+               line-name = "PCH_PWROK_BMC_FPGA";
+       };
+
+       pin_gpio_b5 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(B, 5) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "IRQ_BMC_PCH_SMI_LPC_N";
+       };
+
+       pin_gpio_b7 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(B, 7) GPIO_ACTIVE_LOW>;
+               output-low;
+               line-name = "CPU_SM_WP";
+       };
+
+       pin_gpio_e0 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(E, 0) GPIO_ACTIVE_HIGH>;
+               input;
+               line-name = "PDB_PSU_SEL";
+       };
+
+       pin_gpio_e2 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(E, 2) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "LOCATOR_LED_N";
+       };
+
+       pin_gpio_e5 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(E, 5) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "FM_BMC_DBP_PRESENT_R1_N";
+       };
+
+       pin_gpio_e6 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(E, 6) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "BMC_ME_SECURITY_OVERRIDE_N";
+       };
+
+       pin_gpio_f0 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(F, 0) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "IRQ_BMC_PCH_NMI_R";
+       };
+
+       pin_gpio_f1 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(F, 1) GPIO_ACTIVE_HIGH>;
+               input;
+               line-name = "CPU2_PROCDIS_BMC_N";
+       };
+
+       pin_gpio_f2 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(F, 2) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "RM_THROTTLE_EN_N";
+       };
+
+       pin_gpio_f3 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(F, 3) GPIO_ACTIVE_HIGH>;
+               output-low;
+               line-name = "FM_PMBUS_ALERT_B_EN";
+       };
+
+       pin_gpio_f4 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(F, 4) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "BMC_FORCE_NM_THROTTLE_N";
+       };
+
+       pin_gpio_f6 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(F, 6) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "FM_BMC_CPU_PWR_DEBUG_N";
+       };
+
+       pin_gpio_g7 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(G, 7) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "BMC_PCIE_I2C_MUX_RST_N";
+       };
+
+       pin_gpio_h6 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(H, 6) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "FM_BMC_DBP_PRESENT_R2_N";
+       };
+
+       pin_gpio_i3 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(I, 3) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "SPI_BMC_BIOS_WP_N";
+       };
+
+       pin_gpio_j1 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(J, 1) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "BMC_USB_SEL";
+       };
+
+       pin_gpio_j2 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(J, 2) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "PDB_SMB_RST_N";
+       };
+
+       pin_gpio_j3 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(J, 3) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "SPI_BMC_BIOS_HOLD_N";
+       };
+
+       pin_gpio_l0 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(L, 0) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "PDB_FAN_TACH_SEL";
+       };
+
+       pin_gpio_l1 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(L, 1) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "SYS_RESET_BMC_FPGA_N";
+       };
+
+       pin_gpio_l4 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(L, 4) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "FM_EFUSE_FAN_G1_EN";
+       };
+
+       pin_gpio_l5 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(L, 5) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "FM_EFUSE_FAN_G2_EN";
+       };
+
+       pin_gpio_r6 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(R, 6) GPIO_ACTIVE_HIGH>;
+               input;
+               line-name = "CPU3_PROCDIS_BMC_N";
+       };
+
+       pin_gpio_r7 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(R, 7) GPIO_ACTIVE_HIGH>;
+               input;
+               line-name = "CPU4_PROCDIS_BMC_N";
+       };
+
+       pin_gpio_s1 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(S, 1) GPIO_ACTIVE_HIGH>;
+               output-low;
+               line-name = "DBP_SYSPWROK_BMC";
+       };
+
+       pin_gpio_s2 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(S, 2) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "PCH_RST_RSMRST_N";
+       };
+
+       pin_gpio_s6 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(S, 6) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "BMC_HW_STRAP_5";
+       };
+
+       pin_gpio_z3 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "FM_BMC_PCH_SCI_LPC_N";
+       };
+
+       pin_gpio_aa0 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(AA, 0) GPIO_ACTIVE_HIGH>;
+               output-low;
+               line-name = "FW_PSU_ALERT_EN_N";
+       };
+
+       pin_gpio_aa4 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(AA, 4) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "DBP_CPU_PREQ_N";
+       };
+
+       pin_gpio_ab3 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(AB, 3) GPIO_ACTIVE_HIGH>;
+               output-low;
+               line-name = "BMC_WDTRST";
+       };
+
+       pin_gpio_ac6 {
+               gpio-hog;
+               gpios = <ASPEED_GPIO(AC, 6) GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "ESPI_BMC_ALERT_N";
+       };
+
+};
diff --git a/arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts b/arch/arm/boot/dts/aspeed-bmc-opp-mihawk.dts
new file mode 100644 (file)
index 0000000..e55cc45
--- /dev/null
@@ -0,0 +1,918 @@
+// SPDX-License-Identifier: GPL-2.0+
+/dts-v1/;
+#include "aspeed-g5.dtsi"
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/leds/leds-pca955x.h>
+
+/ {
+       model = "Mihawk BMC";
+       compatible = "ibm,mihawk-bmc", "aspeed,ast2500";
+
+
+       chosen {
+               stdout-path = &uart5;
+               bootargs = "console=ttyS4,115200 earlyprintk";
+       };
+
+       memory@80000000 {
+               reg = <0x80000000 0x20000000>;
+       };
+
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               flash_memory: region@98000000 {
+                       no-map;
+                       reg = <0x98000000 0x04000000>; /* 64M */
+               };
+
+               gfx_memory: framebuffer {
+                       size = <0x01000000>;
+                       alignment = <0x01000000>;
+                       compatible = "shared-dma-pool";
+                       reusable;
+               };
+
+               video_engine_memory: jpegbuffer {
+                       size = <0x02000000>;
+                       alignment = <0x01000000>;
+                       compatible = "shared-dma-pool";
+                       reusable;
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               air-water {
+                       label = "air-water";
+                       gpios = <&gpio ASPEED_GPIO(F, 6) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(F, 6)>;
+               };
+
+               checkstop {
+                       label = "checkstop";
+                       gpios = <&gpio ASPEED_GPIO(J, 2) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(J, 2)>;
+               };
+
+               ps0-presence {
+                       label = "ps0-presence";
+                       gpios = <&gpio ASPEED_GPIO(Z, 2) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(Z, 2)>;
+               };
+
+               ps1-presence {
+                       label = "ps1-presence";
+                       gpios = <&gpio ASPEED_GPIO(Z, 0) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(Z, 0)>;
+               };
+               id-button {
+                       label = "id-button";
+                       gpios = <&gpio ASPEED_GPIO(F, 1) GPIO_ACTIVE_LOW>;
+                       linux,code = <ASPEED_GPIO(F, 1)>;
+               };
+       };
+
+       gpio-keys-polled {
+               compatible = "gpio-keys-polled";
+               poll-interval = <1000>;
+
+               fan0-presence {
+                       label = "fan0-presence";
+                       gpios = <&pca9552 9 GPIO_ACTIVE_LOW>;
+                       linux,code = <9>;
+               };
+
+               fan1-presence {
+                       label = "fan1-presence";
+                       gpios = <&pca9552 10 GPIO_ACTIVE_LOW>;
+                       linux,code = <10>;
+               };
+
+               fan2-presence {
+                       label = "fan2-presence";
+                       gpios = <&pca9552 11 GPIO_ACTIVE_LOW>;
+                       linux,code = <11>;
+               };
+
+               fan3-presence {
+                       label = "fan3-presence";
+                       gpios = <&pca9552 12 GPIO_ACTIVE_LOW>;
+                       linux,code = <12>;
+               };
+
+               fan4-presence {
+                       label = "fan4-presence";
+                       gpios = <&pca9552 13 GPIO_ACTIVE_LOW>;
+                       linux,code = <13>;
+               };
+
+               fan5-presence {
+                       label = "fan5-presence";
+                       gpios = <&pca9552 14 GPIO_ACTIVE_LOW>;
+                       linux,code = <14>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               fault {
+                       retain-state-shutdown;
+                       default-state = "keep";
+                       gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_LOW>;
+               };
+
+               power {
+                       retain-state-shutdown;
+                       default-state = "keep";
+                       gpios = <&gpio ASPEED_GPIO(AA, 1) GPIO_ACTIVE_LOW>;
+               };
+
+               rear-id {
+                       retain-state-shutdown;
+                       default-state = "keep";
+                       gpios = <&gpio ASPEED_GPIO(AA, 2) GPIO_ACTIVE_LOW>;
+               };
+
+               rear-g {
+                       retain-state-shutdown;
+                       default-state = "keep";
+                       gpios = <&gpio ASPEED_GPIO(AA, 4) GPIO_ACTIVE_LOW>;
+               };
+
+               rear-ok {
+                       retain-state-shutdown;
+                       default-state = "keep";
+                       gpios = <&gpio ASPEED_GPIO(Y, 0) GPIO_ACTIVE_LOW>;
+               };
+
+               fan0 {
+                       retain-state-shutdown;
+                       default-state = "keep";
+                       gpios = <&pca9552 0 GPIO_ACTIVE_LOW>;
+               };
+
+               fan1 {
+                       retain-state-shutdown;
+                       default-state = "keep";
+                       gpios = <&pca9552 1 GPIO_ACTIVE_LOW>;
+               };
+
+               fan2 {
+                       retain-state-shutdown;
+                       default-state = "keep";
+                       gpios = <&pca9552 2 GPIO_ACTIVE_LOW>;
+               };
+
+               fan3 {
+                       retain-state-shutdown;
+                       default-state = "keep";
+                       gpios = <&pca9552 3 GPIO_ACTIVE_LOW>;
+               };
+
+               fan4 {
+                       retain-state-shutdown;
+                       default-state = "keep";
+                       gpios = <&pca9552 4 GPIO_ACTIVE_LOW>;
+               };
+
+               fan5 {
+                       retain-state-shutdown;
+                       default-state = "keep";
+                       gpios = <&pca9552 5 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       fsi: gpio-fsi {
+               compatible = "fsi-master-gpio", "fsi-master";
+               #address-cells = <2>;
+               #size-cells = <0>;
+               no-gpio-delays;
+
+               clock-gpios = <&gpio ASPEED_GPIO(E, 6) GPIO_ACTIVE_HIGH>;
+               data-gpios = <&gpio ASPEED_GPIO(E, 7) GPIO_ACTIVE_HIGH>;
+               mux-gpios = <&gpio ASPEED_GPIO(E, 5) GPIO_ACTIVE_HIGH>;
+               enable-gpios = <&gpio ASPEED_GPIO(D, 0) GPIO_ACTIVE_HIGH>;
+               trans-gpios = <&gpio ASPEED_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
+       };
+       iio-hwmon-12v {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 0>;
+       };
+
+       iio-hwmon-5v {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 1>;
+       };
+
+       iio-hwmon-3v {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 2>;
+       };
+
+       iio-hwmon-vdd0 {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 3>;
+       };
+
+       iio-hwmon-vdd1 {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 4>;
+       };
+
+       iio-hwmon-vcs0 {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 5>;
+       };
+
+       iio-hwmon-vcs1 {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 6>;
+       };
+
+       iio-hwmon-vdn0 {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 7>;
+       };
+
+       iio-hwmon-vdn1 {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 8>;
+       };
+
+       iio-hwmon-vio0 {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 9>;
+       };
+
+       iio-hwmon-vio1 {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 10>;
+       };
+
+       iio-hwmon-vddra {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 11>;
+       };
+
+       iio-hwmon-battery {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 12>;
+       };
+
+       iio-hwmon-vddrb {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 13>;
+       };
+
+       iio-hwmon-vddrc {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 14>;
+       };
+
+       iio-hwmon-vddrd {
+               compatible = "iio-hwmon";
+               io-channels = <&adc 15>;
+       };
+};
+
+&pwm_tacho {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default
+               &pinctrl_pwm2_default &pinctrl_pwm3_default
+               &pinctrl_pwm4_default &pinctrl_pwm5_default>;
+
+       fan@0 {
+               reg = <0x00>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x00>;
+       };
+
+       fan@1 {
+               reg = <0x01>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x01>;
+       };
+
+       fan@2 {
+               reg = <0x02>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x02>;
+       };
+
+       fan@3 {
+               reg = <0x03>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x03>;
+       };
+
+       fan@4 {
+               reg = <0x04>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x04>;
+       };
+
+       fan@5 {
+               reg = <0x05>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x05>;
+       };
+
+       fan@6 {
+               reg = <0x00>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x06>;
+       };
+
+       fan@7 {
+               reg = <0x01>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x07>;
+       };
+
+       fan@8 {
+               reg = <0x02>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x08>;
+       };
+
+       fan@9 {
+               reg = <0x03>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x09>;
+       };
+
+       fan@10 {
+               reg = <0x04>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x0a>;
+       };
+
+       fan@11 {
+               reg = <0x05>;
+               aspeed,fan-tach-ch = /bits/ 8 <0x0b>;
+       };
+};
+
+&fmc {
+       status = "okay";
+       flash@0 {
+               status = "okay";
+               label = "bmc";
+               m25p,fast-read;
+               spi-max-frequency = <50000000>;
+               partitions {
+                       #address-cells = < 1 >;
+                       #size-cells = < 1 >;
+                       compatible = "fixed-partitions";
+                       u-boot@0 {
+                               reg = < 0 0x60000 >;
+                               label = "u-boot";
+                       };
+                       u-boot-env@60000 {
+                               reg = < 0x60000 0x20000 >;
+                               label = "u-boot-env";
+                       };
+                       obmc-ubi@80000 {
+                               reg = < 0x80000 0x1F80000 >;
+                               label = "obmc-ubi";
+                       };
+               };
+       };
+       flash@1 {
+               status = "okay";
+               label = "alt-bmc";
+               m25p,fast-read;
+               spi-max-frequency = <50000000>;
+               partitions {
+                       #address-cells = < 1 >;
+                       #size-cells = < 1 >;
+                       compatible = "fixed-partitions";
+                       u-boot@0 {
+                               reg = < 0 0x60000 >;
+                               label = "alt-u-boot";
+                       };
+                       u-boot-env@60000 {
+                               reg = < 0x60000 0x20000 >;
+                               label = "alt-u-boot-env";
+                       };
+                       obmc-ubi@80000 {
+                               reg = < 0x80000 0x1F80000 >;
+                               label = "alt-obmc-ubi";
+                       };
+               };
+       };
+};
+
+&spi1 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_spi1_default>;
+
+       flash@0 {
+               status = "okay";
+               label = "pnor";
+               m25p,fast-read;
+               spi-max-frequency = <100000000>;
+       };
+};
+
+&lpc_ctrl {
+       status = "okay";
+       memory-region = <&flash_memory>;
+       flash = <&spi1>;
+};
+
+&uart1 {
+       /* Rear RS-232 connector */
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd1_default
+                       &pinctrl_rxd1_default
+                       &pinctrl_nrts1_default
+                       &pinctrl_ndtr1_default
+                       &pinctrl_ndsr1_default
+                       &pinctrl_ncts1_default
+                       &pinctrl_ndcd1_default
+                       &pinctrl_nri1_default>;
+};
+
+&uart2 {
+       /* APSS */
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_txd2_default &pinctrl_rxd2_default>;
+};
+
+&uart5 {
+       status = "okay";
+};
+
+&mac0 {
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rmii1_default>;
+       use-ncsi;
+};
+
+&mac1 {
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
+};
+
+&i2c0 {
+       status = "disabled";
+};
+
+&i2c1 {
+       status = "disabled";
+};
+
+&i2c2 {
+       status = "okay";
+
+       /* SAMTEC P0 */
+       /* SAMTEC P1 */
+
+};
+
+&i2c3 {
+       status = "okay";
+
+       /* APSS */
+       /* CPLD */
+
+       /* PCA9516 (repeater) ->
+        *    CLK Buffer 9FGS9092
+        *    CLK Buffer 9DBL0651BKILFT
+        *    CLK Buffer 9DBL0651BKILFT
+        *    Power Supply 0
+        *    Power Supply 1
+        *    PCA 9552 LED
+        */
+
+       power-supply@58 {
+               compatible = "ibm,cffps1";
+               reg = <0x58>;
+       };
+
+       power-supply@5b {
+               compatible = "ibm,cffps1";
+               reg = <0x5b>;
+       };
+
+       pca9552: pca9552@60 {
+               compatible = "nxp,pca9552";
+               reg = <0x60>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               gpio-controller;
+               #gpio-cells = <2>;
+
+               gpio@0 {
+                       reg = <0>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@1 {
+                       reg = <1>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@2 {
+                       reg = <2>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@3 {
+                       reg = <3>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@4 {
+                       reg = <4>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@5 {
+                       reg = <5>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@6 {
+                       reg = <6>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@7 {
+                       reg = <7>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@8 {
+                       reg = <8>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@9 {
+                       reg = <9>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@10 {
+                       reg = <10>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@11 {
+                       reg = <11>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@12 {
+                       reg = <12>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@13 {
+                       reg = <13>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@14 {
+                       reg = <14>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+               gpio@15 {
+                       reg = <15>;
+                       type = <PCA955X_TYPE_GPIO>;
+               };
+
+       };
+
+};
+
+&i2c4 {
+       status = "okay";
+
+       /* CP0 VDD & VCS : IR35221 */
+       /* CP0 VDN : IR35221 */
+       /* CP0 VIO : IR38064 */
+       /* CP0 VDDR : PXM1330 */
+
+       ir35221@70 {
+               compatible = "infineon,ir35221";
+               reg = <0x70>;
+       };
+
+       ir35221@72 {
+               compatible = "infineon,ir35221";
+               reg = <0x72>;
+       };
+
+};
+
+&i2c5 {
+       status = "okay";
+
+       /* CP0 VDD & VCS : IR35221 */
+       /* CP0 VDN : IR35221 */
+       /* CP0 VIO : IR38064 */
+       /* CP0 VDDR : PXM1330 */
+
+       ir35221@70 {
+               compatible = "infineon,ir35221";
+               reg = <0x70>;
+       };
+
+       ir35221@72 {
+               compatible = "infineon,ir35221";
+               reg = <0x72>;
+       };
+
+};
+
+&i2c6 {
+       status = "okay";
+
+       /* pca9548 -> NVMe1 to 8 */
+
+       pca9548@70 {
+               compatible = "nxp,pca9548";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x70>;
+       };
+
+};
+
+&i2c7 {
+       status = "okay";
+
+       /* pca9548 -> NVMe9 to 16 */
+
+       pca9548@70 {
+               compatible = "nxp,pca9548";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x70>;
+       };
+
+};
+
+&i2c8 {
+       status = "okay";
+
+       eeprom@50 {
+               compatible = "atmel,24c64";
+               reg = <0x50>;
+       };
+};
+
+&i2c9 {
+       status = "okay";
+
+       /* pca9545 Riser ->
+       *       PCIe x8  Slot3
+       *       PCIe x16 slot4
+       *       PCIe x8  slot5
+       *       I2C BMC RISER PCA9554
+       *       BMC SCL/SDA PCA9554
+       *       PCA9554
+       */
+
+       /* pca9545 ->
+       *       PCIe x16 Slot1
+       *       PCIe x8  slot2
+       *       PEX8748
+       */
+
+       pca9545riser@70 {
+               compatible = "nxp,pca9545";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x70>;
+
+               i2c-mux-idle-disconnect;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       pca9545@71 {
+               compatible = "nxp,pca9545";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x71>;
+
+               i2c-mux-idle-disconnect;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+};
+
+&i2c10 {
+       status = "okay";
+
+       /* pca9545 Riser ->
+       *       PCIe x8  Slot8
+       *       PCIe x16 slot9
+       *       PCIe x8  slot10
+       *       I2C BMC RISER PCA9554
+       *       BMC SCL/SDA PCA9554
+       *       PCA9554
+       */
+
+       /* pca9545 ->
+       *       PCIe x16 Slot1
+       *       PCIe x8  slot2
+       *       PEX8748
+       */
+
+       pca9545riser@70 {
+               compatible = "nxp,pca9545";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x70>;
+
+               i2c-mux-idle-disconnect;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+
+       pca9545@71 {
+               compatible = "nxp,pca9545";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x71>;
+
+               i2c-mux-idle-disconnect;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+};
+
+&i2c11 {
+       status = "okay";
+
+       /* TPM */
+       /* RTC RX8900CE */
+       /* FPGA for power sequence */
+       /* TMP275A */
+       /* TMP275A */
+       /* EMC1462 */
+
+       tpm@57 {
+               compatible = "infineon,slb9645tt";
+               reg = <0x57>;
+       };
+
+       rtc@32 {
+               compatible = "epson,rx8900";
+               reg = <0x32>;
+       };
+
+       tmp275@48 {
+               compatible = "ti,tmp275";
+               reg = <0x48>;
+       };
+
+       tmp275@49 {
+               compatible = "ti,tmp275";
+               reg = <0x49>;
+       };
+
+       /* chip emc1462 use emc1403 driver */
+       emc1403@4c {
+               compatible = "smsc,emc1403";
+               reg = <0x4c>;
+       };
+
+};
+
+&i2c12 {
+       status = "okay";
+
+       /* pca9545 ->
+       *       SAS BP1
+       *       SAS BP2
+       *       NVMe BP
+       *       M.2 riser
+       */
+
+       pca9545@70 {
+               compatible = "nxp,pca9545";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x70>;
+
+               interrupt-controller;
+               #interrupt-cells = <2>;
+
+               i2c@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0>;
+
+                       eeprom@50 {
+                               compatible = "atmel,24c64";
+                               reg = <0x50>;
+                       };
+               };
+
+               i2c@1 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+
+                       eeprom@50 {
+                               compatible = "atmel,24c64";
+                               reg = <0x50>;
+                       };
+               };
+
+               i2c@2 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <2>;
+
+                       eeprom@50 {
+                               compatible = "atmel,24c64";
+                               reg = <0x50>;
+                       };
+               };
+
+               i2c@3 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <3>;
+
+                       tmp275@48 {
+                               compatible = "ti,tmp275";
+                               reg = <0x48>;
+                       };
+               };
+
+       };
+
+};
+
+&i2c13 {
+       status = "okay";
+
+       /* pca9548 ->
+       *       NVMe BP
+       *       NVMe HDD17 to 24
+       */
+
+       pca9548@70 {
+               compatible = "nxp,pca9548";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x70>;
+       };
+};
+
+&vuart {
+       status = "okay";
+};
+
+&gfx {
+       status = "okay";
+       memory-region = <&gfx_memory>;
+};
+
+&adc {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_adc0_default
+                       &pinctrl_adc1_default
+                       &pinctrl_adc2_default
+                       &pinctrl_adc3_default
+                       &pinctrl_adc4_default
+                       &pinctrl_adc5_default
+                       &pinctrl_adc6_default
+                       &pinctrl_adc7_default
+                       &pinctrl_adc8_default
+                       &pinctrl_adc9_default
+                       &pinctrl_adc10_default
+                       &pinctrl_adc11_default
+                       &pinctrl_adc12_default
+                       &pinctrl_adc13_default
+                       &pinctrl_adc14_default
+                       &pinctrl_adc15_default>;
+};
+
+&wdt1 {
+       aspeed,reset-type = "none";
+       aspeed,external-signal;
+       aspeed,ext-push-pull;
+       aspeed,ext-active-high;
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdtrst1_default>;
+};
+
+&wdt2 {
+       aspeed,alt-boot;
+};
+
+&ibt {
+       status = "okay";
+};
+
+&vhub {
+       status = "okay";
+};
+
+&video {
+       status = "okay";
+       memory-region = <&video_engine_memory>;
+};
+
+#include "ibm-power9-dual.dtsi"
+
index caac895..f67fef1 100644 (file)
                #size-cells = <0>;
                no-gpio-delays;
 
-               clock-gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_HIGH>;
-               data-gpios = <&gpio ASPEED_GPIO(E, 0) GPIO_ACTIVE_HIGH>;
+               clock-gpios = <&gpio ASPEED_GPIO(P, 1) GPIO_ACTIVE_HIGH>;
+               data-gpios = <&gpio ASPEED_GPIO(P, 2) GPIO_ACTIVE_HIGH>;
                mux-gpios = <&gpio ASPEED_GPIO(P, 4) GPIO_ACTIVE_HIGH>;
                enable-gpios = <&gpio ASPEED_GPIO(P, 0) GPIO_ACTIVE_HIGH>;
                trans-gpios = <&gpio ASPEED_GPIO(P, 3) GPIO_ACTIVE_HIGH>;
        };
 
        power-supply@68 {
-               compatible = "ibm,cffps1";
+               compatible = "ibm,cffps2";
                reg = <0x68>;
        };
 
        };
 
        power-supply@69 {
-               compatible = "ibm,cffps1";
+               compatible = "ibm,cffps2";
                reg = <0x69>;
        };
 
        status = "okay";
 };
 
+&sdmmc {
+       status = "okay";
+};
+
+&sdhci1 {
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sd2_default>;
+};
+
 #include "ibm-power9-dual.dtsi"
index 0b9e29c..a27c88d 100644 (file)
         label = "bmc";
 #include "openbmc-flash-layout.dtsi"
        };
+
+       flash@1 {
+               status = "okay";
+               m25p,fast-read;
+               label = "alt";
+       };
 };
 
 &spi {
 &vuart {
        status = "okay";
 };
+
+&wdt2 {
+       aspeed,alt-boot;
+};
index dd4b0b1..dffb595 100644 (file)
                                compatible = "jedec,spi-nor";
                                status = "disabled";
                        };
+                       flash@1 {
+                               reg = < 1 >;
+                               compatible = "jedec,spi-nor";
+                               status = "disabled";
+                       };
+                       flash@2 {
+                               reg = < 2 >;
+                               compatible = "jedec,spi-nor";
+                               status = "disabled";
+                       };
+                       flash@3 {
+                               reg = < 3 >;
+                               compatible = "jedec,spi-nor";
+                               status = "disabled";
+                       };
+                       flash@4 {
+                               reg = < 4 >;
+                               compatible = "jedec,spi-nor";
+                               status = "disabled";
+                       };
                };
 
                spi: spi@1e630000 {
                                reg = <0x1e720000 0x8000>;      // 32K
                        };
 
+                       sdmmc: sd-controller@1e740000 {
+                               compatible = "aspeed,ast2400-sd-controller";
+                               reg = <0x1e740000 0x100>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x1e740000 0x10000>;
+                               clocks = <&syscon ASPEED_CLK_GATE_SDCLK>;
+                               status = "disabled";
+
+                               sdhci0: sdhci@100 {
+                                       compatible = "aspeed,ast2400-sdhci";
+                                       reg = <0x100 0x100>;
+                                       interrupts = <26>;
+                                       sdhci,auto-cmd12;
+                                       clocks = <&syscon ASPEED_CLK_SDIO>;
+                                       status = "disabled";
+                               };
+
+                               sdhci1: sdhci@200 {
+                                       compatible = "aspeed,ast2400-sdhci";
+                                       reg = <0x200 0x100>;
+                                       interrupts = <26>;
+                                       sdhci,auto-cmd12;
+                                       clocks = <&syscon ASPEED_CLK_SDIO>;
+                                       status = "disabled";
+                               };
+                       };
+
                        gpio: gpio@1e780000 {
                                #gpio-cells = <2>;
                                gpio-controller;
index 5b1ca26..e8feb8b 100644 (file)
                                reg = <0x1e720000 0x9000>;      // 36K
                        };
 
+                       sdmmc: sd-controller@1e740000 {
+                               compatible = "aspeed,ast2500-sd-controller";
+                               reg = <0x1e740000 0x100>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0 0x1e740000 0x10000>;
+                               clocks = <&syscon ASPEED_CLK_GATE_SDCLK>;
+                               status = "disabled";
+
+                               sdhci0: sdhci@100 {
+                                       compatible = "aspeed,ast2500-sdhci";
+                                       reg = <0x100 0x100>;
+                                       interrupts = <26>;
+                                       sdhci,auto-cmd12;
+                                       clocks = <&syscon ASPEED_CLK_SDIO>;
+                                       status = "disabled";
+                               };
+
+                               sdhci1: sdhci@200 {
+                                       compatible = "aspeed,ast2500-sdhci";
+                                       reg = <0x200 0x100>;
+                                       interrupts = <26>;
+                                       sdhci,auto-cmd12;
+                                       clocks = <&syscon ASPEED_CLK_SDIO>;
+                                       status = "disabled";
+                               };
+                       };
+
                        gpio: gpio@1e780000 {
                                #gpio-cells = <2>;
                                gpio-controller;
                                compatible = "aspeed,ast2500-gpio";
                                reg = <0x1e780000 0x1000>;
                                interrupts = <20>;
-                               gpio-ranges = <&pinctrl 0 0 220>;
+                               gpio-ranges = <&pinctrl 0 0 232>;
                                clocks = <&syscon ASPEED_CLK_APB>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
                groups = "SDA2";
        };
 
+       pinctrl_sgpm_default: sgpm_default {
+               function = "SGPM";
+               groups = "SGPM";
+       };
+
        pinctrl_sgps1_default: sgps1_default {
                function = "SGPS1";
                groups = "SGPS1";
index 0d695c7..dbfefef 100644 (file)
                     "atmel,at91sam9x5", "atmel,at91sam9";
 
        aliases {
-               serial0 = &dbgu;
-               serial1 = &usart0;
-               serial2 = &usart1;
-               serial3 = &usart2;
-               serial4 = &usart3;
                serial5 = &uart0;
                serial6 = &uart1;
        };
                };
        };
 
-       ahb {
-               apb {
-                       mmc0: mmc@f0008000 {
-                               /* N.B. Aria has no SD card detect (CD), assumed present */
-
-                               pinctrl-0 = <
-                                       &pinctrl_mmc0_slot0_clk_cmd_dat0
-                                       &pinctrl_mmc0_slot0_dat1_3>;
-                               status = "okay";
-                               slot@0 {
-                                       reg = <0>;
-                                       bus-width = <4>;
-                               };
-                       };
-
-                       tcb0: timer@f8008000 {
-                               timer@0 {
-                                       compatible = "atmel,tcb-timer";
-                                       reg = <0>;
-                               };
-
-                               timer@1 {
-                                       compatible = "atmel,tcb-timer";
-                                       reg = <1>;
-                               };
-                       };
-
-                       i2c0: i2c@f8010000 {
-                               status = "okay";
-                       };
-
-                       i2c1: i2c@f8014000 {
-                               status = "okay";
-                       };
-
-                       /* TWD2+TCLK2 hidden behind ethernet, so no i2c2 */
-
-                       usart0: serial@f801c000 {
-                               pinctrl-0 = <&pinctrl_usart0
-                                            &pinctrl_usart0_rts
-                                            &pinctrl_usart0_cts>;
-                               status = "okay";
-                       };
-
-                       usart1: serial@f8020000 {
-                               pinctrl-0 = <&pinctrl_usart1
-                                            /* &pinctrl_usart1_rts */
-                                            /* &pinctrl_usart1_cts */
-                                           >;
-                               status = "okay";
-                       };
-
-                       usart2: serial@f8024000 {
-                               /* cannot activate RTS2+CTS2, clash with
-                                * ethernet on PB0 and PB1 */
-                               pinctrl-0 = <&pinctrl_usart2>;
-                               status = "okay";
-                       };
-
-                       usart3: serial@f8028000 {
-                               compatible = "atmel,at91sam9260-usart";
-                               reg = <0xf8028000 0x200>;
-                               interrupts = <8 4 5>;
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_usart3
-                                            /* &pinctrl_usart3_rts */
-                                            /* &pinctrl_usart3_cts */
-                                           >;
-                               status = "okay";
-                       };
-
-                       macb0: ethernet@f802c000 {
-                               phy-mode = "rmii";
-                               /*
-                                * following can be overwritten by bootloader:
-                                * for example u-boot 'ftd set' command
-                                */
-                               local-mac-address = [00 00 00 00 00 00];
-                               status = "okay";
-                       };
-
-                       /*
-                        * UART0/1 pins are marked as GPIO on
-                        * Aria documentation.
-                        * Change to "okay" if you need additional serial ports
-                        */
-                       uart0: serial@f8040000 {
-                               status = "disabled";
-                       };
-
-                       uart1: serial@f8044000 {
-                               status = "disabled";
-                       };
-
-                       adc0: adc@f804c000 {
-                               status = "okay";
-                               atmel,adc-channels-used = <0xf>;
-                       };
-
-                       dbgu: serial@fffff200 {
-                               status = "okay";
-                       };
-
-                       pinctrl@fffff400 {
-                               w1_0 {
-                                       pinctrl_w1_0: w1_0-0 {
-                                               atmel,pins = <0 21 0x0 0x1>; /* PA21 PIO, pull-up */
-                                       };
-                               };
-                       };
-
-                       rtc@fffffeb0 {
-                               status = "okay";
-                       };
-               };
-
-               usb0: ohci@600000 {
-                       status = "okay";
-                       num-ports = <3>;
-               };
-
-               usb1: ehci@700000 {
-                       status = "okay";
-               };
-       };
-
        leds {
                compatible = "gpio-leds";
 
                pinctrl-0 = <&pinctrl_w1_0>;
        };
 };
+
+&adc0 {
+       status = "okay";
+       atmel,adc-channels-used = <0xf>;
+};
+
+&dbgu {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+};
+
+&i2c1 {
+       status = "okay";
+};
+
+/* TWD2+TCLK2 hidden behind ethernet, so no i2c2 */
+
+&macb0 {
+       phy-mode = "rmii";
+       /*
+        * following can be overwritten by bootloader:
+        * for example u-boot 'ftd set' command
+        */
+       local-mac-address = [00 00 00 00 00 00];
+       status = "okay";
+};
+
+
+&mmc0 {
+       /* N.B. Aria has no SD card detect (CD), assumed present */
+
+       pinctrl-0 = <
+               &pinctrl_mmc0_slot0_clk_cmd_dat0
+               &pinctrl_mmc0_slot0_dat1_3>;
+       status = "okay";
+
+       slot@0 {
+               reg = <0>;
+               bus-width = <4>;
+       };
+};
+
+&pinctrl {
+       w1_0 {
+               pinctrl_w1_0: w1_0-0 {
+                       atmel,pins = <0 21 0x0 0x1>; /* PA21 PIO, pull-up */
+               };
+       };
+};
+
+&rtc {
+       status = "okay";
+};
+
+&tcb0 {
+       timer@0 {
+               compatible = "atmel,tcb-timer";
+               reg = <0>;
+       };
+
+       timer@1 {
+               compatible = "atmel,tcb-timer";
+               reg = <1>;
+       };
+};
+
+/*
+ * UART0/1 pins are marked as GPIO on
+ * Aria documentation.
+ * Change to "okay" if you need additional serial ports
+ */
+&uart0 {
+       status = "disabled";
+};
+
+&uart1 {
+       status = "disabled";
+};
+
+&usart0 {
+       pinctrl-0 = <&pinctrl_usart0
+                    &pinctrl_usart0_rts
+                    &pinctrl_usart0_cts>;
+       status = "okay";
+};
+
+&usart1 {
+       pinctrl-0 = <&pinctrl_usart1
+                    /* &pinctrl_usart1_rts */
+                    /* &pinctrl_usart1_cts */
+                   >;
+       status = "okay";
+};
+
+&usart2 {
+       /* cannot activate RTS2+CTS2, clash with
+        * ethernet on PB0 and PB1 */
+       pinctrl-0 = <&pinctrl_usart2>;
+       status = "okay";
+};
+
+&usart3 {
+       compatible = "atmel,at91sam9260-usart";
+       reg = <0xf8028000 0x200>;
+       interrupts = <8 4 5>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usart3
+                    /* &pinctrl_usart3_rts */
+                    /* &pinctrl_usart3_cts */
+                   >;
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+       num-ports = <3>;
+};
+
+&usb1 {
+       status = "okay";
+};
index 7a34c4d..0267e72 100644 (file)
@@ -6,14 +6,11 @@
  */
 /dts-v1/;
 #include "at91sam9g25.dtsi"
+
 / {
        model = "Acme Systems Arietta G25";
        compatible = "acme,ariettag25", "atmel,at91sam9x5", "atmel,at91sam9";
 
-       aliases {
-               serial0 = &dbgu;
-       };
-
        chosen {
                stdout-path = "serial0:115200n8";
        };
                };
        };
 
-       ahb {
-               apb {
-                       mmc0: mmc@f0008000 {
-                               pinctrl-0 = <
-                                 &pinctrl_mmc0_slot0_clk_cmd_dat0
-                                 &pinctrl_mmc0_slot0_dat1_3>;
-                               status = "okay";
-
-                               slot@0 {
-                                       reg = <0>;
-                                       bus-width = <4>;
-                               };
-                       };
-
-                       tcb0: timer@f8008000 {
-                               timer@0 {
-                                       compatible = "atmel,tcb-timer";
-                                       reg = <0>;
-                               };
-
-                               timer@1 {
-                                       compatible = "atmel,tcb-timer";
-                                       reg = <1>;
-                               };
-                       };
-
-                       usb2: gadget@f803c000 {
-                               status = "okay";
-                       };
-
-                       dbgu: serial@fffff200 {
-                               status = "okay";
-                       };
-
-                       rtc@fffffeb0 {
-                               status = "okay";
-                       };
-               };
-
-               usb0: ohci@600000 {
-                       status = "okay";
-                       num-ports = <3>;
-               };
-
-               usb1: ehci@700000 {
-                       status = "okay";
-               };
-       };
-
        leds {
                compatible = "gpio-leds";
+
                arietta_led {
                        label = "arietta_led";
                        gpios = <&pioB 8 GPIO_ACTIVE_HIGH>; /* PB8 */
                };
        };
 };
+
+&dbgu {
+       status = "okay";
+};
+
+&mmc0 {
+       pinctrl-0 = <
+               &pinctrl_mmc0_slot0_clk_cmd_dat0
+               &pinctrl_mmc0_slot0_dat1_3>;
+       status = "okay";
+
+       slot@0 {
+               reg = <0>;
+               bus-width = <4>;
+       };
+};
+
+&rtc {
+       status = "okay";
+};
+
+&tcb0 {
+       timer@0 {
+               compatible = "atmel,tcb-timer";
+               reg = <0>;
+       };
+
+       timer@1 {
+               compatible = "atmel,tcb-timer";
+               reg = <1>;
+       };
+};
+
+&usb0 {
+       num-ports = <3>;
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
+
+&usb2 {
+       status = "okay";
+};
index 47721c9..feebd54 100644 (file)
                        clock-frequency = <12000000>;
                };
        };
+};
 
-       ahb {
-               apb {
-                       tcb0: timer@f8008000 {
-                               timer@0 {
-                                       compatible = "atmel,tcb-timer";
-                                       reg = <0>;
-                               };
+&adc0 {
+       atmel,adc-ts-wires = <4>;
+       atmel,adc-ts-pressure-threshold = <10000>;
+       status = "okay";
+};
+
+&dbgu {
+       status = "okay";
+};
 
-                               timer@1 {
-                                       compatible = "atmel,tcb-timer";
-                                       reg = <1>;
+&ebi {
+       pinctrl-0 = <&pinctrl_ebi_addr_nand
+                    &pinctrl_ebi_data_0_7>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       nand-controller {
+               pinctrl-0 = <&pinctrl_nand_oe_we
+                            &pinctrl_nand_cs
+                            &pinctrl_nand_rb>;
+               pinctrl-names = "default";
+               status = "okay";
+
+               nand@3 {
+                       reg = <0x3 0x0 0x800000>;
+                       rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>;
+                       cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>;
+                       nand-bus-width = <8>;
+                       nand-ecc-mode = "hw";
+                       nand-ecc-strength = <4>;
+                       nand-ecc-step-size = <512>;
+                       nand-on-flash-bbt;
+                       label = "atmel_nand";
+
+                       partitions {
+                               compatible = "fixed-partitions";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               at91bootstrap@0 {
+                                       label = "at91bootstrap";
+                                       reg = <0x0 0x40000>;
                                };
-                       };
 
-                       mmc0: mmc@f0008000 {
-                               pinctrl-0 = <
-                                       &pinctrl_board_mmc0
-                                       &pinctrl_mmc0_slot0_clk_cmd_dat0
-                                       &pinctrl_mmc0_slot0_dat1_3>;
-                               status = "okay";
-                               slot@0 {
-                                       reg = <0>;
-                                       bus-width = <4>;
-                                       cd-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
+                               uboot@40000 {
+                                       label = "u-boot";
+                                       reg = <0x40000 0x80000>;
                                };
-                       };
 
-                       dbgu: serial@fffff200 {
-                               status = "okay";
-                       };
+                               ubootenv@c0000 {
+                                       label = "U-Boot Env";
+                                       reg = <0xc0000 0x140000>;
+                               };
 
-                       usart0: serial@f801c000 {
-                               status = "okay";
-                       };
+                               kernel@200000 {
+                                       label = "kernel";
+                                       reg = <0x200000 0x600000>;
+                               };
 
-                       i2c0: i2c@f8010000 {
-                               status = "okay";
+                               rootfs@800000 {
+                                       label = "rootfs";
+                                       reg = <0x800000 0x0f800000>;
+                               };
                        };
+               };
+       };
+};
 
-                       adc0: adc@f804c000 {
-                               atmel,adc-ts-wires = <4>;
-                               atmel,adc-ts-pressure-threshold = <10000>;
-                               status = "okay";
-                       };
+&i2c0 {
+       status = "okay";
+};
 
-                       pinctrl@fffff400 {
-                               mmc0 {
-                                       pinctrl_board_mmc0: mmc0-board {
-                                               atmel,pins =
-                                                       <AT91_PIOD 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;  /* PD15 gpio CD pin pull up and deglitch */
-                                       };
-                               };
-                       };
+&mmc0 {
+       pinctrl-0 = <
+               &pinctrl_board_mmc0
+               &pinctrl_mmc0_slot0_clk_cmd_dat0
+               &pinctrl_mmc0_slot0_dat1_3>;
+       status = "okay";
+
+       slot@0 {
+               reg = <0>;
+               bus-width = <4>;
+               cd-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
+       };
+};
 
-                       watchdog@fffffe40 {
-                               status = "okay";
-                       };
+&pinctrl {
+       mmc0 {
+               pinctrl_board_mmc0: mmc0-board {
+                       atmel,pins =
+                               <AT91_PIOD 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;  /* PD15 gpio CD pin pull up and deglitch */
                };
+       };
+};
 
-               ebi: ebi@10000000 {
-                       pinctrl-0 = <&pinctrl_ebi_addr_nand
-                                    &pinctrl_ebi_data_0_7>;
-                       pinctrl-names = "default";
-                       status = "okay";
-
-                       nand_controller: nand-controller {
-                               status = "okay";
-                               pinctrl-0 = <&pinctrl_nand_oe_we
-                                            &pinctrl_nand_cs
-                                            &pinctrl_nand_rb>;
-                               pinctrl-names = "default";
-
-                               nand@3 {
-                                       reg = <0x3 0x0 0x800000>;
-                                       rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>;
-                                       cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>;
-                                       nand-bus-width = <8>;
-                                       nand-ecc-mode = "hw";
-                                       nand-ecc-strength = <4>;
-                                       nand-ecc-step-size = <512>;
-                                       nand-on-flash-bbt;
-                                       label = "atmel_nand";
-
-                                       partitions {
-                                               compatible = "fixed-partitions";
-                                               #address-cells = <1>;
-                                               #size-cells = <1>;
-
-                                               at91bootstrap@0 {
-                                                       label = "at91bootstrap";
-                                                       reg = <0x0 0x40000>;
-                                               };
-
-                                               uboot@40000 {
-                                                       label = "u-boot";
-                                                       reg = <0x40000 0x80000>;
-                                               };
-
-                                               ubootenv@c0000 {
-                                                       label = "U-Boot Env";
-                                                       reg = <0xc0000 0x140000>;
-                                               };
-
-                                               kernel@200000 {
-                                                       label = "kernel";
-                                                       reg = <0x200000 0x600000>;
-                                               };
-
-                                               rootfs@800000 {
-                                                       label = "rootfs";
-                                                       reg = <0x800000 0x0f800000>;
-                                               };
-                                       };
-                               };
-                       };
-               };
+&tcb0 {
+       timer@0 {
+               compatible = "atmel,tcb-timer";
+               reg = <0>;
+       };
+
+       timer@1 {
+               compatible = "atmel,tcb-timer";
+               reg = <1>;
        };
 };
+
+&usart0 {
+       status = "okay";
+};
+
+&watchdog {
+       status = "okay";
+};
index 8fde06a..73e88d1 100644 (file)
 / {
        model = "HCE Cosino Mega 2560";
        compatible = "hce,cosino_mega2560", "atmel,at91sam9x5", "atmel,at91sam9";
+};
+
+&adc0 {
+       atmel,adc-ts-wires = <4>;
+       atmel,adc-ts-pressure-threshold = <10000>;
+       status = "okay";
+};
 
-       ahb {
-               apb {
-                       macb0: ethernet@f802c000 {
-                               phy-mode = "rmii";
-                               status = "okay";
-                       };
+&macb0 {
+       phy-mode = "rmii";
+       status = "okay";
+};
 
-                       adc0: adc@f804c000 {
-                               atmel,adc-ts-wires = <4>;
-                               atmel,adc-ts-pressure-threshold = <10000>;
-                               status = "okay";
-                       };
+&mmc1 {
+       pinctrl-0 = <
+               &pinctrl_mmc1_slot0_clk_cmd_dat0
+               &pinctrl_mmc1_slot0_dat1_3>;
+       status = "okay";
 
-                       rtc@fffffeb0 {
-                               status = "okay";
-                       };
+       slot@0 {
+               reg = <0>;
+               bus-width = <4>;
+               non-removable;
+       };
+};
 
-                       usart1: serial@f8020000 {
-                               status = "okay";
-                       };
+&rtc {
+       status = "okay";
+};
 
-                       usart2: serial@f8024000 {
-                               status = "okay";
-                       };
+&usart1 {
+       status = "okay";
+};
 
-                       usb2: gadget@f803c000 {
-                               atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
-                               status = "okay";
-                       };
+&usart2 {
+       status = "okay";
+};
 
-                       mmc1: mmc@f000c000 {
-                               pinctrl-0 = <
-                                       &pinctrl_mmc1_slot0_clk_cmd_dat0
-                                       &pinctrl_mmc1_slot0_dat1_3>;
-                               status = "okay";
-                               slot@0 {
-                                       reg = <0>;
-                                       bus-width = <4>;
-                                       non-removable;
-                               };
-                       };
-               };
+&usb0 {
+       num-ports = <3>;
+       atmel,vbus-gpio = <0 /* &pioD 18 GPIO_ACTIVE_LOW */
+                          &pioD 19 GPIO_ACTIVE_LOW
+                          &pioD 20 GPIO_ACTIVE_LOW
+                         >;
+       status = "okay";
+};
 
-               usb0: ohci@600000 {
-                       status = "okay";
-                       num-ports = <3>;
-                       atmel,vbus-gpio = <0 /* &pioD 18 GPIO_ACTIVE_LOW */
-                                          &pioD 19 GPIO_ACTIVE_LOW
-                                          &pioD 20 GPIO_ACTIVE_LOW
-                                         >;
-               };
+&usb1 {
+       status = "okay";
+};
 
-               usb1: ehci@700000 {
-                       status = "okay";
-               };
-       };
+&usb2 {
+       atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
+       status = "okay";
 };
index 0620dcd..cb22f5f 100644 (file)
        };
 
        ahb {
-               apb {
-                       tcb0: timer@f8008000 {
-                               timer@0 {
-                                       compatible = "atmel,tcb-timer";
-                                       reg = <0>;
-                               };
-
-                               timer@1 {
-                                       compatible = "atmel,tcb-timer";
-                                       reg = <1>;
-                               };
-                       };
-
-                       usart0: serial@f801c000 {
-                               status = "okay";
-                       };
-
-                       macb0: ethernet@f802c000 {
-                               phy-mode = "rmii";
-                               status = "okay";
-                       };
-
-                       pwm0: pwm@f8034000 {
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_pwm0_pwm0_1
-                                            &pinctrl_pwm0_pwm1_1>;
-                               status = "okay";
-                       };
-
-                       dbgu: serial@fffff200 {
-                               status = "okay";
-                       };
-
-                       watchdog@fffffe40 {
-                               status = "okay";
-                       };
-               };
-
-               usb0: ohci@600000 {
-                       num-ports = <1>;
-                       status = "okay";
-               };
-
-               usb1: ehci@700000 {
-                       status = "okay";
-               };
-
-               ebi: ebi@10000000 {
-                       pinctrl-0 = <&pinctrl_ebi_addr_nand
-                                    &pinctrl_ebi_data_0_7>;
-                       pinctrl-names = "default";
-                       status = "okay";
-
-                       nand_controller: nand-controller {
-                               status = "okay";
-                               pinctrl-0 = <&pinctrl_nand_oe_we
-                                            &pinctrl_nand_cs
-                                            &pinctrl_nand_rb>;
-                               pinctrl-names = "default";
-
-                               nand@3 {
-                                       reg = <0x3 0x0 0x800000>;
-                                       rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>;
-                                       cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>;
-                                       nand-bus-width = <8>;
-                                       nand-ecc-mode = "hw";
-                                       nand-ecc-strength = <4>;
-                                       nand-ecc-step-size = <512>;
-                                       nand-on-flash-bbt;
-                                       label = "atmel_nand";
-
-                                       partitions {
-                                               compatible = "fixed-partitions";
-                                               #address-cells = <1>;
-                                               #size-cells = <1>;
-
-                                               bootstrap@0 {
-                                                       label = "bootstrap";
-                                                       reg = <0x0 0x20000>;
-                                               };
-
-                                               ubi@20000 {
-                                                       label = "ubi";
-                                                       reg = <0x20000 0x7fe0000>;
-                                               };
-                                       };
-                               };
-                       };
-               };
-
                nand0: nand@40000000 {
                        nand-bus-width = <8>;
                        nand-ecc-mode = "hw";
                        atmel,pmecc-sector-size = <512>;
                        nand-on-flash-bbt;
                        status = "okay";
-
                };
        };
 
                };
        };
 };
+
+&dbgu {
+       status = "okay";
+};
+
+&ebi {
+       pinctrl-0 = <&pinctrl_ebi_addr_nand
+                    &pinctrl_ebi_data_0_7>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       nand-controller {
+               pinctrl-0 = <&pinctrl_nand_oe_we
+                            &pinctrl_nand_cs
+                            &pinctrl_nand_rb>;
+               pinctrl-names = "default";
+               status = "okay";
+
+               nand@3 {
+                       reg = <0x3 0x0 0x800000>;
+                       rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>;
+                       cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>;
+                       nand-bus-width = <8>;
+                       nand-ecc-mode = "hw";
+                       nand-ecc-strength = <4>;
+                       nand-ecc-step-size = <512>;
+                       nand-on-flash-bbt;
+                       label = "atmel_nand";
+
+                       partitions {
+                               compatible = "fixed-partitions";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               bootstrap@0 {
+                                       label = "bootstrap";
+                                       reg = <0x0 0x20000>;
+                               };
+
+                               ubi@20000 {
+                                       label = "ubi";
+                                       reg = <0x20000 0x7fe0000>;
+                               };
+                       };
+               };
+       };
+};
+
+&macb0 {
+       phy-mode = "rmii";
+       status = "okay";
+};
+
+&pwm0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm0_pwm0_1
+                    &pinctrl_pwm0_pwm1_1>;
+       status = "okay";
+};
+
+&tcb0 {
+       timer@0 {
+               compatible = "atmel,tcb-timer";
+               reg = <0>;
+       };
+
+       timer@1 {
+               compatible = "atmel,tcb-timer";
+               reg = <1>;
+       };
+};
+
+&usart0 {
+       status = "okay";
+};
+
+&usb0 {
+       num-ports = <1>;
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
+
+&watchdog {
+       status = "okay";
+};
index 7debdea..c4ef74f 100644 (file)
@@ -40,7 +40,7 @@
                        atmel,power-control-gpio = <&pioA 12 GPIO_ACTIVE_LOW>;
                        status = "okay";
 
-                       display0: display {
+                       display0: panel {
                                bits-per-pixel = <16>;
                                atmel,lcdcon-backlight;
                                atmel,dmacon = <0x1>;
index 45e0c6e..62d2185 100644 (file)
                        display = <&display0>;
                        status = "okay";
 
-                       display0: display {
+                       display0: panel {
                                bits-per-pixel = <16>;
                                atmel,lcdcon-backlight;
                                atmel,dmacon = <0x1>;
index d77c69a..dde8827 100644 (file)
 / {
        model = "Atmel AT91SAM9G15 SoC";
        compatible = "atmel,at91sam9g15", "atmel,at91sam9x5";
+};
 
-       ahb {
-               apb {
-                       pinctrl@fffff400 {
-                               atmel,mux-mask = <
-                                     /*    A         B          C     */
-                                      0xffffffff 0xffe0399f 0x00000000  /* pioA */
-                                      0x00040000 0x00047e3f 0x00000000  /* pioB */
-                                      0xfdffffff 0x00000000 0xb83fffff  /* pioC */
-                                      0x003fffff 0x003f8000 0x00000000  /* pioD */
-                                     >;
-                       };
+&pinctrl {
+       atmel,mux-mask = <
+             /*    A         B          C     */
+              0xffffffff 0xffe0399f 0x00000000  /* pioA */
+              0x00040000 0x00047e3f 0x00000000  /* pioB */
+              0xfdffffff 0x00000000 0xb83fffff  /* pioC */
+              0x003fffff 0x003f8000 0x00000000  /* pioD */
+             >;
+};
 
-                       pmc: pmc@fffffc00 {
-                               compatible = "atmel,at91sam9g15-pmc", "atmel,at91sam9x5-pmc", "syscon";
-                       };
-               };
-       };
+&pmc {
+       compatible = "atmel,at91sam9g15-pmc", "atmel,at91sam9x5-pmc", "syscon";
 };
index 97100d2..889a509 100644 (file)
        model = "Atmel AT91SAM9G15-EK";
        compatible = "atmel,at91sam9g15ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
 
-       ahb {
-               apb {
-                       hlcdc: hlcdc@f8038000 {
-                               status = "okay";
-                       };
-               };
-       };
-
        backlight: backlight {
                status = "okay";
        };
@@ -38,3 +30,7 @@
                status = "okay";
        };
 };
+
+&hlcdc {
+       status = "okay";
+};
index a02c6c7..61b0bdb 100644 (file)
 / {
        model = "Atmel AT91SAM9G25-EK";
        compatible = "atmel,at91sam9g25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+};
 
-       ahb {
-               apb {
-                       spi0: spi@f0000000 {
-                               status = "disabled";
-                       };
-
-                       mmc1: mmc@f000c000 {
-                               status = "disabled";
-                       };
-
-                       i2c0: i2c@f8010000 {
-                               ov2640: camera@30 {
-                                       compatible = "ovti,ov2640";
-                                       reg = <0x30>;
-                                       pinctrl-names = "default";
-                                       pinctrl-0 = <&pinctrl_pck0_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>;
-                                       resetb-gpios = <&pioA 7 GPIO_ACTIVE_LOW>;
-                                       pwdn-gpios = <&pioA 13 GPIO_ACTIVE_HIGH>;
-                                       clocks = <&pmc PMC_TYPE_SYSTEM 8>;
-                                       clock-names = "xvclk";
-                                       assigned-clocks = <&pmc PMC_TYPE_SYSTEM 8>;
-                                       assigned-clock-rates = <25000000>;
-                                       status = "okay";
+&i2c0 {
+       camera@30 {
+               compatible = "ovti,ov2640";
+               reg = <0x30>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pck0_as_isi_mck &pinctrl_sensor_power &pinctrl_sensor_reset>;
+               resetb-gpios = <&pioA 7 GPIO_ACTIVE_LOW>;
+               pwdn-gpios = <&pioA 13 GPIO_ACTIVE_HIGH>;
+               clocks = <&pmc PMC_TYPE_SYSTEM 8>;
+               clock-names = "xvclk";
+               assigned-clocks = <&pmc PMC_TYPE_SYSTEM 8>;
+               assigned-clock-rates = <25000000>;
+               status = "okay";
 
-                                       port {
-                                               ov2640_0: endpoint {
-                                                       remote-endpoint = <&isi_0>;
-                                                       bus-width = <8>;
-                                               };
-                                       };
-                               };
+               port {
+                       ov2640_0: endpoint {
+                               remote-endpoint = <&isi_0>;
+                               bus-width = <8>;
                        };
+               };
+       };
+};
 
-                       macb0: ethernet@f802c000 {
-                               phy-mode = "rmii";
-                               status = "okay";
-                       };
+&isi {
+       status = "okay";
 
-                       isi: isi@f8048000 {
-                               status = "okay";
-                               port {
-                                       isi_0: endpoint@0 {
-                                               reg = <0>;
-                                               remote-endpoint = <&ov2640_0>;
-                                               bus-width = <8>;
-                                               vsync-active = <1>;
-                                               hsync-active = <1>;
-                                       };
-                               };
-                       };
+       port {
+               isi_0: endpoint@0 {
+                       reg = <0>;
+                       remote-endpoint = <&ov2640_0>;
+                       bus-width = <8>;
+                       vsync-active = <1>;
+                       hsync-active = <1>;
                };
        };
 };
+
+&macb0 {
+       phy-mode = "rmii";
+       status = "okay";
+};
+
+&mmc1 {
+       status = "disabled";
+};
+
+&spi0 {
+       status = "disabled";
+};
index 449ec71..f966b56 100644 (file)
        model = "Atmel AT91SAM9G35-EK";
        compatible = "atmel,at91sam9g35ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
 
-       ahb {
-               apb {
-                       macb0: ethernet@f802c000 {
-                               phy-mode = "rmii";
-                               status = "okay";
-                       };
-
-                       hlcdc: hlcdc@f8038000 {
-                               status = "okay";
-                       };
-               };
-       };
-
        backlight: backlight {
                status = "okay";
        };
                status = "okay";
        };
 };
+
+&hlcdc {
+       status = "okay";
+};
+
+&macb0 {
+       phy-mode = "rmii";
+       status = "okay";
+};
index 06d74ff..84bed6f 100644 (file)
                        display = <&display0>;
                        status = "okay";
 
-                       display0: display {
+                       display0: panel {
                                bits-per-pixel = <32>;
                                atmel,lcdcon-backlight;
                                atmel,dmacon = <0x1>;
index 3a38694..0de75d3 100644 (file)
@@ -36,7 +36,7 @@
                        display = <&display0>;
                        status = "okay";
 
-                       display0: display {
+                       display0: panel {
                                bits-per-pixel = <16>;
                                atmel,lcdcon-backlight;
                                atmel,dmacon = <0x1>;
index 4e1c3df..ad7c6b3 100644 (file)
 / {
        model = "Atmel AT91SAM9X25-EK";
        compatible = "atmel,at91sam9x25ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+};
 
-       ahb {
-               apb {
-                       can1: can@f8004000 {
-                               status = "okay";
-                       };
+&can1 {
+       status = "okay";
+};
 
-                       macb0: ethernet@f802c000 {
-                               phy-mode = "rmii";
-                               status = "okay";
-                       };
+&macb0 {
+       phy-mode = "rmii";
+       status = "okay";
+};
 
-                       macb1: ethernet@f8030000 {
-                               phy-mode = "rmii";
-                               status = "okay";
-                       };
+&macb1 {
+       phy-mode = "rmii";
+       status = "okay";
+};
 
-                       pwm0: pwm@f8034000 {
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_pwm0_pwm0_1>;
-                               status = "okay";
-                       };
-               };
-       };
+&pwm0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm0_pwm0_1>;
+       status = "okay";
 };
index 7646c68..66675c7 100644 (file)
 / {
        model = "Atmel AT91SAM9X35-EK";
        compatible = "atmel,at91sam9x35ek", "atmel,at91sam9x5ek", "atmel,at91sam9x5", "atmel,at91sam9";
+};
 
-       ahb {
-               apb {
-                       macb0: ethernet@f802c000 {
-                               phy-mode = "rmii";
-                               status = "okay";
-                       };
-                       hlcdc: hlcdc@f8038000 {
-                               status = "okay";
-                       };
-               };
-       };
+&backlight {
+       status = "okay";
+};
 
-       backlight: backlight {
-               status = "okay";
-       };
+&bl_reg {
+       status = "okay";
+};
 
-       bl_reg: backlight_regulator {
-               status = "okay";
-       };
+&hlcdc {
+       status = "okay";
+};
 
-       panel: panel {
-               status = "okay";
-       };
+&macb0 {
+       phy-mode = "rmii";
+       status = "okay";
+};
+
+&panel {
+       status = "okay";
+};
 
-       panel_reg: panel_regulator {
-               status = "okay";
-       };
+&panel_reg {
+       status = "okay";
 };
index ef47c00..7c2eb93 100644 (file)
                                status = "disabled";
                        };
 
-                       rtc@fffffeb0 {
+                       rtc: rtc@fffffeb0 {
                                compatible = "atmel,at91sam9x5-rtc";
                                reg = <0xfffffeb0 0x40>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
index 584f840..f81c9d1 100644 (file)
                                        #pwm-cells = <3>;
                                };
                        };
+               };
+       };
+};
 
-                       pinctrl@fffff400 {
-                               lcd {
-                                       pinctrl_lcd_base: lcd-base-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 27 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDVSYNC */
-                                                        AT91_PIOC 28 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDHSYNC */
-                                                        AT91_PIOC 24 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDDISP */
-                                                        AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDDEN */
-                                                        AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPCK */
-                                       };
+&pinctrl {
+       lcd {
+               pinctrl_lcd_base: lcd-base-0 {
+                       atmel,pins =
+                               <AT91_PIOC 27 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDVSYNC */
+                                AT91_PIOC 28 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDHSYNC */
+                                AT91_PIOC 24 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDDISP */
+                                AT91_PIOC 29 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDDEN */
+                                AT91_PIOC 30 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDPCK */
+               };
 
-                                       pinctrl_lcd_pwm: lcd-pwm-0 {
-                                               atmel,pins = <AT91_PIOC 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;    /* LCDPWM */
-                                       };
+               pinctrl_lcd_pwm: lcd-pwm-0 {
+                       atmel,pins = <AT91_PIOC 26 AT91_PERIPH_A AT91_PINCTRL_NONE>;    /* LCDPWM */
+               };
 
-                                       pinctrl_lcd_rgb444: lcd-rgb-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD0 pin */
-                                                        AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD1 pin */
-                                                        AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD2 pin */
-                                                        AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD3 pin */
-                                                        AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD4 pin */
-                                                        AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD5 pin */
-                                                        AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD6 pin */
-                                                        AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD7 pin */
-                                                        AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD8 pin */
-                                                        AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD9 pin */
-                                                        AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD10 pin */
-                                                        AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD11 pin */
-                                       };
+               pinctrl_lcd_rgb444: lcd-rgb-0 {
+                       atmel,pins =
+                               <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD0 pin */
+                                AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD1 pin */
+                                AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD2 pin */
+                                AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD3 pin */
+                                AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD4 pin */
+                                AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD5 pin */
+                                AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD6 pin */
+                                AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD7 pin */
+                                AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD8 pin */
+                                AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD9 pin */
+                                AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD10 pin */
+                                AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD11 pin */
+               };
 
-                                       pinctrl_lcd_rgb565: lcd-rgb-1 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD0 pin */
-                                                        AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD1 pin */
-                                                        AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD2 pin */
-                                                        AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD3 pin */
-                                                        AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD4 pin */
-                                                        AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD5 pin */
-                                                        AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD6 pin */
-                                                        AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD7 pin */
-                                                        AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD8 pin */
-                                                        AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD9 pin */
-                                                        AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD10 pin */
-                                                        AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD11 pin */
-                                                        AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD12 pin */
-                                                        AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD13 pin */
-                                                        AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD14 pin */
-                                                        AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD15 pin */
-                                       };
+               pinctrl_lcd_rgb565: lcd-rgb-1 {
+                       atmel,pins =
+                               <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD0 pin */
+                                AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD1 pin */
+                                AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD2 pin */
+                                AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD3 pin */
+                                AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD4 pin */
+                                AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD5 pin */
+                                AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD6 pin */
+                                AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD7 pin */
+                                AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD8 pin */
+                                AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD9 pin */
+                                AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD10 pin */
+                                AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD11 pin */
+                                AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD12 pin */
+                                AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD13 pin */
+                                AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD14 pin */
+                                AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD15 pin */
+               };
 
-                                       pinctrl_lcd_rgb666: lcd-rgb-2 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD0 pin */
-                                                        AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD1 pin */
-                                                        AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD2 pin */
-                                                        AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD3 pin */
-                                                        AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD4 pin */
-                                                        AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD5 pin */
-                                                        AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD6 pin */
-                                                        AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD7 pin */
-                                                        AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD8 pin */
-                                                        AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD9 pin */
-                                                        AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD10 pin */
-                                                        AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD11 pin */
-                                                        AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD12 pin */
-                                                        AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD13 pin */
-                                                        AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD14 pin */
-                                                        AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD15 pin */
-                                                        AT91_PIOC 16 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD16 pin */
-                                                        AT91_PIOC 17 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD17 pin */
-                                       };
+               pinctrl_lcd_rgb666: lcd-rgb-2 {
+                       atmel,pins =
+                               <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD0 pin */
+                                AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD1 pin */
+                                AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD2 pin */
+                                AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD3 pin */
+                                AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD4 pin */
+                                AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD5 pin */
+                                AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD6 pin */
+                                AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD7 pin */
+                                AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD8 pin */
+                                AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD9 pin */
+                                AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD10 pin */
+                                AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD11 pin */
+                                AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD12 pin */
+                                AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD13 pin */
+                                AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD14 pin */
+                                AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD15 pin */
+                                AT91_PIOC 16 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD16 pin */
+                                AT91_PIOC 17 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD17 pin */
+               };
 
-                                       pinctrl_lcd_rgb888: lcd-rgb-3 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD0 pin */
-                                                        AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD1 pin */
-                                                        AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD2 pin */
-                                                        AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD3 pin */
-                                                        AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD4 pin */
-                                                        AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD5 pin */
-                                                        AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD6 pin */
-                                                        AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD7 pin */
-                                                        AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD8 pin */
-                                                        AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD9 pin */
-                                                        AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD10 pin */
-                                                        AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD11 pin */
-                                                        AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD12 pin */
-                                                        AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD13 pin */
-                                                        AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD14 pin */
-                                                        AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD15 pin */
-                                                        AT91_PIOC 16 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD16 pin */
-                                                        AT91_PIOC 17 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD17 pin */
-                                                        AT91_PIOC 18 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD18 pin */
-                                                        AT91_PIOC 19 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD19 pin */
-                                                        AT91_PIOC 20 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD20 pin */
-                                                        AT91_PIOC 21 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD21 pin */
-                                                        AT91_PIOC 22 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD22 pin */
-                                                        AT91_PIOC 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD23 pin */
-                                       };
-                               };
-                       };
+               pinctrl_lcd_rgb888: lcd-rgb-3 {
+                       atmel,pins =
+                               <AT91_PIOC 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD0 pin */
+                                AT91_PIOC 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD1 pin */
+                                AT91_PIOC 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD2 pin */
+                                AT91_PIOC 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD3 pin */
+                                AT91_PIOC 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD4 pin */
+                                AT91_PIOC 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD5 pin */
+                                AT91_PIOC 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD6 pin */
+                                AT91_PIOC 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD7 pin */
+                                AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD8 pin */
+                                AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* LCDD9 pin */
+                                AT91_PIOC 10 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD10 pin */
+                                AT91_PIOC 11 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD11 pin */
+                                AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD12 pin */
+                                AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD13 pin */
+                                AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD14 pin */
+                                AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD15 pin */
+                                AT91_PIOC 16 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD16 pin */
+                                AT91_PIOC 17 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD17 pin */
+                                AT91_PIOC 18 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD18 pin */
+                                AT91_PIOC 19 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD19 pin */
+                                AT91_PIOC 20 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD20 pin */
+                                AT91_PIOC 21 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD21 pin */
+                                AT91_PIOC 22 AT91_PERIPH_A AT91_PINCTRL_NONE   /* LCDD22 pin */
+                                AT91_PIOC 23 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* LCDD23 pin */
                };
        };
 };
index b04ebf1..7f00c1f 100644 (file)
@@ -9,51 +9,6 @@
  */
 
 / {
-       ahb {
-               apb {
-                       i2c0: i2c@f8010000 {
-                               qt1070: keyboard@1b {
-                                       compatible = "qt1070";
-                                       reg = <0x1b>;
-                                       interrupt-parent = <&pioA>;
-                                       interrupts = <7 0x0>;
-                                       pinctrl-names = "default";
-                                       pinctrl-0 = <&pinctrl_qt1070_irq>;
-                                       wakeup-source;
-                               };
-                       };
-
-                       hlcdc: hlcdc@f8038000 {
-                               hlcdc-display-controller {
-                                       pinctrl-names = "default";
-                                       pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>;
-
-                                       port@0 {
-                                               hlcdc_panel_output: endpoint@0 {
-                                                       reg = <0>;
-                                                       remote-endpoint = <&panel_input>;
-                                               };
-                                       };
-                               };
-                       };
-
-                       adc0: adc@f804c000 {
-                               atmel,adc-ts-wires = <4>;
-                               atmel,adc-ts-pressure-threshold = <10000>;
-                               status = "okay";
-                       };
-
-                       pinctrl@fffff400 {
-                               board {
-                                       pinctrl_qt1070_irq: qt1070_irq {
-                                               atmel,pins =
-                                                       <AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
-                                       };
-                               };
-                       };
-               };
-       };
-
        backlight: backlight {
                compatible = "pwm-backlight";
                pwms = <&hlcdc_pwm 0 50000 0>;
                status = "disabled";
        };
 };
+
+&adc0 {
+       atmel,adc-ts-wires = <4>;
+       atmel,adc-ts-pressure-threshold = <10000>;
+       status = "okay";
+};
+
+&i2c0 {
+       keyboard@1b {
+               compatible = "qt1070";
+               reg = <0x1b>;
+               interrupt-parent = <&pioA>;
+               interrupts = <7 0x0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_qt1070_irq>;
+               wakeup-source;
+       };
+};
+
+&hlcdc {
+       hlcdc-display-controller {
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_lcd_base &pinctrl_lcd_rgb888>;
+
+               port@0 {
+                       hlcdc_panel_output: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&panel_input>;
+                       };
+               };
+       };
+};
+
+&pinctrl {
+       board {
+               pinctrl_qt1070_irq: qt1070_irq {
+                       atmel,pins =
+                               <AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;
+               };
+       };
+};
index 2ad0a43..c934928 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
-       ahb {
-               apb {
-                       mmc0: mmc@f0008000 {
-                               pinctrl-0 = <
-                                       &pinctrl_board_mmc0
-                                       &pinctrl_mmc0_slot0_clk_cmd_dat0
-                                       &pinctrl_mmc0_slot0_dat1_3>;
-                               status = "okay";
-                               slot@0 {
-                                       reg = <0>;
-                                       bus-width = <4>;
-                                       cd-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
-                               };
-                       };
-
-                       mmc1: mmc@f000c000 {
-                               pinctrl-0 = <
-                                       &pinctrl_board_mmc1
-                                       &pinctrl_mmc1_slot0_clk_cmd_dat0
-                                       &pinctrl_mmc1_slot0_dat1_3>;
-                               status = "okay";
-                               slot@0 {
-                                       reg = <0>;
-                                       bus-width = <4>;
-                                       cd-gpios = <&pioD 14 GPIO_ACTIVE_HIGH>;
-                               };
-                       };
-
-                       dbgu: serial@fffff200 {
-                               status = "okay";
-                       };
-
-                       usart0: serial@f801c000 {
-                               atmel,use-dma-rx;
-                               atmel,use-dma-tx;
-                               status = "okay";
-                       };
-
-                       usb2: gadget@f803c000 {
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&pinctrl_board_usb2>;
-                               atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
-                               status = "okay";
-                       };
-
-                       i2c0: i2c@f8010000 {
-                               status = "okay";
-
-                               wm8731: wm8731@1a {
-                                       compatible = "wm8731";
-                                       reg = <0x1a>;
-                               };
-                       };
-
-                       adc0: adc@f804c000 {
-                               atmel,adc-ts-wires = <4>;
-                               atmel,adc-ts-pressure-threshold = <10000>;
-                               status = "okay";
-                       };
-
-                       pinctrl@fffff400 {
-                               camera_sensor {
-                                       pinctrl_pck0_as_isi_mck: pck0_as_isi_mck-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOC 15 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* ISI_MCK */
-                                       };
-
-                                       pinctrl_sensor_power: sensor_power-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOA 13 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
-                                       };
-
-                                       pinctrl_sensor_reset: sensor_reset-0 {
-                                               atmel,pins =
-                                                       <AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
-                                       };
-                               };
-
-                               mmc0 {
-                                       pinctrl_board_mmc0: mmc0-board {
-                                               atmel,pins =
-                                                       <AT91_PIOD 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;  /* PD15 gpio CD pin pull up and deglitch */
-                                       };
-                               };
-
-                               mmc1 {
-                                       pinctrl_board_mmc1: mmc1-board {
-                                               atmel,pins =
-                                                       <AT91_PIOD 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;  /* PD14 gpio CD pin pull up and deglitch */
-                                       };
-                               };
-
-                               usb2 {
-                                       pinctrl_board_usb2: usb2-board {
-                                               atmel,pins =
-                                                       <AT91_PIOB 16 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;          /* PB16 gpio vbus sense, deglitch */
-                                       };
-                               };
-                       };
-
-                       spi0: spi@f0000000 {
-                               status = "disabled"; /* conflicts with mmc1 */
-                               cs-gpios = <&pioA 14 0>, <0>, <0>, <0>;
-                               m25p80@0 {
-                                       compatible = "atmel,at25df321a";
-                                       spi-max-frequency = <50000000>;
-                                       reg = <0>;
-                               };
-                       };
-
-                       watchdog@fffffe40 {
-                               status = "okay";
-                       };
-
-                       ssc0: ssc@f0010000 {
-                               status = "okay";
-                       };
-               };
-
-               usb0: ohci@600000 {
-                       status = "okay";
-                       num-ports = <3>;
-                       atmel,vbus-gpio = <0 /* &pioD 18 GPIO_ACTIVE_LOW *//* Activate to have access to port A */
-                                          &pioD 19 GPIO_ACTIVE_LOW
-                                          &pioD 20 GPIO_ACTIVE_LOW
-                                         >;
-               };
-
-               usb1: ehci@700000 {
-                       status = "okay";
-               };
-       };
-
        sound {
                compatible = "atmel,sam9x5-wm8731-audio";
 
                atmel,audio-codec = <&wm8731>;
        };
 };
+
+&adc0 {
+       atmel,adc-ts-wires = <4>;
+       atmel,adc-ts-pressure-threshold = <10000>;
+       status = "okay";
+};
+
+&dbgu {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+
+       wm8731: wm8731@1a {
+               compatible = "wm8731";
+               reg = <0x1a>;
+       };
+};
+
+&mmc0 {
+       pinctrl-0 = <
+               &pinctrl_board_mmc0
+               &pinctrl_mmc0_slot0_clk_cmd_dat0
+               &pinctrl_mmc0_slot0_dat1_3>;
+       status = "okay";
+
+       slot@0 {
+               reg = <0>;
+               bus-width = <4>;
+               cd-gpios = <&pioD 15 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+&mmc1 {
+       pinctrl-0 = <
+               &pinctrl_board_mmc1
+               &pinctrl_mmc1_slot0_clk_cmd_dat0
+               &pinctrl_mmc1_slot0_dat1_3>;
+       status = "okay";
+
+       slot@0 {
+               reg = <0>;
+               bus-width = <4>;
+               cd-gpios = <&pioD 14 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+&pinctrl {
+       camera_sensor {
+               pinctrl_pck0_as_isi_mck: pck0_as_isi_mck-0 {
+                       atmel,pins =
+                               <AT91_PIOC 15 AT91_PERIPH_C AT91_PINCTRL_NONE>; /* ISI_MCK */
+               };
+
+               pinctrl_sensor_power: sensor_power-0 {
+                       atmel,pins =
+                               <AT91_PIOA 13 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+               };
+
+               pinctrl_sensor_reset: sensor_reset-0 {
+                       atmel,pins =
+                               <AT91_PIOA 7 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+               };
+       };
+
+       mmc0 {
+               pinctrl_board_mmc0: mmc0-board {
+                       atmel,pins =
+                               <AT91_PIOD 15 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;  /* PD15 gpio CD pin pull up and deglitch */
+               };
+       };
+
+       mmc1 {
+               pinctrl_board_mmc1: mmc1-board {
+                       atmel,pins =
+                               <AT91_PIOD 14 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP_DEGLITCH>;  /* PD14 gpio CD pin pull up and deglitch */
+               };
+       };
+
+       usb2 {
+               pinctrl_board_usb2: usb2-board {
+                       atmel,pins =
+                               <AT91_PIOB 16 AT91_PERIPH_GPIO AT91_PINCTRL_DEGLITCH>;          /* PB16 gpio vbus sense, deglitch */
+               };
+       };
+};
+
+&spi0 {
+       cs-gpios = <&pioA 14 0>, <0>, <0>, <0>;
+       status = "disabled"; /* conflicts with mmc1 */
+
+       m25p80@0 {
+               compatible = "atmel,at25df321a";
+               spi-max-frequency = <50000000>;
+               reg = <0>;
+       };
+};
+
+&ssc0 {
+       status = "okay";
+};
+
+&usart0 {
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       status = "okay";
+};
+
+&usb0 {
+       num-ports = <3>;
+       atmel,vbus-gpio = <0 /* &pioD 18 GPIO_ACTIVE_LOW *//* Activate to have access to port A */
+                          &pioD 19 GPIO_ACTIVE_LOW
+                          &pioD 20 GPIO_ACTIVE_LOW
+                         >;
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
+
+&usb2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_board_usb2>;
+       atmel,vbus-gpio = <&pioB 16 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&watchdog {
+       status = "okay";
+};
index db8a601..6c8ce39 100644 (file)
@@ -8,6 +8,11 @@
        compatible = "raspberrypi,model-a-plus", "brcm,bcm2835";
        model = "Raspberry Pi Model A+";
 
+       memory@0 {
+               device_type = "memory";
+               reg = <0 0x10000000>;
+       };
+
        leds {
                act {
                        gpios = <&gpio 47 GPIO_ACTIVE_HIGH>;
 
 &hdmi {
        hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
 };
 
 &pwm {
        status = "okay";
 };
 
+&sdhost {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhost_gpio48>;
+       bus-width = <4>;
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_gpio14>;
index 067d1f0..17fdd48 100644 (file)
@@ -8,6 +8,11 @@
        compatible = "raspberrypi,model-a", "brcm,bcm2835";
        model = "Raspberry Pi Model A";
 
+       memory@0 {
+               device_type = "memory";
+               reg = <0 0x10000000>;
+       };
+
        leds {
                act {
                        gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
@@ -94,6 +99,8 @@
 
 &hdmi {
        hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
 };
 
 &pwm {
        status = "okay";
 };
 
+&sdhost {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhost_gpio48>;
+       bus-width = <4>;
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_gpio14>;
index 1e40d67..b0355c2 100644 (file)
@@ -9,6 +9,11 @@
        compatible = "raspberrypi,model-b-plus", "brcm,bcm2835";
        model = "Raspberry Pi Model B+";
 
+       memory@0 {
+               device_type = "memory";
+               reg = <0 0x20000000>;
+       };
+
        leds {
                act {
                        gpios = <&gpio 47 GPIO_ACTIVE_HIGH>;
 
 &hdmi {
        hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
 };
 
 &pwm {
        status = "okay";
 };
 
+&sdhost {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhost_gpio48>;
+       bus-width = <4>;
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_gpio14>;
index 28e7513..33b3b5c 100644 (file)
@@ -9,6 +9,11 @@
        compatible = "raspberrypi,model-b-rev2", "brcm,bcm2835";
        model = "Raspberry Pi Model B rev2";
 
+       memory@0 {
+               device_type = "memory";
+               reg = <0 0x10000000>;
+       };
+
        leds {
                act {
                        gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
@@ -94,6 +99,8 @@
 
 &hdmi {
        hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
 };
 
 &pwm {
        status = "okay";
 };
 
+&sdhost {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhost_gpio48>;
+       bus-width = <4>;
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_gpio14>;
index 31ff602..2b69957 100644 (file)
@@ -9,6 +9,11 @@
        compatible = "raspberrypi,model-b", "brcm,bcm2835";
        model = "Raspberry Pi Model B";
 
+       memory@0 {
+               device_type = "memory";
+               reg = <0 0x10000000>;
+       };
+
        leds {
                act {
                        gpios = <&gpio 16 GPIO_ACTIVE_LOW>;
@@ -89,6 +94,8 @@
 
 &hdmi {
        hpd-gpios = <&gpio 46 GPIO_ACTIVE_HIGH>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
 };
 
 &pwm {
        status = "okay";
 };
 
+&sdhost {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhost_gpio48>;
+       bus-width = <4>;
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_gpio14>;
index 4764a25..a75c882 100644 (file)
 
 &hdmi {
        hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
+};
+
+&sdhost {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhost_gpio48>;
+       bus-width = <4>;
+       status = "okay";
 };
 
 &uart0 {
index ef22c2d..58059c2 100644 (file)
                };
        };
 
+       memory@0 {
+               device_type = "memory";
+               reg = <0 0x20000000>;
+       };
+
        reg_3v3: fixed-regulator {
                compatible = "regulator-fixed";
                regulator-name = "3V3";
index ba0167d..09a088f 100644 (file)
        compatible = "raspberrypi,model-zero-w", "brcm,bcm2835";
        model = "Raspberry Pi Zero W";
 
+       memory@0 {
+               device_type = "memory";
+               reg = <0 0x20000000>;
+       };
+
        chosen {
                /* 8250 auxiliary UART instead of pl011 */
                stdout-path = "serial1:115200n8";
 
 &hdmi {
        hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
 };
 
 &sdhci {
        };
 };
 
+&sdhost {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhost_gpio48>;
+       bus-width = <4>;
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_gpio32 &uart0_ctsrts_gpio30>;
index 3b35a8a..6dd93c6 100644 (file)
        compatible = "raspberrypi,model-zero", "brcm,bcm2835";
        model = "Raspberry Pi Zero";
 
+       memory@0 {
+               device_type = "memory";
+               reg = <0 0x20000000>;
+       };
+
        leds {
                act {
                        gpios = <&gpio 47 GPIO_ACTIVE_HIGH>;
 
 &hdmi {
        hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
+};
+
+&sdhost {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhost_gpio48>;
+       bus-width = <4>;
+       status = "okay";
 };
 
 &uart0 {
index 715d50c..6c6a7f6 100644 (file)
@@ -1,11 +1,6 @@
 #include <dt-bindings/power/raspberrypi-power.h>
 
 / {
-       memory@0 {
-               device_type = "memory";
-               reg = <0 0x10000000>;
-       };
-
        leds {
                compatible = "gpio-leds";
 
        status = "okay";
 };
 
-&sdhci {
-       pinctrl-names = "default";
-       pinctrl-0 = <&emmc_gpio48>;
-       bus-width = <4>;
-};
-
-&sdhost {
-       pinctrl-names = "default";
-       pinctrl-0 = <&sdhost_gpio48>;
-       status = "okay";
-       bus-width = <4>;
-};
-
 &usb {
        power-domains = <&power RPI_POWER_DOMAIN_USB>;
 };
 
-&hdmi {
-       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
-       status = "okay";
-};
-
 &vec {
        power-domains = <&power RPI_POWER_DOMAIN_VEC>;
        status = "okay";
index 7b4e651..0455a68 100644 (file)
@@ -10,6 +10,7 @@
        model = "Raspberry Pi 2 Model B";
 
        memory@0 {
+               device_type = "memory";
                reg = <0 0x40000000>;
        };
 
 
 &hdmi {
        hpd-gpios = <&gpio 46 GPIO_ACTIVE_LOW>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
 };
 
 &pwm {
        status = "okay";
 };
 
+&sdhost {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhost_gpio48>;
+       bus-width = <4>;
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_gpio14>;
index 7f4437a..66ab35e 100644 (file)
@@ -14,6 +14,7 @@
        };
 
        memory@0 {
+               device_type = "memory";
                reg = <0 0x20000000>;
        };
 
 
 &hdmi {
        hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
 };
 
 &pwm {
index c6fa34c..74ed6d0 100644 (file)
@@ -15,6 +15,7 @@
        };
 
        memory@0 {
+               device_type = "memory";
                reg = <0 0x40000000>;
        };
 
 
 &hdmi {
        hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
 };
 
 &pwm {
index ce71f57..054ecaa 100644 (file)
@@ -15,6 +15,7 @@
        };
 
        memory@0 {
+               device_type = "memory";
                reg = <0 0x40000000>;
        };
 
 
 &hdmi {
        hpd-gpios = <&expgpio 4 GPIO_ACTIVE_LOW>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
 };
 
 /* uart0 communicates with the BT module */
index 6c8233a..588d941 100644 (file)
 
 &hdmi {
        hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>;
+       power-domains = <&power RPI_POWER_DOMAIN_HDMI>;
+       status = "okay";
+};
+
+&sdhost {
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdhost_gpio48>;
+       bus-width = <4>;
+       status = "okay";
 };
 
 &uart0 {
index 81399b2..7c3cb7e 100644 (file)
@@ -5,6 +5,7 @@
 
 / {
        memory@0 {
+               device_type = "memory";
                reg = <0 0x40000000>;
        };
 
index 4b21ddb..2d191fc 100644 (file)
 
                uart0: serial@7e201000 {
                        compatible = "brcm,bcm2835-pl011", "arm,pl011", "arm,primecell";
-                       reg = <0x7e201000 0x1000>;
+                       reg = <0x7e201000 0x200>;
                        interrupts = <2 25>;
                        clocks = <&clocks BCM2835_CLOCK_UART>,
                                 <&clocks BCM2835_CLOCK_VPU>;
 
                spi: spi@7e204000 {
                        compatible = "brcm,bcm2835-spi";
-                       reg = <0x7e204000 0x1000>;
+                       reg = <0x7e204000 0x200>;
                        interrupts = <2 22>;
                        clocks = <&clocks BCM2835_CLOCK_VPU>;
                        dmas = <&dma 6>, <&dma 7>;
 
                i2c0: i2c@7e205000 {
                        compatible = "brcm,bcm2835-i2c";
-                       reg = <0x7e205000 0x1000>;
+                       reg = <0x7e205000 0x200>;
                        interrupts = <2 21>;
                        clocks = <&clocks BCM2835_CLOCK_VPU>;
                        #address-cells = <1>;
index 5b2b1ed..f2e7609 100644 (file)
        flash: m25p80@0 {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "m25p64";
+               compatible = "jedec,spi-nor";
                spi-max-frequency = <30000000>;
                m25p,fast-read;
                reg = <0>;
index 714e971..de7f85e 100644 (file)
        phy-supply = <&ldousb_reg>;
 };
 
-&gpio7 {
+&gpio7_target {
        ti,no-reset-on-init;
        ti,no-idle-on-init;
 };
index 23faede..21e5914 100644 (file)
                        };
                };
 
-               target-module@51000 {                   /* 0x48051000, ap 45 2e.0 */
+               gpio7_target: target-module@51000 {             /* 0x48051000, ap 45 2e.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
                        ti,hwmods = "gpio7";
                        reg = <0x51000 0x4>,
 
                target-module@80000 {                   /* 0x48480000, ap 31 16.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       reg = <0x80000 0x4>;
+                       reg = <0x80020 0x4>;
                        reg-names = "rev";
                        clocks = <&l4per2_clkctrl DRA7_L4PER2_DCAN2_CLKCTRL 0>;
                        clock-names = "fck";
 
                target-module@c000 {                    /* 0x4ae3c000, ap 30 04.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       reg = <0xc000 0x4>;
+                       reg = <0xc020 0x4>;
                        reg-names = "rev";
                        clocks = <&wkupaon_clkctrl DRA7_WKUPAON_DCAN1_CLKCTRL 0>;
                        clock-names = "fck";
index 28ebb4e..214b9e6 100644 (file)
@@ -32,7 +32,7 @@
  *
  * Datamanual Revisions:
  *
- * AM572x Silicon Revision 2.0: SPRS953B, Revised November 2016
+ * AM572x Silicon Revision 2.0: SPRS953F, Revised May 2019
  * AM572x Silicon Revision 1.1: SPRS915R, Revised November 2016
  *
  */
 
        mmc3_pins_default: mmc3_pins_default {
                pinctrl-single,pins = <
-                       DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_clk.mmc3_clk */
-                       DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */
-                       DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */
-                       DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */
-                       DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */
-                       DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */
+                       DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_clk.mmc3_clk */
+                       DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */
+                       DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */
+                       DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */
+                       DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */
+                       DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */
                >;
        };
 
        mmc3_pins_hs: mmc3_pins_hs {
                pinctrl-single,pins = <
-                       DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_clk.mmc3_clk */
-                       DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */
-                       DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */
-                       DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */
-                       DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */
-                       DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */
+                       DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_clk.mmc3_clk */
+                       DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */
+                       DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */
+                       DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */
+                       DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */
+                       DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */
                >;
        };
 
        mmc3_pins_sdr12: mmc3_pins_sdr12 {
                pinctrl-single,pins = <
-                       DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_clk.mmc3_clk */
-                       DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */
-                       DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */
-                       DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */
-                       DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */
-                       DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */
+                       DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_clk.mmc3_clk */
+                       DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */
+                       DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */
+                       DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */
+                       DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */
+                       DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */
                >;
        };
 
        mmc3_pins_sdr25: mmc3_pins_sdr25 {
                pinctrl-single,pins = <
-                       DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_clk.mmc3_clk */
-                       DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */
-                       DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */
-                       DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */
-                       DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */
-                       DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */
+                       DRA7XX_CORE_IOPAD(0x377c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_clk.mmc3_clk */
+                       DRA7XX_CORE_IOPAD(0x3780, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_cmd.mmc3_cmd */
+                       DRA7XX_CORE_IOPAD(0x3784, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat0.mmc3_dat0 */
+                       DRA7XX_CORE_IOPAD(0x3788, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat1.mmc3_dat1 */
+                       DRA7XX_CORE_IOPAD(0x378c, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat2.mmc3_dat2 */
+                       DRA7XX_CORE_IOPAD(0x3790, (PIN_INPUT_PULLUP | MODE_SELECT | MUX_MODE0)) /* mmc3_dat3.mmc3_dat3 */
                >;
        };
 
index a0c270f..da07647 100644 (file)
 
        display: display {
                model = "320x240x4";
-               native-mode = <&timing0>;
                bits-per-pixel = <4>;
                ac-prescale = <17>;
 
                display-timings {
+                       native-mode = <&timing0>;
                        timing0: 320x240 {
                                hactive = <320>;
                                hback-porch = <0>;
index 5659c4a..7848184 100644 (file)
                };
 
                adc: adc@126c0000 {
-                       compatible = "samsung,exynos3250-adc",
-                                    "samsung,exynos-adc-v2";
+                       compatible = "samsung,exynos3250-adc";
                        reg = <0x126C0000 0x100>;
                        interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "adc", "sclk";
index 462a540..dfceb15 100644 (file)
                        buck1_reg: BUCK1 {
                                regulator-name = "vdd_mif";
                                regulator-min-microvolt = <850000>;
-                               regulator-max-microvolt = <1100000>;
+                               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-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-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-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-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-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-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-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>;
+                               regulator-max-microvolt = <3000000>;
                                op_mode = <1>; /* Normal Mode */
                        };
                };
index dc6fa6f..6fcb78a 100644 (file)
 
                        buck4_reg: BUCK4 {
                                regulator-name = "vdd_g3d";
-                               regulator-min-microvolt = <1000000>;
-                               regulator-max-microvolt = <1000000>;
+                               regulator-min-microvolt = <850000>;
+                               regulator-max-microvolt = <1300000>;
                                regulator-always-on;
                                regulator-boot-on;
                                op_mode = <1>;
        status = "okay";
 };
 
+&mali {
+       mali-supply = <&buck4_reg>;
+       status = "okay";
+};
+
 &mixer {
        status = "okay";
 };
index fd9226d..c952a61 100644 (file)
        status = "okay";
 };
 
+&mali {
+       mali-supply = <&buck4_reg>;
+       status = "okay";
+};
+
 &mixer {
        status = "okay";
 };
index d5e0392..81729cf 100644 (file)
                        iommus = <&sysmmu_rotator>;
                };
 
+               mali: gpu@11800000 {
+                       compatible = "samsung,exynos5250-mali", "arm,mali-t604";
+                       reg = <0x11800000 0x5000>;
+                       interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "job", "mmu", "gpu";
+                       clocks = <&clock CLK_G3D>;
+                       clock-names = "core";
+                       operating-points-v2 = <&gpu_opp_table>;
+                       power-domains = <&pd_g3d>;
+                       status = "disabled";
+
+                       gpu_opp_table: gpu-opp-table {
+                               compatible = "operating-points-v2";
+
+                               opp-100000000 {
+                                       opp-hz = /bits/ 64 <100000000>;
+                                       opp-microvolt = <925000>;
+                               };
+                               opp-160000000 {
+                                       opp-hz = /bits/ 64 <160000000>;
+                                       opp-microvolt = <925000>;
+                               };
+                               opp-266000000 {
+                                       opp-hz = /bits/ 64 <266000000>;
+                                       opp-microvolt = <1025000>;
+                               };
+                               opp-350000000 {
+                                       opp-hz = /bits/ 64 <350000000>;
+                                       opp-microvolt = <1075000>;
+                               };
+                               opp-400000000 {
+                                       opp-hz = /bits/ 64 <400000000>;
+                                       opp-microvolt = <1125000>;
+                               };
+                               opp-450000000 {
+                                       opp-hz = /bits/ 64 <450000000>;
+                                       opp-microvolt = <1150000>;
+                               };
+                               opp-533000000 {
+                                       opp-hz = /bits/ 64 <533000000>;
+                                       opp-microvolt = <1250000>;
+                               };
+                       };
+               };
+
                tmu: tmu@10060000 {
                        compatible = "samsung,exynos5250-tmu";
                        reg = <0x10060000 0x100>;
                        clock-names = "sata", "sclk_sata";
                        phys = <&sata_phy>;
                        phy-names = "sata-phy";
+                       ports-implemented = <0x1>;
                        status = "disabled";
                };
 
index f78db68..9eb48ca 100644 (file)
                                regulator-name = "vdd_ldo10";
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
                                regulator-state-mem {
                                        regulator-off-in-suspend;
                                };
index 55d4dbf..7d51e0f 100644 (file)
                        label = "MFC";
                };
 
-               msc_pd: power-domain@10044120 {
+               g3d_pd: power-domain@10044080 {
                        compatible = "samsung,exynos4210-pd";
-                       reg = <0x10044120 0x20>;
+                       reg = <0x10044080 0x20>;
                        #power-domain-cells = <0>;
-                       label = "MSC";
+                       label = "G3D";
                };
 
                disp_pd: power-domain@100440c0 {
                        label = "MAU";
                };
 
+               msc_pd: power-domain@10044120 {
+                       compatible = "samsung,exynos4210-pd";
+                       reg = <0x10044120 0x20>;
+                       #power-domain-cells = <0>;
+                       label = "MSC";
+               };
+
                pinctrl_0: pinctrl@13400000 {
                        compatible = "samsung,exynos5420-pinctrl";
                        reg = <0x13400000 0x1000>;
index e0f470f..4398f2d 100644 (file)
                                regulator-name = "vdd_ldo10";
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
                                regulator-state-mem {
                                        regulator-off-in-suspend;
                                };
index 57d3b31..de639ee 100644 (file)
 &mfc {
        compatible = "samsung,mfc-v8";
 };
+
+&soc {
+       cam_pd: power-domain@10045100 {
+               compatible = "samsung,exynos4210-pd";
+               reg = <0x10045100 0x20>;
+               #power-domain-cells = <0>;
+               label = "CAM";
+       };
+};
index f4535d6..521714f 100644 (file)
@@ -20,7 +20,7 @@
        };
 
        chosen {
-               bootargs = "console=ttyS0,19200n8";
+               bootargs = "console=ttyS0,19200n8 root=/dev/mtdblock3 rw rootfstype=squashfs,jffs2 rootwait";
                stdout-path = &uart0;
        };
 
                        /* 16MB of flash */
                        reg = <0x30000000 0x01000000>;
 
-                       partition@0 {
-                               label = "RedBoot";
-                               reg = <0x00000000 0x00020000>;
-                               read-only;
-                       };
-                       partition@20000 {
-                               label = "Kernel";
-                               reg = <0x00020000 0x00300000>;
-                       };
-                       partition@320000 {
-                               label = "Ramdisk";
-                               reg = <0x00320000 0x00600000>;
-                       };
-                       partition@920000 {
-                               label = "Application";
-                               reg = <0x00920000 0x00600000>;
-                       };
-                       partition@f20000 {
-                               label = "VCTL";
-                               reg = <0x00f20000 0x00020000>;
-                               read-only;
-                       };
-                       partition@f40000 {
-                               label = "CurConf";
-                               reg = <0x00f40000 0x000a0000>;
-                               read-only;
-                       };
-                       partition@fe0000 {
-                               label = "FIS directory";
-                               reg = <0x00fe0000 0x00020000>;
-                               read-only;
+                       partitions {
+                               compatible = "redboot-fis";
+                               /* Eraseblock at 0xfe0000 */
+                               fis-index-block = <0x1fc>;
                        };
                };
 
index 2bb9534..a98af03 100644 (file)
@@ -24,7 +24,7 @@
        };
 
        chosen {
-               bootargs = "console=ttyS0,19200n8 root=/dev/sda1 rw rootwait";
+               bootargs = "console=ttyS0,19200n8 root=/dev/mtdblock3 rw rootfstype=squashfs,jffs2 rootwait";
                stdout-path = &uart0;
        };
 
@@ -36,8 +36,8 @@
                        wakeup-source;
                        linux,code = <KEY_WPS_BUTTON>;
                        label = "WPS";
-                       /* Conflict with NAND flash */
-                       gpios = <&gpio0 17 GPIO_ACTIVE_LOW>;
+                       /* Conflicts with TVC and extended flash */
+                       gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
                };
 
                button-setup {
                        /* 16MB of flash */
                        reg = <0x30000000 0x01000000>;
 
-                       partition@0 {
-                               label = "BOOT";
-                               reg = <0x00000000 0x00020000>;
-                               read-only;
-                       };
-                       partition@120000 {
-                               label = "Kern";
-                               reg = <0x00020000 0x00300000>;
-                       };
-                       partition@320000 {
-                               label = "Ramdisk";
-                               reg = <0x00320000 0x00600000>;
-                       };
-                       partition@920000 {
-                               label = "Application";
-                               reg = <0x00920000 0x00600000>;
-                       };
-                       partition@f20000 {
-                               label = "VCTL";
-                               reg = <0x00f20000 0x00020000>;
-                               read-only;
-                       };
-                       partition@f40000 {
-                               label = "CurConf";
-                               reg = <0x00f40000 0x000a0000>;
-                               read-only;
-                       };
-                       partition@fe0000 {
-                               label = "FIS directory";
-                               reg = <0x00fe0000 0x00020000>;
-                               read-only;
+                       partitions {
+                               compatible = "redboot-fis";
+                               /* Eraseblock at 0xfe0000 */
+                               fis-index-block = <0x1fc>;
                        };
                };
 
                syscon: syscon@40000000 {
                        pinctrl {
                                /*
-                                * gpio0egrp cover line 16 used by HD LED
-                                * gpio0fgrp cover line 17, 18 used by wireless LED and reset button
-                                * gpio0hgrp cover line 21, 22 used by MDIO for Marvell PHY
-                                * gpio0kgrp cover line 31 used by USB LED
+                                * gpio0agrp cover line 0, used by WPS button
+                                * gpio0fgrp cover line 16 used by HD LED
+                                * gpio0ggrp cover line 17, 18 used by wireless LAN LED and
+                                * reset button OR USB ID select on 17 and USB VBUS select
+                                * on 18. (Confusing.)
+                                * gpio0igrp cover line 21, 22 used by MDIO for Marvell PHY
                                 */
                                gpio0_default_pins: pinctrl-gpio0 {
                                        mux {
                                                function = "gpio0";
-                                               groups = "gpio0egrp",
+                                               groups = "gpio0agrp",
                                                "gpio0fgrp",
-                                               "gpio0hgrp";
+                                               "gpio0ggrp",
+                                               "gpio0igrp";
                                        };
                                };
                                /*
index dbecd6d..7d4301b 100644 (file)
@@ -14,8 +14,8 @@
                bits-per-pixel = <16>;
                fsl,pcr = <0xcad08b80>;
                bus-width = <18>;
-               native-mode = <&qvga_timings>;
                display-timings {
+                       native-mode = <&qvga_timings>;
                        qvga_timings: 320x240 {
                                clock-frequency = <6500000>;
                                hactive = <320>;
index ad2f7e8..80a7f96 100644 (file)
@@ -14,8 +14,8 @@
                bits-per-pixel = <16>;
                fsl,pcr = <0xfa208b80>;
                bus-width = <18>;
-               native-mode = <&dvi_svga_timings>;
                display-timings {
+                       native-mode = <&dvi_svga_timings>;
                        dvi_svga_timings: 800x600 {
                                clock-frequency = <40000000>;
                                hactive = <800>;
index d60d8f4..24027a1 100644 (file)
@@ -14,8 +14,8 @@
                bits-per-pixel = <16>;
                fsl,pcr = <0xfa208b80>;
                bus-width = <18>;
-               native-mode = <&dvi_vga_timings>;
                display-timings {
+                       native-mode = <&dvi_vga_timings>;
                        dvi_vga_timings: 640x480 {
                                clock-frequency = <31250000>;
                                hactive = <640>;
index f8544a9..05cccd1 100644 (file)
@@ -76,8 +76,8 @@
                bits-per-pixel = <16>;
                fsl,pcr = <0xfa208b80>;
                bus-width = <18>;
-               native-mode = <&wvga_timings>;
                display-timings {
+                       native-mode = <&wvga_timings>;
                        wvga_timings: 640x480 {
                                hactive = <640>;
                                vactive = <480>;
index 087c6e2..6f1e8ce 100644 (file)
 
        display: display {
                model = "Chimei-LW700AT9003";
-               native-mode = <&timing0>;
                bits-per-pixel = <16>;  /* non-standard but required */
                fsl,pcr = <0xfae80083>; /* non-standard but required */
                display-timings {
+                       native-mode = <&timing0>;
                        timing0: 800x480 {
                                clock-frequency = <33000033>;
                                hactive = <800>;
index 84fc8df..9c3ec82 100644 (file)
 
        display0: CMO-QVGA {
                model = "CMO-QVGA";
-               native-mode = <&timing0>;
                bits-per-pixel = <16>;
                fsl,pcr = <0xfad08b80>;
 
                display-timings {
+                       native-mode = <&timing0>;
                        timing0: 320x240 {
                                clock-frequency = <6500000>;
                                hactive = <320>;
index 5e5e282..0cd75da 100644 (file)
 
        display: display {
                model = "Primeview-PD050VL1";
-               native-mode = <&timing0>;
                bits-per-pixel = <16>;  /* non-standard but required */
                fsl,pcr = <0xf0c88080>; /* non-standard but required */
                display-timings {
+                       native-mode = <&timing0>;
                        timing0: 640x480 {
                                hactive = <640>;
                                vactive = <480>;
index 5606f41..bf883e4 100644 (file)
 
        display0: LQ035Q7 {
                model = "Sharp-LQ035Q7";
-               native-mode = <&timing0>;
                bits-per-pixel = <16>;
                fsl,pcr = <0xf00080c0>;
 
                display-timings {
+                       native-mode = <&timing0>;
                        timing0: 240x320 {
                                clock-frequency = <5500000>;
                                hactive = <240>;
index 10acc53..719ed5c 100644 (file)
@@ -54,7 +54,8 @@
        };
 
        panel {
-               compatible = "edt,etm070080dh6";
+               compatible = "edt,etm0700g0dh6";
+               pinctrl-0 = <&pinctrl_display_gpio>;
                enable-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>;
 
                port {
index 1beac22..019dda6 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rmii";
+       phy-handle = <&ethphy>;
        status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy: ethernet-phy@0 {
+                       reg = <0>;
+                       micrel,led-mode = <0>;
+               };
+       };
 };
 
 &hdmi {
index 7a85116..2418cf8 100644 (file)
        non-removable;
        vmmc-supply = <&reg_3p3v>;
        vqmmc-supply = <&reg_wlan_vmmc>;
-       vqmmc-1-8-v;
-       ocr-limit = <0x180>;     /* 1.65v - 2.1v */
        cap-power-off-card;
        keep-power-in-suspend;
        status = "okay";
index 82802f8..d434868 100644 (file)
        };
 
        rtc@51 {
-               compatible = "nxp,rtc8564";
+               compatible = "epson,rtc8564";
                reg = <0x51>;
        };
 
index 50d9a98..2cfb411 100644 (file)
                spdif-out;
        };
 
+       reg_1p5v: regulator-1p5v {
+               compatible = "regulator-fixed";
+               regulator-name = "1P5V";
+               regulator-min-microvolt = <1500000>;
+               regulator-max-microvolt = <1500000>;
+               regulator-always-on;
+       };
+
+       reg_1p8v: regulator-1p8v {
+               compatible = "regulator-fixed";
+               regulator-name = "1P8V";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+       };
+
+       reg_2p8v: regulator-2p8v {
+               compatible = "regulator-fixed";
+               regulator-name = "2P8V";
+               regulator-min-microvolt = <2800000>;
+               regulator-max-microvolt = <2800000>;
+               regulator-always-on;
+       };
+
        reg_2p5v: regulator-2p5v {
                compatible = "regulator-fixed";
                regulator-name = "2P5V";
                VDDIO-supply = <&reg_3p3v>;
                lrclk-strength = <3>;
        };
+
+       camera@3c {
+               compatible = "ovti,ov5645";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ov5645>;
+               reg = <0x3c>;
+               clocks = <&clks IMX6QDL_CLK_CKO2>;
+               clock-names = "xclk";
+               clock-frequency = <24000000>;
+               vdddo-supply = <&reg_1p8v>;
+               vdda-supply = <&reg_2p8v>;
+               vddd-supply = <&reg_1p5v>;
+               enable-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+               reset-gpios = <&gpio4 14 GPIO_ACTIVE_LOW>;
+
+               port {
+                       ov5645_to_mipi_csi2: endpoint {
+                               remote-endpoint = <&mipi_csi2_in>;
+                               clock-lanes = <0>;
+                               data-lanes = <1 2>;
+                       };
+               };
+       };
 };
 
 &iomuxc {
                                MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b030
                                MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b030
                                MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
-                               MX6QDL_PAD_GPIO_6__ENET_IRQ             0x000b1
                        >;
                };
 
                        >;
                };
 
+               pinctrl_ov5645: ov5645grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_3__CCM_CLKO2            0x000b0
+                               MX6QDL_PAD_GPIO_6__GPIO1_IO06           0x1b0b0
+                               MX6QDL_PAD_KEY_COL4__GPIO4_IO14         0x1b0b0
+                       >;
+               };
+
                pinctrl_spdif: spdifgrp {
                        fsl,pins = <
                                MX6QDL_PAD_ENET_RXD0__SPDIF_OUT         0x1b0b0
        pinctrl-0 = <&pinctrl_enet>;
        phy-mode = "rgmii-id";
        phy-reset-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>;
-       interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_HIGH>,
-                             <&intc 0 119 IRQ_TYPE_LEVEL_HIGH>;
-       fsl,err006687-workaround-present;
        status = "okay";
 };
 
+&mipi_csi {
+       status = "okay";
+
+       port@0 {
+               reg = <0>;
+
+               mipi_csi2_in: endpoint {
+                       remote-endpoint = <&ov5645_to_mipi_csi2>;
+                       clock-lanes = <0>;
+                       data-lanes = <1 2>;
+               };
+       };
+};
+
 &spdif {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_spdif>;
index 4b80193..e6b4b85 100644 (file)
 
                gpmi: gpmi-nand@112000 {
                        compatible = "fsl,imx6q-gpmi-nand";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
                        reg = <0x00112000 0x2000>, <0x00114000 0x2000>;
                        reg-names = "gpmi-nand", "bch";
                        interrupts = <0 15 IRQ_TYPE_LEVEL_HIGH>;
                        };
 
                        anatop: anatop@20c8000 {
-                               compatible = "fsl,imx6q-anatop", "syscon", "simple-bus";
+                               compatible = "fsl,imx6q-anatop", "syscon", "simple-mfd";
                                reg = <0x020c8000 0x1000>;
                                interrupts = <0 49 IRQ_TYPE_LEVEL_HIGH>,
                                             <0 54 IRQ_TYPE_LEVEL_HIGH>,
index b36fc01..3a96b55 100644 (file)
                };
        };
 
-       intc: interrupt-controller@a01000 {
-               compatible = "arm,cortex-a9-gic";
-               #interrupt-cells = <3>;
-               interrupt-controller;
-               reg = <0x00a01000 0x1000>,
-                     <0x00a00100 0x100>;
-               interrupt-parent = <&intc>;
-       };
-
        clocks {
                ckil {
                        compatible = "fixed-clock";
                        clocks = <&clks IMX6SL_CLK_OCRAM>;
                };
 
+               intc: interrupt-controller@a01000 {
+                       compatible = "arm,cortex-a9-gic";
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       reg = <0x00a01000 0x1000>,
+                             <0x00a00100 0x100>;
+                       interrupt-parent = <&intc>;
+               };
+
                L2: l2-cache@a02000 {
                        compatible = "arm,pl310-cache";
                        reg = <0x00a02000 0x1000>;
index b0a77ff..13c7ba7 100644 (file)
                };
        };
 
-       intc: interrupt-controller@a01000 {
-               compatible = "arm,cortex-a9-gic";
-               #interrupt-cells = <3>;
-               interrupt-controller;
-               reg = <0x00a01000 0x1000>,
-                     <0x00a00100 0x100>;
-               interrupt-parent = <&intc>;
-       };
-
        ckil: clock-ckil {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                        reg = <0x00900000 0x20000>;
                };
 
+               intc: interrupt-controller@a01000 {
+                       compatible = "arm,cortex-a9-gic";
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       reg = <0x00a01000 0x1000>,
+                             <0x00a00100 0x100>;
+                       interrupt-parent = <&intc>;
+               };
+
                L2: l2-cache@a02000 {
                        compatible = "arm,pl310-cache";
                        reg = <0x00a02000 0x1000>;
                                        compatible = "fsl,imx6sl-uart", "fsl,imx6q-uart",
                                                     "fsl,imx21-uart";
                                        reg = <0x02018000 0x4000>;
-                                       interrupts =<GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                                       interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
                                        dmas = <&sdma 31 4 0>, <&sdma 32 4 0>;
                                        dma-names = "rx", "tx";
                                        clocks = <&clks IMX6SLL_CLK_UART4_IPG>,
                        };
 
                        sdma: dma-controller@20ec000 {
-                               compatible = "fsl,imx6sll-sdma", "fsl,imx35-sdma";
+                               compatible = "fsl,imx6sll-sdma", "fsl,imx6ul-sdma";
                                reg = <0x020ec000 0x4000>;
                                interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6SLL_CLK_IPG>,
                                compatible = "fsl,imx6sll-uart", "fsl,imx6q-uart",
                                             "fsl,imx21-uart";
                                reg = <0x021f4000 0x4000>;
-                               interrupts =<GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
                                dmas = <&sdma 33 4 0>, <&sdma 34 4 0>;
                                dma-names = "rx", "tx";
                                clocks = <&clks IMX6SLL_CLK_UART5_IPG>,
index bb25add..531a52c 100644 (file)
                };
        };
 
-       intc: interrupt-controller@a01000 {
-               compatible = "arm,cortex-a9-gic";
-               #interrupt-cells = <3>;
-               interrupt-controller;
-               reg = <0x00a01000 0x1000>,
-                     <0x00a00100 0x100>;
-               interrupt-parent = <&intc>;
-       };
-
        ckil: clock-ckil {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                        clocks = <&clks IMX6SX_CLK_OCRAM>;
                };
 
+               intc: interrupt-controller@a01000 {
+                       compatible = "arm,cortex-a9-gic";
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       reg = <0x00a01000 0x1000>,
+                             <0x00a00100 0x100>;
+                       interrupt-parent = <&intc>;
+               };
+
                L2: l2-cache@a02000 {
                        compatible = "arm,pl310-cache";
                        reg = <0x00a02000 0x1000>;
                                         <&clks IMX6SX_CLK_ENET_PTP>;
                                clock-names = "ipg", "ahb", "ptp",
                                              "enet_clk_ref", "enet_out";
-                               fsl,num-tx-queues=<3>;
-                               fsl,num-rx-queues=<3>;
+                               fsl,num-tx-queues = <3>;
+                               fsl,num-rx-queues = <3>;
                                status = "disabled";
                        };
 
diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6310-s-43.dts b/arch/arm/boot/dts/imx6ul-kontron-n6310-s-43.dts
new file mode 100644 (file)
index 0000000..5bad296
--- /dev/null
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 exceet electronics GmbH
+ * Copyright (C) 2018 Kontron Electronics GmbH
+ * Copyright (c) 2019 Krzysztof Kozlowski <krzk@kernel.org>
+ */
+
+#include "imx6ul-kontron-n6310-s.dts"
+
+/ {
+       model = "Kontron N6310 S 43";
+       compatible = "kontron,imx6ul-n6310-s-43", "kontron,imx6ul-n6310-s",
+                    "kontron,imx6ul-n6310-som", "fsl,imx6ul";
+
+       backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm7 0 5000000>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+               status = "okay";
+       };
+};
+
+&i2c4 {
+       touchscreen@5d {
+               compatible = "goodix,gt928";
+               reg = <0x5d>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_cap_touch>;
+               interrupt-parent = <&gpio5>;
+               interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
+               reset-gpios = <&gpio5 8 GPIO_ACTIVE_HIGH>;
+               irq-gpios = <&gpio5 6 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+&lcdif {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lcdif_dat &pinctrl_lcdif_ctrl>;
+       /* Leave status disabled because of missing display panel node */
+};
+
+&pwm7 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm7>;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_cap_touch: captouchgrp {
+               fsl,pins = <
+                       MX6UL_PAD_SNVS_TAMPER6__GPIO5_IO06      0x1b0b0 /* Touch Interrupt */
+                       MX6UL_PAD_SNVS_TAMPER7__GPIO5_IO07      0x1b0b0 /* Touch Reset */
+                       MX6UL_PAD_SNVS_TAMPER8__GPIO5_IO08      0x1b0b0 /* Touch Wake */
+               >;
+       };
+
+       pinctrl_lcdif_ctrl: lcdifctrlgrp {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_CLK__LCDIF_CLK            0x79
+                       MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE      0x79
+                       MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC        0x79
+                       MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC        0x79
+                       MX6UL_PAD_LCD_RESET__LCDIF_RESET        0x79
+               >;
+       };
+
+       pinctrl_lcdif_dat: lcdifdatgrp {
+               fsl,pins = <
+                       MX6UL_PAD_LCD_DATA00__LCDIF_DATA00      0x79
+                       MX6UL_PAD_LCD_DATA01__LCDIF_DATA01      0x79
+                       MX6UL_PAD_LCD_DATA02__LCDIF_DATA02      0x79
+                       MX6UL_PAD_LCD_DATA03__LCDIF_DATA03      0x79
+                       MX6UL_PAD_LCD_DATA04__LCDIF_DATA04      0x79
+                       MX6UL_PAD_LCD_DATA05__LCDIF_DATA05      0x79
+                       MX6UL_PAD_LCD_DATA06__LCDIF_DATA06      0x79
+                       MX6UL_PAD_LCD_DATA07__LCDIF_DATA07      0x79
+                       MX6UL_PAD_LCD_DATA08__LCDIF_DATA08      0x79
+                       MX6UL_PAD_LCD_DATA09__LCDIF_DATA09      0x79
+                       MX6UL_PAD_LCD_DATA10__LCDIF_DATA10      0x79
+                       MX6UL_PAD_LCD_DATA11__LCDIF_DATA11      0x79
+                       MX6UL_PAD_LCD_DATA12__LCDIF_DATA12      0x79
+                       MX6UL_PAD_LCD_DATA13__LCDIF_DATA13      0x79
+                       MX6UL_PAD_LCD_DATA14__LCDIF_DATA14      0x79
+                       MX6UL_PAD_LCD_DATA15__LCDIF_DATA15      0x79
+                       MX6UL_PAD_LCD_DATA16__LCDIF_DATA16      0x79
+                       MX6UL_PAD_LCD_DATA17__LCDIF_DATA17      0x79
+                       MX6UL_PAD_LCD_DATA18__LCDIF_DATA18      0x79
+                       MX6UL_PAD_LCD_DATA19__LCDIF_DATA19      0x79
+                       MX6UL_PAD_LCD_DATA20__LCDIF_DATA20      0x79
+                       MX6UL_PAD_LCD_DATA21__LCDIF_DATA21      0x79
+                       MX6UL_PAD_LCD_DATA22__LCDIF_DATA22      0x79
+                       MX6UL_PAD_LCD_DATA23__LCDIF_DATA23      0x79
+               >;
+       };
+
+       pinctrl_pwm7: pwm7grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_VSYNC__PWM7_OUT           0x110b0
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6310-s.dts b/arch/arm/boot/dts/imx6ul-kontron-n6310-s.dts
new file mode 100644 (file)
index 0000000..0205fd5
--- /dev/null
@@ -0,0 +1,420 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 exceet electronics GmbH
+ * Copyright (C) 2018 Kontron Electronics GmbH
+ * Copyright (c) 2019 Krzysztof Kozlowski <krzk@kernel.org>
+ */
+
+/dts-v1/;
+
+#include "imx6ul-kontron-n6310-som.dtsi"
+
+/ {
+       model = "Kontron N6310 S";
+       compatible = "kontron,imx6ul-n6310-s", "kontron,imx6ul-n6310-som",
+                    "fsl,imx6ul";
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               led1 {
+                       label = "debug-led1";
+                       gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led2 {
+                       label = "debug-led2";
+                       gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+
+               led3 {
+                       label = "debug-led3";
+                       gpios = <&gpio5 2 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+               };
+       };
+
+       pwm-beeper {
+               compatible = "pwm-beeper";
+               pwms = <&pwm8 0 5000>;
+       };
+
+       reg_3v3: regulator-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       reg_usb_otg1_vbus: regulator-usb-otg1-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_otg1_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio1 4 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_vref_adc: regulator-vref-adc {
+               compatible = "regulator-fixed";
+               regulator-name = "vref-adc";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&adc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_adc1>;
+       num-channels = <3>;
+       vref-supply = <&reg_vref_adc>;
+       status = "okay";
+};
+
+&can2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan2>;
+       status = "okay";
+};
+
+&ecspi1 {
+       cs-gpios = <&gpio4 26 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       status = "okay";
+
+       eeprom@0 {
+               compatible = "anvo,anv32e61w", "atmel,at25";
+               reg = <0>;
+               spi-max-frequency = <20000000>;
+               spi-cpha;
+               spi-cpol;
+               pagesize = <1>;
+               size = <8192>;
+               address-width = <16>;
+       };
+};
+
+&fec1 {
+       pinctrl-0 = <&pinctrl_enet1>;
+       /delete-node/ mdio;
+};
+
+&fec2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet2 &pinctrl_enet2_mdio>;
+       phy-mode = "rmii";
+       phy-handle = <&ethphy2>;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy1: ethernet-phy@1 {
+                       reg = <1>;
+                       micrel,led-mode = <0>;
+                       clocks = <&clks IMX6UL_CLK_ENET_REF>;
+                       clock-names = "rmii-ref";
+               };
+
+               ethphy2: ethernet-phy@2 {
+                       reg = <2>;
+                       micrel,led-mode = <0>;
+                       clocks = <&clks IMX6UL_CLK_ENET2_REF>;
+                       clock-names = "rmii-ref";
+               };
+       };
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+};
+
+&i2c4 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c4>;
+       status = "okay";
+
+       rtc@32 {
+               compatible = "epson,rx8900";
+               reg = <0x32>;
+       };
+};
+
+&pwm8 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm8>;
+       status = "okay";
+};
+
+&snvs_poweroff {
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       linux,rs485-enabled-at-boot-time;
+       rs485-rx-during-tx;
+       rs485-rts-active-low;
+       uart-has-rtscts;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
+       fsl,uart-has-rtscts;
+       status = "okay";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       status = "okay";
+};
+
+&usbotg1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg1>;
+       dr_mode = "otg";
+       srp-disable;
+       hnp-disable;
+       adp-disable;
+       vbus-supply = <&reg_usb_otg1_vbus>;
+       status = "okay";
+};
+
+&usbotg2 {
+       dr_mode = "host";
+       disable-over-current;
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       cd-gpios = <&gpio1 19 GPIO_ACTIVE_LOW>;
+       keep-power-in-suspend;
+       wakeup-source;
+       vmmc-supply = <&reg_3v3>;
+       voltage-ranges = <3300 3300>;
+       no-1-8-v;
+       status = "okay";
+};
+
+&usdhc2 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>;
+       non-removable;
+       keep-power-in-suspend;
+       wakeup-source;
+       vmmc-supply = <&reg_3v3>;
+       voltage-ranges = <3300 3300>;
+       no-1-8-v;
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl-0 = <&pinctrl_reset_out &pinctrl_gpio>;
+
+       pinctrl_adc1: adc1grp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO02__GPIO1_IO02        0xb0
+                       MX6UL_PAD_GPIO1_IO03__GPIO1_IO03        0xb0
+                       MX6UL_PAD_GPIO1_IO08__GPIO1_IO08        0xb0
+               >;
+       };
+
+       /* FRAM */
+       pinctrl_ecspi1: ecspi1grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_DATA07__ECSPI1_MISO       0x100b1
+                       MX6UL_PAD_CSI_DATA06__ECSPI1_MOSI       0x100b1
+                       MX6UL_PAD_CSI_DATA04__ECSPI1_SCLK       0x100b1
+                       MX6UL_PAD_CSI_DATA05__GPIO4_IO26        0x100b1 /* ECSPI1-CS1 */
+               >;
+       };
+
+       pinctrl_enet2: enet2grp {
+               fsl,pins = <
+                       MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN      0x1b0b0
+                       MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER      0x1b0b0
+                       MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
+                       MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
+                       MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN      0x1b0b0
+                       MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
+                       MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
+                       MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b009
+               >;
+       };
+
+       pinctrl_enet2_mdio: enet2mdiogrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO07__ENET2_MDC         0x1b0b0
+                       MX6UL_PAD_GPIO1_IO06__ENET2_MDIO        0x1b0b0
+               >;
+       };
+
+       pinctrl_flexcan2: flexcan2grp{
+               fsl,pins = <
+                       MX6UL_PAD_UART2_RTS_B__FLEXCAN2_RX      0x1b020
+                       MX6UL_PAD_UART2_CTS_B__FLEXCAN2_TX      0x1b020
+               >;
+       };
+
+       pinctrl_gpio: gpiogrp {
+               fsl,pins = <
+                       MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05      0x1b0b0 /* DOUT1 */
+                       MX6UL_PAD_SNVS_TAMPER4__GPIO5_IO04      0x1b0b0 /* DIN1 */
+                       MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01      0x1b0b0 /* DOUT2 */
+                       MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00      0x1b0b0 /* DIN2 */
+               >;
+       };
+
+       pinctrl_gpio_leds: gpioledsgrp {
+               fsl,pins = <
+                       MX6UL_PAD_UART5_TX_DATA__GPIO1_IO30     0x1b0b0 /* LED H14 */
+                       MX6UL_PAD_SNVS_TAMPER3__GPIO5_IO03      0x1b0b0 /* LED H15 */
+                       MX6UL_PAD_SNVS_TAMPER2__GPIO5_IO02      0x1b0b0 /* LED H16 */
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_PIXCLK__I2C1_SCL          0x4001b8b0
+                       MX6UL_PAD_CSI_MCLK__I2C1_SDA            0x4001b8b0
+               >;
+       };
+
+       pinctrl_i2c4: i2c4grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART2_TX_DATA__I2C4_SCL       0x4001f8b0
+                       MX6UL_PAD_UART2_RX_DATA__I2C4_SDA       0x4001f8b0
+               >;
+       };
+
+       pinctrl_pwm8: pwm8grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_HSYNC__PWM8_OUT           0x110b0
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART1_TX_DATA__UART1_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART1_RX_DATA__UART1_DCE_RX   0x1b0b1
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_DATA04__UART2_DCE_TX     0x1b0b1
+                       MX6UL_PAD_NAND_DATA05__UART2_DCE_RX     0x1b0b1
+                       MX6UL_PAD_NAND_DATA06__UART2_DCE_CTS    0x1b0b1
+                       /*
+                        * mux unused RTS to make sure it doesn't cause
+                        * any interrupts when it is undefined
+                        */
+                       MX6UL_PAD_NAND_DATA07__UART2_DCE_RTS    0x1b0b1
+               >;
+       };
+
+       pinctrl_uart3: uart3grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX   0x1b0b1
+                       MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS    0x1b0b1
+                       MX6UL_PAD_UART3_RTS_B__UART3_DCE_RTS    0x1b0b1
+               >;
+       };
+
+       pinctrl_uart4: uart4grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART4_TX_DATA__UART4_DCE_TX   0x1b0b1
+                       MX6UL_PAD_UART4_RX_DATA__UART4_DCE_RX   0x1b0b1
+               >;
+       };
+
+       pinctrl_usbotg1: usbotg1 {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO04__GPIO1_IO04        0x1b0b0
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX6UL_PAD_SD1_CMD__USDHC1_CMD           0x17059
+                       MX6UL_PAD_SD1_CLK__USDHC1_CLK           0x10059
+                       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
+                       MX6UL_PAD_UART1_RTS_B__GPIO1_IO19       0x100b1 /* SD1_CD */
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x10059
+                       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
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x100b9
+                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD         0x170b9
+                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0     0x170b9
+                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1     0x170b9
+                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2     0x170b9
+                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3     0x170b9
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x100f9
+                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD         0x170f9
+                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0     0x170f9
+                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1     0x170f9
+                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2     0x170f9
+                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3     0x170f9
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO09__WDOG1_WDOG_ANY    0x30b0
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx6ul-kontron-n6310-som.dtsi b/arch/arm/boot/dts/imx6ul-kontron-n6310-som.dtsi
new file mode 100644 (file)
index 0000000..a896b23
--- /dev/null
@@ -0,0 +1,134 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017 exceet electronics GmbH
+ * Copyright (C) 2018 Kontron Electronics GmbH
+ * Copyright (c) 2019 Krzysztof Kozlowski <krzk@kernel.org>
+ */
+
+#include "imx6ul.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "Kontron N6310 SOM";
+       compatible = "kontron,imx6ul-n6310-som", "fsl,imx6ul";
+
+       memory@80000000 {
+               reg = <0x80000000 0x10000000>;
+               device_type = "memory";
+       };
+};
+
+&ecspi2 {
+       cs-gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi2>;
+       status = "okay";
+
+       spi-flash@0 {
+               compatible = "mxicy,mx25v8035f", "jedec,spi-nor";
+               spi-max-frequency = <50000000>;
+               reg = <0>;
+       };
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet1 &pinctrl_enet1_mdio>;
+       phy-mode = "rmii";
+       phy-handle = <&ethphy1>;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy1: ethernet-phy@1 {
+                       reg = <1>;
+                       micrel,led-mode = <0>;
+                       clocks = <&clks IMX6UL_CLK_ENET_REF>;
+                       clock-names = "rmii-ref";
+               };
+       };
+};
+
+&fec2 {
+       phy-mode = "rmii";
+       status = "disabled";
+};
+
+&qspi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_qspi>;
+       status = "okay";
+
+       spi-flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "spi-nand";
+               spi-max-frequency = <108000000>;
+               spi-tx-bus-width = <4>;
+               spi-rx-bus-width = <4>;
+               reg = <0>;
+
+               partition@0 {
+                       label = "ubi1";
+                       reg = <0x00000000 0x08000000>;
+               };
+
+               partition@8000000 {
+                       label = "ubi2";
+                       reg = <0x08000000 0x08000000>;
+               };
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_reset_out>;
+
+       pinctrl_ecspi2: ecspi2grp {
+               fsl,pins = <
+                       MX6UL_PAD_CSI_DATA03__ECSPI2_MISO      0x100b1
+                       MX6UL_PAD_CSI_DATA02__ECSPI2_MOSI      0x100b1
+                       MX6UL_PAD_CSI_DATA00__ECSPI2_SCLK      0x100b1
+                       MX6UL_PAD_CSI_DATA01__GPIO4_IO22       0x100b1
+               >;
+       };
+
+       pinctrl_enet1: enet1grp {
+               fsl,pins = <
+                       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  0x4001b009
+               >;
+       };
+
+       pinctrl_enet1_mdio: enet1mdiogrp {
+               fsl,pins = <
+                       MX6UL_PAD_GPIO1_IO07__ENET1_MDC         0x1b0b0
+                       MX6UL_PAD_GPIO1_IO06__ENET1_MDIO        0x1b0b0
+               >;
+       };
+
+       pinctrl_qspi: qspigrp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_WP_B__QSPI_A_SCLK        0x70a1
+                       MX6UL_PAD_NAND_READY_B__QSPI_A_DATA00   0x70a1
+                       MX6UL_PAD_NAND_CE0_B__QSPI_A_DATA01     0x70a1
+                       MX6UL_PAD_NAND_CE1_B__QSPI_A_DATA02     0x70a1
+                       MX6UL_PAD_NAND_CLE__QSPI_A_DATA03       0x70a1
+                       MX6UL_PAD_NAND_DQS__QSPI_A_SS0_B        0x70a1
+               >;
+       };
+
+       pinctrl_reset_out: rstoutgrp {
+               fsl,pins = <
+                       MX6UL_PAD_SNVS_TAMPER9__GPIO5_IO09      0x1b0b0
+               >;
+       };
+};
index 0e59ee5..8ecdb9a 100644 (file)
@@ -56,7 +56,7 @@
                stdout-path = &uart1;
        };
 
-       backlight {
+       backlight: backlight {
                compatible = "pwm-backlight";
                pwms = <&pwm3 0 191000>;
                brightness-levels = <0 4 8 16 32 64 128 255>;
                gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
        };
 
+       panel: panel {
+               compatible = "armadeus,st0700-adapt";
+               power-supply = <&reg_3v3>;
+               backlight = <&backlight>;
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&lcdif_out>;
+                       };
+               };
+       };
+
        reg_5v: regulator-5v {
                compatible = "regulator-fixed";
                regulator-name = "5V";
 &lcdif {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_lcdif>;
-       display = <&display0>;
-       lcd-supply = <&reg_3v3>;
        status = "okay";
 
-       display0: display0 {
-               bits-per-pixel = <32>;
-               bus-width = <18>;
-
-               display-timings {
-                       timing0: timing0 {
-                               clock-frequency = <33000033>;
-                               hactive = <800>;
-                               vactive = <480>;
-                               hback-porch = <96>;
-                               hfront-porch = <96>;
-                               vback-porch = <20>;
-                               vfront-porch = <21>;
-                               hsync-len = <64>;
-                               vsync-len = <4>;
-                               de-active = <1>;
-                               pixelclk-active = <0>;
-                       };
+       port {
+               lcdif_out: endpoint {
+                       remote-endpoint = <&panel_in>;
                };
        };
 };
@@ -7,10 +7,9 @@
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/pwm/pwm.h>
-#include "imx6ul.dtsi"
 
 / {
-       model = "Phytec phyCORE i.MX6 UltraLite";
+       model = "PHYTEC phyCORE-i.MX6 UltraLite";
        compatible = "phytec,imx6ul-pcl063", "fsl,imx6ul";
 
        chosen {
@@ -31,8 +30,7 @@
                pinctrl-0 = <&pinctrl_gpioleds_som>;
                compatible = "gpio-leds";
 
-               led_green {
-                       label = "phycore:green";
+               phycore-green {
                        gpios = <&gpio5 4 GPIO_ACTIVE_HIGH>;
                        linux,default-trigger = "heartbeat";
                };
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet1>;
        phy-mode = "rmii";
-       phy-handle = <&ethphy0>;
-       status = "okay";
+       phy-handle = <&ethphy1>;
+       status = "disabled";
 
        mdio: mdio {
                #address-cells = <1>;
                #size-cells = <0>;
 
-               ethphy0: ethernet-phy@1 {
+               ethphy1: ethernet-phy@1 {
                        reg = <1>;
                        interrupt-parent = <&gpio1>;
                        interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
                        micrel,led-mode = <1>;
                        clocks = <&clks IMX6UL_CLK_ENET_REF>;
                        clock-names = "rmii-ref";
+                       status = "disabled";
                };
        };
 };
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_gpmi_nand>;
        nand-on-flash-bbt;
-       status = "okay";
+       status = "disabled";
 };
 
 &i2c1 {
        pinctrl-names = "default";
-       pinctrl-0 =<&pinctrl_i2c1>;
+       pinctrl-0 = <&pinctrl_i2c1>;
        clock-frequency = <100000>;
        status = "okay";
 
        status = "okay";
 };
 
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       bus-width = <8>;
+       no-1-8-v;
+       non-removable;
+       status = "disabled";
+};
+
 &iomuxc {
        pinctrl_enet1: enet1grp {
                fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO07__ENET1_MDC         0x1b0b0
-                       MX6UL_PAD_GPIO1_IO06__ENET1_MDIO        0x1b0b0
+                       MX6UL_PAD_GPIO1_IO07__ENET1_MDC         0x10010
+                       MX6UL_PAD_GPIO1_IO06__ENET1_MDIO        0x10010
                        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
+                       MX6UL_PAD_ENET1_TX_EN__ENET1_TX_EN      0x1b010
+                       MX6UL_PAD_ENET1_TX_DATA0__ENET1_TDATA00 0x1b010
+                       MX6UL_PAD_ENET1_TX_DATA1__ENET1_TDATA01 0x1b010
+                       MX6UL_PAD_ENET1_TX_CLK__ENET1_REF_CLK1  0x4001b010
                        MX6UL_PAD_GPIO1_IO02__GPIO1_IO02        0x17059
                >;
        };
                >;
        };
 
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX6UL_PAD_NAND_WE_B__USDHC2_CMD         0x170f9
+                       MX6UL_PAD_NAND_RE_B__USDHC2_CLK         0x100f9
+                       MX6UL_PAD_NAND_DATA00__USDHC2_DATA0     0x170f9
+                       MX6UL_PAD_NAND_DATA01__USDHC2_DATA1     0x170f9
+                       MX6UL_PAD_NAND_DATA02__USDHC2_DATA2     0x170f9
+                       MX6UL_PAD_NAND_DATA03__USDHC2_DATA3     0x170f9
+                       MX6UL_PAD_NAND_DATA04__USDHC2_DATA4     0x170f9
+                       MX6UL_PAD_NAND_DATA05__USDHC2_DATA5     0x170f9
+                       MX6UL_PAD_NAND_DATA06__USDHC2_DATA6     0x170f9
+                       MX6UL_PAD_NAND_DATA07__USDHC2_DATA7     0x170f9
+               >;
+       };
+
 };
@@ -5,13 +5,15 @@
  */
 
 /dts-v1/;
-#include "imx6ul-phytec-pcl063.dtsi"
-#include "imx6ul-phytec-phyboard-segin.dtsi"
-#include "imx6ul-phytec-peb-eval-01.dtsi"
+#include "imx6ul.dtsi"
+#include "imx6ul-phytec-phycore-som.dtsi"
+#include "imx6ul-phytec-segin.dtsi"
+#include "imx6ul-phytec-segin-peb-eval-01.dtsi"
 
 / {
-       model = "Phytec phyBOARD-Segin i.MX6 UltraLite Full Featured";
-       compatible = "phytec,imx6ul-pbacd10", "phytec,imx6ul-pcl063", "fsl,imx6ul";
+       model = "PHYTEC phyBOARD-Segin i.MX6 UltraLite Full Featured with NAND";
+       compatible = "phytec,imx6ul-pbacd10-nand", "phytec,imx6ul-pbacd10",
+                    "phytec,imx6ul-pcl063", "fsl,imx6ul";
 };
 
 &adc1 {
 };
 
 &ecspi3 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_ecspi3>;
-       cs-gpios = <&gpio1 20 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&ethphy1 {
+       status = "okay";
+};
+
+&ethphy2 {
+       status = "okay";
+};
+
+&fec1 {
        status = "okay";
 };
 
        status = "okay";
 };
 
+&gpmi {
+       status = "okay";
+};
+
 &i2c_rtc {
        status = "okay";
 };
 &usdhc1 {
        status = "okay";
 };
-
-&iomuxc {
-       pinctrl_ecspi3: ecspi3grp {
-               fsl,pins = <
-                       MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO      0x10b0
-                       MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI      0x10b0
-                       MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK    0x10b0
-                       MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20     0x10b0
-               >;
-       };
-};
                };
        };
 
-       user_leds: leds {
+       user_leds: user-leds {
                compatible = "gpio-leds";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_user_leds>;
                status = "disabled";
 
-               led_yellow {
-                       gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
-                       linux,default-trigger = "default-on";
+               user-led1 {
+                       gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "gpio";
+                       default-state = "on";
                };
 
-               led_red {
-                       gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
-                       linux,default-trigger = "default-on";
+               user-led2 {
+                       gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "gpio";
+                       default-state = "on";
                };
        };
 };
@@ -5,7 +5,7 @@
  */
 
 / {
-       model = "Phytec phyBOARD-Segin i.MX6 UltraLite";
+       model = "PHYTEC phyBOARD-Segin i.MX6 UltraLite";
        compatible = "phytec,imx6ul-pbacd-10", "phytec,imx6ul-pcl063", "fsl,imx6ul";
 
        aliases {
        assigned-clock-rates = <786432000>;
 };
 
+&ecspi3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi3>;
+       cs-gpios = <&gpio1 20 GPIO_ACTIVE_HIGH>;
+       status = "disabled";
+};
+
 &fec2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet2>;
        phy-mode = "rmii";
-       phy-handle = <&ethphy1>;
+       phy-handle = <&ethphy2>;
        status = "disabled";
 };
 
 };
 
 &mdio {
-       ethphy1: ethernet-phy@2 {
+       ethphy2: ethernet-phy@2 {
                reg = <2>;
                micrel,led-mode = <1>;
                clocks = <&clks IMX6UL_CLK_ENET2_REF>;
                clock-names = "rmii-ref";
+               status = "disabled";
        };
 };
 
                >;
        };
 
+       pinctrl_ecspi3: ecspi3grp {
+               fsl,pins = <
+                       MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO      0x10b0
+                       MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI      0x10b0
+                       MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK    0x10b0
+                       MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20     0x10b0
+               >;
+       };
+
        pinctrl_enet2: enet2grp {
                fsl,pins = <
                        MX6UL_PAD_ENET2_RX_EN__ENET2_RX_EN      0x1b0b0
                        MX6UL_PAD_ENET2_RX_ER__ENET2_RX_ER      0x1b0b0
                        MX6UL_PAD_ENET2_RX_DATA0__ENET2_RDATA00 0x1b0b0
                        MX6UL_PAD_ENET2_RX_DATA1__ENET2_RDATA01 0x1b0b0
-                       MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN      0x1b0b0
-                       MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b0b0
-                       MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b0b0
-                       MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b031
+                       MX6UL_PAD_ENET2_TX_EN__ENET2_TX_EN      0x1b010
+                       MX6UL_PAD_ENET2_TX_DATA0__ENET2_TDATA00 0x1b010
+                       MX6UL_PAD_ENET2_TX_DATA1__ENET2_TDATA01 0x1b010
+                       MX6UL_PAD_ENET2_TX_CLK__ENET2_REF_CLK2  0x4001b010
                >;
        };
 
index 81d4b49..f008036 100644 (file)
                };
        };
 
-       intc: interrupt-controller@a01000 {
-               compatible = "arm,gic-400", "arm,cortex-a7-gic";
-               interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
-               #interrupt-cells = <3>;
-               interrupt-controller;
-               interrupt-parent = <&intc>;
-               reg = <0x00a01000 0x1000>,
-                     <0x00a02000 0x2000>,
-                     <0x00a04000 0x2000>,
-                     <0x00a06000 0x2000>;
-       };
-
        timer {
                compatible = "arm,armv7-timer";
                interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_LOW)>,
                        reg = <0x00900000 0x20000>;
                };
 
+               intc: interrupt-controller@a01000 {
+                       compatible = "arm,gic-400", "arm,cortex-a7-gic";
+                       interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(1) | IRQ_TYPE_LEVEL_HIGH)>;
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       interrupt-parent = <&intc>;
+                       reg = <0x00a01000 0x1000>,
+                             <0x00a02000 0x2000>,
+                             <0x00a04000 0x2000>,
+                             <0x00a06000 0x2000>;
+               };
+
                dma_apbh: dma-apbh@1804000 {
                        compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
                        reg = <0x01804000 0x2000>;
                                        clocks = <&clks IMX6UL_CLK_ECSPI1>,
                                                 <&clks IMX6UL_CLK_ECSPI1>;
                                        clock-names = "ipg", "per";
+                                       dmas = <&sdma 3 7 1>, <&sdma 4 7 2>;
+                                       dma-names = "rx", "tx";
                                        status = "disabled";
                                };
 
                                        clocks = <&clks IMX6UL_CLK_ECSPI2>,
                                                 <&clks IMX6UL_CLK_ECSPI2>;
                                        clock-names = "ipg", "per";
+                                       dmas = <&sdma 5 7 1>, <&sdma 6 7 2>;
+                                       dma-names = "rx", "tx";
                                        status = "disabled";
                                };
 
                                        clocks = <&clks IMX6UL_CLK_ECSPI3>,
                                                 <&clks IMX6UL_CLK_ECSPI3>;
                                        clock-names = "ipg", "per";
+                                       dmas = <&sdma 7 7 1>, <&sdma 8 7 2>;
+                                       dma-names = "rx", "tx";
                                        status = "disabled";
                                };
 
                                        clocks = <&clks IMX6UL_CLK_ECSPI4>,
                                                 <&clks IMX6UL_CLK_ECSPI4>;
                                        clock-names = "ipg", "per";
+                                       dmas = <&sdma 9 7 1>, <&sdma 10 7 2>;
+                                       dma-names = "rx", "tx";
                                        status = "disabled";
                                };
 
                                         <&clks IMX6UL_CLK_ENET2_REF_125M>;
                                clock-names = "ipg", "ahb", "ptp",
                                              "enet_clk_ref", "enet_out";
-                               fsl,num-tx-queues=<1>;
-                               fsl,num-rx-queues=<1>;
+                               fsl,num-tx-queues = <1>;
+                               fsl,num-rx-queues = <1>;
                                status = "disabled";
                        };
 
                                         <&clks IMX6UL_CLK_ENET_REF>;
                                clock-names = "ipg", "ahb", "ptp",
                                              "enet_clk_ref", "enet_out";
-                               fsl,num-tx-queues=<1>;
-                               fsl,num-rx-queues=<1>;
+                               fsl,num-tx-queues = <1>;
+                               fsl,num-rx-queues = <1>;
                                status = "disabled";
                        };
 
                                         <&clks IMX6UL_CLK_USDHC1>,
                                         <&clks IMX6UL_CLK_USDHC1>;
                                clock-names = "ipg", "ahb", "per";
-                               fsl,tuning-step= <2>;
+                               fsl,tuning-step = <2>;
                                fsl,tuning-start-tap = <20>;
                                bus-width = <4>;
                                status = "disabled";
                                         <&clks IMX6UL_CLK_USDHC2>;
                                clock-names = "ipg", "ahb", "per";
                                bus-width = <4>;
-                               fsl,tuning-step= <2>;
+                               fsl,tuning-step = <2>;
                                fsl,tuning-start-tap = <20>;
                                status = "disabled";
                        };
                                };
                        };
 
+                       csi: csi@21c4000 {
+                               compatible = "fsl,imx6ul-csi", "fsl,imx7-csi";
+                               reg = <0x021c4000 0x4000>;
+                               interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6UL_CLK_CSI>;
+                               clock-names = "mclk";
+                               status = "disabled";
+                       };
+
                        lcdif: lcdif@21c8000 {
                                compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif";
                                reg = <0x021c8000 0x4000>;
diff --git a/arch/arm/boot/dts/imx6ull-phytec-phycore-som.dtsi b/arch/arm/boot/dts/imx6ull-phytec-phycore-som.dtsi
new file mode 100644 (file)
index 0000000..56cd16e
--- /dev/null
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 PHYTEC Messtechnik GmbH
+ * Author: Stefan Riedmueller <s.riedmueller@phytec.de>
+ */
+
+#include "imx6ul-phytec-phycore-som.dtsi"
+
+/ {
+       model = "PHYTEC phyCORE-i.MX6 ULL";
+       compatible = "phytec,imx6ull-pcl063", "fsl,imx6ull";
+};
+
+&iomuxc {
+       /delete-node/ gpioledssomgrp;
+};
+
+&iomuxc_snvs {
+       pinctrl_gpioleds_som: gpioledssomgrp {
+               fsl,pins = <
+                       MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04     0x0b0b0
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-emmc.dts b/arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-emmc.dts
new file mode 100644 (file)
index 0000000..9648d4e
--- /dev/null
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 PHYTEC Messtechnik GmbH
+ * Author: Stefan Riedmueller <s.riedmueller@phytec.de>
+ */
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include "imx6ull-phytec-phycore-som.dtsi"
+#include "imx6ull-phytec-segin.dtsi"
+#include "imx6ull-phytec-segin-peb-eval-01.dtsi"
+
+/ {
+       model = "PHYTEC phyBOARD-Segin i.MX6 ULL Full Featured with eMMC";
+       compatible = "phytec,imx6ull-pbacd10-emmc", "phytec,imx6ull-pbacd10",
+                    "phytec,imx6ull-pcl063","fsl,imx6ull";
+};
+
+&adc1 {
+       status = "okay";
+};
+
+&can1 {
+       status = "okay";
+};
+
+&tlv320 {
+       status = "okay";
+};
+
+&ecspi3 {
+       status = "okay";
+};
+
+&ethphy1 {
+       status = "okay";
+};
+
+&ethphy2 {
+       status = "okay";
+};
+
+&fec1 {
+       status = "okay";
+};
+
+&fec2 {
+       status = "okay";
+};
+
+&i2c_rtc {
+       status = "okay";
+};
+
+&reg_can1_en {
+       status = "okay";
+};
+
+&reg_sound_1v8 {
+       status = "okay";
+};
+
+&reg_sound_3v3 {
+       status = "okay";
+};
+
+&sai2 {
+       status = "okay";
+};
+
+&sound {
+       status = "okay";
+};
+
+&uart5 {
+       status = "okay";
+};
+
+&usbotg1 {
+       status = "okay";
+};
+
+&usbotg2 {
+       status = "okay";
+};
+
+&usdhc1 {
+       status = "okay";
+};
+
+&usdhc2 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-nand.dts b/arch/arm/boot/dts/imx6ull-phytec-segin-ff-rdk-nand.dts
new file mode 100644 (file)
index 0000000..656baf8
--- /dev/null
@@ -0,0 +1,93 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 PHYTEC Messtechnik GmbH
+ * Author: Stefan Riedmueller <s.riedmueller@phytec.de>
+ */
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include "imx6ull-phytec-phycore-som.dtsi"
+#include "imx6ull-phytec-segin.dtsi"
+#include "imx6ull-phytec-segin-peb-eval-01.dtsi"
+
+/ {
+       model = "PHYTEC phyBOARD-Segin i.MX6 ULL Full Featured with NAND";
+       compatible = "phytec,imx6ull-pbacd10-nand", "phytec,imx6ull-pbacd10",
+                    "phytec,imx6ull-pcl063", "fsl,imx6ull";
+};
+
+&adc1 {
+       status = "okay";
+};
+
+&can1 {
+       status = "okay";
+};
+
+&tlv320 {
+       status = "okay";
+};
+
+&ecspi3 {
+       status = "okay";
+};
+
+&ethphy1 {
+       status = "okay";
+};
+
+&ethphy2 {
+       status = "okay";
+};
+
+&fec1 {
+       status = "okay";
+};
+
+&fec2 {
+       status = "okay";
+};
+
+&gpmi {
+       status = "okay";
+};
+
+&i2c_rtc {
+       status = "okay";
+};
+
+&reg_can1_en {
+       status = "okay";
+};
+
+&reg_sound_1v8 {
+       status = "okay";
+};
+
+&reg_sound_3v3 {
+       status = "okay";
+};
+
+&sai2 {
+       status = "okay";
+};
+
+&sound {
+       status = "okay";
+};
+
+&uart5 {
+       status = "okay";
+};
+
+&usbotg1 {
+       status = "okay";
+};
+
+&usbotg2 {
+       status = "okay";
+};
+
+&usdhc1 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-phytec-segin-lc-rdk-nand.dts b/arch/arm/boot/dts/imx6ull-phytec-segin-lc-rdk-nand.dts
new file mode 100644 (file)
index 0000000..e168494
--- /dev/null
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 PHYTEC Messtechnik GmbH
+ * Author: Stefan Riedmueller <s.riedmueller@phytec.de>
+ */
+
+/dts-v1/;
+#include "imx6ull.dtsi"
+#include "imx6ull-phytec-phycore-som.dtsi"
+#include "imx6ull-phytec-segin.dtsi"
+#include "imx6ull-phytec-segin-peb-eval-01.dtsi"
+
+/ {
+       model = "PHYTEC phyBOARD-Segin i.MX6 ULL Low Cost with NAND";
+       compatible = "phytec,imx6ull-pbacd10-nand", "phytec,imx6ull-pbacd10",
+                    "phytec,imx6ull-pcl063", "fsl,imx6ull";
+};
+
+&adc1 {
+       status = "okay";
+};
+
+&ethphy1 {
+       status = "okay";
+};
+
+&fec1 {
+       status = "okay";
+};
+
+&gpmi {
+       status = "okay";
+};
+
+&i2c_rtc {
+       status = "okay";
+};
+
+&usbotg1 {
+       status = "okay";
+};
+
+&usdhc1 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/imx6ull-phytec-segin-peb-eval-01.dtsi b/arch/arm/boot/dts/imx6ull-phytec-segin-peb-eval-01.dtsi
new file mode 100644 (file)
index 0000000..ff08d95
--- /dev/null
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 PHYTEC Messtechnik GmbH
+ * Author: Stefan Riedmueller <s.riedmueller@phytec.de>
+ */
+
+#include "imx6ul-phytec-segin-peb-eval-01.dtsi"
+
+&iomuxc {
+       /delete-node/ gpio_keysgrp;
+};
+
+&iomuxc_snvs {
+       pinctrl_gpio_keys: gpio_keysgrp {
+               fsl,pins = <
+                       MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00     0x79
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx6ull-phytec-segin.dtsi b/arch/arm/boot/dts/imx6ull-phytec-segin.dtsi
new file mode 100644 (file)
index 0000000..c1595fc
--- /dev/null
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 PHYTEC Messtechnik GmbH
+ * Author: Stefan Riedmueller <s.riedmueller@phytec.de>
+ */
+
+#include "imx6ul-phytec-segin.dtsi"
+
+/ {
+       model = "PHYTEC phyBOARD-Segin i.MX6 ULL";
+       compatible = "phytec,imx6ull-pbacd-10", "phytec,imx6ull-pcl063","fsl,imx6ull";
+};
+
+&iomuxc {
+       /delete-node/ flexcan1engrp;
+       /delete-node/ rtcintgrp;
+       /delete-node/ stmpegrp;
+};
+
+&iomuxc_snvs {
+       princtrl_flexcan1_en: flexcan1engrp {
+               fsl,pins = <
+                       MX6ULL_PAD_SNVS_TAMPER2__GPIO5_IO02     0x17059
+               >;
+       };
+
+       pinctrl_rtc_int: rtcintgrp {
+               fsl,pins = <
+                       MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01     0x17059
+               >;
+       };
+
+       pinctrl_stmpe: stmpegrp {
+               fsl,pins = <
+                       MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03     0x17059
+               >;
+       };
+};
index 895fbde..917eb0b 100644 (file)
@@ -54,6 +54,7 @@
                regulator-name = "+V3.3";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
+               regulator-always-on;
        };
 
        reg_module_3v3_avdd: regulator-module-3v3-avdd {
@@ -61,6 +62,7 @@
                regulator-name = "+V3.3_AVDD_AUDIO";
                regulator-min-microvolt = <3300000>;
                regulator-max-microvolt = <3300000>;
+               regulator-always-on;
        };
 
        sound {
 };
 
 &fec1 {
-       pinctrl-names = "default";
+       pinctrl-names = "default", "sleep";
        pinctrl-0 = <&pinctrl_enet1>;
+       pinctrl-1 = <&pinctrl_enet1_sleep>;
        clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
                <&clks IMX7D_ENET_AXI_ROOT_CLK>,
                <&clks IMX7D_ENET1_TIME_ROOT_CLK>,
        fsl,magic-packet;
 };
 
+&flexcan1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       status = "disabled";
+};
+
+&flexcan2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan2>;
+       status = "disabled";
+};
+
 &gpmi {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_gpmi_nand>;
 
 &i2c1 {
        clock-frequency = <100000>;
-       pinctrl-names = "default";
+       pinctrl-names = "default", "gpio";
        pinctrl-0 = <&pinctrl_i2c1 &pinctrl_i2c1_int>;
+       pinctrl-1 = <&pinctrl_i2c1_recovery &pinctrl_i2c1_int>;
+       scl-gpios = <&gpio1 4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+       sda-gpios = <&gpio1 5 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+
        status = "okay";
 
        codec: sgtl5000@a {
 
 &i2c4 {
        clock-frequency = <100000>;
-       pinctrl-names = "default";
+       pinctrl-names = "default", "gpio";
        pinctrl-0 = <&pinctrl_i2c4>;
+       pinctrl-1 = <&pinctrl_i2c4_recovery>;
+       scl-gpios = <&gpio7 8 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+       sda-gpios = <&gpio7 9 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
 };
 
 &lcdif {
        status = "okay";
 };
 
-&snvs_pwrkey {
-       status = "disabled";
-};
-
 &uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart1 &pinctrl_uart1_ctrl1 &pinctrl_uart1_ctrl2>;
        vmmc-supply = <&reg_module_3v3>;
        vqmmc-supply = <&reg_DCDC3>;
        non-removable;
+       sdhci-caps-mask = <0x80000000 0x0>;
 };
 
 &iomuxc {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4>;
+       pinctrl-0 = <&pinctrl_gpio1 &pinctrl_gpio2 &pinctrl_gpio3 &pinctrl_gpio4
+                    &pinctrl_gpio7>;
 
        pinctrl_gpio1: gpio1-grp {
                fsl,pins = <
-                       MX7D_PAD_ENET1_RGMII_RD3__GPIO7_IO3     0x74 /* SODIMM 55 */
-                       MX7D_PAD_ENET1_RGMII_RD2__GPIO7_IO2     0x74 /* SODIMM 63 */
                        MX7D_PAD_SAI1_RX_SYNC__GPIO6_IO16       0x14 /* SODIMM 77 */
                        MX7D_PAD_EPDC_DATA09__GPIO2_IO9         0x14 /* SODIMM 89 */
                        MX7D_PAD_EPDC_DATA08__GPIO2_IO8         0x74 /* SODIMM 91 */
                >;
        };
 
+       pinctrl_gpio7: gpio7-grp { /* Alternatively CAN1 */
+               fsl,pins = <
+                       MX7D_PAD_ENET1_RGMII_RD3__GPIO7_IO3     0x14 /* SODIMM 55 */
+                       MX7D_PAD_ENET1_RGMII_RD2__GPIO7_IO2     0x14 /* SODIMM 63 */
+               >;
+       };
+
        pinctrl_i2c1_int: i2c1-int-grp { /* PMIC / TOUCH */
                fsl,pins = <
                        MX7D_PAD_GPIO1_IO13__GPIO1_IO13 0x79
                >;
        };
 
+       pinctrl_enet1_sleep: enet1sleepgrp {
+               fsl,pins = <
+                       MX7D_PAD_ENET1_RGMII_RX_CTL__GPIO7_IO4          0x0
+                       MX7D_PAD_ENET1_RGMII_RD0__GPIO7_IO0             0x0
+                       MX7D_PAD_ENET1_RGMII_RD1__GPIO7_IO1             0x0
+                       MX7D_PAD_ENET1_RGMII_RXC__GPIO7_IO5             0x0
+
+                       MX7D_PAD_ENET1_RGMII_TX_CTL__GPIO7_IO10         0x0
+                       MX7D_PAD_ENET1_RGMII_TD0__GPIO7_IO6             0x0
+                       MX7D_PAD_ENET1_RGMII_TD1__GPIO7_IO7             0x0
+                       MX7D_PAD_GPIO1_IO12__GPIO1_IO12                 0x0
+                       MX7D_PAD_SD2_CD_B__GPIO5_IO9                    0x0
+                       MX7D_PAD_SD2_WP__GPIO5_IO10                     0x0
+               >;
+       };
+
        pinctrl_ecspi3_cs: ecspi3-cs-grp {
                fsl,pins = <
                        MX7D_PAD_I2C2_SDA__GPIO4_IO11           0x14
                >;
        };
 
+       pinctrl_flexcan1: flexcan1-grp {
+               fsl,pins = <
+                       MX7D_PAD_ENET1_RGMII_RD3__FLEXCAN1_TX   0x79 /* SODIMM 55 */
+                       MX7D_PAD_ENET1_RGMII_RD2__FLEXCAN1_RX   0x79 /* SODIMM 63 */
+               >;
+       };
+
        pinctrl_flexcan2: flexcan2-grp {
                fsl,pins = <
-                       MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX        0x59
-                       MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX        0x59
+                       MX7D_PAD_GPIO1_IO14__FLEXCAN2_RX        0x79 /* SODIMM 188 */
+                       MX7D_PAD_GPIO1_IO15__FLEXCAN2_TX        0x79 /* SODIMM 178 */
                >;
        };
 
                >;
        };
 
+       pinctrl_i2c4_recovery: i2c4-recoverygrp {
+               fsl,pins = <
+                       MX7D_PAD_ENET1_RGMII_TD2__GPIO7_IO8     0x4000007f
+                       MX7D_PAD_ENET1_RGMII_TD3__GPIO7_IO9     0x4000007f
+               >;
+       };
+
        pinctrl_lcdif_dat: lcdif-dat-grp {
                fsl,pins = <
                        MX7D_PAD_LCD_DATA00__LCD_DATA0          0x79
                >;
        };
 
+       pinctrl_i2c1_recovery: i2c1-recoverygrp {
+               fsl,pins = <
+                       MX7D_PAD_LPSR_GPIO1_IO04__GPIO1_IO4     0x4000007f
+                       MX7D_PAD_LPSR_GPIO1_IO05__GPIO1_IO5     0x4000007f
+               >;
+       };
+
        pinctrl_cd_usdhc1: usdhc1-cd-grp {
                fsl,pins = <
                        MX7D_PAD_LPSR_GPIO1_IO00__GPIO1_IO0     0x59 /* CD */
index e615674..7646284 100644 (file)
@@ -44,7 +44,7 @@
                          <&clks IMX7D_ENET1_TIME_ROOT_CLK>;
        assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
        assigned-clock-rates = <0>, <100000000>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-handle = <&ethphy0>;
        fsl,magic-packet;
        status = "okay";
                #size-cells = <0>;
 
                ethphy0: ethernet-phy@0 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
                        reg = <0>;
                };
 
                ethphy1: ethernet-phy@1 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
                        reg = <1>;
                };
        };
@@ -70,7 +72,7 @@
                          <&clks IMX7D_ENET2_TIME_ROOT_CLK>;
        assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
        assigned-clock-rates = <0>, <100000000>;
-       phy-mode = "rgmii";
+       phy-mode = "rgmii-id";
        phy-handle = <&ethphy1>;
        fsl,magic-packet;
        status = "okay";
diff --git a/arch/arm/boot/dts/imx7d-zii-rmu2.dts b/arch/arm/boot/dts/imx7d-zii-rmu2.dts
new file mode 100644 (file)
index 0000000..2b8d6cc
--- /dev/null
@@ -0,0 +1,357 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Device tree file for ZII's RMU2 board
+ *
+ * RMU - Remote Modem Unit
+ *
+ * Copyright (C) 2019 Zodiac Inflight Innovations
+ */
+
+/dts-v1/;
+#include <dt-bindings/thermal/thermal.h>
+#include "imx7d.dtsi"
+
+/ {
+       model = "ZII RMU2 Board";
+       compatible = "zii,imx7d-rmu2", "fsl,imx7d";
+
+       chosen {
+               stdout-path = &uart2;
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+               pinctrl-0 = <&pinctrl_leds_debug>;
+               pinctrl-names = "default";
+
+               debug {
+                       label = "zii:green:debug1";
+                       gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+};
+
+&cpu0 {
+       arm-supply = <&sw1a_reg>;
+};
+
+&ecspi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       cs-gpios = <&gpio4 19 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               spi-max-frequency = <20000000>;
+               reg = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet1>;
+       assigned-clocks = <&clks IMX7D_ENET1_TIME_ROOT_SRC>,
+                         <&clks IMX7D_ENET1_TIME_ROOT_CLK>;
+       assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>;
+       assigned-clock-rates = <0>, <100000000>;
+       phy-mode = "rgmii";
+       phy-handle = <&fec1_phy>;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               fec1_phy: ethernet-phy@0 {
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_enet1_phy_reset>,
+                                   <&pinctrl_enet1_phy_interrupt>;
+                       reg = <0>;
+                       interrupt-parent = <&gpio1>;
+                       interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
+                       reset-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>;
+               };
+       };
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pmic@8 {
+               compatible = "fsl,pfuze3000";
+               reg = <0x08>;
+
+               regulators {
+                       sw1a_reg: sw1a {
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <3300000>;
+                               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>;
+                               regulator-always-on;
+                       };
+
+                       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;
+                       };
+               };
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c04";
+               reg = <0x50>;
+       };
+
+       eeprom@52 {
+               compatible = "atmel,24c04";
+               reg = <0x52>;
+       };
+};
+
+&snvs_rtc {
+       status = "disabled";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       assigned-clocks = <&clks IMX7D_UART2_ROOT_SRC>;
+       assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>;
+       status = "okay";
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       assigned-clocks = <&clks IMX7D_UART4_ROOT_SRC>;
+       assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>;
+       status = "okay";
+
+       rave-sp {
+               compatible = "zii,rave-sp-rdu2";
+               current-speed = <1000000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               watchdog {
+                       compatible = "zii,rave-sp-watchdog";
+               };
+
+               eeprom@a3 {
+                       compatible = "zii,rave-sp-eeprom";
+                       reg = <0xa3 0x4000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       zii,eeprom-name = "main-eeprom";
+               };
+       };
+};
+
+&usbotg2 {
+       dr_mode = "host";
+       disable-over-current;
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       bus-width = <4>;
+       no-1-8-v;
+       no-sdio;
+       keep-power-in-suspend;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       bus-width = <8>;
+       no-1-8-v;
+       non-removable;
+       no-sdio;
+       no-sd;
+       keep-power-in-suspend;
+       status = "okay";
+};
+
+&wdog1 {
+       status = "disabled";
+};
+
+&iomuxc {
+       pinctrl_ecspi1: ecspi1grp {
+               fsl,pins = <
+                       MX7D_PAD_ECSPI1_SCLK__ECSPI1_SCLK       0x2
+                       MX7D_PAD_ECSPI1_MOSI__ECSPI1_MOSI       0x2
+                       MX7D_PAD_ECSPI1_MISO__ECSPI1_MISO       0x2
+                       MX7D_PAD_ECSPI1_SS0__GPIO4_IO19         0x59
+               >;
+       };
+
+       pinctrl_enet1: enet1grp {
+               fsl,pins = <
+                       MX7D_PAD_SD2_CD_B__ENET1_MDIO                           0x3
+                       MX7D_PAD_SD2_WP__ENET1_MDC                              0x3
+                       MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC               0x1
+                       MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0               0x1
+                       MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1               0x1
+                       MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2               0x1
+                       MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3               0x1
+                       MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL         0x1
+                       MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC               0x1
+                       MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0               0x1
+                       MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1               0x1
+                       MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2               0x1
+                       MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3               0x1
+                       MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL         0x1
+               >;
+       };
+
+       pinctrl_enet1_phy_reset: enet1phyresetgrp {
+               fsl,pins = <
+                       MX7D_PAD_SD2_RESET_B__GPIO5_IO11        0x14
+
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX7D_PAD_I2C1_SDA__I2C1_SDA             0x4000007f
+                       MX7D_PAD_I2C1_SCL__I2C1_SCL             0x4000007f
+               >;
+       };
+
+       pinctrl_leds_debug: ledsgrp {
+               fsl,pins = <
+                       MX7D_PAD_EPDC_DATA08__GPIO2_IO8         0x59
+               >;
+       };
+
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX7D_PAD_UART2_RX_DATA__UART2_DCE_RX    0x79
+                       MX7D_PAD_UART2_TX_DATA__UART2_DCE_TX    0x79
+               >;
+       };
+
+       pinctrl_uart4: uart4grp {
+               fsl,pins = <
+                       MX7D_PAD_SD2_DATA0__UART4_DCE_RX        0x79
+                       MX7D_PAD_SD2_DATA1__UART4_DCE_TX        0x79
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX7D_PAD_SD1_CMD__SD1_CMD               0x59
+                       MX7D_PAD_SD1_CLK__SD1_CLK               0x19
+                       MX7D_PAD_SD1_DATA0__SD1_DATA0           0x59
+                       MX7D_PAD_SD1_DATA1__SD1_DATA1           0x59
+                       MX7D_PAD_SD1_DATA2__SD1_DATA2           0x59
+                       MX7D_PAD_SD1_DATA3__SD1_DATA3           0x59
+               >;
+       };
+
+       pinctrl_usdhc3: usdhc3grp {
+               fsl,pins = <
+                       MX7D_PAD_SD3_CMD__SD3_CMD               0x59
+                       MX7D_PAD_SD3_CLK__SD3_CLK               0x19
+                       MX7D_PAD_SD3_DATA0__SD3_DATA0           0x59
+                       MX7D_PAD_SD3_DATA1__SD3_DATA1           0x59
+                       MX7D_PAD_SD3_DATA2__SD3_DATA2           0x59
+                       MX7D_PAD_SD3_DATA3__SD3_DATA3           0x59
+                       MX7D_PAD_SD3_DATA4__SD3_DATA4           0x59
+                       MX7D_PAD_SD3_DATA5__SD3_DATA5           0x59
+                       MX7D_PAD_SD3_DATA6__SD3_DATA6           0x59
+                       MX7D_PAD_SD3_DATA7__SD3_DATA7           0x59
+                       MX7D_PAD_SD3_RESET_B__SD3_RESET_B       0x59
+               >;
+       };
+};
+
+&iomuxc_lpsr {
+       pinctrl_enet1_phy_interrupt: enet1phyinterruptgrp {
+               fsl,phy = <
+                       MX7D_PAD_LPSR_GPIO1_IO02__GPIO1_IO2     0x08
+               >;
+       };
+};
index 4a78ddc..39812c9 100644 (file)
        status = "disabled";
 };
 
-&snvs_pwrkey {
-       status = "disabled";
-};
-
 &iomuxc {
        pinctrl_ecspi1: ecspi1grp {
                fsl,pins = <
index 42528d2..9c8dd32 100644 (file)
                        <&clks IMX7D_ENET_PHY_REF_ROOT_CLK>;
                clock-names = "ipg", "ahb", "ptp",
                        "enet_clk_ref", "enet_out";
-               fsl,num-tx-queues=<3>;
-               fsl,num-rx-queues=<3>;
+               fsl,num-tx-queues = <3>;
+               fsl,num-rx-queues = <3>;
                status = "disabled";
        };
 
index c1a4fff..710f850 100644 (file)
                compatible = "fsl,imx7d-tempmon";
                interrupt-parent = <&gpc>;
                interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
-               fsl,tempmon =<&anatop>;
+               fsl,tempmon = <&anatop>;
                nvmem-cells = <&tempmon_calib>,
                        <&tempmon_temp_grade>;
                nvmem-cell-names = "calib", "temp_grade";
                                        <&clks IMX7D_ENET_PHY_REF_ROOT_CLK>;
                                clock-names = "ipg", "ahb", "ptp",
                                        "enet_clk_ref", "enet_out";
-                               fsl,num-tx-queues=<3>;
-                               fsl,num-rx-queues=<3>;
+                               fsl,num-tx-queues = <3>;
+                               fsl,num-rx-queues = <3>;
                                status = "disabled";
                        };
                };
index 56907bb..6859a3a 100644 (file)
                reg = <0x40000000 0x800000>;
                ranges;
 
+               edma1: dma-controller@40080000 {
+                       #dma-cells = <2>;
+                       compatible = "fsl,imx7ulp-edma";
+                       reg = <0x40080000 0x2000>,
+                               <0x40210000 0x1000>;
+                       dma-channels = <32>;
+                       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 16 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-names = "dma", "dmamux0";
+                       clocks = <&pcc2 IMX7ULP_CLK_DMA1>,
+                                <&pcc2 IMX7ULP_CLK_DMA_MUX1>;
+               };
+
                crypto: crypto@40240000 {
                        compatible = "fsl,sec-v4.0";
                        #address-cells = <1>;
                        clocks = <&scg1 IMX7ULP_CLK_NIC1_BUS_DIV>,
                                 <&scg1 IMX7ULP_CLK_NIC1_DIV>,
                                 <&pcc2 IMX7ULP_CLK_USDHC0>;
-                       clock-names ="ipg", "ahb", "per";
+                       clock-names = "ipg", "ahb", "per";
                        assigned-clocks = <&pcc2 IMX7ULP_CLK_USDHC0>;
                        assigned-clock-parents = <&scg1 IMX7ULP_CLK_NIC1_DIV>;
                        bus-width = <4>;
                        fsl,tuning-start-tap = <20>;
-                       fsl,tuning-step= <2>;
+                       fsl,tuning-step = <2>;
                        status = "disabled";
                };
 
                        clocks = <&scg1 IMX7ULP_CLK_NIC1_BUS_DIV>,
                                 <&scg1 IMX7ULP_CLK_NIC1_DIV>,
                                 <&pcc2 IMX7ULP_CLK_USDHC1>;
-                       clock-names ="ipg", "ahb", "per";
+                       clock-names = "ipg", "ahb", "per";
                        assigned-clocks = <&pcc2 IMX7ULP_CLK_USDHC1>;
                        assigned-clock-parents = <&scg1 IMX7ULP_CLK_NIC1_DIV>;
                        bus-width = <4>;
                        fsl,tuning-start-tap = <20>;
-                       fsl,tuning-step= <2>;
+                       fsl,tuning-step = <2>;
                        status = "disabled";
                };
 
index a88eb22..994cabc 100644 (file)
 &pcie0 {
        status = "okay";
 };
+
+&rtc {
+       /*
+        * There is a s35390a available on the i2c bus, the internal rtc isn't
+        * working (probably no crystal assembled).
+        */
+       status = "disabled";
+};
index 96d239d..bed1dfe 100644 (file)
                 */
                vin-supply = <&vcc_3v3>;
        };
+
+       vddee: regulator-vddee {
+               /*
+                * Silergy SY8089AAC-GP 2A continuous, 3A peak, 1MHz
+                * Synchronous Step Down Regulator. Also called VDDAO
+                * in a part of the schematics.
+                */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDEE";
+               regulator-min-microvolt = <860000>;
+               regulator-max-microvolt = <1140000>;
+
+               vin-supply = <&vcc_5v>;
+
+               pwms = <&pwm_cd 1 1148 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
 };
 
 &cpu0 {
        };
 };
 
+&mali {
+       mali-supply = <&vddee>;
+};
+
 &saradc {
        status = "okay";
        vref-supply = <&vcc_1v8>;
 
 &pwm_cd {
        status = "okay";
-       pinctrl-0 = <&pwm_c1_pins>;
+       pinctrl-0 = <&pwm_c1_pins>, <&pwm_d_pins>;
        pinctrl-names = "default";
-       clocks = <&clkc CLKID_XTAL>;
-       clock-names = "clkin0";
+       clocks = <&clkc CLKID_XTAL>, <&clkc CLKID_XTAL>;
+       clock-names = "clkin0", "clkin1";
 };
 
 &rtc {
index bb27b34..6e39ad5 100644 (file)
                regulator-boot-on;
                regulator-always-on;
        };
+
+       vddee: regulator-vddee {
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDEE";
+               regulator-min-microvolt = <860000>;
+               regulator-max-microvolt = <1140000>;
+
+               vin-supply = <&vcc_5v>;
+
+               pwms = <&pwm_cd 1 1148 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
 };
 
 &cpu0 {
        };
 };
 
+&mali {
+       mali-supply = <&vddee>;
+};
+
 &saradc {
        status = "okay";
        vref-supply = <&vcc_1v8>;
 
 &pwm_cd {
        status = "okay";
-       pinctrl-0 = <&pwm_c1_pins>;
+       pinctrl-0 = <&pwm_c1_pins>, <&pwm_d_pins>;
        pinctrl-names = "default";
-       clocks = <&clkc CLKID_XTAL>;
-       clock-names = "clkin0";
+       clocks = <&clkc CLKID_XTAL>, <&clkc CLKID_XTAL>;
+       clock-names = "clkin0", "clkin1";
 };
 
 &uart_AO {
index 86c4614..a24eccc 100644 (file)
                vin-supply = <&p5v0>;
        };
 
+       vddee: regulator-vddee {
+               /* Monolithic Power Systems MP2161 */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDEE";
+               regulator-min-microvolt = <860000>;
+               regulator-max-microvolt = <1140000>;
+
+               vin-supply = <&p5v0>;
+
+               pwms = <&pwm_cd 1 12218 0>;
+               pwm-dutycycle-range = <91 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
        vdd_rtc: regulator-vdd-rtc {
                /*
                 * Torex Semiconductor XC6215 configured for a fixed output of
        cpu-supply = <&vcck>;
 };
 
+&efuse {
+       ethernet_mac_address: mac@1b4 {
+               reg = <0x1b4 0x6>;
+       };
+};
+
 &ethmac {
        status = "okay";
 
        phy-handle = <&eth_phy>;
        amlogic,tx-delay-ns = <4>;
 
+       nvmem-cells = <&ethernet_mac_address>;
+       nvmem-cell-names = "mac-address";
+
        mdio {
                compatible = "snps,dwmac-mdio";
                #address-cells = <1>;
        pinctrl-names = "default";
 };
 
+&mali {
+       mali-supply = <&vddee>;
+};
+
 &saradc {
        status = "okay";
        vref-supply = <&vcc_1v8>;
 
 &pwm_cd {
        status = "okay";
-       pinctrl-0 = <&pwm_c1_pins>;
+       pinctrl-0 = <&pwm_c1_pins>, <&pwm_d_pins>;
        pinctrl-names = "default";
-       clocks = <&clkc CLKID_XTAL>;
-       clock-names = "clkin0";
+       clocks = <&clkc CLKID_XTAL>, <&clkc CLKID_XTAL>;
+       clock-names = "clkin0", "clkin1";
 };
 
 &rtc {
index fba2c70..099bf8e 100644 (file)
                        };
                };
 
+               pwm_d_pins: pwm-d {
+                       mux {
+                               groups = "pwm_d";
+                               function = "pwm_d";
+                               bias-disable;
+                       };
+               };
+
                uart_b0_pins: uart-b0 {
                        mux {
                                groups = "uart_tx_b0",
                 <&clkc CLKID_MPLL2>,
                 <&clkc CLKID_MPLL2>;
        clock-names = "stmmaceth", "clkin0", "clkin1";
+       rx-fifo-depth = <4096>;
+       tx-fifo-depth = <2048>;
 
        resets = <&reset RESET_ETHERNET>;
        reset-names = "stmmaceth";
diff --git a/arch/arm/boot/dts/mt7629-rfb.dts b/arch/arm/boot/dts/mt7629-rfb.dts
new file mode 100644 (file)
index 0000000..3621b7d
--- /dev/null
@@ -0,0 +1,263 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include "mt7629.dtsi"
+
+/ {
+       model = "MediaTek MT7629 reference board";
+       compatible = "mediatek,mt7629-rfb", "mediatek,mt7629";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               reset {
+                       label = "factory";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&pio 60 GPIO_ACTIVE_LOW>;
+               };
+
+               wps {
+                       label = "wps";
+                       linux,code = <KEY_WPS_BUTTON>;
+                       gpios = <&pio 58 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0x40000000 0x10000000>;
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       reg_5v: regulator-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+};
+
+&eth {
+       pinctrl-names = "default";
+       pinctrl-0 = <&eth_pins>;
+       pinctrl-1 = <&ephy_leds_pins>;
+       status = "okay";
+
+       gmac1: mac@1 {
+               compatible = "mediatek,eth-mac";
+               reg = <1>;
+               phy-handle = <&phy0>;
+       };
+
+       mdio: mdio-bus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               phy0: ethernet-phy@0 {
+                       reg = <0>;
+                       phy-mode = "gmii";
+               };
+       };
+};
+
+&i2c {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c_pins>;
+       status = "okay";
+};
+
+&qspi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&qspi_pins>;
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               label = "u-boot";
+                               reg = <0x00000 0x60000>;
+                               read-only;
+                       };
+
+                       partition@60000 {
+                               label = "u-boot-env";
+                               reg = <0x60000 0x10000>;
+                               read-only;
+                       };
+
+                       factory: partition@70000 {
+                               label = "factory";
+                               reg = <0x70000 0x40000>;
+                               read-only;
+                       };
+
+                       partition@b0000 {
+                               label = "kernel";
+                               reg = <0xb0000 0xb50000>;
+                       };
+               };
+       };
+};
+
+&pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie_pins>;
+};
+
+&pciephy1 {
+       status = "okay";
+};
+
+&pio {
+       eth_pins: eth-pins {
+               mux {
+                       function = "eth";
+                       groups = "mdc_mdio";
+               };
+       };
+
+       ephy_leds_pins: ephy-leds-pins {
+               mux {
+                       function = "led";
+                       groups = "gphy_leds_0", "ephy_leds";
+               };
+       };
+
+       i2c_pins: i2c-pins {
+               mux {
+                       function = "i2c";
+                       groups =  "i2c_0";
+               };
+
+               conf {
+                       pins = "I2C_SDA", "I2C_SCL";
+                       drive-strength = <4>;
+                       bias-disable;
+               };
+       };
+
+       pcie_pins: pcie-pins {
+               mux {
+                       function = "pcie";
+                       groups = "pcie_clkreq",
+                                "pcie_pereset",
+                                "pcie_wake";
+               };
+       };
+
+       pwm_pins: pwm-pins {
+               mux {
+                       function = "pwm";
+                       groups = "pwm_0";
+               };
+       };
+
+       /* SPI-NOR is shared pin with serial NAND */
+       qspi_pins: qspi-pins {
+               mux {
+                       function = "flash";
+                       groups = "spi_nor";
+               };
+       };
+
+       /* Serial NAND is shared pin with SPI-NOR */
+       serial_nand_pins: serial-nand-pins {
+               mux {
+                       function = "flash";
+                       groups = "snfi";
+               };
+       };
+
+       spi_pins: spi-pins {
+               mux {
+                       function = "spi";
+                       groups = "spi_0";
+               };
+       };
+
+       uart0_pins: uart0-pins {
+               mux {
+                       function = "uart";
+                       groups = "uart0_txd_rxd" ;
+               };
+       };
+
+       uart1_pins: uart1-pins {
+               mux {
+                       function = "uart";
+                       groups = "uart1_0_tx_rx" ;
+               };
+       };
+
+       uart2_pins: uart2-pins {
+               mux {
+                       function = "uart";
+                       groups = "uart2_0_txd_rxd" ;
+               };
+       };
+
+       watchdog_pins: watchdog-pins {
+               mux {
+                       function = "watchdog";
+                       groups = "watchdog";
+               };
+       };
+};
+
+&spi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&spi_pins>;
+       status = "okay";
+};
+
+&ssusb {
+       vusb33-supply = <&reg_3p3v>;
+       vbus-supply = <&reg_5v>;
+       status = "okay";
+};
+
+&u3phy0 {
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pins>;
+       status = "okay";
+};
+
+&watchdog {
+       pinctrl-names = "default";
+       pinctrl-0 = <&watchdog_pins>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/mt7629.dtsi b/arch/arm/boot/dts/mt7629.dtsi
new file mode 100644 (file)
index 0000000..9608bc2
--- /dev/null
@@ -0,0 +1,481 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ *
+ * Author: Ryder Lee <ryder.lee@mediatek.com>
+ */
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/mt7629-clk.h>
+#include <dt-bindings/power/mt7622-power.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/reset/mt7629-resets.h>
+
+/ {
+       compatible = "mediatek,mt7629";
+       interrupt-parent = <&sysirq>;
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               enable-method = "mediatek,mt6589-smp";
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0x0>;
+                       clock-frequency = <1250000000>;
+                       cci-control-port = <&cci_control2>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a7";
+                       reg = <0x1>;
+                       clock-frequency = <1250000000>;
+                       cci-control-port = <&cci_control2>;
+               };
+       };
+
+       pmu {
+               compatible = "arm,cortex-a7-pmu";
+               interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_SPI 9 IRQ_TYPE_LEVEL_LOW>;
+               interrupt-affinity = <&cpu0>, <&cpu1>;
+       };
+
+       clk20m: oscillator-0 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <20000000>;
+               clock-output-names = "clk20m";
+       };
+
+       clk40m: oscillator-1 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <40000000>;
+               clock-output-names = "clkxtal";
+       };
+
+       timer {
+               compatible = "arm,armv7-timer";
+               interrupt-parent = <&gic>;
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+               clock-frequency = <20000000>;
+       };
+
+       soc {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               infracfg: syscon@10000000 {
+                       compatible = "mediatek,mt7629-infracfg", "syscon";
+                       reg = <0x10000000 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               pericfg: syscon@10002000 {
+                       compatible = "mediatek,mt7629-pericfg", "syscon";
+                       reg = <0x10002000 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               scpsys: scpsys@10006000 {
+                       compatible = "mediatek,mt7629-scpsys",
+                                    "mediatek,mt7622-scpsys";
+                       #power-domain-cells = <1>;
+                       reg = <0x10006000 0x1000>;
+                       clocks = <&topckgen CLK_TOP_HIF_SEL>;
+                       clock-names = "hif_sel";
+                       assigned-clocks = <&topckgen CLK_TOP_HIF_SEL>;
+                       assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>;
+                       infracfg = <&infracfg>;
+               };
+
+               timer: timer@10009000 {
+                       compatible = "mediatek,mt7629-timer",
+                                    "mediatek,mt6765-timer";
+                       reg = <0x10009000 0x60>;
+                       interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clk20m>;
+                       clock-names = "clk20m";
+               };
+
+               sysirq: interrupt-controller@10200a80 {
+                       compatible = "mediatek,mt7629-sysirq",
+                                    "mediatek,mt6577-sysirq";
+                       reg = <0x10200a80 0x20>;
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       interrupt-parent = <&gic>;
+               };
+
+               apmixedsys: syscon@10209000 {
+                       compatible = "mediatek,mt7629-apmixedsys", "syscon";
+                       reg = <0x10209000 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               rng: rng@1020f000 {
+                       compatible = "mediatek,mt7629-rng",
+                                    "mediatek,mt7623-rng";
+                       reg = <0x1020f000 0x100>;
+                       clocks = <&infracfg CLK_INFRA_TRNG_PD>;
+                       clock-names = "rng";
+               };
+
+               topckgen: syscon@10210000 {
+                       compatible = "mediatek,mt7629-topckgen", "syscon";
+                       reg = <0x10210000 0x1000>;
+                       #clock-cells = <1>;
+               };
+
+               watchdog: watchdog@10212000 {
+                       compatible = "mediatek,mt7629-wdt",
+                                    "mediatek,mt6589-wdt";
+                       reg = <0x10212000 0x100>;
+               };
+
+               pio: pinctrl@10217000 {
+                       compatible = "mediatek,mt7629-pinctrl";
+                       reg = <0x10217000 0x8000>,
+                             <0x10005000 0x1000>;
+                       reg-names = "base", "eint";
+                       gpio-controller;
+                       gpio-ranges = <&pio 0 0 79>;
+                       #gpio-cells = <2>;
+                       #interrupt-cells = <2>;
+                       interrupt-controller;
+                       interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-parent = <&gic>;
+               };
+
+               gic: interrupt-controller@10300000 {
+                       compatible = "arm,gic-400";
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       interrupt-parent = <&gic>;
+                       reg = <0x10310000 0x1000>,
+                             <0x10320000 0x1000>,
+                             <0x10340000 0x2000>,
+                             <0x10360000 0x2000>;
+               };
+
+               cci: cci@10390000 {
+                       compatible = "arm,cci-400";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x10390000 0x1000>;
+                       ranges = <0 0x10390000 0x10000>;
+
+                       cci_control0: slave-if@1000 {
+                               compatible = "arm,cci-400-ctrl-if";
+                               interface-type = "ace-lite";
+                               reg = <0x1000 0x1000>;
+                       };
+
+                       cci_control1: slave-if@4000 {
+                               compatible = "arm,cci-400-ctrl-if";
+                               interface-type = "ace";
+                               reg = <0x4000 0x1000>;
+                       };
+
+                       cci_control2: slave-if@5000 {
+                               compatible = "arm,cci-400-ctrl-if";
+                               interface-type = "ace";
+                               reg = <0x5000 0x1000>;
+                       };
+
+                       pmu@9000 {
+                               compatible = "arm,cci-400-pmu,r1";
+                               reg = <0x9000 0x5000>;
+                               interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>;
+                       };
+               };
+
+               uart0: serial@11002000 {
+                       compatible = "mediatek,mt7629-uart",
+                                    "mediatek,mt6577-uart";
+                       reg = <0x11002000 0x400>;
+                       interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&topckgen CLK_TOP_UART_SEL>,
+                                <&pericfg CLK_PERI_UART0_PD>;
+                       clock-names = "baud", "bus";
+                       status = "disabled";
+               };
+
+               uart1: serial@11003000 {
+                       compatible = "mediatek,mt7629-uart",
+                                    "mediatek,mt6577-uart";
+                       reg = <0x11003000 0x400>;
+                       interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&topckgen CLK_TOP_UART_SEL>,
+                                <&pericfg CLK_PERI_UART1_PD>;
+                       clock-names = "baud", "bus";
+                       status = "disabled";
+               };
+
+               uart2: serial@11004000 {
+                       compatible = "mediatek,mt7629-uart",
+                                    "mediatek,mt6577-uart";
+                       reg = <0x11004000 0x400>;
+                       interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&topckgen CLK_TOP_UART_SEL>,
+                                <&pericfg CLK_PERI_UART2_PD>;
+                       clock-names = "baud", "bus";
+                       status = "disabled";
+               };
+
+               i2c: i2c@11007000 {
+                       compatible = "mediatek,mt7629-i2c",
+                                    "mediatek,mt2712-i2c";
+                       reg = <0x11007000 0x90>,
+                             <0x11000100 0x80>;
+                       interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>;
+                       clock-div = <4>;
+                       clocks = <&pericfg CLK_PERI_I2C0_PD>,
+                                <&pericfg CLK_PERI_AP_DMA_PD>;
+                       clock-names = "main", "dma";
+                       assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>;
+                       assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               spi: spi@1100a000 {
+                       compatible = "mediatek,mt7629-spi",
+                                    "mediatek,mt7622-spi";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x1100a000 0x100>;
+                       interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&topckgen CLK_TOP_SYSPLL3_D2>,
+                                <&topckgen CLK_TOP_SPI0_SEL>,
+                                <&pericfg CLK_PERI_SPI0_PD>;
+                       clock-names = "parent-clk", "sel-clk", "spi-clk";
+                       status = "disabled";
+               };
+
+               qspi: spi@11014000 {
+                       compatible = "mediatek,mt7629-nor",
+                                    "mediatek,mt8173-nor";
+                       reg = <0x11014000 0xe0>;
+                       clocks = <&pericfg CLK_PERI_FLASH_PD>,
+                                <&topckgen CLK_TOP_FLASH_SEL>;
+                       clock-names = "spi", "sf";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               ssusbsys: syscon@1a000000 {
+                       compatible = "mediatek,mt7629-ssusbsys", "syscon";
+                       reg = <0x1a000000 0x1000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+               };
+
+               ssusb: usb@1a0c0000 {
+                       compatible = "mediatek,mt7629-xhci",
+                                    "mediatek,mtk-xhci";
+                       reg = <0x1a0c0000 0x01000>,
+                             <0x1a0c3e00 0x0100>;
+                       reg-names = "mac", "ippc";
+                       interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&ssusbsys CLK_SSUSB_SYS_EN>,
+                                <&ssusbsys CLK_SSUSB_REF_EN>,
+                                <&ssusbsys CLK_SSUSB_MCU_EN>,
+                                <&ssusbsys CLK_SSUSB_DMA_EN>;
+                       clock-names = "sys_ck", "ref_ck", "mcu_ck", "dma_ck";
+                       assigned-clocks = <&topckgen CLK_TOP_AXI_SEL>,
+                                         <&topckgen CLK_TOP_SATA_SEL>,
+                                         <&topckgen CLK_TOP_HIF_SEL>;
+                       assigned-clock-parents = <&topckgen CLK_TOP_SYSPLL1_D2>,
+                                                <&topckgen CLK_TOP_UNIVPLL2_D4>,
+                                                <&topckgen CLK_TOP_UNIVPLL1_D2>;
+                       power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF1>;
+                       phys = <&u2port0 PHY_TYPE_USB2>,
+                              <&u3port0 PHY_TYPE_USB3>;
+                       status = "disabled";
+               };
+
+               u3phy0: usb-phy@1a0c4000 {
+                       compatible = "mediatek,generic-tphy-v2";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x1a0c4000 0xe00>;
+                       status = "disabled";
+
+                       u2port0: usb-phy@0 {
+                               reg = <0 0x700>;
+                               clocks = <&ssusbsys CLK_SSUSB_U2_PHY_EN>;
+                               clock-names = "ref";
+                               #phy-cells = <1>;
+                               status = "okay";
+                       };
+
+                       u3port0: usb-phy@700 {
+                               reg = <0x700 0x700>;
+                               clocks = <&clk20m>;
+                               clock-names = "ref";
+                               #phy-cells = <1>;
+                               status = "okay";
+                       };
+               };
+
+               pciesys: syscon@1a100800 {
+                       compatible = "mediatek,mt7629-pciesys", "syscon";
+                       reg = <0x1a100800 0x1000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+               };
+
+               pcie: pcie@1a140000 {
+                       compatible = "mediatek,mt7629-pcie";
+                       device_type = "pci";
+                       reg = <0x1a140000 0x1000>,
+                             <0x1a145000 0x1000>;
+                       reg-names = "subsys","port1";
+                       #address-cells = <3>;
+                       #size-cells = <2>;
+                       interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_LOW>,
+                                    <GIC_SPI 229 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&pciesys CLK_PCIE_P1_MAC_EN>,
+                                <&pciesys CLK_PCIE_P0_AHB_EN>,
+                                <&pciesys CLK_PCIE_P1_AUX_EN>,
+                                <&pciesys CLK_PCIE_P1_AXI_EN>,
+                                <&pciesys CLK_PCIE_P1_OBFF_EN>,
+                                <&pciesys CLK_PCIE_P1_PIPE_EN>;
+                       clock-names = "sys_ck1", "ahb_ck1",
+                                     "aux_ck1", "axi_ck1",
+                                     "obff_ck1", "pipe_ck1";
+                       assigned-clocks = <&topckgen CLK_TOP_SATA_SEL>,
+                                         <&topckgen CLK_TOP_AXI_SEL>,
+                                         <&topckgen CLK_TOP_HIF_SEL>;
+                       assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL2_D4>,
+                                                <&topckgen CLK_TOP_SYSPLL1_D2>,
+                                                <&topckgen CLK_TOP_UNIVPLL1_D2>;
+                       phys = <&pcieport1 PHY_TYPE_PCIE>;
+                       phy-names = "pcie-phy1";
+                       power-domains = <&scpsys MT7622_POWER_DOMAIN_HIF0>;
+                       bus-range = <0x00 0xff>;
+                       ranges = <0x82000000 0 0x20000000 0x20000000 0 0x10000000>;
+
+                       pcie1: pcie@1,0 {
+                               device_type = "pci";
+                               reg = <0x0800 0 0 0 0>;
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               #interrupt-cells = <1>;
+                               ranges;
+                               num-lanes = <1>;
+                               interrupt-map-mask = <0 0 0 7>;
+                               interrupt-map = <0 0 0 1 &pcie_intc1 0>,
+                                               <0 0 0 2 &pcie_intc1 1>,
+                                               <0 0 0 3 &pcie_intc1 2>,
+                                               <0 0 0 4 &pcie_intc1 3>;
+
+                               pcie_intc1: interrupt-controller {
+                                       interrupt-controller;
+                                       #address-cells = <0>;
+                                       #interrupt-cells = <1>;
+                               };
+                       };
+               };
+
+               pciephy1: pcie-phy@1a14a000 {
+                       compatible = "mediatek,generic-tphy-v2";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x1a14a000 0x1000>;
+                       status = "disabled";
+
+                       pcieport1: port1phy@0 {
+                               reg = <0 0x1000>;
+                               clocks = <&clk20m>;
+                               clock-names = "ref";
+                               #phy-cells = <1>;
+                               status = "okay";
+                       };
+               };
+
+               ethsys: syscon@1b000000 {
+                       compatible = "mediatek,mt7629-ethsys", "syscon";
+                       reg = <0x1b000000 0x1000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+               };
+
+               eth: ethernet@1b100000 {
+                       compatible = "mediatek,mt7629-eth","syscon";
+                       reg = <0x1b100000 0x20000>;
+                       interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_LOW>,
+                                    <GIC_SPI 224 IRQ_TYPE_LEVEL_LOW>,
+                                    <GIC_SPI 225 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&topckgen CLK_TOP_ETH_SEL>,
+                                <&topckgen CLK_TOP_F10M_REF_SEL>,
+                                <&ethsys CLK_ETH_ESW_EN>,
+                                <&ethsys CLK_ETH_GP0_EN>,
+                                <&ethsys CLK_ETH_GP1_EN>,
+                                <&ethsys CLK_ETH_GP2_EN>,
+                                <&ethsys CLK_ETH_FE_EN>,
+                                <&sgmiisys0 CLK_SGMII_TX_EN>,
+                                <&sgmiisys0 CLK_SGMII_RX_EN>,
+                                <&sgmiisys0 CLK_SGMII_CDR_REF>,
+                                <&sgmiisys0 CLK_SGMII_CDR_FB>,
+                                <&sgmiisys1 CLK_SGMII_TX_EN>,
+                                <&sgmiisys1 CLK_SGMII_RX_EN>,
+                                <&sgmiisys1 CLK_SGMII_CDR_REF>,
+                                <&sgmiisys1 CLK_SGMII_CDR_FB>,
+                                <&apmixedsys CLK_APMIXED_SGMIPLL>,
+                                <&apmixedsys CLK_APMIXED_ETH2PLL>;
+                       clock-names = "ethif", "sgmiitop", "esw", "gp0", "gp1",
+                                     "gp2", "fe", "sgmii_tx250m", "sgmii_rx250m",
+                                     "sgmii_cdr_ref", "sgmii_cdr_fb",
+                                     "sgmii2_tx250m", "sgmii2_rx250m",
+                                     "sgmii2_cdr_ref", "sgmii2_cdr_fb",
+                                     "sgmii_ck", "eth2pll";
+                       assigned-clocks = <&topckgen CLK_TOP_ETH_SEL>,
+                                         <&topckgen CLK_TOP_F10M_REF_SEL>;
+                       assigned-clock-parents = <&topckgen CLK_TOP_UNIVPLL1_D2>,
+                                                <&topckgen CLK_TOP_SGMIIPLL_D2>;
+                       power-domains = <&scpsys MT7622_POWER_DOMAIN_ETHSYS>;
+                       mediatek,ethsys = <&ethsys>;
+                       mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
+                       mediatek,infracfg = <&infracfg>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               sgmiisys0: syscon@1b128000 {
+                       compatible = "mediatek,mt7629-sgmiisys", "syscon";
+                       reg = <0x1b128000 0x3000>;
+                       #clock-cells = <1>;
+                       mediatek,physpeed = "2500";
+               };
+
+               sgmiisys1: syscon@1b130000 {
+                       compatible = "mediatek,mt7629-sgmiisys", "syscon";
+                       reg = <0x1b130000 0x3000>;
+                       #clock-cells = <1>;
+                       mediatek,physpeed = "2500";
+               };
+       };
+};
index c53f427..41744cc 100644 (file)
@@ -8,7 +8,11 @@
 /include/ "nspire.dtsi"
 
 &lcd {
-       lcd-type = "classic";
+       port {
+               clcd_pads: endpoint {
+                       remote-endpoint = <&panel_in>;
+               };
+       };
 };
 
 &fast_timer {
                        #interrupt-cells = <1>;
                };
        };
+
+       panel {
+               compatible = "ti,nspire-classic-lcd-panel";
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&clcd_pads>;
+                       };
+               };
+       };
        chosen {
                bootargs = "debug earlyprintk console=tty0 console=ttyS0,115200n8 root=/dev/ram0";
        };
index da95c37..0c16b04 100644 (file)
@@ -9,7 +9,11 @@
 /include/ "nspire.dtsi"
 
 &lcd {
-       lcd-type = "cx";
+       port {
+               clcd_pads: endpoint {
+                       remote-endpoint = <&panel_in>;
+               };
+       };
 };
 
 &fast_timer {
                        };
                };
        };
+
+       panel {
+               compatible = "ti,nspire-cx-lcd-panel";
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&clcd_pads>;
+                       };
+               };
+       };
        chosen {
                bootargs = "debug earlyprintk console=tty0 console=ttyAMA0,115200n8 root=/dev/ram0";
        };
index c35fd66..d9a0fd7 100644 (file)
                        reg = <0xC0000000 0x1000>;
                        interrupts = <21>;
 
-                       clocks = <&apb_pclk>;
-                       clock-names = "apb_pclk";
+                       /*
+                        * We assume the same clock is fed to APB and CLCDCLK.
+                        * There is some code to scale the clock down by a factor
+                        * 48 for the display so likely the frequency to the
+                        * display is 1MHz and the CLCDCLK is 48 MHz.
+                        */
+                       clocks = <&apb_pclk>, <&apb_pclk>;
+                       clock-names = "clcdclk", "apb_pclk";
                };
 
                adc: adc@C4000000 {
index b295f6f..d01fc87 100644 (file)
                reg = <0x80000000 0x20000000>; /* 512 MB */
        };
 
+       chosen {
+               stdout-path = &uart3;
+       };
+
        aliases {
                display0 = &lcd;
                display1 = &tv0;
index 5441e9f..6681d45 100644 (file)
@@ -41,7 +41,6 @@
                regulator-name = "VWLAN";
                gpio = <&gpio2 3 GPIO_ACTIVE_HIGH>; /* gpio 35 */
                enable-active-high;
-               regulator-boot-off;
        };
 
        leds {
index 56cb10b..51806c7 100644 (file)
                clock-frequency = <0>;
        };
 
+       pmu {
+               compatible = "arm,cortex-a7-pmu";
+               interrupts-extended = <&gic GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>,
+                                     <&gic GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&cpu0>, <&cpu1>;
+       };
+
        /* External SCIF clock */
        scif_clk: scif {
                compatible = "fixed-clock";
index 3ff2592..ebf5b7c 100644 (file)
                         <&cpg_clocks R8A7779_CLK_S>,
                         <&scif_clk>;
                clock-names = "fck", "brg_int", "scif_clk";
-               power-domains = <&cpg_clocks>;
+               power-domains = <&sysc R8A7779_PD_ALWAYS_ON>;
                status = "disabled";
        };
 
                         <&cpg_clocks R8A7779_CLK_S>,
                         <&scif_clk>;
                clock-names = "fck", "brg_int", "scif_clk";
-               power-domains = <&cpg_clocks>;
+               power-domains = <&sysc R8A7779_PD_ALWAYS_ON>;
                status = "disabled";
        };
 
index 0290ea4..c776321 100644 (file)
                compatible = "rockchip,rockchip-spi";
                reg = <0x20074000 0x1000>;
                interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-               clocks =<&cru PCLK_SPI>, <&cru SCLK_SPI>;
+               clocks = <&cru PCLK_SPI>, <&cru SCLK_SPI>;
                clock-names = "apb-pclk","spi_pclk";
                dmas = <&pdma 8>, <&pdma 9>;
                dma-names = "tx", "rx";
diff --git a/arch/arm/boot/dts/rk3229-xms6.dts b/arch/arm/boot/dts/rk3229-xms6.dts
new file mode 100644 (file)
index 0000000..679fc2b
--- /dev/null
@@ -0,0 +1,283 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "rk3229.dtsi"
+
+/ {
+       model = "Mecer Xtreme Mini S6";
+       compatible = "mecer,xms6", "rockchip,rk3229";
+
+       memory@60000000 {
+               device_type = "memory";
+               reg = <0x60000000 0x40000000>;
+       };
+
+       dc_12v: dc-12v-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "dc_12v";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+       };
+
+       ext_gmac: ext_gmac {
+               compatible = "fixed-clock";
+               clock-frequency = <125000000>;
+               clock-output-names = "ext_gmac";
+               #clock-cells = <0>;
+       };
+
+       power-led {
+               compatible = "gpio-leds";
+
+               blue {
+                       gpios = <&gpio3 21 GPIO_ACTIVE_HIGH>;
+                       default-state = "on";
+               };
+       };
+
+       vcc_host: vcc-host-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&host_vbus_drv>;
+               regulator-name = "vcc_host";
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vcc_phy: vcc-phy-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               regulator-name = "vcc_phy";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vccio_1v8>;
+       };
+
+       vcc_sys: vcc-sys-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&dc_12v>;
+       };
+
+       vccio_1v8: vccio-1v8-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vccio_1v8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vccio_3v3: vccio-3v3-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vccio_3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               vin-supply = <&vcc_sys>;
+       };
+
+       vdd_arm: vdd-arm-regulator {
+               compatible = "pwm-regulator";
+               pwms = <&pwm1 0 25000 1>;
+               pwm-supply = <&vcc_sys>;
+               regulator-name = "vdd_arm";
+               regulator-min-microvolt = <950000>;
+               regulator-max-microvolt = <1400000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       vdd_log: vdd-log-regulator {
+               compatible = "pwm-regulator";
+               pwms = <&pwm2 0 25000 1>;
+               pwm-supply = <&vcc_sys>;
+               regulator-name = "vdd_log";
+               regulator-min-microvolt = <1000000>;
+               regulator-max-microvolt = <1300000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&cpu1 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&cpu2 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&cpu3 {
+       cpu-supply = <&vdd_arm>;
+};
+
+&emmc {
+       cap-mmc-highspeed;
+       disable-wp;
+       non-removable;
+       status = "okay";
+};
+
+&gmac {
+       assigned-clocks = <&cru SCLK_MAC_SRC>;
+       assigned-clock-rates = <50000000>;
+       clock_in_out = "output";
+       phy-handle = <&phy>;
+       phy-mode = "rmii";
+       phy-supply = <&vcc_phy>;
+       status = "okay";
+
+       mdio {
+               compatible = "snps,dwmac-mdio";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               phy: phy@0 {
+                       compatible = "ethernet-phy-id1234.d400",
+                                    "ethernet-phy-ieee802.3-c22";
+                       reg = <0>;
+                       clocks = <&cru SCLK_MAC_PHY>;
+                       phy-is-integrated;
+                       resets = <&cru SRST_MACPHY>;
+               };
+       };
+};
+
+&gpu {
+       mali-supply = <&vdd_log>;
+       status = "okay";
+};
+
+&hdmi {
+       status = "okay";
+};
+
+&hdmi_phy {
+       status = "okay";
+};
+
+&iep_mmu {
+       status = "okay";
+};
+
+&io_domains {
+       status = "okay";
+
+       vccio1-supply = <&vccio_3v3>;
+       vccio2-supply = <&vccio_1v8>;
+       vccio4-supply = <&vccio_3v3>;
+};
+
+&pinctrl {
+       usb {
+               host_vbus_drv: host-vbus-drv {
+                       rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&pwm1 {
+       status = "okay";
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&sdmmc {
+       cap-mmc-highspeed;
+       disable-wp;
+       status = "okay";
+};
+
+&tsadc {
+       rockchip,hw-tshut-mode = <0>;
+       status = "okay";
+};
+
+&u2phy0 {
+       status = "okay";
+
+       u2phy0_host: host-port {
+               phy-supply = <&vcc_host>;
+               status = "okay";
+       };
+
+       u2phy0_otg: otg-port {
+               phy-supply = <&vcc_host>;
+               status = "okay";
+       };
+};
+
+&u2phy1 {
+       status = "okay";
+
+       u2phy1_host: host-port {
+               phy-supply = <&vcc_host>;
+               status = "okay";
+       };
+
+       u2phy1_otg: otg-port {
+               phy-supply = <&vcc_host>;
+               status = "okay";
+       };
+};
+
+&uart2 {
+       pinctrl-0 = <&uart21_xfer>;
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host0_ohci {
+       status = "okay";
+};
+
+&usb_host1_ehci {
+       status = "okay";
+};
+
+&usb_host1_ohci {
+       status = "okay";
+};
+
+&usb_host2_ehci {
+       status = "okay";
+};
+
+&usb_host2_ohci {
+       status = "okay";
+};
+
+&usb_otg {
+       status = "okay";
+};
+
+&vop {
+       status = "okay";
+};
+
+&vop_mmu {
+       status = "okay";
+};
index 8204407..2afd686 100644 (file)
@@ -97,7 +97,7 @@
        };
 
        panel: panel {
-               compatible ="lg,lp079qx1-sp0v", "simple-panel";
+               compatible = "lg,lp079qx1-sp0v", "simple-panel";
                backlight = <&backlight>;
                enable-gpios = <&gpio7 RK_PA4 GPIO_ACTIVE_HIGH>;
                pinctrl-0 = <&lcd_cs>;
diff --git a/arch/arm/boot/dts/rk3288-fennec.dts b/arch/arm/boot/dts/rk3288-fennec.dts
deleted file mode 100644 (file)
index 4847cf9..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-
-/dts-v1/;
-
-#include "rk3288.dtsi"
-
-/ {
-       model = "Rockchip RK3288 Fennec Board";
-       compatible = "rockchip,rk3288-fennec", "rockchip,rk3288";
-
-       memory@0 {
-               reg = <0x0 0x0 0x0 0x80000000>;
-               device_type = "memory";
-       };
-
-       ext_gmac: external-gmac-clock {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <125000000>;
-               clock-output-names = "ext_gmac";
-       };
-
-       vcc_sys: vsys-regulator {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc_sys";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               regulator-always-on;
-               regulator-boot-on;
-       };
-};
-
-&cpu0 {
-       cpu0-supply = <&vdd_cpu>;
-};
-
-&emmc {
-       bus-width = <8>;
-       cap-mmc-highspeed;
-       non-removable;
-       pinctrl-names = "default";
-       pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>;
-       status = "okay";
-};
-
-&gmac {
-       assigned-clocks = <&cru SCLK_MAC>;
-       assigned-clock-parents = <&ext_gmac>;
-       clock_in_out = "input";
-       pinctrl-names = "default";
-       pinctrl-0 = <&rgmii_pins>, <&phy_rst>, <&phy_pmeb>, <&phy_int>;
-       phy-supply = <&vcc_lan>;
-       phy-mode = "rgmii";
-       snps,reset-active-low;
-       snps,reset-delays-us = <0 10000 1000000>;
-       snps,reset-gpio = <&gpio4 RK_PB0 GPIO_ACTIVE_LOW>;
-       tx_delay = <0x30>;
-       rx_delay = <0x10>;
-       status = "okay";
-};
-
-&gpu {
-       mali-supply = <&vdd_gpu>;
-       status = "okay";
-};
-
-&hdmi {
-       status = "okay";
-};
-
-&i2c0 {
-       status = "okay";
-       clock-frequency = <400000>;
-
-       rk808: pmic@1b {
-               compatible = "rockchip,rk808";
-               reg = <0x1b>;
-               interrupt-parent = <&gpio0>;
-               interrupts = <RK_PA4 IRQ_TYPE_LEVEL_LOW>;
-               #clock-cells = <1>;
-               clock-output-names = "xin32k", "rk808-clkout2";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pmic_int &global_pwroff>;
-               rockchip,system-power-controller;
-               wakeup-source;
-
-               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>;
-               vcc10-supply = <&vcc_io>;
-               vcc11-supply = <&vcc_io>;
-               vcc12-supply = <&vcc_io>;
-               vddio-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>;
-                               };
-                       };
-
-                       vccio_pmu: LDO_REG1 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <3300000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-name = "vccio_pmu";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <3300000>;
-                               };
-                       };
-
-                       vcca_33: LDO_REG2 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <3300000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-name = "vcca_33";
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-
-                       vdd_10: LDO_REG3 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1000000>;
-                               regulator-max-microvolt = <1000000>;
-                               regulator-name = "vdd_10";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1000000>;
-                               };
-                       };
-
-                       vcc_wl: LDO_REG4 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-name = "vcc_wl";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1800000>;
-                               };
-                       };
-
-                       vccio_sd: LDO_REG5 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-name = "vccio_sd";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <3300000>;
-                               };
-                       };
-
-                       vdd10_lcd: LDO_REG6 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1000000>;
-                               regulator-max-microvolt = <1000000>;
-                               regulator-name = "vdd10_lcd";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1000000>;
-                               };
-                       };
-
-                       vcc_18: LDO_REG7 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-name = "vcc_18";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1800000>;
-                               };
-                       };
-
-                       vcc18_lcd: LDO_REG8 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-name = "vcc18_lcd";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                                       regulator-suspend-microvolt = <1800000>;
-                               };
-                       };
-
-                       vcc_sd: SWITCH_REG1 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-name = "vcc_sd";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                               };
-                       };
-
-                       vcc_lan: SWITCH_REG2 {
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-name = "vcc_lan";
-                               regulator-state-mem {
-                                       regulator-on-in-suspend;
-                               };
-                       };
-               };
-       };
-};
-
-&pinctrl {
-       pcfg_output_high: pcfg-output-high {
-               output-high;
-       };
-
-       pcfg_output_low: pcfg-output-low {
-               output-low;
-       };
-
-       pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
-               drive-strength = <8>;
-       };
-
-       pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma {
-               bias-pull-up;
-               drive-strength = <8>;
-       };
-
-       gmac {
-               phy_int: phy-int {
-                       rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-
-               phy_pmeb: phy-pmeb {
-                       rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-
-               phy_rst: phy-rst {
-                       rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_output_high>;
-               };
-       };
-
-       pmic {
-               pmic_int: pmic-int {
-                       rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-       };
-
-       usbphy {
-               host_drv: host-drv {
-                       rockchip,pins = <0 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-};
-
-&uart2 {
-       status = "okay";
-};
-
-&usbphy {
-       pinctrl-names = "default";
-       pinctrl-0 = <&host_drv>;
-       vbus_drv-gpios = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
-       status = "okay";
-};
-
-&usb_host0_ehci {
-       status = "okay";
-};
-
-&usb_host1 {
-       status = "okay";
-};
-
-&usb_otg {
-       status = "okay";
-};
-
-&usb_hsic {
-       status = "okay";
-};
-
-&vopb {
-       status = "okay";
-};
-
-&vopb_mmu {
-       status = "okay";
-};
-
-&vopl {
-       status = "okay";
-};
-
-&vopl_mmu {
-       status = "okay";
-};
index 2935768..81e4e95 100644 (file)
                compatible = "gpio-leds";
 
                act-led {
-                       gpios=<&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>;
-                       linux,default-trigger="mmc0";
+                       gpios = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "mmc0";
                };
 
                heartbeat-led {
-                       gpios=<&gpio1 RK_PD1 GPIO_ACTIVE_HIGH>;
-                       linux,default-trigger="heartbeat";
+                       gpios = <&gpio1 RK_PD1 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
                };
 
                pwr-led {
 
 &saradc {
        vref-supply = <&vcc18_ldo1>;
-       status ="okay";
+       status = "okay";
 };
 
 &sdmmc {
 };
 
 &usb_otg {
-       status= "okay";
+       status = "okay";
 };
 
 &vopb {
index 1cadb52..ffb60f8 100644 (file)
@@ -10,6 +10,7 @@
 #include <dt-bindings/input/input.h>
 #include "rk3288-veyron.dtsi"
 #include "rk3288-veyron-analog-audio.dtsi"
+#include "rk3288-veyron-edp.dtsi"
 #include "rk3288-veyron-sdmmc.dtsi"
 
 / {
                i2c20 = &i2c_tunnel;
        };
 
-       backlight: backlight {
-               compatible = "pwm-backlight";
-               brightness-levels = <
-                         0   1   2   3   4   5   6   7
-                         8   9  10  11  12  13  14  15
-                        16  17  18  19  20  21  22  23
-                        24  25  26  27  28  29  30  31
-                        32  33  34  35  36  37  38  39
-                        40  41  42  43  44  45  46  47
-                        48  49  50  51  52  53  54  55
-                        56  57  58  59  60  61  62  63
-                        64  65  66  67  68  69  70  71
-                        72  73  74  75  76  77  78  79
-                        80  81  82  83  84  85  86  87
-                        88  89  90  91  92  93  94  95
-                        96  97  98  99 100 101 102 103
-                       104 105 106 107 108 109 110 111
-                       112 113 114 115 116 117 118 119
-                       120 121 122 123 124 125 126 127
-                       128 129 130 131 132 133 134 135
-                       136 137 138 139 140 141 142 143
-                       144 145 146 147 148 149 150 151
-                       152 153 154 155 156 157 158 159
-                       160 161 162 163 164 165 166 167
-                       168 169 170 171 172 173 174 175
-                       176 177 178 179 180 181 182 183
-                       184 185 186 187 188 189 190 191
-                       192 193 194 195 196 197 198 199
-                       200 201 202 203 204 205 206 207
-                       208 209 210 211 212 213 214 215
-                       216 217 218 219 220 221 222 223
-                       224 225 226 227 228 229 230 231
-                       232 233 234 235 236 237 238 239
-                       240 241 242 243 244 245 246 247
-                       248 249 250 251 252 253 254 255>;
-               default-brightness-level = <128>;
-               enable-gpios = <&gpio7 RK_PA2 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&bl_en>;
-               pwms = <&pwm0 0 1000000 0>;
-               post-pwm-on-delay-ms = <10>;
-               pwm-off-delay-ms = <10>;
-       };
-
        gpio-charger {
                compatible = "gpio-charger";
                charger-type = "mains";
                };
        };
 
-       panel: panel {
-               compatible ="innolux,n116bge", "simple-panel";
-               status = "okay";
-               power-supply = <&vcc33_lcd>;
-               backlight = <&backlight>;
-
-               ports {
-                       panel_in: port {
-                               panel_in_edp: endpoint {
-                                       remote-endpoint = <&edp_out_panel>;
-                               };
-                       };
-               };
-       };
-
        /* A non-regulated voltage from power supply or battery */
        vccsys: vccsys {
                compatible = "regulator-fixed";
        };
 };
 
-&edp {
-       status = "okay";
-
-       pinctrl-names = "default";
-       pinctrl-0 = <&edp_hpd>;
-
-       ports {
-               edp_out: port@1 {
-                       reg = <1>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       edp_out_panel: endpoint@0 {
-                               reg = <0>;
-                               remote-endpoint = <&panel_in_edp>;
-                       };
-               };
-       };
-};
-
-&edp_phy {
-       status = "okay";
-};
-
-&pwm0 {
-       status = "okay";
-};
-
 &rk808 {
        vcc11-supply = <&vcc_5v>;
 
        };
 };
 
-&vopl {
-       status = "okay";
-};
-
-&vopl_mmu {
-       status = "okay";
-};
-
 &pinctrl {
        pinctrl-0 = <
                /* Common for sleep and wake, but no owners */
                &bt_dev_wake_sleep
        >;
 
-       backlight {
-               bl_en: bl-en {
-                       rockchip,pins = <7 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
        buttons {
                ap_lid_int_l: ap-lid-int-l {
                        rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
diff --git a/arch/arm/boot/dts/rk3288-veyron-edp.dtsi b/arch/arm/boot/dts/rk3288-veyron-edp.dtsi
new file mode 100644 (file)
index 0000000..b12e061
--- /dev/null
@@ -0,0 +1,172 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Veyron (and derivatives) fragment for the edp displays
+ *
+ * Copyright 2019 Google LLC
+ */
+
+/ {
+       backlight_regulator: backlight-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio2 RK_PB4 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&bl_pwr_en>;
+               regulator-name = "backlight_regulator";
+               vin-supply = <&vcc33_sys>;
+               startup-delay-us = <15000>;
+       };
+
+       panel_regulator: panel-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio7 RK_PB6 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&lcd_enable_h>;
+               regulator-name = "panel_regulator";
+               vin-supply = <&vcc33_sys>;
+       };
+
+       vcc18_lcd: vcc18-lcd {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&avdd_1v8_disp_en>;
+               regulator-name = "vcc18_lcd";
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc18_wl>;
+       };
+
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               brightness-levels = <
+                         0   1   2   3   4   5   6   7
+                         8   9  10  11  12  13  14  15
+                        16  17  18  19  20  21  22  23
+                        24  25  26  27  28  29  30  31
+                        32  33  34  35  36  37  38  39
+                        40  41  42  43  44  45  46  47
+                        48  49  50  51  52  53  54  55
+                        56  57  58  59  60  61  62  63
+                        64  65  66  67  68  69  70  71
+                        72  73  74  75  76  77  78  79
+                        80  81  82  83  84  85  86  87
+                        88  89  90  91  92  93  94  95
+                        96  97  98  99 100 101 102 103
+                       104 105 106 107 108 109 110 111
+                       112 113 114 115 116 117 118 119
+                       120 121 122 123 124 125 126 127
+                       128 129 130 131 132 133 134 135
+                       136 137 138 139 140 141 142 143
+                       144 145 146 147 148 149 150 151
+                       152 153 154 155 156 157 158 159
+                       160 161 162 163 164 165 166 167
+                       168 169 170 171 172 173 174 175
+                       176 177 178 179 180 181 182 183
+                       184 185 186 187 188 189 190 191
+                       192 193 194 195 196 197 198 199
+                       200 201 202 203 204 205 206 207
+                       208 209 210 211 212 213 214 215
+                       216 217 218 219 220 221 222 223
+                       224 225 226 227 228 229 230 231
+                       232 233 234 235 236 237 238 239
+                       240 241 242 243 244 245 246 247
+                       248 249 250 251 252 253 254 255>;
+               default-brightness-level = <128>;
+               enable-gpios = <&gpio7 RK_PA2 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&bl_en>;
+               pwms = <&pwm0 0 1000000 0>;
+               post-pwm-on-delay-ms = <10>;
+               pwm-off-delay-ms = <10>;
+               power-supply = <&backlight_regulator>;
+       };
+
+       panel: panel {
+               compatible = "innolux,n116bge", "simple-panel";
+               status = "okay";
+               power-supply = <&panel_regulator>;
+               backlight = <&backlight>;
+
+               panel-timing {
+                       clock-frequency = <74250000>;
+                       hactive = <1366>;
+                       hfront-porch = <136>;
+                       hback-porch = <60>;
+                       hsync-len = <30>;
+                       hsync-active = <0>;
+                       vactive = <768>;
+                       vfront-porch = <8>;
+                       vback-porch = <12>;
+                       vsync-len = <12>;
+                       vsync-active = <0>;
+               };
+
+               ports {
+                       panel_in: port {
+                               panel_in_edp: endpoint {
+                                       remote-endpoint = <&edp_out_panel>;
+                               };
+                       };
+               };
+       };
+};
+
+&edp {
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&edp_hpd>;
+
+       ports {
+               edp_out: port@1 {
+                       reg = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       edp_out_panel: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&panel_in_edp>;
+                       };
+               };
+       };
+};
+
+&edp_phy {
+       status = "okay";
+};
+
+&pwm0 {
+       status = "okay";
+};
+
+&vopl {
+       status = "okay";
+};
+
+&vopl_mmu {
+       status = "okay";
+};
+
+&pinctrl {
+       backlight {
+               bl_pwr_en: bl_pwr_en {
+                       rockchip,pins = <2 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               bl_en: bl-en {
+                       rockchip,pins = <7 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       lcd {
+               lcd_enable_h: lcd-en {
+                       rockchip,pins = <7 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               avdd_1v8_disp_en: avdd-1v8-disp-en {
+                       rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/rk3288-veyron-fievel.dts b/arch/arm/boot/dts/rk3288-veyron-fievel.dts
new file mode 100644 (file)
index 0000000..9a0f550
--- /dev/null
@@ -0,0 +1,522 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Veyron Fievel Rev 0+ board device tree source
+ *
+ * Copyright 2016 Google, Inc
+ */
+
+/dts-v1/;
+#include "rk3288-veyron.dtsi"
+#include "rk3288-veyron-analog-audio.dtsi"
+
+/ {
+       model = "Google Fievel";
+       compatible = "google,veyron-fievel-rev8", "google,veyron-fievel-rev7",
+                    "google,veyron-fievel-rev6", "google,veyron-fievel-rev5",
+                    "google,veyron-fievel-rev4", "google,veyron-fievel-rev3",
+                    "google,veyron-fievel-rev2", "google,veyron-fievel-rev1",
+                    "google,veyron-fievel-rev0", "google,veyron-fievel",
+                    "google,veyron", "rockchip,rk3288";
+
+       /delete-node/ bt-activity;
+
+       vccsys: vccsys {
+               compatible = "regulator-fixed";
+               regulator-name = "vccsys";
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       /*
+        * vcc33_pmuio and vcc33_io is sourced directly from vcc33_sys,
+        * enabled by vcc_18
+        */
+       vcc33_io: vcc33-io {
+               compatible = "regulator-fixed";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-name = "vcc33_io";
+       };
+
+       vcc5_host1: vcc5-host1-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio5 RK_PC2 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&hub_usb1_pwr_en>;
+               regulator-name = "vcc5_host1";
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       vcc5_host2: vcc5-host2-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio5 RK_PB6 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&hub_usb2_pwr_en>;
+               regulator-name = "vcc5_host2";
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       vcc5v_otg: vcc5v-otg-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio0 RK_PB4 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&usb_otg_pwr_en>;
+               regulator-name = "vcc5_otg";
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       ext_gmac: external-gmac-clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <125000000>;
+               clock-output-names = "ext_gmac";
+       };
+};
+
+&gmac {
+       status = "okay";
+
+       assigned-clocks = <&cru SCLK_MAC>;
+       assigned-clock-parents = <&ext_gmac>;
+       clock_in_out = "input";
+       phy-handle = <&ethphy>;
+       phy-mode = "rgmii";
+       phy-supply = <&vcc33_lan>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&rgmii_pins>, <&phy_rst>, <&phy_pmeb>, <&phy_int>;
+       rx_delay = <0x10>;
+       tx_delay = <0x30>;
+
+       /*
+        * Reset for the RTL8211 PHY which requires a 10-ms reset pulse (low)
+        * with a 30ms settling time.
+        */
+       snps,reset-gpio = <&gpio4 RK_PB0 0>;
+       snps,reset-active-low;
+       snps,reset-delays-us = <0 10000 30000>;
+       wakeup-source;
+
+       mdio0 {
+               compatible = "snps,dwmac-mdio";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy: ethernet-phy@1 {
+                       reg = <1>;
+               };
+       };
+};
+
+&rk808 {
+       dvs-gpios = <&gpio7 RK_PB4 GPIO_ACTIVE_HIGH>,
+                   <&gpio7 RK_PB7 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pmic_int_l &dvs_1 &dvs_2>;
+
+       vcc6-supply = <&vcc33_sys>;
+       vcc10-supply = <&vcc33_sys>;
+       vcc11-supply = <&vcc_5v>;
+       vcc12-supply = <&vcc33_sys>;
+
+       regulators {
+               /delete-node/ LDO_REG1;
+
+               /*
+                * According to the schematic, vcc18_lcdt is for
+                * HDMI_AVDD_1V8
+                */
+               vcc18_lcdt: LDO_REG2 {
+                       regulator-always-on;
+                       regulator-boot-on;
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-name = "vdd18_lcdt";
+                       regulator-state-mem {
+                               regulator-off-in-suspend;
+                       };
+               };
+
+               /*
+                * This is not a pwren anymore, but the real power supply,
+                * vdd10_lcd for HDMI_AVDD_1V0
+                */
+               vdd10_lcd: LDO_REG7 {
+                       regulator-always-on;
+                       regulator-boot-on;
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-name = "vdd10_lcd";
+                       regulator-state-mem {
+                               regulator-off-in-suspend;
+                       };
+               };
+
+               /* for usb camera */
+               vcc33_ccd: LDO_REG8 {
+                       regulator-always-on;
+                       regulator-boot-on;
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-name = "vcc33_ccd";
+                       regulator-state-mem {
+                               regulator-off-in-suspend;
+                       };
+               };
+
+               vcc33_lan: SWITCH_REG2 {
+                       regulator-name = "vcc33_lan";
+               };
+       };
+};
+
+&sdio0 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       btmrvl: btmrvl@2 {
+               compatible = "marvell,sd8897-bt";
+               reg = <2>;
+               interrupt-parent = <&gpio4>;
+               interrupts = <RK_PD7 IRQ_TYPE_LEVEL_LOW>;
+               marvell,wakeup-pin = /bits/ 16 <13>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&bt_host_wake_l>;
+       };
+};
+
+&vcc50_hdmi {
+       enable-active-high;
+       gpio = <&gpio5 RK_PC3 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&vcc50_hdmi_en>;
+};
+
+&vcc_5v {
+       enable-active-high;
+       gpio = <&gpio7 RK_PC5 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&drv_5v>;
+};
+
+&gpio0 {
+       gpio-line-names = "PMIC_SLEEP_AP",
+                         "DDRIO_PWROFF",
+                         "DDRIO_RETEN",
+                         "TS3A227E_INT_L",
+                         "PMIC_INT_L",
+                         "PWR_KEY_L",
+                         "HUB_USB1_nFALUT",
+                         "PHY_PMEB",
+
+                         "PHY_INT",
+                         "REC_MODE_L",
+                         "OTP_OUT",
+                         "",
+                         "USB_OTG_POWER_EN",
+                         "AP_WARM_RESET_H",
+                         "USB_OTG_nFALUT",
+                         "I2C0_SDA_PMIC",
+
+                         "I2C0_SCL_PMIC",
+                         "DEVMODE_L",
+                         "USB_INT";
+};
+
+&gpio2 {
+       gpio-line-names = "CONFIG0",
+                         "CONFIG1",
+                         "CONFIG2",
+                         "",
+                         "",
+                         "",
+                         "",
+                         "CONFIG3",
+
+                         "",
+                         "EMMC_RST_L",
+                         "",
+                         "",
+                         "BL_PWR_EN",
+                         "",
+                         "TOUCH_INT",
+                         "TOUCH_RST",
+
+                         "I2C3_SCL_TP",
+                         "I2C3_SDA_TP";
+};
+
+&gpio3 {
+       gpio-line-names = "FLASH0_D0",
+                         "FLASH0_D1",
+                         "FLASH0_D2",
+                         "FLASH0_D3",
+                         "FLASH0_D4",
+                         "FLASH0_D5",
+                         "FLASH0_D6",
+                         "FLASH0_D7",
+
+                         "VCC5V_GOOD_H",
+                         "",
+                         "",
+                         "",
+                         "",
+                         "",
+                         "",
+                         "",
+
+                         "FLASH0_CS2/EMMC_CMD",
+                         "",
+                         "FLASH0_DQS/EMMC_CLKO",
+                         "",
+                         "",
+                         "",
+                         "",
+                         "",
+
+                         "PHY_TXD2",
+                         "PHY_TXD3",
+                         "MAC_RXD2",
+                         "MAC_RXD3",
+                         "PHY_TXD0",
+                         "PHY_TXD1",
+                         "MAC_RXD0",
+                         "MAC_RXD1";
+};
+
+&gpio4 {
+       gpio-line-names = "MAC_MDC",
+                         "MAC_RXDV",
+                         "MAC_RXER",
+                         "MAC_CLK",
+                         "PHY_TXEN",
+                         "MAC_MDIO",
+                         "MAC_RXCLK",
+                         "",
+
+                         "PHY_RST",
+                         "PHY_TXCLK",
+                         "",
+                         "",
+                         "",
+                         "",
+                         "",
+                         "",
+
+                         "UART0_RXD",
+                         "UART0_TXD",
+                         "UART0_CTS_L",
+                         "UART0_RTS_L",
+                         "SDIO0_D0",
+                         "SDIO0_D1",
+                         "SDIO0_D2",
+                         "SDIO0_D3",
+
+                         "SDIO0_CMD",
+                         "SDIO0_CLK",
+                         "BT_DEV_WAKE",
+                         "",
+                         "WIFI_ENABLE_H",
+                         "BT_ENABLE_L",
+                         "WIFI_HOST_WAKE",
+                         "BT_HOST_WAKE";
+};
+
+&gpio5 {
+       gpio-line-names = "",
+                         "",
+                         "",
+                         "",
+                         "",
+                         "",
+                         "",
+                         "",
+
+                         "",
+                         "",
+                         "",
+                         "",
+                         "USB_OTG_CTL1",
+                         "HUB_USB2_CTL1",
+                         "HUB_USB2_PWR_EN",
+                         "HUB_USB_ILIM_SEL",
+
+                         "USB_OTG_STATUS_L",
+                         "HUB_USB1_CTL1",
+                         "HUB_USB1_PWR_EN",
+                         "VCC50_HDMI_EN";
+};
+
+&gpio6 {
+       gpio-line-names = "I2S0_SCLK",
+                         "I2S0_LRCK_RX",
+                         "I2S0_LRCK_TX",
+                         "I2S0_SDI",
+                         "I2S0_SDO0",
+                         "HP_DET_H",
+                         "",
+                         "INT_CODEC",
+
+                         "I2S0_CLK",
+                         "I2C2_SDA",
+                         "I2C2_SCL",
+                         "MICDET",
+                         "",
+                         "",
+                         "",
+                         "",
+
+                         "HUB_USB2_nFALUT",
+                         "USB_OTG_ILIM_SEL";
+};
+
+&gpio7 {
+       gpio-line-names = "LCD_BL_PWM",
+                         "PWM_LOG",
+                         "BL_EN",
+                         "PWR_LED1",
+                         "TPM_INT_H",
+                         "SPK_ON",
+                         "FW_WP_AP",
+                         "",
+
+                         "CPU_NMI",
+                         "DVSOK",
+                         "",
+                         "EDP_HPD",
+                         "DVS1",
+                         "",
+                         "LCD_EN",
+                         "DVS2",
+
+                         "HDMI_CEC",
+                         "I2C4_SDA",
+                         "I2C4_SCL",
+                         "I2C5_SDA_HDMI",
+                         "I2C5_SCL_HDMI",
+                         "5V_DRV",
+                         "UART2_RXD",
+                         "UART2_TXD";
+};
+
+&gpio8 {
+       gpio-line-names = "RAM_ID0",
+                         "RAM_ID1",
+                         "RAM_ID2",
+                         "RAM_ID3",
+                         "I2C1_SDA_TPM",
+                         "I2C1_SCL_TPM",
+                         "SPI2_CLK",
+                         "SPI2_CS0",
+
+                         "SPI2_RXD",
+                         "SPI2_TXD";
+};
+
+&pinctrl {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+
+               /* For usb bc1.2 */
+               &usb_otg_ilim_sel
+               &usb_usb_ilim_sel
+
+               /* Wake only */
+               &bt_dev_wake_awake
+               &pwr_led1_on
+       >;
+
+       pinctrl-1 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+
+               /* For usb bc1.2 */
+               &usb_otg_ilim_sel
+               &usb_usb_ilim_sel
+
+               /* Sleep only */
+               &bt_dev_wake_sleep
+               &pwr_led1_blink
+       >;
+
+       buck-5v {
+               drv_5v: drv-5v {
+                       rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       gmac {
+               phy_rst: phy-rst {
+                       rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_output_high>;
+               };
+
+               phy_pmeb: phy-pmeb {
+                       rockchip,pins = <0 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               phy_int: phy-int {
+                       rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       hdmi {
+               vcc50_hdmi_en: vcc50-hdmi-en {
+                       rockchip,pins = <5 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       leds {
+               pwr_led1_on: pwr-led1-on {
+                       rockchip,pins = <7 RK_PA3 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+
+               pwr_led1_blink: pwr-led1-blink {
+                       rockchip,pins = <7 RK_PA3 RK_FUNC_GPIO &pcfg_output_high>;
+               };
+       };
+
+       pmic {
+               dvs_1: dvs-1 {
+                       rockchip,pins = <7 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+
+               dvs_2: dvs-2 {
+                       rockchip,pins = <7 RK_PB7 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+
+       usb-bc12 {
+               usb_otg_ilim_sel: usb-otg-ilim-sel {
+                       rockchip,pins = <6 RK_PC1 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+
+               usb_usb_ilim_sel: usb-usb-ilim-sel {
+                       rockchip,pins = <5 RK_PB7 RK_FUNC_GPIO &pcfg_output_low>;
+               };
+       };
+
+       usb-host {
+               hub_usb1_pwr_en: hub_usb1_pwr_en {
+                       rockchip,pins = <5 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               hub_usb2_pwr_en: hub_usb2_pwr_en {
+                       rockchip,pins = <5 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               usb_otg_pwr_en: usb_otg_pwr_en {
+                       rockchip,pins = <0 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
index fcd1191..8038620 100644 (file)
                     "google,veyron-jaq-rev3", "google,veyron-jaq-rev2",
                     "google,veyron-jaq-rev1", "google,veyron-jaq",
                     "google,veyron", "rockchip,rk3288";
-
-       panel_regulator: panel-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio7 RK_PB6 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&lcd_enable_h>;
-               regulator-name = "panel_regulator";
-               startup-delay-us = <100000>;
-               vin-supply = <&vcc33_sys>;
-       };
-
-       vcc18_lcd: vcc18-lcd {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&avdd_1v8_disp_en>;
-               regulator-name = "vcc18_lcd";
-               regulator-always-on;
-               regulator-boot-on;
-               vin-supply = <&vcc18_wl>;
-       };
-
-       backlight_regulator: backlight-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio2 RK_PB4 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&bl_pwr_en>;
-               regulator-name = "backlight_regulator";
-               vin-supply = <&vcc33_sys>;
-               startup-delay-us = <15000>;
-       };
 };
 
 &backlight {
                232 233 234 235 236 237 238 239
                240 241 242 243 244 245 246 247
                248 249 250 251 252 253 254 255>;
-       power-supply = <&backlight_regulator>;
-};
-
-&panel {
-       power-supply = <&panel_regulator>;
 };
 
 &rk808 {
 };
 
 &pinctrl {
-       backlight {
-               bl_pwr_en: bl_pwr_en {
-                       rockchip,pins = <2 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
        buck-5v {
                drv_5v: drv-5v {
                        rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
 
-       lcd {
-               lcd_enable_h: lcd-en {
-                       rockchip,pins = <7 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-
-               avdd_1v8_disp_en: avdd-1v8-disp-en {
-                       rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
        pmic {
                dvs_1: dvs-1 {
                        rockchip,pins = <7 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>;
index 164561f..a6ee44f 100644 (file)
                     "google,veyron-jerry-rev5", "google,veyron-jerry-rev4",
                     "google,veyron-jerry-rev3", "google,veyron-jerry",
                     "google,veyron", "rockchip,rk3288";
-
-       panel_regulator: panel-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio7 RK_PB6 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&lcd_enable_h>;
-               regulator-name = "panel_regulator";
-               startup-delay-us = <100000>;
-               vin-supply = <&vcc33_sys>;
-       };
-
-       vcc18_lcd: vcc18-lcd {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&avdd_1v8_disp_en>;
-               regulator-name = "vcc18_lcd";
-               regulator-always-on;
-               regulator-boot-on;
-               vin-supply = <&vcc18_wl>;
-       };
-
-       backlight_regulator: backlight-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio2 RK_PB4 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&bl_pwr_en>;
-               regulator-name = "backlight_regulator";
-               vin-supply = <&vcc33_sys>;
-               startup-delay-us = <15000>;
-       };
-};
-
-&backlight {
-       power-supply = <&backlight_regulator>;
-};
-
-&panel {
-       power-supply= <&panel_regulator>;
 };
 
 &rk808 {
        };
 };
 
+&sdio0 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       mwifiex: wifi@1 {
+               compatible = "marvell,sd8897";
+               reg = <1>;
+
+               marvell,caldata-txpwrlimit-2g = /bits/ 8 <
+0x01 0x00 0x06 0x00 0x08 0x02 0x89 0x01
+0x24 0x00 0x67 0x09 0x14 0x01 0x00 0x0f 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c
+0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c
+0x0d 0x09 0x0e 0x09 0x0f 0x09 0x89 0x01 0x24 0x00 0x67 0x09 0x14 0x02 0x00 0x0f
+0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c 0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09
+0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x89 0x01
+0x24 0x00 0x67 0x09 0x14 0x03 0x00 0x0f 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c
+0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c
+0x0d 0x09 0x0e 0x09 0x0f 0x09 0x89 0x01 0x24 0x00 0x67 0x09 0x14 0x04 0x00 0x0f
+0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c 0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09
+0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x89 0x01
+0x24 0x00 0x67 0x09 0x14 0x05 0x00 0x0f 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c
+0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c
+0x0d 0x09 0x0e 0x09 0x0f 0x09 0x89 0x01 0x24 0x00 0x67 0x09 0x14 0x06 0x00 0x0f
+0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c 0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09
+0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x89 0x01
+0x24 0x00 0x67 0x09 0x14 0x07 0x00 0x0f 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c
+0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c
+0x0d 0x09 0x0e 0x09 0x0f 0x09 0x89 0x01 0x24 0x00 0x67 0x09 0x14 0x08 0x00 0x0f
+0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c 0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09
+0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x89 0x01
+0x24 0x00 0x67 0x09 0x14 0x09 0x00 0x0f 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c
+0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c
+0x0d 0x09 0x0e 0x09 0x0f 0x09 0x89 0x01 0x24 0x00 0x67 0x09 0x14 0x0a 0x00 0x0f
+0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c 0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09
+0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x89 0x01
+0x24 0x00 0x67 0x09 0x14 0x0b 0x00 0x0f 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c
+0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c
+0x0d 0x09 0x0e 0x09 0x0f 0x09 0x89 0x01 0x24 0x00 0x67 0x09 0x14 0x0c 0x00 0x0f
+0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c 0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09
+0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x89 0x01
+0x24 0x00 0x67 0x09 0x14 0x0d 0x00 0x0f 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0c
+0x05 0x0c 0x06 0x0c 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0c 0x0b 0x0c 0x0c 0x0c
+0x0d 0x09 0x0e 0x09 0x0f 0x09>;
+
+               marvell,caldata-txpwrlimit-5g-sub0 = /bits/ 8 <
+0x01 0x00 0x06 0x00 0xf0 0x01 0x89 0x01
+0x3a 0x00 0x88 0x13 0x14 0x24 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a
+0x06 0x0a 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x09
+0x0e 0x09 0x0f 0x09 0x10 0x05 0x11 0x05 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05
+0x16 0x05 0x17 0x05 0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00
+0x88 0x13 0x14 0x28 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a 0x06 0x0a
+0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x09 0x0e 0x09
+0x0f 0x09 0x10 0x05 0x11 0x05 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x05
+0x17 0x05 0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13
+0x14 0x2c 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x09
+0x08 0x09 0x09 0x09 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x09 0x0e 0x09 0x0f 0x09
+0x10 0x05 0x11 0x05 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x05 0x17 0x05
+0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13 0x14 0x30
+0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x09 0x08 0x09
+0x09 0x09 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x10 0x05
+0x11 0x05 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x05 0x17 0x05 0x18 0x05
+0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13 0x14 0x34 0x01 0x0c
+0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x09 0x08 0x09 0x09 0x09
+0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x10 0x05 0x11 0x05
+0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x05 0x17 0x05 0x18 0x05 0x19 0x05
+0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13 0x14 0x38 0x01 0x0c 0x02 0x0c
+0x03 0x0c 0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0a
+0x0b 0x0a 0x0c 0x0a 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x10 0x05 0x11 0x05 0x12 0x05
+0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x05 0x17 0x05 0x18 0x05 0x19 0x05 0x1a 0x05
+0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13 0x14 0x3c 0x01 0x0c 0x02 0x0c 0x03 0x0c
+0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0a 0x0b 0x0a
+0x0c 0x0a 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x10 0x05 0x11 0x05 0x12 0x05 0x13 0x05
+0x14 0x05 0x15 0x05 0x16 0x05 0x17 0x05 0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05
+0x89 0x01 0x3a 0x00 0x88 0x13 0x14 0x40 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a
+0x05 0x0a 0x06 0x0a 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a
+0x0d 0x09 0x0e 0x09 0x0f 0x09 0x10 0x05 0x11 0x05 0x12 0x05 0x13 0x05 0x14 0x05
+0x15 0x05 0x16 0x05 0x17 0x05 0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05>;
+
+               marvell,caldata-txpwrlimit-5g-sub1 = /bits/ 8 <
+0x01 0x00 0x06 0x00 0xaa 0x02 0x89 0x01
+0x3a 0x00 0x88 0x13 0x14 0x64 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a
+0x06 0x0a 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x09
+0x0e 0x09 0x0f 0x09 0x10 0x05 0x11 0x05 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05
+0x16 0x05 0x17 0x05 0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00
+0x88 0x13 0x14 0x68 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a 0x06 0x0a
+0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x09 0x0e 0x09
+0x0f 0x09 0x10 0x05 0x11 0x05 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x05
+0x17 0x05 0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13
+0x14 0x6c 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x09
+0x08 0x09 0x09 0x09 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x09 0x0e 0x09 0x0f 0x09
+0x10 0x05 0x11 0x05 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x05 0x17 0x05
+0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13 0x14 0x70
+0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x09 0x08 0x09
+0x09 0x09 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x10 0x05
+0x11 0x05 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x05 0x17 0x05 0x18 0x05
+0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13 0x14 0x74 0x01 0x0c
+0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x09 0x08 0x09 0x09 0x09
+0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x10 0x05 0x11 0x05
+0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x05 0x17 0x05 0x18 0x05 0x19 0x05
+0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13 0x14 0x78 0x01 0x0c 0x02 0x0c
+0x03 0x0c 0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0a
+0x0b 0x0a 0x0c 0x0a 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x10 0x05 0x11 0x05 0x12 0x05
+0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x05 0x17 0x05 0x18 0x05 0x19 0x05 0x1a 0x05
+0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13 0x14 0x7c 0x01 0x0c 0x02 0x0c 0x03 0x0c
+0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0a 0x0b 0x0a
+0x0c 0x0a 0x0d 0x09 0x0e 0x09 0x0f 0x09 0x10 0x05 0x11 0x05 0x12 0x05 0x13 0x05
+0x14 0x05 0x15 0x05 0x16 0x05 0x17 0x05 0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05
+0x89 0x01 0x3a 0x00 0x88 0x13 0x14 0x80 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a
+0x05 0x0a 0x06 0x0a 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a
+0x0d 0x09 0x0e 0x09 0x0f 0x09 0x10 0x05 0x11 0x05 0x12 0x05 0x13 0x05 0x14 0x05
+0x15 0x05 0x16 0x05 0x17 0x05 0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01
+0x3a 0x00 0x88 0x13 0x14 0x84 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a
+0x06 0x0a 0x07 0x09 0x08 0x09 0x09 0x09 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x09
+0x0e 0x09 0x0f 0x09 0x10 0x05 0x11 0x05 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05
+0x16 0x05 0x17 0x05 0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00
+0x88 0x13 0x14 0x88 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a 0x06 0x0a
+0x07 0x08 0x08 0x08 0x09 0x08 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x08 0x0e 0x08
+0x0f 0x08 0x10 0x04 0x11 0x04 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x04
+0x17 0x04 0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13
+0x14 0x8c 0x01 0x0c 0x02 0x0c 0x03 0x0c 0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x08
+0x08 0x08 0x09 0x08 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x08 0x0e 0x08 0x0f 0x08
+0x10 0x04 0x11 0x04 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x04 0x17 0x04
+0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05>;
+
+               marvell,caldata-txpwrlimit-5g-sub2 = /bits/ 8 <
+0x01 0x00 0x06 0x00 0x36 0x01 0x89 0x01
+0x3a 0x00 0x88 0x13 0x14 0x95 0x01 0x0b 0x02 0x0b 0x03 0x0b 0x04 0x0a 0x05 0x0a
+0x06 0x0a 0x07 0x08 0x08 0x08 0x09 0x08 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x08
+0x0e 0x08 0x0f 0x08 0x10 0x04 0x11 0x04 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05
+0x16 0x04 0x17 0x04 0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00
+0x88 0x13 0x14 0x99 0x01 0x0b 0x02 0x0b 0x03 0x0b 0x04 0x0a 0x05 0x0a 0x06 0x0a
+0x07 0x08 0x08 0x08 0x09 0x08 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x08 0x0e 0x08
+0x0f 0x08 0x10 0x04 0x11 0x04 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x04
+0x17 0x04 0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13
+0x14 0x9d 0x01 0x0b 0x02 0x0b 0x03 0x0b 0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x08
+0x08 0x08 0x09 0x08 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x08 0x0e 0x08 0x0f 0x08
+0x10 0x04 0x11 0x04 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x04 0x17 0x04
+0x18 0x05 0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13 0x14 0xa1
+0x01 0x0b 0x02 0x0b 0x03 0x0b 0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x08 0x08 0x08
+0x09 0x08 0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x08 0x0e 0x08 0x0f 0x08 0x10 0x04
+0x11 0x04 0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x04 0x17 0x04 0x18 0x05
+0x19 0x05 0x1a 0x05 0x1b 0x05 0x89 0x01 0x3a 0x00 0x88 0x13 0x14 0xa5 0x01 0x0b
+0x02 0x0b 0x03 0x0b 0x04 0x0a 0x05 0x0a 0x06 0x0a 0x07 0x08 0x08 0x08 0x09 0x08
+0x0a 0x0a 0x0b 0x0a 0x0c 0x0a 0x0d 0x08 0x0e 0x08 0x0f 0x08 0x10 0x04 0x11 0x04
+0x12 0x05 0x13 0x05 0x14 0x05 0x15 0x05 0x16 0x04 0x17 0x04 0x18 0x05 0x19 0x05
+0x1a 0x05 0x1b 0x05>;
+       };
+};
+
 &sdmmc {
        disable-wp;
        pinctrl-names = "default";
 };
 
 &pinctrl {
-       backlight {
-               bl_pwr_en: bl_pwr_en {
-                       rockchip,pins = <2 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
        buck-5v {
                drv_5v: drv-5v {
                        rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
 
-       lcd {
-               lcd_enable_h: lcd-en {
-                       rockchip,pins = <7 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-
-               avdd_1v8_disp_en: avdd-1v8-disp-en {
-                       rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
        pmic {
                dvs_1: dvs-1 {
                        rockchip,pins = <7 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>;
index 9008e70..55955b0 100644 (file)
                     "google,veyron-minnie-rev0", "google,veyron-minnie",
                     "google,veyron", "rockchip,rk3288";
 
-       backlight_regulator: backlight-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio2 RK_PB4 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&bl_pwr_en>;
-               regulator-name = "backlight_regulator";
-               vin-supply = <&vcc33_sys>;
-               startup-delay-us = <15000>;
-       };
-
-       panel_regulator: panel-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio7 RK_PB6 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&lcd_enable_h>;
-               regulator-name = "panel_regulator";
-               startup-delay-us = <100000>;
-               vin-supply = <&vcc33_sys>;
-       };
-
-       vcc18_lcd: vcc18-lcd {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&avdd_1v8_disp_en>;
-               regulator-name = "vcc18_lcd";
-               regulator-always-on;
-               regulator-boot-on;
-               vin-supply = <&vcc18_wl>;
-       };
-
        volume_buttons: volume-buttons {
                compatible = "gpio-keys";
                pinctrl-names = "default";
                        232 233 234 235 236 237 238 239
                        240 241 242 243 244 245 246 247
                        248 249 250 251 252 253 254 255>;
-       power-supply = <&backlight_regulator>;
 };
 
 &i2c_tunnel {
 
 &panel {
        compatible = "auo,b101ean01", "simple-panel";
-       power-supply= <&panel_regulator>;
+
+       /delete-node/ panel-timing;
+
+       panel-timing {
+               clock-frequency = <66666667>;
+               hactive = <1280>;
+               hfront-porch = <18>;
+               hback-porch = <21>;
+               hsync-len = <32>;
+               vactive = <800>;
+               vfront-porch = <4>;
+               vback-porch = <8>;
+               vsync-len = <18>;
+       };
 };
 
 &rk808 {
 };
 
 &pinctrl {
-       backlight {
-               bl_pwr_en: bl_pwr_en {
-                       rockchip,pins = <2 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
        buck-5v {
                drv_5v: drv-5v {
                        rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
 
-       lcd {
-               lcd_enable_h: lcd-en {
-                       rockchip,pins = <7 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-
-               avdd_1v8_disp_en: avdd-1v8-disp-en {
-                       rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
        pmic {
                dvs_1: dvs-1 {
                        rockchip,pins = <7 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>;
index 9b6f4d9..f420499 100644 (file)
        compatible = "google,veyron-pinky-rev2", "google,veyron-pinky",
                     "google,veyron", "rockchip,rk3288";
 
+       /delete-node/backlight-regulator;
+       /delete-node/panel-regulator;
        /delete-node/emmc-pwrseq;
+       /delete-node/vcc18-lcd;
+};
+
+&backlight {
+       /delete-property/power-supply;
 };
 
 &emmc {
        i2c-scl-rising-time-ns = <300>;
 };
 
+&panel {
+       power-supply = <&vcc33_lcd>;
+};
+
 &pinctrl {
+       /delete-node/ lcd;
+
+       backlight {
+               /delete-node/ bl_pwr_en;
+       };
+
        buttons {
                pwr_key_h: pwr-key-h {
                        rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>;
index 9b140db..2f2989b 100644 (file)
                     "google,veyron-speedy-rev5", "google,veyron-speedy-rev4",
                     "google,veyron-speedy-rev3", "google,veyron-speedy-rev2",
                     "google,veyron-speedy", "google,veyron", "rockchip,rk3288";
-
-       panel_regulator: panel-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio7 RK_PB6 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&lcd_enable_h>;
-               regulator-name = "panel_regulator";
-               startup-delay-us = <100000>;
-               vin-supply = <&vcc33_sys>;
-       };
-
-       vcc18_lcd: vcc18-lcd {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio2 RK_PB5 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&avdd_1v8_disp_en>;
-               regulator-name = "vcc18_lcd";
-               regulator-always-on;
-               regulator-boot-on;
-               vin-supply = <&vcc18_wl>;
-       };
-
-       backlight_regulator: backlight-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio2 RK_PB4 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&bl_pwr_en>;
-               regulator-name = "backlight_regulator";
-               vin-supply = <&vcc33_sys>;
-               startup-delay-us = <15000>;
-       };
-};
-
-&backlight {
-       power-supply = <&backlight_regulator>;
 };
 
 &cpu_alert0 {
        temperature = <90000>;
 };
 
-&panel {
-       power-supply= <&panel_regulator>;
-};
-
 &rk808 {
        pinctrl-names = "default";
        pinctrl-0 = <&pmic_int_l>;
 };
 
 &pinctrl {
-       backlight {
-               bl_pwr_en: bl_pwr_en {
-                       rockchip,pins = <2 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
        buck-5v {
                drv_5v: drv-5v {
                        rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
 
-       lcd {
-               lcd_enable_h: lcd-en {
-                       rockchip,pins = <7 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-
-               avdd_1v8_disp_en: avdd-1v8-disp-en {
-                       rockchip,pins = <2 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
        pmic {
                dvs_1: dvs-1 {
                        rockchip,pins = <7 RK_PB4 RK_FUNC_GPIO &pcfg_pull_down>;
diff --git a/arch/arm/boot/dts/rk3288-veyron-tiger.dts b/arch/arm/boot/dts/rk3288-veyron-tiger.dts
new file mode 100644 (file)
index 0000000..2755720
--- /dev/null
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Veyron Tiger Rev 0+ board device tree source
+ *
+ * Copyright 2016 Google, Inc
+ */
+
+/dts-v1/;
+#include "rk3288-veyron-fievel.dts"
+#include "rk3288-veyron-edp.dtsi"
+
+/ {
+       model = "Google Tiger";
+       compatible = "google,veyron-tiger-rev8", "google,veyron-tiger-rev7",
+                    "google,veyron-tiger-rev6", "google,veyron-tiger-rev5",
+                    "google,veyron-tiger-rev4", "google,veyron-tiger-rev3",
+                    "google,veyron-tiger-rev2", "google,veyron-tiger-rev1",
+                    "google,veyron-tiger-rev0", "google,veyron-tiger",
+                    "google,veyron", "rockchip,rk3288";
+
+       /delete-node/ vcc18-lcd;
+};
+
+&backlight {
+       /* Tiger panel PWM must be >= 1%, so start non-zero brightness at 3 */
+       brightness-levels = <
+                 0   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>;
+};
+
+&backlight_regulator {
+       vin-supply = <&vccsys>;
+};
+
+&i2c3 {
+       status = "okay";
+
+       clock-frequency = <400000>;
+       i2c-scl-falling-time-ns = <50>;
+       i2c-scl-rising-time-ns = <300>;
+
+       touchscreen@10 {
+               compatible = "elan,ekth3500";
+               reg = <0x10>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <RK_PB6 IRQ_TYPE_EDGE_FALLING>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&touch_int &touch_rst>;
+               reset-gpios = <&gpio2 RK_PB7 GPIO_ACTIVE_LOW>;
+               vcc33-supply = <&vcc33_io>;
+               vccio-supply = <&vcc33_io>;
+               wakeup-source;
+       };
+};
+
+&panel {
+       compatible = "auo,b101ean01", "simple-panel";
+
+       /delete-node/ panel-timing;
+
+       panel-timing {
+               clock-frequency = <66666667>;
+               hactive = <1280>;
+               hfront-porch = <18>;
+               hback-porch = <21>;
+               hsync-len = <32>;
+               vactive = <800>;
+               vfront-porch = <4>;
+               vback-porch = <8>;
+               vsync-len = <18>;
+       };
+};
+
+&pinctrl {
+       lcd {
+               /delete-node/ avdd-1v8-disp-en;
+       };
+
+       touchscreen {
+               touch_int: touch-int {
+                       rockchip,pins = <2 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               touch_rst: touch-rst {
+                       rockchip,pins = <2 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
index 8fc8eac..7525e3d 100644 (file)
                        rockchip,pins = <4 RK_PD7 RK_FUNC_GPIO &pcfg_pull_down>;
                };
 
+               bt_host_wake_l: bt-host-wake-l {
+                       rockchip,pins = <4 RK_PD7 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
                /*
                 * We run sdio0 at max speed; bump up drive strength.
                 * We also have external pulls, so disable the internal ones.
index ec19664..4f3993c 100644 (file)
@@ -85,6 +85,7 @@
                                clocks = <&l4_main_clk>;
                                clock-names = "apb_pclk";
                                resets = <&rst DMA_RESET>;
+                               reset-names = "dma";
                        };
                };
 
 
                nand0: nand@ff900000 {
                        #address-cells = <0x1>;
-                       #size-cells = <0x1>;
+                       #size-cells = <0x0>;
                        compatible = "altr,socfpga-denali-nand";
                        reg = <0xff900000 0x100000>,
                              <0xffb80000 0x10000>;
index a0a6d85..2a86e72 100644 (file)
@@ -68,6 +68,8 @@
                                #dma-requests = <32>;
                                clocks = <&l4_main_clk>;
                                clock-names = "apb_pclk";
+                               resets = <&rst DMA_RESET>, <&rst DMA_OCP_RESET>;
+                               reset-names = "dma", "dma-ocp";
                        };
                };
 
 
                nand: nand@ffb90000 {
                        #address-cells = <1>;
-                       #size-cells = <1>;
+                       #size-cells = <0>;
                        compatible = "altr,socfpga-denali-nand";
                        reg = <0xffb90000 0x72000>,
                              <0xffb80000 0x10000>;
                        cdns,fifo-width = <4>;
                        cdns,trigger-address = <0x00000000>;
                        clocks = <&qspi_clk>;
-                       resets = <&rst QSPI_RESET>;
+                       resets = <&rst QSPI_RESET>, <&rst QSPI_OCP_RESET>;
+                       reset-names = "qspi", "qspi-ocp";
                        status = "disabled";
                };
 
index e36e0a0..9bd9e04 100644 (file)
@@ -9,12 +9,18 @@
 &nand {
        status = "okay";
 
-       partition@nand-boot {
-               label = "Boot and fpga data";
-               reg = <0x0 0x1C00000>;
-       };
-       partition@nand-rootfs {
-               label = "Root Filesystem - JFFS2";
-               reg = <0x1C00000 0x6400000>;
+       nand@0 {
+               reg = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               partition@0 {
+                       label = "Boot and fpga data";
+                       reg = <0x0 0x1C00000>;
+               };
+               partition@1c00000 {
+                       label = "Root Filesystem - JFFS2";
+                       reg = <0x1C00000 0x6400000>;
+               };
        };
 };
index 355b3db..a060718 100644 (file)
 
                hps_temp0 {
                        label = "BTN_0";                        /* TEMP_OS */
-                       gpios = <&portc 18 GPIO_ACTIVE_LOW>;    /* HPS_GPIO60 */
+                       gpios = <&portc 18 GPIO_ACTIVE_LOW>;    /* HPS_GPI5 */
                        linux,code = <BTN_0>;
                };
 
                hps_hkey0 {
-                       label = "BTN_1";                        /* DIS_PWR */
-                       gpios = <&portc 19 GPIO_ACTIVE_LOW>;    /* HPS_GPIO61 */
+                       label = "GP_SWITCH";                    /* GP_SWITCH */
+                       gpios = <&portc 19 GPIO_ACTIVE_LOW>;    /* HPS_GPI6 */
                        linux,code = <BTN_1>;
                };
 
                hps_hkey1 {
-                       label = "hps_hkey1";                    /* POWER_DOWN */
-                       gpios = <&portc 20 GPIO_ACTIVE_LOW>;    /* HPS_GPIO62 */
+                       label = "RESET_SWITCH";                 /* RESET_SWITCH */
+                       gpios = <&portc 20 GPIO_ACTIVE_LOW>;    /* HPS_GPI7 */
+                       linux,code = <BTN_2>;
+               };
+
+               hps_hkey2 {
+                       label = "POWER_DOWN";                   /* POWER_DOWN */
+                       gpios = <&portc 4 GPIO_ACTIVE_LOW>;     /* HPS_GPIO62 */
                        linux,code = <KEY_POWER>;
                };
+
+               hps_hkey3 {
+                       label = "SENSE";                        /* SENSE */
+                       gpios = <&porta 9 GPIO_ACTIVE_LOW>;     /* HPS_GPIO9 */
+                       linux,code = <BTN_3>;
+               };
        };
 
        regulator-usb-nrst {
                        rxd1-skew-ps = <0>;
                        rxd2-skew-ps = <0>;
                        rxd3-skew-ps = <0>;
+                       txd0-skew-ps = <0>;
+                       txd1-skew-ps = <0>;
+                       txd2-skew-ps = <0>;
+                       txd3-skew-ps = <0>;
                        txen-skew-ps = <0>;
-                       txc-skew-ps = <2600>;
+                       txc-skew-ps = <1860>;
                        rxdv-skew-ps = <0>;
-                       rxc-skew-ps = <2000>;
+                       rxc-skew-ps = <1860>;
                };
        };
 };
diff --git a/arch/arm/boot/dts/ste-ab8500.dtsi b/arch/arm/boot/dts/ste-ab8500.dtsi
new file mode 100644 (file)
index 0000000..55fff4d
--- /dev/null
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2012 Linaro Ltd
+ */
+
+#include <dt-bindings/clock/ste-ab8500.h>
+
+/ {
+       soc {
+               prcmu@80157000 {
+                       ab8500 {
+                               compatible = "stericsson,ab8500";
+                               interrupt-parent = <&intc>;
+                               interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+
+                               ab8500_clock: clock-controller {
+                                       compatible = "stericsson,ab8500-clk";
+                                       #clock-cells = <1>;
+                               };
+
+                               ab8500_gpio: ab8500-gpio {
+                                       compatible = "stericsson,ab8500-gpio";
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                               };
+
+                               ab8500-rtc {
+                                       compatible = "stericsson,ab8500-rtc";
+                                       interrupts = <17 IRQ_TYPE_LEVEL_HIGH
+                                                     18 IRQ_TYPE_LEVEL_HIGH>;
+                                       interrupt-names = "60S", "ALARM";
+                               };
+
+                               ab8500-gpadc {
+                                       compatible = "stericsson,ab8500-gpadc";
+                                       interrupts = <32 IRQ_TYPE_LEVEL_HIGH
+                                                     39 IRQ_TYPE_LEVEL_HIGH>;
+                                       interrupt-names = "HW_CONV_END", "SW_CONV_END";
+                                       vddadc-supply = <&ab8500_ldo_tvout_reg>;
+                               };
+
+                               ab8500_battery: ab8500_battery {
+                                       stericsson,battery-type = "LIPO";
+                                       thermistor-on-batctrl;
+                               };
+
+                               ab8500_fg {
+                                       compatible = "stericsson,ab8500-fg";
+                                       battery    = <&ab8500_battery>;
+                               };
+
+                               ab8500_btemp {
+                                       compatible = "stericsson,ab8500-btemp";
+                                       battery    = <&ab8500_battery>;
+                               };
+
+                               ab8500_charger {
+                                       compatible      = "stericsson,ab8500-charger";
+                                       battery         = <&ab8500_battery>;
+                                       vddadc-supply   = <&ab8500_ldo_tvout_reg>;
+                               };
+
+                               ab8500_chargalg {
+                                       compatible      = "stericsson,ab8500-chargalg";
+                                       battery         = <&ab8500_battery>;
+                               };
+
+                               ab8500_usb {
+                                       compatible = "stericsson,ab8500-usb";
+                                       interrupts = < 90 IRQ_TYPE_LEVEL_HIGH
+                                                      96 IRQ_TYPE_LEVEL_HIGH
+                                                      14 IRQ_TYPE_LEVEL_HIGH
+                                                      15 IRQ_TYPE_LEVEL_HIGH
+                                                      79 IRQ_TYPE_LEVEL_HIGH
+                                                      74 IRQ_TYPE_LEVEL_HIGH
+                                                      75 IRQ_TYPE_LEVEL_HIGH>;
+                                       interrupt-names = "ID_WAKEUP_R",
+                                                         "ID_WAKEUP_F",
+                                                         "VBUS_DET_F",
+                                                         "VBUS_DET_R",
+                                                         "USB_LINK_STATUS",
+                                                         "USB_ADP_PROBE_PLUG",
+                                                         "USB_ADP_PROBE_UNPLUG";
+                                       vddulpivio18-supply = <&ab8500_ldo_intcore_reg>;
+                                       v-ape-supply = <&db8500_vape_reg>;
+                                       musb_1v8-supply = <&db8500_vsmps2_reg>;
+                                       clocks = <&prcmu_clk PRCMU_SYSCLK>;
+                                       clock-names = "sysclk";
+                               };
+
+                               ab8500-ponkey {
+                                       compatible = "stericsson,ab8500-poweron-key";
+                                       interrupts = <6 IRQ_TYPE_LEVEL_HIGH
+                                                     7 IRQ_TYPE_LEVEL_HIGH>;
+                                       interrupt-names = "ONKEY_DBF", "ONKEY_DBR";
+                               };
+
+                               ab8500-sysctrl {
+                                       compatible = "stericsson,ab8500-sysctrl";
+                               };
+
+                               ab8500-pwm {
+                                       compatible = "stericsson,ab8500-pwm";
+                                       clocks = <&ab8500_clock AB8500_SYSCLK_INT>;
+                                       clock-names = "intclk";
+                               };
+
+                               ab8500-debugfs {
+                                       compatible = "stericsson,ab8500-debug";
+                               };
+
+                               codec: ab8500-codec {
+                                       compatible = "stericsson,ab8500-codec";
+
+                                       V-AUD-supply = <&ab8500_ldo_audio_reg>;
+                                       V-AMIC1-supply = <&ab8500_ldo_anamic1_reg>;
+                                       V-AMIC2-supply = <&ab8500_ldo_anamic2_reg>;
+                                       V-DMIC-supply = <&ab8500_ldo_dmic_reg>;
+
+                                       clocks = <&ab8500_clock AB8500_SYSCLK_AUDIO>;
+                                       clock-names = "audioclk";
+
+                                       stericsson,earpeice-cmv = <950>; /* Units in mV. */
+                               };
+
+                               ext_regulators: ab8500-ext-regulators {
+                                       compatible = "stericsson,ab8500-ext-regulator";
+
+                                       ab8500_ext1_reg: ab8500_ext1 {
+                                               regulator-min-microvolt = <1800000>;
+                                               regulator-max-microvolt = <1800000>;
+                                               regulator-boot-on;
+                                               regulator-always-on;
+                                       };
+
+                                       ab8500_ext2_reg: ab8500_ext2 {
+                                               regulator-min-microvolt = <1360000>;
+                                               regulator-max-microvolt = <1360000>;
+                                               regulator-boot-on;
+                                               regulator-always-on;
+                                       };
+
+                                       ab8500_ext3_reg: ab8500_ext3 {
+                                               regulator-min-microvolt = <3400000>;
+                                               regulator-max-microvolt = <3400000>;
+                                               regulator-boot-on;
+                                       };
+                               };
+
+                               ab8500-regulators {
+                                       compatible = "stericsson,ab8500-regulator";
+                                       vin-supply = <&ab8500_ext3_reg>;
+
+                                       // supplies to the display/camera
+                                       ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
+                                               regulator-min-microvolt = <2500000>;
+                                               regulator-max-microvolt = <2900000>;
+                                               regulator-boot-on;
+                                               /* BUG: If turned off MMC will be affected. */
+                                               regulator-always-on;
+                                       };
+
+                                       // supplies to the on-board eMMC
+                                       ab8500_ldo_aux2_reg: ab8500_ldo_aux2 {
+                                               regulator-min-microvolt = <1100000>;
+                                               regulator-max-microvolt = <3300000>;
+                                       };
+
+                                       // supply for VAUX3; SDcard slots
+                                       ab8500_ldo_aux3_reg: ab8500_ldo_aux3 {
+                                               regulator-min-microvolt = <1100000>;
+                                               regulator-max-microvolt = <3300000>;
+                                       };
+
+                                       // supply for v-intcore12; VINTCORE12 LDO
+                                       ab8500_ldo_intcore_reg: ab8500_ldo_intcore {
+                                       };
+
+                                       // supply for tvout; gpadc; TVOUT LDO
+                                       ab8500_ldo_tvout_reg: ab8500_ldo_tvout {
+                                       };
+
+                                       // supply for ab8500-vaudio; VAUDIO LDO
+                                       ab8500_ldo_audio_reg: ab8500_ldo_audio {
+                                       };
+
+                                       // supply for v-anamic1 VAMIC1 LDO
+                                       ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
+                                       };
+
+                                       // supply for v-amic2; VAMIC2 LDO; reuse constants for AMIC1
+                                       ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 {
+                                       };
+
+                                       // supply for v-dmic; VDMIC LDO
+                                       ab8500_ldo_dmic_reg: ab8500_ldo_dmic {
+                                       };
+
+                                       // supply for U8500 CSI/DSI; VANA LDO
+                                       ab8500_ldo_ana_reg: ab8500_ldo_ana {
+                                       };
+                               };
+                       };
+               };
+
+               sound {
+                       stericsson,audio-codec = <&codec>;
+                       clocks = <&prcmu_clk PRCMU_SYSCLK>, <&ab8500_clock AB8500_SYSCLK_ULP>, <&ab8500_clock AB8500_SYSCLK_INT>;
+                       clock-names = "sysclk", "ulpclk", "intclk";
+               };
+
+               mcde@a0350000 {
+                       vana-supply = <&ab8500_ldo_ana_reg>;
+
+                       dsi@a0351000 {
+                               vana-supply = <&ab8500_ldo_ana_reg>;
+                       };
+                       dsi@a0352000 {
+                               vana-supply = <&ab8500_ldo_ana_reg>;
+                       };
+                       dsi@a0353000 {
+                               vana-supply = <&ab8500_ldo_ana_reg>;
+                       };
+               };
+       };
+};
index b1a3113..a53657b 100644 (file)
@@ -8,7 +8,6 @@
 #include <dt-bindings/mfd/dbx500-prcmu.h>
 #include <dt-bindings/arm/ux500_pm_domains.h>
 #include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/clock/ste-ab8500.h>
 
 / {
        #address-cells = <1>;
@@ -44,6 +43,7 @@
                        clocks = <&prcmu_clk PRCMU_ARMSS>;
                        clock-names = "cpu";
                        clock-latency = <20000>;
+                       #cooling-cells = <2>;
                };
                CPU1: cpu@301 {
                        device_type = "cpu";
                };
        };
 
+       thermal-zones {
+               /*
+                * Thermal zone for the SoC, using the thermal sensor in the
+                * PRCMU for temperature and the cpufreq driver for passive
+                * cooling.
+                */
+               cpu_thermal: cpu-thermal {
+                       polling-delay-passive = <0>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&thermal>;
+
+                       trips {
+                               cpu_alert: cpu-alert {
+                                       temperature = <70000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                               cpu-crit {
+                                       temperature = <85000>;
+                                       hysteresis = <0>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               trip = <&cpu_alert>;
+                               cooling-device = <&CPU0 0 2>;
+                               contribution = <100>;
+                       };
+               };
+       };
+
        soc {
                #address-cells = <1>;
                #size-cells = <1>;
                };
 
                funnel@801a6000 {
-                       compatible = "arm,coresight-funnel", "arm,primecell";
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
                        reg = <0x801a6000 0x1000>;
 
                        clocks = <&prcmu_clk PRCMU_APETRACECLK>, <&prcmu_clk PRCMU_APEATCLK>;
                };
 
                replicator {
-                       compatible = "arm,coresight-replicator";
+                       compatible = "arm,coresight-static-replicator";
                        clocks = <&prcmu_clk PRCMU_APEATCLK>;
                        clock-names = "atclk";
 
                                reg = <0x80157450 0xC>;
                        };
 
-                       thermal@801573c0 {
+                       thermal: thermal@801573c0 {
                                compatible = "stericsson,db8500-thermal";
                                reg = <0x801573c0 0x40>;
+                               interrupt-parent = <&prcmu>;
                                interrupts = <21 IRQ_TYPE_LEVEL_HIGH>,
                                             <22 IRQ_TYPE_LEVEL_HIGH>;
                                interrupt-names = "IRQ_HOTMON_LOW", "IRQ_HOTMON_HIGH";
-                               status = "disabled";
+                               #thermal-sensor-cells = <0>;
                        };
 
                        db8500-prcmu-regulators {
                                db8500_esram34_ret_reg: db8500_esram34_ret {
                                };
                        };
-
-                       ab8500 {
-                               compatible = "stericsson,ab8500";
-                               interrupt-parent = <&intc>;
-                               interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-
-                               ab8500_clock: clock-controller {
-                                       compatible = "stericsson,ab8500-clk";
-                                       #clock-cells = <1>;
-                               };
-
-                               ab8500_gpio: ab8500-gpio {
-                                       compatible = "stericsson,ab8500-gpio";
-                                       gpio-controller;
-                                       #gpio-cells = <2>;
-                               };
-
-                               ab8500-rtc {
-                                       compatible = "stericsson,ab8500-rtc";
-                                       interrupts = <17 IRQ_TYPE_LEVEL_HIGH
-                                                     18 IRQ_TYPE_LEVEL_HIGH>;
-                                       interrupt-names = "60S", "ALARM";
-                               };
-
-                               ab8500-gpadc {
-                                       compatible = "stericsson,ab8500-gpadc";
-                                       interrupts = <32 IRQ_TYPE_LEVEL_HIGH
-                                                     39 IRQ_TYPE_LEVEL_HIGH>;
-                                       interrupt-names = "HW_CONV_END", "SW_CONV_END";
-                                       vddadc-supply = <&ab8500_ldo_tvout_reg>;
-                               };
-
-                               ab8500_battery: ab8500_battery {
-                                       stericsson,battery-type = "LIPO";
-                                       thermistor-on-batctrl;
-                               };
-
-                               ab8500_fg {
-                                       compatible = "stericsson,ab8500-fg";
-                                       battery    = <&ab8500_battery>;
-                               };
-
-                               ab8500_btemp {
-                                       compatible = "stericsson,ab8500-btemp";
-                                       battery    = <&ab8500_battery>;
-                               };
-
-                               ab8500_charger {
-                                       compatible      = "stericsson,ab8500-charger";
-                                       battery         = <&ab8500_battery>;
-                                       vddadc-supply   = <&ab8500_ldo_tvout_reg>;
-                               };
-
-                               ab8500_chargalg {
-                                       compatible      = "stericsson,ab8500-chargalg";
-                                       battery         = <&ab8500_battery>;
-                               };
-
-                               ab8500_usb {
-                                       compatible = "stericsson,ab8500-usb";
-                                       interrupts = < 90 IRQ_TYPE_LEVEL_HIGH
-                                                      96 IRQ_TYPE_LEVEL_HIGH
-                                                      14 IRQ_TYPE_LEVEL_HIGH
-                                                      15 IRQ_TYPE_LEVEL_HIGH
-                                                      79 IRQ_TYPE_LEVEL_HIGH
-                                                      74 IRQ_TYPE_LEVEL_HIGH
-                                                      75 IRQ_TYPE_LEVEL_HIGH>;
-                                       interrupt-names = "ID_WAKEUP_R",
-                                                         "ID_WAKEUP_F",
-                                                         "VBUS_DET_F",
-                                                         "VBUS_DET_R",
-                                                         "USB_LINK_STATUS",
-                                                         "USB_ADP_PROBE_PLUG",
-                                                         "USB_ADP_PROBE_UNPLUG";
-                                       vddulpivio18-supply = <&ab8500_ldo_intcore_reg>;
-                                       v-ape-supply = <&db8500_vape_reg>;
-                                       musb_1v8-supply = <&db8500_vsmps2_reg>;
-                                       clocks = <&prcmu_clk PRCMU_SYSCLK>;
-                                       clock-names = "sysclk";
-                               };
-
-                               ab8500-ponkey {
-                                       compatible = "stericsson,ab8500-poweron-key";
-                                       interrupts = <6 IRQ_TYPE_LEVEL_HIGH
-                                                     7 IRQ_TYPE_LEVEL_HIGH>;
-                                       interrupt-names = "ONKEY_DBF", "ONKEY_DBR";
-                               };
-
-                               ab8500-sysctrl {
-                                       compatible = "stericsson,ab8500-sysctrl";
-                               };
-
-                               ab8500-pwm {
-                                       compatible = "stericsson,ab8500-pwm";
-                                       clocks = <&ab8500_clock AB8500_SYSCLK_INT>;
-                                       clock-names = "intclk";
-                               };
-
-                               ab8500-debugfs {
-                                       compatible = "stericsson,ab8500-debug";
-                               };
-
-                               codec: ab8500-codec {
-                                       compatible = "stericsson,ab8500-codec";
-
-                                       V-AUD-supply = <&ab8500_ldo_audio_reg>;
-                                       V-AMIC1-supply = <&ab8500_ldo_anamic1_reg>;
-                                       V-AMIC2-supply = <&ab8500_ldo_anamic2_reg>;
-                                       V-DMIC-supply = <&ab8500_ldo_dmic_reg>;
-
-                                       clocks = <&ab8500_clock AB8500_SYSCLK_AUDIO>;
-                                       clock-names = "audioclk";
-
-                                       stericsson,earpeice-cmv = <950>; /* Units in mV. */
-                               };
-
-                               ext_regulators: ab8500-ext-regulators {
-                                       compatible = "stericsson,ab8500-ext-regulator";
-
-                                       ab8500_ext1_reg: ab8500_ext1 {
-                                               regulator-min-microvolt = <1800000>;
-                                               regulator-max-microvolt = <1800000>;
-                                               regulator-boot-on;
-                                               regulator-always-on;
-                                       };
-
-                                       ab8500_ext2_reg: ab8500_ext2 {
-                                               regulator-min-microvolt = <1360000>;
-                                               regulator-max-microvolt = <1360000>;
-                                               regulator-boot-on;
-                                               regulator-always-on;
-                                       };
-
-                                       ab8500_ext3_reg: ab8500_ext3 {
-                                               regulator-min-microvolt = <3400000>;
-                                               regulator-max-microvolt = <3400000>;
-                                               regulator-boot-on;
-                                       };
-                               };
-
-                               ab8500-regulators {
-                                       compatible = "stericsson,ab8500-regulator";
-                                       vin-supply = <&ab8500_ext3_reg>;
-
-                                       // supplies to the display/camera
-                                       ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
-                                               regulator-min-microvolt = <2500000>;
-                                               regulator-max-microvolt = <2900000>;
-                                               regulator-boot-on;
-                                               /* BUG: If turned off MMC will be affected. */
-                                               regulator-always-on;
-                                       };
-
-                                       // supplies to the on-board eMMC
-                                       ab8500_ldo_aux2_reg: ab8500_ldo_aux2 {
-                                               regulator-min-microvolt = <1100000>;
-                                               regulator-max-microvolt = <3300000>;
-                                       };
-
-                                       // supply for VAUX3; SDcard slots
-                                       ab8500_ldo_aux3_reg: ab8500_ldo_aux3 {
-                                               regulator-min-microvolt = <1100000>;
-                                               regulator-max-microvolt = <3300000>;
-                                       };
-
-                                       // supply for v-intcore12; VINTCORE12 LDO
-                                       ab8500_ldo_intcore_reg: ab8500_ldo_intcore {
-                                       };
-
-                                       // supply for tvout; gpadc; TVOUT LDO
-                                       ab8500_ldo_tvout_reg: ab8500_ldo_tvout {
-                                       };
-
-                                       // supply for ab8500-usb; USB LDO
-                                       ab8500_ldo_usb_reg: ab8500_ldo_usb {
-                                       };
-
-                                       // supply for ab8500-vaudio; VAUDIO LDO
-                                       ab8500_ldo_audio_reg: ab8500_ldo_audio {
-                                       };
-
-                                       // supply for v-anamic1 VAMIC1 LDO
-                                       ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
-                                       };
-
-                                       // supply for v-amic2; VAMIC2 LDO; reuse constants for AMIC1
-                                       ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 {
-                                       };
-
-                                       // supply for v-dmic; VDMIC LDO
-                                       ab8500_ldo_dmic_reg: ab8500_ldo_dmic {
-                                       };
-
-                                       // supply for U8500 CSI/DSI; VANA LDO
-                                       ab8500_ldo_ana_reg: ab8500_ldo_ana {
-                                       };
-                               };
-                       };
                };
 
                i2c@80004000 {
                sound {
                        compatible = "stericsson,snd-soc-mop500";
                        stericsson,cpu-dai = <&msp1 &msp3>;
-                       stericsson,audio-codec = <&codec>;
-                       clocks = <&prcmu_clk PRCMU_SYSCLK>, <&ab8500_clock AB8500_SYSCLK_ULP>, <&ab8500_clock AB8500_SYSCLK_INT>;
-                       clock-names = "sysclk", "ulpclk", "intclk";
                };
 
                msp0: msp@80123000 {
                        reg = <0xa0350000 0x1000>;
                        interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
                        epod-supply = <&db8500_b2r2_mcde_reg>;
-                       vana-supply = <&ab8500_ldo_ana_reg>;
                        clocks = <&prcmu_clk PRCMU_MCDECLK>, /* Main MCDE clock */
                                 <&prcmu_clk PRCMU_LCDCLK>, /* LCD clock */
                                 <&prcmu_clk PRCMU_PLLDSI>; /* HDMI clock */
                        dsi0: dsi@a0351000 {
                                compatible = "ste,mcde-dsi";
                                reg = <0xa0351000 0x1000>;
-                               vana-supply = <&ab8500_ldo_ana_reg>;
                                clocks = <&prcmu_clk PRCMU_DSI0CLK>, <&prcmu_clk PRCMU_DSI0ESCCLK>;
                                clock-names = "hs", "lp";
                                #address-cells = <1>;
                        dsi1: dsi@a0352000 {
                                compatible = "ste,mcde-dsi";
                                reg = <0xa0352000 0x1000>;
-                               vana-supply = <&ab8500_ldo_ana_reg>;
                                clocks = <&prcmu_clk PRCMU_DSI1CLK>, <&prcmu_clk PRCMU_DSI1ESCCLK>;
                                clock-names = "hs", "lp";
                                #address-cells = <1>;
                        dsi2: dsi@a0353000 {
                                compatible = "ste,mcde-dsi";
                                reg = <0xa0353000 0x1000>;
-                               vana-supply = <&ab8500_ldo_ana_reg>;
                                /* This DSI port only has the Low Power / Energy Save clock */
                                clocks = <&prcmu_clk PRCMU_DSI2ESCCLK>;
                                clock-names = "lp";
index 8e3e947..4946743 100644 (file)
@@ -3,6 +3,8 @@
  * Copyright 2014 Linaro Ltd.
  */
 
+#include "ste-ab8500.dtsi"
+
 / {
        soc {
                prcmu@80157000 {
index 8662119..2c382d2 100644 (file)
                                                groups =
                                                "lcdvsi0_a_1", /* VSI0 for LCD */
                                                "lcd_d0_d7_a_1", /* Data lines */
-                                               "lcd_d8_d11_a_1", /* TV-out */
                                                "lcdvsi1_a_1"; /* VSI1 for HDMI */
                                        };
                                        default_mux2 {
index b17998f..e32d0c3 100644 (file)
@@ -38,6 +38,8 @@
                                interrupt-controller;
                                vcc-supply = <&db8500_vsmps2_reg>;
                                vio-supply = <&db8500_vsmps2_reg>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&stmpe_stuib_mode>;
 
                                wakeup-source;
                                st,autosleep-timeout = <1024>;
                };
 
                pinctrl {
+                       /* Pull up this GPIO pin */
+                       stmpe {
+                               stmpe_stuib_mode: stmpe_stuib {
+                                       stuib_cfg {
+                                               ste,pins = "GPIO218_AH11";
+                                               ste,config = <&gpio_in_pu>;
+                                       };
+                               };
+                       };
                        prox {
                                prox_stuib_mode: prox_stuib {
                                        stuib_cfg {
index 6422c53..4f6acbd 100644 (file)
                                                regulator-name = "V-TVOUT";
                                        };
 
-                                       ab8500_ldo_usb_reg: ab8500_ldo_usb {
-                                               regulator-name = "dummy";
-                                       };
-
                                        ab8500_ldo_audio_reg: ab8500_ldo_audio {
                                                regulator-name = "V-AUD";
                                        };
index aed940b..b78be5f 100644 (file)
@@ -4,6 +4,8 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 #include "ste-hrefprev60.dtsi"
 #include "ste-href-stuib.dtsi"
 
                i2c@80110000 {
                        /* Only one of these will be used */
                        bu21013_tp@5c {
-                               touch-gpio = <&gpio2 12 0x4>;
-                               reset-gpio = <&tc3589x_gpio 13 0x4>;
+                               interrupt-parent = <&gpio2>;
+                               interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
+                               touch-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+                               reset-gpios = <&tc3589x_gpio 13 GPIO_LINE_OPEN_DRAIN>;
                        };
                        bu21013_tp@5d {
-                               touch-gpio = <&gpio2 12 0x4>;
-                               reset-gpio = <&tc3589x_gpio 13 0x4>;
+                               interrupt-parent = <&gpio2>;
+                               interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
+                               touch-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+                               reset-gpios = <&tc3589x_gpio 13 GPIO_LINE_OPEN_DRAIN>;
                        };
                };
        };
index 0f3c3b8..9be513a 100644 (file)
@@ -6,6 +6,8 @@
  */
 
 /dts-v1/;
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
 #include "ste-hrefv60plus.dtsi"
 #include "ste-href-stuib.dtsi"
 
                i2c@80110000 {
                        /* Only one of these will be used */
                        bu21013_tp@5c {
-                               touch-gpio = <&gpio2 20 0x4>;
-                               reset-gpio = <&gpio4 17 0x4>;
+                               interrupt-parent = <&gpio2>;
+                               interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+                               touch-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>;
+                               reset-gpios = <&gpio4 17 GPIO_LINE_OPEN_DRAIN>;
                        };
                        bu21013_tp@5d {
-                               touch-gpio = <&gpio2 20 0x4>;
-                               reset-gpio = <&gpio4 17 0x4>;
+                               interrupt-parent = <&gpio2>;
+                               interrupts = <20 IRQ_TYPE_LEVEL_LOW>;
+                               touch-gpios = <&gpio2 20 GPIO_ACTIVE_LOW>;
+                               reset-gpios = <&gpio4 17 GPIO_LINE_OPEN_DRAIN>;
                        };
                };
        };
index 04066f9..41ed21a 100644 (file)
                 */
                gpio-sck = <&gpio0 5 GPIO_ACTIVE_HIGH>;
                gpio-mosi = <&gpio0 4 GPIO_ACTIVE_HIGH>;
-               /*
-                * It's not actually active high, but the frameworks assume
-                * the polarity of the passed-in GPIO is "normal" (active
-                * high) then actively drives the line low to select the
-                * chip.
-                */
-               cs-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+               cs-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
                num-chipselects = <1>;
 
                /*
index 3428290..efbc446 100644 (file)
                        pinctrl-0 = <&ssp0_snowball_mode>;
                };
 
-               cpufreq-cooling {
-                       status = "okay";
-               };
-
                prcmu@80157000 {
                        cpufreq {
                                status = "okay";
                        };
 
-                       thermal@801573c0 {
-                               num-trips = <4>;
-
-                               trip0-temp = <70000>;
-                               trip0-type = "active";
-                               trip0-cdev-num = <1>;
-                               trip0-cdev-name0 = "thermal-cpufreq-0";
-
-                               trip1-temp = <75000>;
-                               trip1-type = "active";
-                               trip1-cdev-num = <1>;
-                               trip1-cdev-name0 = "thermal-cpufreq-0";
-
-                               trip2-temp = <80000>;
-                               trip2-type = "active";
-                               trip2-cdev-num = <1>;
-                               trip2-cdev-name0 = "thermal-cpufreq-0";
-
-                               trip3-temp = <85000>;
-                               trip3-type = "critical";
-                               trip3-cdev-num = <0>;
-
-                               status = "okay";
-                       };
-
                        ab8500 {
                                ab8500-gpio {
                                        /*
                                                regulator-name = "V-TVOUT";
                                        };
 
-                                       ab8500_ldo_usb_reg: ab8500_ldo_usb {
-                                               regulator-name = "dummy";
-                                       };
-
                                        ab8500_ldo_audio_reg: ab8500_ldo_audio {
                                                regulator-name = "V-AUD";
                                        };
index 73ea84d..ba08624 100644 (file)
                dma-ranges = <0xc0000000 0x0 0x10000000>;
        };
 
-       regulators {
-               compatible = "simple-bus";
-               #address-cells = <1>;
-               #size-cells = <0>;
+       vdda: regulator-vdda {
+               compatible = "regulator-fixed";
+               regulator-name = "vdda";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
 
-               reg_vref: regulator@0 {
-                       compatible = "regulator-fixed";
-                       reg = <0>;
-                       regulator-name = "vref";
-                       regulator-min-microvolt = <3300000>;
-                       regulator-max-microvolt = <3300000>;
-               };
+       vref: regulator-vref {
+               compatible = "regulator-fixed";
+               regulator-name = "vref";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
        };
 
        leds {
 &adc {
        pinctrl-names = "default";
        pinctrl-0 = <&adc3_in8_pin>;
-       vref-supply = <&reg_vref>;
+       vdda-supply = <&vdda>;
+       vref-supply = <&vref>;
        status = "okay";
        adc3: adc@200 {
                st,adc-channels = <8>;
index 4a49544..5c8a826 100644 (file)
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
                };
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
                };
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
                };
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
                };
index a25b700..d26f93f 100644 (file)
@@ -94,6 +94,7 @@
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
                };
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
                };
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
                };
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
                };
index ab78ad5..e4d3c58 100644 (file)
@@ -87,6 +87,7 @@
 };
 
 &adc_12 {
+       vdda-supply = <&vdda>;
        vref-supply = <&vdda>;
        status = "okay";
        adc1: adc@0 {
index df64701..e4a0d51 100644 (file)
@@ -24,8 +24,6 @@
                                reg = <0x0 0x400>;
                                clocks = <&rcc GPIOA>;
                                st,bank-name = "GPIOA";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 0 16>;
                                status = "disabled";
                        };
 
@@ -37,8 +35,6 @@
                                reg = <0x1000 0x400>;
                                clocks = <&rcc GPIOB>;
                                st,bank-name = "GPIOB";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 16 16>;
                                status = "disabled";
                        };
 
@@ -50,8 +46,6 @@
                                reg = <0x2000 0x400>;
                                clocks = <&rcc GPIOC>;
                                st,bank-name = "GPIOC";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 32 16>;
                                status = "disabled";
                        };
 
@@ -63,8 +57,6 @@
                                reg = <0x3000 0x400>;
                                clocks = <&rcc GPIOD>;
                                st,bank-name = "GPIOD";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 48 16>;
                                status = "disabled";
                        };
 
@@ -76,8 +68,6 @@
                                reg = <0x4000 0x400>;
                                clocks = <&rcc GPIOE>;
                                st,bank-name = "GPIOE";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 64 16>;
                                status = "disabled";
                        };
 
@@ -89,8 +79,6 @@
                                reg = <0x5000 0x400>;
                                clocks = <&rcc GPIOF>;
                                st,bank-name = "GPIOF";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 80 16>;
                                status = "disabled";
                        };
 
                                reg = <0x6000 0x400>;
                                clocks = <&rcc GPIOG>;
                                st,bank-name = "GPIOG";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 96 16>;
                                status = "disabled";
                        };
 
                                reg = <0x7000 0x400>;
                                clocks = <&rcc GPIOH>;
                                st,bank-name = "GPIOH";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 112 16>;
                                status = "disabled";
                        };
 
                                reg = <0x8000 0x400>;
                                clocks = <&rcc GPIOI>;
                                st,bank-name = "GPIOI";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 128 16>;
                                status = "disabled";
                        };
 
                                reg = <0x9000 0x400>;
                                clocks = <&rcc GPIOJ>;
                                st,bank-name = "GPIOJ";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 144 16>;
                                status = "disabled";
                        };
 
                                reg = <0xa000 0x400>;
                                clocks = <&rcc GPIOK>;
                                st,bank-name = "GPIOK";
-                               ngpios = <8>;
-                               gpio-ranges = <&pinctrl 0 160 8>;
                                status = "disabled";
                        };
 
                                };
                        };
 
+                       fmc_pins_a: fmc-0 {
+                               pins1 {
+                                       pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
+                                                <STM32_PINMUX('D', 5, AF12)>, /* FMC_NWE */
+                                                <STM32_PINMUX('D', 11, AF12)>, /* FMC_A16_FMC_CLE */
+                                                <STM32_PINMUX('D', 12, AF12)>, /* FMC_A17_FMC_ALE */
+                                                <STM32_PINMUX('D', 14, AF12)>, /* FMC_D0 */
+                                                <STM32_PINMUX('D', 15, AF12)>, /* FMC_D1 */
+                                                <STM32_PINMUX('D', 0, AF12)>, /* FMC_D2 */
+                                                <STM32_PINMUX('D', 1, AF12)>, /* FMC_D3 */
+                                                <STM32_PINMUX('E', 7, AF12)>, /* FMC_D4 */
+                                                <STM32_PINMUX('E', 8, AF12)>, /* FMC_D5 */
+                                                <STM32_PINMUX('E', 9, AF12)>, /* FMC_D6 */
+                                                <STM32_PINMUX('E', 10, AF12)>, /* FMC_D7 */
+                                                <STM32_PINMUX('G', 9, AF12)>; /* FMC_NE2_FMC_NCE */
+                                       bias-disable;
+                                       drive-push-pull;
+                                       slew-rate = <1>;
+                               };
+                               pins2 {
+                                       pinmux = <STM32_PINMUX('D', 6, AF12)>; /* FMC_NWAIT */
+                                       bias-pull-up;
+                               };
+                       };
+
+                       fmc_sleep_pins_a: fmc-sleep-0 {
+                               pins {
+                                       pinmux = <STM32_PINMUX('D', 4, ANALOG)>, /* FMC_NOE */
+                                                <STM32_PINMUX('D', 5, ANALOG)>, /* FMC_NWE */
+                                                <STM32_PINMUX('D', 11, ANALOG)>, /* FMC_A16_FMC_CLE */
+                                                <STM32_PINMUX('D', 12, ANALOG)>, /* FMC_A17_FMC_ALE */
+                                                <STM32_PINMUX('D', 14, ANALOG)>, /* FMC_D0 */
+                                                <STM32_PINMUX('D', 15, ANALOG)>, /* FMC_D1 */
+                                                <STM32_PINMUX('D', 0, ANALOG)>, /* FMC_D2 */
+                                                <STM32_PINMUX('D', 1, ANALOG)>, /* FMC_D3 */
+                                                <STM32_PINMUX('E', 7, ANALOG)>, /* FMC_D4 */
+                                                <STM32_PINMUX('E', 8, ANALOG)>, /* FMC_D5 */
+                                                <STM32_PINMUX('E', 9, ANALOG)>, /* FMC_D6 */
+                                                <STM32_PINMUX('E', 10, ANALOG)>, /* FMC_D7 */
+                                                <STM32_PINMUX('D', 6, ANALOG)>, /* FMC_NWAIT */
+                                                <STM32_PINMUX('G', 9, ANALOG)>; /* FMC_NE2_FMC_NCE */
+                               };
+                       };
+
                        i2c1_pins_a: i2c1-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */
                                };
                        };
 
-                       m_can1_sleep_pins_a: m_can1-sleep@0 {
+                       m_can1_sleep_pins_a: m_can1-sleep-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('H', 13, ANALOG)>, /* CAN1_TX */
                                                 <STM32_PINMUX('I', 9, ANALOG)>; /* CAN1_RX */
                                clocks = <&rcc GPIOZ>;
                                st,bank-name = "GPIOZ";
                                st,bank-ioport = <11>;
-                               ngpios = <8>;
-                               gpio-ranges = <&pinctrl_z 0 400 8>;
                                status = "disabled";
                        };
 
index f3f0e37..0615d1c 100644 (file)
                #size-cells = <1>;
                ranges;
 
+               mcuram2: mcuram2@10000000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x10000000 0x40000>;
+                       no-map;
+               };
+
+               vdev0vring0: vdev0vring0@10040000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x10040000 0x1000>;
+                       no-map;
+               };
+
+               vdev0vring1: vdev0vring1@10041000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x10041000 0x1000>;
+                       no-map;
+               };
+
+               vdev0buffer: vdev0buffer@10042000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x10042000 0x4000>;
+                       no-map;
+               };
+
+               mcuram: mcuram@30000000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x30000000 0x40000>;
+                       no-map;
+               };
+
+               retram: retram@38000000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x38000000 0x10000>;
+                       no-map;
+               };
+
                gpu_reserved: gpu@d4000000 {
                        reg = <0xd4000000 0x4000000>;
                        no-map;
                        default-state = "off";
                };
        };
+
+       sound {
+               compatible = "audio-graph-card";
+               label = "STM32MP1-DK";
+               routing =
+                       "Playback" , "MCLK",
+                       "Capture" , "MCLK",
+                       "MICL" , "Mic Bias";
+               dais = <&sai2a_port &sai2b_port>;
+               status = "okay";
+       };
 };
 
 &cec {
                        };
                };
        };
+
+       cs42l51: cs42l51@4a {
+               compatible = "cirrus,cs42l51";
+               reg = <0x4a>;
+               #sound-dai-cells = <0>;
+               VL-supply = <&v3v3>;
+               VD-supply = <&v1v8_audio>;
+               VA-supply = <&v1v8_audio>;
+               VAHP-supply = <&v1v8_audio>;
+               reset-gpios = <&gpiog 9 GPIO_ACTIVE_LOW>;
+               clocks = <&sai2a>;
+               clock-names = "MCLK";
+               status = "okay";
+
+               cs42l51_port: port {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       cs42l51_tx_endpoint: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&sai2a_endpoint>;
+                               frame-master;
+                               bitclock-master;
+                       };
+
+                       cs42l51_rx_endpoint: endpoint@1 {
+                               reg = <1>;
+                               remote-endpoint = <&sai2b_endpoint>;
+                               frame-master;
+                               bitclock-master;
+                       };
+               };
+       };
 };
 
 &i2c4 {
        };
 };
 
+&m4_rproc {
+       memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
+                       <&vdev0vring1>, <&vdev0buffer>;
+       mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
+       mbox-names = "vq0", "vq1", "shutdown";
+       interrupt-parent = <&exti>;
+       interrupts = <68 1>;
+       status = "okay";
+};
+
 &rng1 {
        status = "okay";
 };
        status = "okay";
 };
 
+&sai2 {
+       clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
+       clock-names = "pclk", "x8k", "x11k";
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;
+       pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>;
+       status = "okay";
+
+       sai2a: audio-controller@4400b004 {
+               #clock-cells = <0>;
+               dma-names = "tx";
+               clocks = <&rcc SAI2_K>;
+               clock-names = "sai_ck";
+               status = "okay";
+
+               sai2a_port: port {
+                       sai2a_endpoint: endpoint {
+                               remote-endpoint = <&cs42l51_tx_endpoint>;
+                               format = "i2s";
+                               mclk-fs = <256>;
+                               dai-tdm-slot-num = <2>;
+                               dai-tdm-slot-width = <32>;
+                       };
+               };
+       };
+
+       sai2b: audio-controller@4400b024 {
+               dma-names = "rx";
+               st,sync = <&sai2a 2>;
+               clocks = <&rcc SAI2_K>, <&sai2a>;
+               clock-names = "sai_ck", "MCLK";
+               status = "okay";
+
+               sai2b_port: port {
+                       sai2b_endpoint: endpoint {
+                               remote-endpoint = <&cs42l51_rx_endpoint>;
+                               format = "i2s";
+                               mclk-fs = <256>;
+                               dai-tdm-slot-num = <2>;
+                               dai-tdm-slot-width = <32>;
+                       };
+               };
+       };
+};
+
 &sdmmc1 {
        pinctrl-names = "default", "opendrain", "sleep";
        pinctrl-0 = <&sdmmc1_b4_pins_a>;
index 4fe7f71..1d426ea 100644 (file)
                #size-cells = <1>;
                ranges;
 
+               mcuram2: mcuram2@10000000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x10000000 0x40000>;
+                       no-map;
+               };
+
+               vdev0vring0: vdev0vring0@10040000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x10040000 0x1000>;
+                       no-map;
+               };
+
+               vdev0vring1: vdev0vring1@10041000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x10041000 0x1000>;
+                       no-map;
+               };
+
+               vdev0buffer: vdev0buffer@10042000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x10042000 0x4000>;
+                       no-map;
+               };
+
+               mcuram: mcuram@30000000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x30000000 0x40000>;
+                       no-map;
+               };
+
+               retram: retram@38000000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x38000000 0x10000>;
+                       no-map;
+               };
+
                gpu_reserved: gpu@e8000000 {
                        reg = <0xe8000000 0x8000000>;
                        no-map;
        status = "okay";
 };
 
+&m4_rproc {
+       memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
+                       <&vdev0vring1>, <&vdev0buffer>;
+       mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
+       mbox-names = "vq0", "vq1", "shutdown";
+       interrupt-parent = <&exti>;
+       interrupts = <68 1>;
+       status = "okay";
+};
+
 &rng1 {
        status = "okay";
 };
index feb8f77..89d29b5 100644 (file)
 &dsi {
        #address-cells = <1>;
        #size-cells = <0>;
+       phy-dsi-supply = <&reg18>;
        status = "okay";
 
        ports {
        };
 };
 
+&fmc {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&fmc_pins_a>;
+       pinctrl-1 = <&fmc_sleep_pins_a>;
+       status = "okay";
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       nand@0 {
+               reg = <0>;
+               nand-on-flash-bbt;
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+};
+
 &i2c2 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c2_pins_a>;
index 0c4e6eb..9b11654 100644 (file)
                };
        };
 
+       booster: regulator-booster {
+               compatible = "st,stm32mp1-booster";
+               st,syscfg = <&syscfg>;
+               status = "disabled";
+       };
+
        soc {
                compatible = "simple-bus";
                #address-cells = <1>;
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
                        timer@15 {
 
                        pwm {
                                compatible = "st,stm32-pwm";
+                               #pwm-cells = <3>;
                                status = "disabled";
                        };
 
                        clocks = <&rcc ADC12>, <&rcc ADC12_K>;
                        clock-names = "bus", "adc";
                        interrupt-controller;
+                       st,syscfg = <&syscfg>;
                        #interrupt-cells = <1>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        dma-requests = <48>;
                };
 
+               fmc: nand-controller@58002000 {
+                       compatible = "st,stm32mp15-fmc2";
+                       reg = <0x58002000 0x1000>,
+                             <0x80000000 0x1000>,
+                             <0x88010000 0x1000>,
+                             <0x88020000 0x1000>,
+                             <0x81000000 0x1000>,
+                             <0x89010000 0x1000>,
+                             <0x89020000 0x1000>;
+                       interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
+                       dmas = <&mdma1 20 0x10 0x12000a02 0x0 0x0>,
+                              <&mdma1 20 0x10 0x12000a08 0x0 0x0>,
+                              <&mdma1 21 0x10 0x12000a0a 0x0 0x0>;
+                       dma-names = "tx", "rx", "ecc";
+                       clocks = <&rcc FMC_K>;
+                       resets = <&rcc FMC_R>;
+                       status = "disabled";
+               };
+
                qspi: spi@58003000 {
                        compatible = "st,stm32f469-qspi";
                        reg = <0x58003000 0x1000>, <0x70000000 0x10000000>;
                        reg-names = "qspi", "qspi_mm";
                        interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
+                       dmas = <&mdma1 22 0x10 0x100002 0x0 0x0>,
+                              <&mdma1 22 0x10 0x100008 0x0 0x0>;
+                       dma-names = "tx", "rx";
                        clocks = <&rcc QSPI_K>;
                        resets = <&rcc QSPI_R>;
                        status = "disabled";
                        status = "disabled";
                };
        };
+
+       mlahb {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               dma-ranges = <0x00000000 0x38000000 0x10000>,
+                            <0x10000000 0x10000000 0x60000>,
+                            <0x30000000 0x30000000 0x60000>;
+
+               m4_rproc: m4@10000000 {
+                       compatible = "st,stm32mp1-m4";
+                       reg = <0x10000000 0x40000>,
+                             <0x30000000 0x40000>,
+                             <0x38000000 0x10000>;
+                       resets = <&rcc MCU_R>;
+                       st,syscfg-holdboot = <&rcc 0x10C 0x1>;
+                       st,syscfg-tz = <&rcc 0x000 0x1>;
+                       status = "disabled";
+               };
+       };
 };
index 6c254ec..8692b11 100644 (file)
 };
 
 &emac {
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        status = "okay";
 };
 
index 38a2c41..816d534 100644 (file)
@@ -68,7 +68,7 @@
 };
 
 &emac {
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        status = "okay";
 };
 
index 7306c65..6ca02e8 100644 (file)
 };
 
 &emac {
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        status = "okay";
 };
 
index cc988cc..47dea09 100644 (file)
@@ -80,7 +80,7 @@
 };
 
 &emac {
-       phy = <&phy0>;
+       phy-handle = <&phy0>;
        status = "okay";
 };
 
index 80ecd78..d4e319d 100644 (file)
@@ -58,7 +58,7 @@
 &emac {
        pinctrl-names = "default";
        pinctrl-0 = <&emac_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        status = "okay";
 };
 
index 247fa27..8a7b4c5 100644 (file)
@@ -94,7 +94,7 @@
 };
 
 &emac {
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        status = "okay";
 };
 
index 58ad2ad..a843e57 100644 (file)
 };
 
 &emac {
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        status = "okay";
 };
 
index a8e537f..845f768 100644 (file)
 };
 
 &emac {
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        status = "okay";
 };
 
index 0f1e781..83287b6 100644 (file)
 };
 
 &emac {
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        status = "okay";
 };
 
index e88daa4..ce823c4 100644 (file)
                timer@1c20c00 {
                        compatible = "allwinner,sun4i-a10-timer";
                        reg = <0x01c20c00 0x90>;
-                       interrupts = <22>;
+                       interrupts = <22>,
+                                    <23>,
+                                    <24>,
+                                    <25>,
+                                    <67>,
+                                    <68>;
                        clocks = <&osc24M>;
                };
 
                wdt: watchdog@1c20c90 {
                        compatible = "allwinner,sun4i-a10-wdt";
                        reg = <0x01c20c90 0x10>;
+                       interrupts = <24>;
+                       clocks = <&osc24M>;
                };
 
                rtc: rtc@1c20d00 {
index 5340b41..7033a12 100644 (file)
@@ -98,7 +98,7 @@
 &emac {
        pinctrl-names = "default";
        pinctrl-0 = <&emac_pa_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        status = "okay";
 };
 
index b5ee8fb..1f74ba1 100644 (file)
@@ -91,7 +91,7 @@
 &emac {
        pinctrl-names = "default";
        pinctrl-0 = <&emac_pd_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        status = "okay";
 };
 
index fde559a..f9fc1c8 100644 (file)
@@ -49,7 +49,7 @@
        compatible = "allwinner,q8-a13", "allwinner,sun5i-a13";
 
        panel: panel {
-               compatible = "bananapi,s070wv20-ct16", "simple-panel";
+               compatible = "bananapi,s070wv20-ct16";
                power-supply = <&reg_vcc3v3>;
                enable-gpios = <&axp_gpio 0 GPIO_ACTIVE_HIGH>; /* AXP GPIO0 */
                backlight = <&backlight>;
index 2fb438c..cfb1efc 100644 (file)
                timer@1c20c00 {
                        compatible = "allwinner,sun4i-a10-timer";
                        reg = <0x01c20c00 0x90>;
-                       interrupts = <22>;
+                       interrupts = <22>,
+                                    <23>,
+                                    <24>,
+                                    <25>,
+                                    <67>,
+                                    <68>;
                        clocks = <&ccu CLK_HOSC>;
                };
 
                wdt: watchdog@1c20c90 {
                        compatible = "allwinner,sun4i-a10-wdt";
                        reg = <0x01c20c90 0x10>;
+                       interrupts = <24>;
+                       clocks = <&osc24M>;
                };
 
                ir0: ir@1c21800 {
index c3d56dc..93a15ea 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &i2c0 {
        };
 };
 
+&mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v0>;
        bus-width = <4>;
index 09832b4..049e6ab 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
-       snps,reset-gpio = <&pio 0 21 GPIO_ACTIVE_HIGH>;
-       snps,reset-active-low;
-       snps,reset-delays-us = <0 10000 30000>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        status = "okay";
 };
 
+&mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+               reset-gpios = <&pio 0 21 GPIO_ACTIVE_LOW>;
+               reset-assert-us = <10000>;
+               reset-deassert-us = <30000>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_dcdc1>;
        bus-width = <4>;
index 091eb2a..6cc8ccf 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        status = "okay";
 };
 
+&mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index 6eafb63..a645c8f 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        phy-supply = <&reg_dldo1>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &ir {
        status = "okay";
 };
 
+&mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_dcdc1>;
        bus-width = <4>;
index ca036f9..648f247 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        phy-supply = <&reg_dldo1>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &ir {
        status = "okay";
 };
 
+&mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_dcdc1>;
        bus-width = <4>;
index dcddc33..bbeb743 100644 (file)
                                     <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 22 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&osc24M>;
                };
 
                wdt1: watchdog@1c20ca0 {
                        compatible = "allwinner,sun6i-a31-wdt";
                        reg = <0x01c20ca0 0x20>;
+                       interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&osc24M>;
                };
 
                spdif: spdif@1c21000 {
                        snps,fixed-burst;
                        snps,force_sf_dma_mode;
                        status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
+
+                       mdio: mdio {
+                               compatible = "snps,dwmac-mdio";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                       };
                };
 
                crypto: crypto-engine@1c15000 {
                };
 
                ir: ir@1f02000 {
-                       compatible = "allwinner,sun5i-a13-ir";
+                       compatible = "allwinner,sun6i-a31-ir";
                        clocks = <&apb0_gates 1>, <&ir_clk>;
                        clock-names = "apb", "ir";
                        resets = <&apb0_rst 1>;
index 72a02c0..1d15e15 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        status = "okay";
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &ir {
        status = "okay";
 };
 
+&mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &ohci1 {
        status = "okay";
 };
index 4865c32..0af48e1 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        phy-supply = <&reg_dldo1>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        };
 };
 
+&mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_dcdc1>;
        bus-width = <4>;
index 8e724c5..708caee 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        phy-supply = <&reg_dldo1>;
-       snps,reset-gpio = <&pio 0 21 GPIO_ACTIVE_HIGH>; /* PA21 */
-       snps,reset-active-low;
-       snps,reset-delays-us = <0 10000 30000>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &ir {
        status = "okay";
 };
 
+&mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+               reset-gpios = <&pio 0 21 GPIO_ACTIVE_LOW>; /* PA21 */
+               reset-assert-us = <10000>;
+               reset-deassert-us = <30000>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_dcdc1>;
        bus-width = <4>;
index e2bfe00..32d5d45 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        phy-supply = <&reg_gmac_3v3>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index 4df9216..bb3987e 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        phy-supply = <&reg_gmac_3v3>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index 0176e9d..01ccff7 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        phy-supply = <&reg_gmac_3v3>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &i2c0 {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index 08e5a5a..b8203e4 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &ohci0 {
        status = "okay";
 };
index 99f531b..8c8dee6 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index fd0153f..3def2a3 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        phy-supply = <&reg_gmac_vdd>;
-       /* phy reset config */
-       snps,reset-gpio = <&pio 0 17 GPIO_ACTIVE_HIGH>; /* PA17 */
-       snps,reset-active-low;
-       /* wait 1s after reset, otherwise fail to read phy id */
-       snps,reset-delays-us = <0 10000 1000000>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &i2c0 {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+               reset-gpios = <&pio 0 17 GPIO_ACTIVE_LOW>; /* PA17 */
+               reset-assert-us = <10000>;
+               /* wait 1s after reset, otherwise fail to read phy id */
+               reset-deassert-us = <1000000>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v0>;
        bus-width = <4>;
index 5f1c4f5..358ed5f 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        phy-supply = <&reg_gmac_3v3>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &i2c0 {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index 7449aac..413505f 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &i2c0 {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index b90a760..946c272 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        status = "okay";
+};
 
+&gmac_mdio {
        phy1: ethernet-phy@1 {
                reg = <1>;
        };
index 3e170cf..17fa890 100644 (file)
        phy-mode = "rgmii";
        phy-supply = <&reg_gmac_3v3>;
        status = "okay";
-       /delete-property/#address-cells;
-       /delete-property/#size-cells;
 
        fixed-link {
                speed = <1000>;
index b8a1aaa..6bff9e7 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &i2c0 {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index f0e6a96..6f9c54b 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        };
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index c34a83f..230d62a 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy3>;
+       phy-handle = <&phy3>;
        phy-mode = "rgmii";
        phy-supply = <&reg_vcc3v3>;
-
-       snps,reset-gpio = <&pio 0 17 GPIO_ACTIVE_HIGH>;
-       snps,reset-active-low;
-       snps,reset-delays-us = <0 10000 1000000>;
        status = "okay";
-
-       phy3: ethernet-phy@3 {
-               reg = <3>;
-       };
 };
 
 &hdmi {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy3: ethernet-phy@3 {
+               reg = <3>;
+               reset-gpios = <&pio 0 17 GPIO_ACTIVE_LOW>; /* PA17 */
+               reset-assert-us = <10000>;
+               /* wait 1s after reset, otherwise fail to read phy id */
+               reset-deassert-us = <1000000>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index e40dd47..2adbac8 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        };
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index 56f451c..9ba6277 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        vref-supply = <&reg_vcc3v0>;
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index 0dcba07..359bd0d 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>, <&gmac_txerr>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        };
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index 9628041..2e328d2 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        phy-supply = <&reg_gmac_3v3>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index 7b35326..d75b2e2 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        phy-supply = <&reg_gmac_3v3>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &i2c0 {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index 173b676..fce2f7f 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &hdmi {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index 14a88aa..cc8271d 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_mii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "mii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &i2c0 {
        status = "okay";
 };
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index f8475a3..3bfae98 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &i2c0 {
 
 #include "axp209.dtsi"
 
+&gmac_mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_vcc3v3>;
        bus-width = <4>;
index 9ad8e44..49380de 100644 (file)
                        num-cs = <1>;
                };
 
+               csi0: csi@1c09000 {
+                       compatible = "allwinner,sun7i-a20-csi0";
+                       reg = <0x01c09000 0x1000>;
+                       interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_AHB_CSI0>, <&ccu CLK_CSI0>,
+                                <&ccu CLK_CSI_SCLK>, <&ccu CLK_DRAM_CSI0>;
+                       clock-names = "bus", "mod", "isp", "ram";
+                       resets = <&ccu RST_CSI0>;
+                       status = "disabled";
+               };
+
                emac: ethernet@1c0b000 {
                        compatible = "allwinner,sun4i-a10-emac";
                        reg = <0x01c0b000 0x1000>;
                        };
 
                        /omit-if-no-ref/
+                       csi0_8bits_pins: csi-8bits-pins {
+                               pins = "PE0", "PE2", "PE3", "PE4", "PE5",
+                                      "PE6", "PE7", "PE8", "PE9", "PE10",
+                                      "PE11";
+                               function = "csi0";
+                       };
+
+                       /omit-if-no-ref/
+                       csi0_clk_pin: csi-clk-pin {
+                               pins = "PE1";
+                               function = "csi0";
+                       };
+
+                       /omit-if-no-ref/
                        emac_pa_pins: emac-pa-pins {
                                pins = "PA0", "PA1", "PA2",
                                       "PA3", "PA4", "PA5", "PA6",
                wdt: watchdog@1c20c90 {
                        compatible = "allwinner,sun4i-a10-wdt";
                        reg = <0x01c20c90 0x10>;
+                       interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&osc24M>;
                };
 
                rtc: rtc@1c20d00 {
                        snps,fixed-burst;
                        snps,force_sf_dma_mode;
                        status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
+
+                       gmac_mdio: mdio {
+                               compatible = "snps,dwmac-mdio";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                       };
                };
 
                hstimer@1c60000 {
index af2fa69..52eed0a 100644 (file)
                };
 
                timer@1c20c00 {
-                       compatible = "allwinner,sun4i-a10-timer";
+                       compatible = "allwinner,sun8i-a23-timer";
                        reg = <0x01c20c00 0xa0>;
                        interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
                        compatible = "allwinner,sun6i-a31-wdt";
                        reg = <0x01c20ca0 0x20>;
                        interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&osc24M>;
                };
 
                pwm: pwm@1c21400 {
index 5659c63..51097c7 100644 (file)
@@ -63,7 +63,7 @@
 };
 
 &panel {
-       compatible = "bananapi,s070wv20-ct16", "simple-panel";
+       compatible = "bananapi,s070wv20-ct16";
 };
 
 &tcon0_out {
index ea299d3..fb92850 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&hdmi_out_con>;
+                       };
+               };
+       };
+
        leds {
                compatible = "gpio-leds";
 
        cpu-supply = <&reg_dcdc3>;
 };
 
+&de {
+       status = "okay";
+};
+
 &ehci0 {
        /* GL830 USB-to-SATA bridge here */
        status = "okay";
        status = "okay";
 };
 
+&hdmi {
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
 &mdio {
        rgmii_phy: ethernet-phy@1 {
                compatible = "ethernet-phy-ieee802.3-c22";
index ada6d08..523be66 100644 (file)
                display_clocks: clock@1000000 {
                        compatible = "allwinner,sun8i-a83t-de2-clk";
                        reg = <0x01000000 0x100000>;
-                       clocks = <&ccu CLK_PLL_DE>,
-                                <&ccu CLK_BUS_DE>;
-                       clock-names = "mod",
-                                     "bus";
+                       clocks = <&ccu CLK_BUS_DE>,
+                                <&ccu CLK_PLL_DE>;
+                       clock-names = "bus",
+                                     "mod";
                        resets = <&ccu RST_BUS_DE>;
                        #clock-cells = <1>;
                        #reset-cells = <1>;
                };
 
                timer@1c20c00 {
-                       compatible = "allwinner,sun4i-a10-timer";
+                       compatible = "allwinner,sun8i-a23-timer";
                        reg = <0x01c20c00 0xa0>;
                        interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
                        resets = <&ccu RST_BUS_HDMI1>;
                        reset-names = "ctrl";
                        phys = <&hdmi_phy>;
-                       phy-names = "hdmi-phy";
+                       phy-names = "phy";
                        pinctrl-names = "default";
                        pinctrl-0 = <&hdmi_pins>;
                        status = "disabled";
 
                r_cir: ir@1f02000 {
                        compatible = "allwinner,sun8i-a83t-ir",
-                               "allwinner,sun5i-a13-ir";
+                               "allwinner,sun6i-a31-ir";
                        clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>;
                        clock-names = "apb", "ir";
                        resets = <&r_ccu RST_APB0_IR>;
index 6007d0c..bde0681 100644 (file)
                        compatible = "allwinner,sun8i-r40-de2-clk",
                                     "allwinner,sun8i-h3-de2-clk";
                        reg = <0x01000000 0x100000>;
-                       clocks = <&ccu CLK_DE>,
-                                <&ccu CLK_BUS_DE>;
-                       clock-names = "mod",
-                                     "bus";
+                       clocks = <&ccu CLK_BUS_DE>,
+                                <&ccu CLK_DE>;
+                       clock-names = "bus",
+                                     "mod";
                        resets = <&ccu RST_BUS_DE>;
                        #clock-cells = <1>;
                        #reset-cells = <1>;
                wdt: watchdog@1c20c90 {
                        compatible = "allwinner,sun4i-a10-wdt";
                        reg = <0x01c20c90 0x10>;
+                       interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&osc24M>;
                };
 
                uart0: serial@1c28000 {
                        resets = <&ccu RST_BUS_HDMI1>;
                        reset-names = "ctrl";
                        phys = <&hdmi_phy>;
-                       phy-names = "hdmi-phy";
+                       phy-names = "phy";
                        status = "disabled";
 
                        ports {
diff --git a/arch/arm/boot/dts/sun8i-s3-lichee-zero-plus.dts b/arch/arm/boot/dts/sun8i-s3-lichee-zero-plus.dts
new file mode 100644 (file)
index 0000000..d18192d
--- /dev/null
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 Icenowy Zheng <icenowy@aosc.io>
+ */
+
+/dts-v1/;
+#include "sun8i-v3.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "Sipeed Lichee Zero Plus";
+       compatible = "sipeed,lichee-zero-plus", "sochip,s3",
+                    "allwinner,sun8i-v3";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       reg_vcc3v3: vcc3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&mmc0 {
+       broken-cd;
+       bus-width = <4>;
+       vmmc-supply = <&reg_vcc3v3>;
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-0 = <&uart0_pb_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&usb_otg {
+       dr_mode = "peripheral";
+       status = "okay";
+};
+
+&usbphy {
+       usb0_id_det-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun8i-v3.dtsi b/arch/arm/boot/dts/sun8i-v3.dtsi
new file mode 100644 (file)
index 0000000..6ae8645
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2019 Icenowy Zheng <icenowy@aosc.io>
+ */
+
+#include "sun8i-v3s.dtsi"
+
+&ccu {
+       compatible = "allwinner,sun8i-v3-ccu";
+};
+
+&pio {
+       compatible = "allwinner,sun8i-v3-pinctrl";
+};
index d7aef12..23ba56d 100644 (file)
                display_clocks: clock@1000000 {
                        compatible = "allwinner,sun8i-v3s-de2-clk";
                        reg = <0x01000000 0x100000>;
-                       clocks = <&ccu CLK_DE>,
-                                <&ccu CLK_BUS_DE>;
-                       clock-names = "mod",
-                                     "bus";
+                       clocks = <&ccu CLK_BUS_DE>,
+                                <&ccu CLK_DE>;
+                       clock-names = "bus",
+                                     "mod";
                        resets = <&ccu RST_BUS_DE>;
                        #clock-cells = <1>;
                        #reset-cells = <1>;
                };
 
                timer@1c20c00 {
-                       compatible = "allwinner,sun4i-a10-timer";
+                       compatible = "allwinner,sun8i-v3s-timer";
                        reg = <0x01c20c00 0xa0>;
                        interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+                                    <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&osc24M>;
                };
 
                        compatible = "allwinner,sun6i-a31-wdt";
                        reg = <0x01c20ca0 0x20>;
                        interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&osc24M>;
                };
 
                lradc: lradc@1c22800 {
index 18156ff..d3b337b 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        phy-supply = <&reg_cldo1>;
        status = "okay";
-
-       phy1: ethernet-phy@1 {
-               reg = <1>;
-       };
 };
 
 &i2c3 {
        status = "okay";
 };
 
+&mdio {
+       phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
 &mmc0 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc0_pins>;
index 2ed28d9..bbc6335 100644 (file)
 &gmac {
        pinctrl-names = "default";
        pinctrl-0 = <&gmac_rgmii_pins>;
-       phy = <&phy1>;
+       phy-handle = <&phy1>;
        phy-mode = "rgmii";
        phy-supply = <&reg_cldo1>;
        status = "okay";
+};
 
+&mdio {
        phy1: ethernet-phy@1 {
                reg = <1>;
        };
index 0c1eec9..c34d505 100644 (file)
                        snps,fixed-burst;
                        snps,force_sf_dma_mode;
                        status = "disabled";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
+
+                       mdio: mdio {
+                               compatible = "snps,dwmac-mdio";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                       };
                };
 
                ehci0: usb@a00000 {
                };
 
                r_ir: ir@8002000 {
-                       compatible = "allwinner,sun5i-a13-ir";
+                       compatible = "allwinner,sun6i-a31-ir";
                        interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
                        pinctrl-names = "default";
                        pinctrl-0 = <&r_ir_pins>;
index 84977d4..eba190b 100644 (file)
                display_clocks: clock@1000000 {
                        /* compatible is in per SoC .dtsi file */
                        reg = <0x01000000 0x100000>;
-                       clocks = <&ccu CLK_DE>,
-                                <&ccu CLK_BUS_DE>;
-                       clock-names = "mod",
-                                     "bus";
+                       clocks = <&ccu CLK_BUS_DE>,
+                                <&ccu CLK_DE>;
+                       clock-names = "bus",
+                                     "mod";
                        resets = <&ccu RST_BUS_DE>;
                        #clock-cells = <1>;
                        #reset-cells = <1>;
                };
 
                timer@1c20c00 {
-                       compatible = "allwinner,sun4i-a10-timer";
+                       compatible = "allwinner,sun8i-a23-timer";
                        reg = <0x01c20c00 0xa0>;
                        interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
                        compatible = "allwinner,sun6i-a31-wdt";
                        reg = <0x01c20ca0 0x20>;
                        interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&osc24M>;
                };
 
                spdif: spdif@1c21000 {
                        resets = <&ccu RST_BUS_HDMI1>;
                        reset-names = "ctrl";
                        phys = <&hdmi_phy>;
-                       phy-names = "hdmi-phy";
+                       phy-names = "phy";
                        status = "disabled";
 
                        ports {
                };
 
                ir: ir@1f02000 {
-                       compatible = "allwinner,sun5i-a13-ir";
+                       compatible = "allwinner,sun6i-a31-ir";
                        clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>;
                        clock-names = "apb", "ir";
                        resets = <&r_ccu RST_APB0_IR>;
index d6a1fc2..dfae90a 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * ARM Ltd. Versatile Express
  *
index 8e57e15..2e29d77 100644 (file)
                        };
                };
        };
-};
\ No newline at end of file
+};
index 3fa0cbe..0f3870d 100644 (file)
                reg = <0>;
        };
 
-       n25q128a13_2: flash@1 {
+       n25q128a13_2: flash@2 {
                compatible = "n25q128a13", "jedec,spi-nor";
                #address-cells = <1>;
                #size-cells = <1>;
                spi-max-frequency = <66000000>;
                spi-rx-bus-width = <2>;
-               reg = <1>;
+               reg = <2>;
        };
 };
 
index 9466913..2873224 100644 (file)
 };
 
 &i2c0 {
-       clock-frequency = <400000>;
+       clock-frequency = <100000>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c0>;
        status = "okay";
        };
 };
 
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       watchdog@38 {
+               compatible = "zii,rave-wdt";
+               reg = <0x38>;
+       };
+};
+
 &snvsrtc {
        status = "disabled";
 };
                >;
        };
 
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       VF610_PAD_PTB16__I2C1_SCL               0x37ff
+                       VF610_PAD_PTB17__I2C1_SDA               0x37ff
+               >;
+       };
+
        pinctrl_leds_debug: pinctrl-leds-debug {
                fsl,pins = <
                        VF610_PAD_PTD3__GPIO_82                 0x31c2
index d7019e8..dc8a5f3 100644 (file)
                #gpio-cells = <2>;
                reg = <0x20>;
                gpio-controller;
+               interrupt-parent = <&gpio1>;
+               interrupts = <31 IRQ_TYPE_EDGE_FALLING>;
        };
 
        lm75@4e {
                        VF610_PAD_PTB15__I2C0_SDA               0x37ff
                >;
        };
-               pinctrl_i2c1: i2c1grp {
+
+       pinctrl_i2c1: i2c1grp {
                fsl,pins = <
                        VF610_PAD_PTB16__I2C1_SCL               0x37ff
                        VF610_PAD_PTB17__I2C1_SDA               0x37ff
                >;
        };
 
-       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_PTB26__GPIO_96               0x31c2
index 9dde83c..77e1484 100644 (file)
                >;
        };
 
-       pinctrl_i2c1: i2c1grp {
-               fsl,pins = <
-                       VF610_PAD_PTB16__I2C1_SCL               0x37ff
-                       VF610_PAD_PTB17__I2C1_SDA               0x37ff
-               >;
-       };
-
        pinctrl_leds_debug: pinctrl-leds-debug {
                fsl,pins = <
                        VF610_PAD_PTD3__GPIO_82                 0x31c2
index 60130bd..6edb961 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include <linux/device.h>
-#include <linux/gpio.h>
+#include <linux/gpio/driver.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/platform_device.h>
diff --git a/arch/arm/configs/acs5k_defconfig b/arch/arm/configs/acs5k_defconfig
deleted file mode 100644 (file)
index bcb8bda..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_KS8695=y
-CONFIG_MACH_KS8695=y
-CONFIG_MACH_DSM320=y
-CONFIG_MACH_ACS5K=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCI=y
-CONFIG_PCI_DEBUG=y
-CONFIG_PCCARD=y
-CONFIG_YENTA=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_KS8695_ETHER=y
-CONFIG_PRISM54=m
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_KS8695=y
-CONFIG_SERIAL_KS8695_CONSOLE=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PCA953X=y
-CONFIG_WATCHDOG=y
-CONFIG_KS8695_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_PCF8563=y
-CONFIG_EXT2_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_FTRACE is not set
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff --git a/arch/arm/configs/acs5k_tiny_defconfig b/arch/arm/configs/acs5k_tiny_defconfig
deleted file mode 100644 (file)
index e802cde..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_KS8695=y
-CONFIG_MACH_ACS5K=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyAM0,115200 init=/bin/sh"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-# CONFIG_BLK_DEV is not set
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_ARM_KS8695_ETHER=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_KS8695=y
-CONFIG_SERIAL_KS8695_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PCA953X=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_KS8695_WATCHDOG=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_PCF8563=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_SQUASHFS=y
-# CONFIG_NETWORK_FILESYSTEMS is not set
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_FTRACE is not set
-CONFIG_DEBUG_USER=y
index 019828d..1857df9 100644 (file)
@@ -20,20 +20,11 @@ CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 CONFIG_SLAB_FREELIST_RANDOM=y
-CONFIG_JUMP_LABEL=y
-CONFIG_STRICT_KERNEL_RWX=y
-CONFIG_GCC_PLUGINS=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEBUG_FS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_MQ_IOSCHED_DEADLINE is not set
-# CONFIG_MQ_IOSCHED_KYBER is not set
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_ASPEED=y
 CONFIG_MACH_ASPEED_G4=y
 CONFIG_VMSPLIT_2G=y
 CONFIG_AEABI=y
-# CONFIG_COMPACTION is not set
 CONFIG_UACCESS_WITH_MEMCPY=y
 CONFIG_SECCOMP=y
 # CONFIG_ATAGS is not set
@@ -42,7 +33,15 @@ CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_KEXEC=y
+CONFIG_FIRMWARE_MEMMAP=y
+CONFIG_JUMP_LABEL=y
+CONFIG_STRICT_KERNEL_RWX=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEBUG_FS is not set
+# CONFIG_MQ_IOSCHED_DEADLINE is not set
+# CONFIG_MQ_IOSCHED_KYBER is not set
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_COMPACTION is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_PACKET_DIAG=y
@@ -51,18 +50,11 @@ CONFIG_UNIX_DIAG=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_SYN_COOKIES=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_DIAG is not set
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_ADVANCED is not set
 CONFIG_VLAN_8021Q=y
 CONFIG_NET_NCSI=y
-CONFIG_BPF_STREAM_PARSER=y
 # CONFIG_WIRELESS is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -140,7 +132,6 @@ CONFIG_ASPEED_BT_IPMI_BMC=y
 CONFIG_HW_RANDOM_TIMERIOMEM=y
 # CONFIG_I2C_COMPAT is not set
 CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_MUX=y
 CONFIG_I2C_MUX_PCA9541=y
 CONFIG_I2C_MUX_PCA954x=y
 CONFIG_I2C_ASPEED=y
@@ -204,6 +195,7 @@ CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
+CONFIG_EDAC=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_DS1307=y
 CONFIG_RTC_DRV_PCF8523=y
@@ -218,13 +210,13 @@ CONFIG_IIO=y
 CONFIG_ASPEED_ADC=y
 CONFIG_MAX1363=y
 CONFIG_BMP280=y
+CONFIG_RAS=y
 CONFIG_FSI=y
 CONFIG_FSI_MASTER_GPIO=y
 CONFIG_FSI_MASTER_HUB=y
 CONFIG_FSI_MASTER_AST_CF=y
 CONFIG_FSI_SCOM=y
 CONFIG_FSI_SBEFIFO=y
-CONFIG_FIRMWARE_MEMMAP=y
 CONFIG_FANOTIFY=y
 CONFIG_OVERLAY_FS=y
 CONFIG_TMPFS=y
@@ -237,6 +229,17 @@ CONFIG_SQUASHFS=y
 CONFIG_SQUASHFS_XZ=y
 CONFIG_SQUASHFS_ZSTD=y
 # CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_FORTIFY_SOURCE=y
+# CONFIG_CRYPTO_ECHAINIV is not set
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_USER_API_HASH=y
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+# CONFIG_XZ_DEC_SPARC is not set
 CONFIG_PRINTK_TIME=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_INFO=y
@@ -255,14 +258,3 @@ CONFIG_FUNCTION_TRACER=y
 # CONFIG_RUNTIME_TESTING_MENU is not set
 CONFIG_DEBUG_WX=y
 CONFIG_DEBUG_USER=y
-CONFIG_HARDENED_USERCOPY=y
-CONFIG_FORTIFY_SOURCE=y
-# CONFIG_CRYPTO_ECHAINIV is not set
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_USER_API_HASH=y
-# CONFIG_CRYPTO_HW is not set
-# CONFIG_XZ_DEC_X86 is not set
-# CONFIG_XZ_DEC_POWERPC is not set
-# CONFIG_XZ_DEC_IA64 is not set
-# CONFIG_XZ_DEC_SPARC is not set
index 28fe392..597536c 100644 (file)
@@ -20,29 +20,33 @@ CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
 CONFIG_SLAB=y
 CONFIG_SLAB_FREELIST_RANDOM=y
-CONFIG_JUMP_LABEL=y
-CONFIG_STRICT_KERNEL_RWX=y
-CONFIG_GCC_PLUGINS=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEBUG_FS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_MQ_IOSCHED_DEADLINE is not set
-# CONFIG_MQ_IOSCHED_KYBER is not set
 CONFIG_ARCH_MULTI_V6=y
-# CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_ASPEED=y
 CONFIG_MACH_ASPEED_G5=y
+CONFIG_MACH_ASPEED_G6=y
 # CONFIG_CACHE_L2X0 is not set
+CONFIG_SMP=y
+# CONFIG_ARM_CPU_TOPOLOGY is not set
 CONFIG_VMSPLIT_2G=y
-# CONFIG_COMPACTION is not set
+CONFIG_NR_CPUS=2
+CONFIG_HIGHMEM=y
 CONFIG_UACCESS_WITH_MEMCPY=y
 CONFIG_SECCOMP=y
 # CONFIG_ATAGS is not set
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_KEXEC=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_KERNEL_MODE_NEON=y
+CONFIG_FIRMWARE_MEMMAP=y
+CONFIG_JUMP_LABEL=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEBUG_FS is not set
+# CONFIG_MQ_IOSCHED_DEADLINE is not set
+# CONFIG_MQ_IOSCHED_KYBER is not set
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_SUSPEND is not set
+# CONFIG_COMPACTION is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_PACKET_DIAG=y
@@ -50,19 +54,20 @@ CONFIG_UNIX=y
 CONFIG_UNIX_DIAG=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
 CONFIG_SYN_COOKIES=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_DIAG is not set
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_ADVANCED is not set
 CONFIG_VLAN_8021Q=y
 CONFIG_NET_NCSI=y
-CONFIG_BPF_STREAM_PARSER=y
 # CONFIG_WIRELESS is not set
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
@@ -145,6 +150,7 @@ CONFIG_I2C_MUX_PCA9541=y
 CONFIG_I2C_MUX_PCA954x=y
 CONFIG_I2C_ASPEED=y
 CONFIG_I2C_FSI=y
+CONFIG_SPI=y
 CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_ASPEED=y
@@ -195,6 +201,10 @@ CONFIG_USB_CONFIGFS_F_LB_SS=y
 CONFIG_USB_CONFIGFS_F_FS=y
 CONFIG_USB_CONFIGFS_F_HID=y
 CONFIG_USB_CONFIGFS_F_PRINTER=y
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_ASPEED=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_CLASS_FLASH=y
@@ -228,7 +238,6 @@ CONFIG_FSI_MASTER_HUB=y
 CONFIG_FSI_MASTER_AST_CF=y
 CONFIG_FSI_SCOM=y
 CONFIG_FSI_SBEFIFO=y
-CONFIG_FIRMWARE_MEMMAP=y
 CONFIG_FANOTIFY=y
 CONFIG_OVERLAY_FS=y
 CONFIG_TMPFS=y
@@ -241,6 +250,16 @@ CONFIG_SQUASHFS=y
 CONFIG_SQUASHFS_XZ=y
 CONFIG_SQUASHFS_ZSTD=y
 # CONFIG_NETWORK_FILESYSTEMS is not set
+CONFIG_HARDENED_USERCOPY=y
+CONFIG_FORTIFY_SOURCE=y
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_USER_API_HASH=y
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_XZ_DEC_X86 is not set
+# CONFIG_XZ_DEC_POWERPC is not set
+# CONFIG_XZ_DEC_IA64 is not set
+# CONFIG_XZ_DEC_SPARC is not set
 CONFIG_PRINTK_TIME=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_INFO=y
@@ -259,14 +278,3 @@ CONFIG_FUNCTION_TRACER=y
 # CONFIG_RUNTIME_TESTING_MENU is not set
 CONFIG_DEBUG_WX=y
 CONFIG_DEBUG_USER=y
-CONFIG_HARDENED_USERCOPY=y
-CONFIG_FORTIFY_SOURCE=y
-# CONFIG_CRYPTO_ECHAINIV is not set
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_USER_API_HASH=y
-# CONFIG_CRYPTO_HW is not set
-# CONFIG_XZ_DEC_X86 is not set
-# CONFIG_XZ_DEC_POWERPC is not set
-# CONFIG_XZ_DEC_IA64 is not set
-# CONFIG_XZ_DEC_SPARC is not set
index dcf7610..519ff58 100644 (file)
@@ -37,6 +37,14 @@ CONFIG_CMA=y
 CONFIG_SECCOMP=y
 CONFIG_KEXEC=y
 CONFIG_CRASH_DUMP=y
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPUFREQ_DT=y
+CONFIG_ARM_RASPBERRYPI_CPUFREQ=y
 CONFIG_VFP=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 # CONFIG_SUSPEND is not set
@@ -132,6 +140,7 @@ CONFIG_DMA_BCM2835=y
 CONFIG_STAGING=y
 CONFIG_SND_BCM2835=m
 CONFIG_VIDEO_BCM2835=m
+CONFIG_CLK_RASPBERRYPI=y
 CONFIG_MAILBOX=y
 CONFIG_BCM2835_MBOX=y
 # CONFIG_IOMMU_SUPPORT is not set
index 9a32a8c..b34970c 100644 (file)
@@ -17,6 +17,9 @@ CONFIG_MODVERSIONS=y
 CONFIG_PARTITION_ADVANCED=y
 # CONFIG_IOSCHED_DEADLINE is not set
 # CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_MULTIPLATFORM=y
+CONFIG_ARCH_MULTI_V7=n
+CONFIG_ARCH_MULTI_V5=y
 CONFIG_ARCH_DAVINCI=y
 CONFIG_ARCH_DAVINCI_DM644x=y
 CONFIG_ARCH_DAVINCI_DM355=y
@@ -129,9 +132,11 @@ CONFIG_SPI=y
 CONFIG_SPI_DAVINCI=m
 CONFIG_PINCTRL_DA850_PUPD=m
 CONFIG_PINCTRL_SINGLE=y
+CONFIG_GPIOLIB=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_PCA953X=y
 CONFIG_GPIO_PCA953X_IRQ=y
+CONFIG_RESET_CONTROLLER=y
 CONFIG_POWER_RESET=y
 CONFIG_POWER_RESET_GPIO=y
 CONFIG_SYSCON_REBOOT_MODE=m
index 2e6a863..08db1c8 100644 (file)
@@ -92,9 +92,12 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
+CONFIG_ATA=y
+# CONFIG_SATA_PMP is not set
+CONFIG_SATA_AHCI_PLATFORM=y
+# CONFIG_ATA_SFF is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_DM=y
 CONFIG_DM_CRYPT=m
index a53b292..9bfffbe 100644 (file)
@@ -60,6 +60,7 @@ CONFIG_ARM_IMX6Q_CPUFREQ=y
 CONFIG_ARM_IMX_CPUFREQ_DT=y
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
 CONFIG_VFP=y
 CONFIG_NEON=y
 CONFIG_PM_DEBUG=y
@@ -272,6 +273,7 @@ CONFIG_VIDEO_IMX_PXP=y
 CONFIG_VIDEO_ADV7180=m
 CONFIG_VIDEO_OV2680=m
 CONFIG_VIDEO_OV5640=m
+CONFIG_VIDEO_OV5645=m
 CONFIG_IMX_IPUV3_CORE=y
 CONFIG_DRM=y
 CONFIG_DRM_PANEL_LVDS=y
diff --git a/arch/arm/configs/iop13xx_defconfig b/arch/arm/configs/iop13xx_defconfig
deleted file mode 100644 (file)
index 30cdb28..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_IOP13XX=y
-CONFIG_MACH_IQ81340SC=y
-CONFIG_MACH_IQ81340MC=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="ip=bootp root=nfs console=ttyS0,115200 nfsroot=,tcp,v3,wsize=8192,rsize=8192"
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_AOUT=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IPV6=y
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
-# CONFIG_IPV6_SIT is not set
-CONFIG_MTD=y
-CONFIG_MTD_REDBOOT_PARTS=y
-CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
-CONFIG_MTD_REDBOOT_PARTS_READONLY=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=2
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_ISCSI_ATTRS=y
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_RAID0=y
-CONFIG_MD_RAID1=y
-CONFIG_MD_RAID10=y
-CONFIG_MD_RAID456=y
-CONFIG_BLK_DEV_DM=y
-CONFIG_NETDEVICES=y
-CONFIG_E1000=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_IOP3XX=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DMADEVICES=y
-CONFIG_INTEL_IOP_ADMA=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_TMPFS=y
-CONFIG_ECRYPT_FS=y
-CONFIG_JFFS2_FS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-CONFIG_SMB_FS=m
-CONFIG_CIFS=m
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
-CONFIG_DEBUG_USER=y
-CONFIG_KEYS=y
-CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_LRW=y
-CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_XCBC=y
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MICHAEL_MIC=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=y
-CONFIG_CRYPTO_SHA512=y
-CONFIG_CRYPTO_TGR192=y
-CONFIG_CRYPTO_WP512=y
-CONFIG_CRYPTO_AES=y
-CONFIG_CRYPTO_ANUBIS=y
-CONFIG_CRYPTO_ARC4=y
-CONFIG_CRYPTO_BLOWFISH=y
-CONFIG_CRYPTO_CAST5=y
-CONFIG_CRYPTO_CAST6=y
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_KHAZAD=y
-CONFIG_CRYPTO_SERPENT=y
-CONFIG_CRYPTO_TEA=y
-CONFIG_CRYPTO_TWOFISH=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRC_CCITT=y
-CONFIG_LIBCRC32C=y
diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig
deleted file mode 100644 (file)
index 089eca4..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_IOP33X=y
-CONFIG_ARCH_IQ80331=y
-CONFIG_MACH_IQ80332=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc iop3xx_init_atu=y"
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_AOUT=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IPV6=y
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
-# CONFIG_IPV6_SIT is not set
-CONFIG_MTD=y
-CONFIG_MTD_REDBOOT_PARTS=y
-CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
-CONFIG_MTD_REDBOOT_PARTS_READONLY=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-CONFIG_MD_RAID0=y
-CONFIG_MD_RAID1=y
-CONFIG_MD_RAID456=y
-CONFIG_BLK_DEV_DM=y
-CONFIG_NETDEVICES=y
-CONFIG_E1000=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_IOP3XX=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DMADEVICES=y
-CONFIG_INTEL_IOP_ADMA=y
-CONFIG_NET_DMA=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_LL_UART_8250=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/ks8695_defconfig b/arch/arm/configs/ks8695_defconfig
deleted file mode 100644 (file)
index df62d4d..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_KS8695=y
-CONFIG_MACH_KS8695=y
-CONFIG_MACH_DSM320=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_PCI=y
-CONFIG_PCI_DEBUG=y
-CONFIG_PCCARD=y
-CONFIG_YENTA=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20410000,3145728 root=/dev/ram0 rw"
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IPV6 is not set
-CONFIG_MTD=y
-CONFIG_MTD_REDBOOT_PARTS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_PRISM54=m
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_KS8695=y
-CONFIG_SERIAL_KS8695_CONSOLE=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_EXT2_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_FTRACE is not set
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
index 0cdc6c7..09deb57 100644 (file)
@@ -12,6 +12,7 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_EMBEDDED=y
 CONFIG_SLAB=y
+# CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_LPC32XX=y
 CONFIG_AEABI=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
@@ -93,6 +94,7 @@ CONFIG_SERIAL_HS_LPC32XX_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C_CHARDEV=y
 CONFIG_I2C_PNX=y
+CONFIG_GPIO_LPC32XX=y
 CONFIG_SPI=y
 CONFIG_SPI_PL022=y
 CONFIG_GPIO_SYSFS=y
index 2012370..bd01887 100644 (file)
@@ -14,6 +14,18 @@ CONFIG_ARCH_ASPEED=y
 CONFIG_MACH_ASPEED_G4=y
 CONFIG_ARCH_AT91=y
 CONFIG_SOC_AT91SAM9=y
+CONFIG_ARCH_DAVINCI=y
+CONFIG_ARCH_DAVINCI_DM644x=y
+CONFIG_ARCH_DAVINCI_DM355=y
+CONFIG_ARCH_DAVINCI_DM646x=y
+CONFIG_ARCH_DAVINCI_DA830=y
+CONFIG_ARCH_DAVINCI_DA850=y
+CONFIG_ARCH_DAVINCI_DM365=y
+CONFIG_MACH_SFFSDR=y
+CONFIG_MACH_NEUROS_OSD2=y
+CONFIG_MACH_DM355_LEOPARD=y
+CONFIG_MACH_MITYOMAPL138=y
+CONFIG_MACH_OMAPL138_HAWKBOARD=y
 CONFIG_ARCH_MXC=y
 CONFIG_MACH_MX21ADS=y
 CONFIG_MACH_MX27ADS=y
index 6a40bc2..13ba532 100644 (file)
@@ -9,6 +9,8 @@ CONFIG_ARCH_VIRT=y
 CONFIG_ARCH_ALPINE=y
 CONFIG_ARCH_ARTPEC=y
 CONFIG_MACH_ARTPEC6=y
+CONFIG_ARCH_ASPEED=y
+CONFIG_MACH_ASPEED_G6=y
 CONFIG_ARCH_AT91=y
 CONFIG_SOC_SAMA5D2=y
 CONFIG_SOC_SAMA5D3=y
@@ -102,6 +104,7 @@ CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m
 CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
 CONFIG_CPUFREQ_DT=y
 CONFIG_ARM_IMX6Q_CPUFREQ=y
+CONFIG_ARM_RASPBERRYPI_CPUFREQ=y
 CONFIG_QORIQ_CPUFREQ=y
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_CPUIDLE=y
@@ -197,7 +200,9 @@ CONFIG_MTD_NAND_GPMI_NAND=y
 CONFIG_MTD_NAND_BRCMNAND=y
 CONFIG_MTD_NAND_VF610_NFC=y
 CONFIG_MTD_NAND_DAVINCI=y
+CONFIG_MTD_NAND_STM32_FMC2=y
 CONFIG_MTD_SPI_NOR=y
+CONFIG_SPI_ASPEED_SMC=m
 CONFIG_MTD_UBI=y
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
@@ -304,7 +309,11 @@ CONFIG_INPUT_STPMIC1_ONKEY=y
 CONFIG_SERIO_AMBAKMI=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=5
+CONFIG_SERIAL_8250_RUNTIME_UARTS=5
 CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_ASPEED_VUART=m
 CONFIG_SERIAL_8250_SHARE_IRQ=y
 CONFIG_SERIAL_8250_BCM2835AUX=y
 CONFIG_SERIAL_8250_DW=y
@@ -349,6 +358,8 @@ CONFIG_SERIAL_STM32=y
 CONFIG_SERIAL_STM32_CONSOLE=y
 CONFIG_SERIAL_DEV_BUS=y
 CONFIG_VIRTIO_CONSOLE=y
+CONFIG_ASPEED_KCS_IPMI_BMC=m
+CONFIG_ASPEED_BT_IPMI_BMC=m
 CONFIG_HW_RANDOM=y
 CONFIG_HW_RANDOM_ST=y
 CONFIG_TCG_TPM=m
@@ -358,6 +369,7 @@ CONFIG_I2C_ARB_GPIO_CHALLENGE=m
 CONFIG_I2C_MUX_PCA954x=y
 CONFIG_I2C_MUX_PINCTRL=y
 CONFIG_I2C_DEMUX_PINCTRL=y
+CONFIG_I2C_ASPEED=m
 CONFIG_I2C_AT91=m
 CONFIG_I2C_BCM2835=y
 CONFIG_I2C_CADENCE=y
@@ -403,6 +415,7 @@ CONFIG_SPI_SH_MSIOF=m
 CONFIG_SPI_SH_HSPI=y
 CONFIG_SPI_SIRF=y
 CONFIG_SPI_STM32=m
+CONFIG_SPI_STM32_QSPI=m
 CONFIG_SPI_SUN4I=y
 CONFIG_SPI_SUN6I=y
 CONFIG_SPI_TEGRA114=y
@@ -461,6 +474,7 @@ CONFIG_CHARGER_MAX77693=m
 CONFIG_CHARGER_MAX8997=m
 CONFIG_CHARGER_MAX8998=m
 CONFIG_CHARGER_TPS65090=y
+CONFIG_SENSORS_ASPEED=m
 CONFIG_SENSORS_IIO_HWMON=y
 CONFIG_SENSORS_LM90=y
 CONFIG_SENSORS_LM95245=y
@@ -559,7 +573,7 @@ CONFIG_REGULATOR_MAX8997=m
 CONFIG_REGULATOR_MAX8998=m
 CONFIG_REGULATOR_MAX77686=y
 CONFIG_REGULATOR_MAX77693=m
-CONFIG_REGULATOR_MAX77802=m
+CONFIG_REGULATOR_MAX77802=y
 CONFIG_REGULATOR_PALMAS=y
 CONFIG_REGULATOR_PBIAS=y
 CONFIG_REGULATOR_PWM=y
@@ -569,6 +583,7 @@ CONFIG_REGULATOR_RK808=y
 CONFIG_REGULATOR_RN5T618=y
 CONFIG_REGULATOR_S2MPS11=y
 CONFIG_REGULATOR_S5M8767=y
+CONFIG_REGULATOR_STM32_BOOSTER=m
 CONFIG_REGULATOR_STM32_VREFBUF=m
 CONFIG_REGULATOR_STPMIC1=y
 CONFIG_REGULATOR_TI_ABB=y
@@ -590,6 +605,7 @@ CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_MEDIA_USB_SUPPORT=y
 CONFIG_USB_VIDEO_CLASS=m
 CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_ASPEED=m
 CONFIG_VIDEO_STM32_DCMI=m
 CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS=m
 CONFIG_VIDEO_S5P_FIMC=m
@@ -634,6 +650,7 @@ CONFIG_DRM_ATMEL_HLCDC=m
 CONFIG_DRM_RCAR_DU=m
 CONFIG_DRM_RCAR_LVDS=y
 CONFIG_DRM_SUN4I=m
+CONFIG_DRM_MSM=m
 CONFIG_DRM_FSL_DCU=m
 CONFIG_DRM_TEGRA=y
 CONFIG_DRM_STM=m
@@ -659,6 +676,7 @@ CONFIG_DRM_MXSFB=m
 CONFIG_DRM_PL111=m
 CONFIG_DRM_LIMA=m
 CONFIG_DRM_PANFROST=m
+CONFIG_DRM_ASPEED_GFX=m
 CONFIG_FB_EFI=y
 CONFIG_FB_WM8505=y
 CONFIG_FB_SH_MOBILE_LCDC=y
@@ -758,6 +776,7 @@ CONFIG_USB_MXS_PHY=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_FSL_USB2=y
 CONFIG_USB_RENESAS_USBHS_UDC=m
+CONFIG_USB_ASPEED_VHUB=m
 CONFIG_USB_CONFIGFS=m
 CONFIG_USB_CONFIGFS_SERIAL=y
 CONFIG_USB_CONFIGFS_ACM=y
@@ -866,6 +885,7 @@ CONFIG_RTC_DRV_TEGRA=y
 CONFIG_RTC_DRV_ST_LPC=y
 CONFIG_RTC_DRV_STM32=y
 CONFIG_RTC_DRV_CPCAP=m
+CONFIG_RTC_DRV_ASPEED=m
 CONFIG_DMADEVICES=y
 CONFIG_AT_HDMAC=y
 CONFIG_AT_XDMAC=y
@@ -902,6 +922,7 @@ CONFIG_STAGING_BOARD=y
 CONFIG_COMMON_CLK_MAX77686=y
 CONFIG_COMMON_CLK_RK808=m
 CONFIG_COMMON_CLK_S2MPS11=m
+CONFIG_CLK_RASPBERRYPI=y
 CONFIG_COMMON_CLK_QCOM=y
 CONFIG_QCOM_CLK_RPM=y
 CONFIG_APQ_MMCC_8084=y
@@ -915,6 +936,9 @@ CONFIG_TEGRA_IOMMU_SMMU=y
 CONFIG_REMOTEPROC=m
 CONFIG_ST_REMOTEPROC=m
 CONFIG_RPMSG_VIRTIO=m
+CONFIG_ASPEED_LPC_CTRL=m
+CONFIG_ASPEED_LPC_SNOOP=m
+CONFIG_ASPEED_P2A_CTRL=m
 CONFIG_RASPBERRYPI_POWER=y
 CONFIG_QCOM_GSBI=y
 CONFIG_QCOM_PM=y
@@ -947,6 +971,7 @@ CONFIG_ARM_TEGRA_DEVFREQ=m
 CONFIG_TI_AEMIF=y
 CONFIG_IIO=y
 CONFIG_IIO_SW_TRIGGER=y
+CONFIG_ASPEED_ADC=m
 CONFIG_AT91_ADC=m
 CONFIG_AT91_SAMA5D2_ADC=m
 CONFIG_BERLIN2_ADC=m
diff --git a/arch/arm/configs/nuc910_defconfig b/arch/arm/configs/nuc910_defconfig
deleted file mode 100644 (file)
index 63dba62..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_RELAY=y
-CONFIG_USER_NS=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_SLAB=y
-CONFIG_ARCH_W90X900=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
-CONFIG_KEXEC=y
-CONFIG_FPE_NWFPE=y
-CONFIG_MTD=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_SCSI=y
-# CONFIG_SCSI_PROC_FS is not set
-CONFIG_BLK_DEV_SD=y
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_DEVKMEM is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=1
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_USB=y
-CONFIG_USB_MON=y
-CONFIG_USB_STORAGE=y
-# CONFIG_DNOTIFY is not set
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_ROMFS_FS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/nuc950_defconfig b/arch/arm/configs/nuc950_defconfig
deleted file mode 100644 (file)
index cb5a878..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_RELAY=y
-CONFIG_USER_NS=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_SLAB=y
-CONFIG_ARCH_W90X900=y
-# CONFIG_MACH_W90P910EVB is not set
-CONFIG_MACH_W90P950EVB=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
-CONFIG_KEXEC=y
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_MISC=y
-CONFIG_MTD=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_SCSI=y
-# CONFIG_SCSI_PROC_FS is not set
-CONFIG_BLK_DEV_SD=y
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_DEVKMEM is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=1
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FB_NUC900=y
-CONFIG_GPM1040A0_320X240=y
-CONFIG_FB_NUC900_DEBUG=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x16=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_USB=y
-CONFIG_USB_MON=y
-CONFIG_USB_STORAGE=y
-# CONFIG_DNOTIFY is not set
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_ROMFS_FS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_DEBUG_FS=y
diff --git a/arch/arm/configs/nuc960_defconfig b/arch/arm/configs/nuc960_defconfig
deleted file mode 100644 (file)
index f7af84e..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_RELAY=y
-CONFIG_USER_NS=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_SLAB=y
-CONFIG_ARCH_W90X900=y
-# CONFIG_MACH_W90P910EVB is not set
-CONFIG_MACH_W90N960EVB=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M"
-CONFIG_KEXEC=y
-CONFIG_FPE_NWFPE=y
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_MISC=y
-CONFIG_MTD=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_SCSI=y
-# CONFIG_SCSI_PROC_FS is not set
-CONFIG_BLK_DEV_SD=y
-# CONFIG_SCSI_LOWLEVEL is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_DEVKMEM is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=1
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_USB=y
-CONFIG_USB_MON=y
-CONFIG_USB_STORAGE=y
-# CONFIG_DNOTIFY is not set
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_ROMFS_FS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_CRC32 is not set
index 34433bf..02f1e7b 100644 (file)
@@ -147,6 +147,7 @@ CONFIG_REGULATOR_QCOM_SMD_RPM=y
 CONFIG_REGULATOR_QCOM_SPMI=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_DRM=y
+CONFIG_DRM_MSM=m
 CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
index 2a786f5..8a0fae9 100644 (file)
@@ -5,26 +5,6 @@
 #ifdef CONFIG_ARM_CPU_TOPOLOGY
 
 #include <linux/cpumask.h>
-
-struct cputopo_arm {
-       int thread_id;
-       int core_id;
-       int socket_id;
-       cpumask_t thread_sibling;
-       cpumask_t core_sibling;
-};
-
-extern struct cputopo_arm cpu_topology[NR_CPUS];
-
-#define topology_physical_package_id(cpu)      (cpu_topology[cpu].socket_id)
-#define topology_core_id(cpu)          (cpu_topology[cpu].core_id)
-#define topology_core_cpumask(cpu)     (&cpu_topology[cpu].core_sibling)
-#define topology_sibling_cpumask(cpu)  (&cpu_topology[cpu].thread_sibling)
-
-void init_cpu_topology(void);
-void store_cpu_topology(unsigned int cpuid);
-const struct cpumask *cpu_coregroup_mask(int cpu);
-
 #include <linux/arch_topology.h>
 
 /* Replace task scheduler's default frequency-invariant accounting */
diff --git a/arch/arm/include/debug/ks8695.S b/arch/arm/include/debug/ks8695.S
deleted file mode 100644 (file)
index eb4d371..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/include/debug/ks8695.S
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- *
- * KS8695 - Debug macros
- */
-
-#define KS8695_UART_PA 0x03ffe000
-#define KS8695_UART_VA 0xf00fe000
-#define KS8695_URTH    (0x04)
-#define KS8695_URLS    (0x14)
-#define URLS_URTE      (1 << 6)
-#define URLS_URTHRE    (1 << 5)
-
-       .macro  addruart, rp, rv, tmp
-               ldr     \rp, =KS8695_UART_PA            @ physical base address
-               ldr     \rv, =KS8695_UART_VA            @ virtual base address
-       .endm
-
-       .macro  senduart, rd, rx
-               str     \rd, [\rx, #KS8695_URTH]        @ Write to Transmit Holding Register
-       .endm
-
-       .macro  busyuart, rd, rx
-1001:          ldr     \rd, [\rx, #KS8695_URLS]        @ Read Line Status Register
-               tst     \rd, #URLS_URTE                 @ Holding & Shift registers empty?
-               beq     1001b
-       .endm
-
-       .macro  waituart, rd, rx
-1001:          ldr     \rd, [\rx, #KS8695_URLS]        @ Read Line Status Register
-               tst     \rd, #URLS_URTHRE               @ Holding Register empty?
-               beq     1001b
-       .endm
index 1c5f795..25f0666 100644 (file)
 #define SCIF_PHYS      CONFIG_DEBUG_UART_PHYS
 #define SCIF_VIRT      ((SCIF_PHYS & 0x00ffffff) | 0xfd000000)
 
-#if CONFIG_DEBUG_UART_PHYS < 0xe6e00000
+#if defined(CONFIG_DEBUG_R7S9210_SCIF2) || defined(CONFIG_DEBUG_R7S9210_SCIF4)
+/* RZ/A2 SCIFA */
+#define FTDR           0x06
+#define FSR            0x08
+#elif CONFIG_DEBUG_UART_PHYS < 0xe6e00000
 /* SCIFA */
 #define FTDR           0x20
 #define FSR            0x14
index c626f89..c516900 100644 (file)
 #define U8500_UART0_PHYS_BASE  (0x80120000)
 #define U8500_UART1_PHYS_BASE  (0x80121000)
 #define U8500_UART2_PHYS_BASE  (0x80007000)
-#define U8500_UART0_VIRT_BASE  (0xf8120000)
-#define U8500_UART1_VIRT_BASE  (0xf8121000)
-#define U8500_UART2_VIRT_BASE  (0xf8007000)
 #define __UX500_PHYS_UART(n)   U8500_UART##n##_PHYS_BASE
-#define __UX500_VIRT_UART(n)   U8500_UART##n##_VIRT_BASE
 #endif
 
-#if !defined(__UX500_PHYS_UART) || !defined(__UX500_VIRT_UART)
+#if !defined(__UX500_PHYS_UART)
 #error Unknown SOC
 #endif
 
 #define UX500_PHYS_UART(n)     __UX500_PHYS_UART(n)
-#define UX500_VIRT_UART(n)     __UX500_VIRT_UART(n)
 #define UART_PHYS_BASE UX500_PHYS_UART(CONFIG_UX500_DEBUG_UART)
-#define UART_VIRT_BASE UX500_VIRT_UART(CONFIG_UX500_DEBUG_UART)
+#define UART_VIRT_BASE (0xfff07000)
 
        .macro  addruart, rp, rv, tmp
        ldr     \rp, =UART_PHYS_BASE            @ no, physical address
index d17cb1e..5b9faba 100644 (file)
@@ -177,17 +177,6 @@ static inline void parse_dt_topology(void) {}
 static inline void update_cpu_capacity(unsigned int cpuid) {}
 #endif
 
- /*
- * cpu topology table
- */
-struct cputopo_arm cpu_topology[NR_CPUS];
-EXPORT_SYMBOL_GPL(cpu_topology);
-
-const struct cpumask *cpu_coregroup_mask(int cpu)
-{
-       return &cpu_topology[cpu].core_sibling;
-}
-
 /*
  * The current assumption is that we can power gate each core independently.
  * This will be superseded by DT binding once available.
@@ -197,32 +186,6 @@ const struct cpumask *cpu_corepower_mask(int cpu)
        return &cpu_topology[cpu].thread_sibling;
 }
 
-static void update_siblings_masks(unsigned int cpuid)
-{
-       struct cputopo_arm *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
-       int cpu;
-
-       /* update core and thread sibling masks */
-       for_each_possible_cpu(cpu) {
-               cpu_topo = &cpu_topology[cpu];
-
-               if (cpuid_topo->socket_id != cpu_topo->socket_id)
-                       continue;
-
-               cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
-               if (cpu != cpuid)
-                       cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
-
-               if (cpuid_topo->core_id != cpu_topo->core_id)
-                       continue;
-
-               cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
-               if (cpu != cpuid)
-                       cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
-       }
-       smp_wmb();
-}
-
 /*
  * store_cpu_topology is called at boot when only one cpu is running
  * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
@@ -230,7 +193,7 @@ static void update_siblings_masks(unsigned int cpuid)
  */
 void store_cpu_topology(unsigned int cpuid)
 {
-       struct cputopo_arm *cpuid_topo = &cpu_topology[cpuid];
+       struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
        unsigned int mpidr;
 
        /* If the cpu topology has been already set, just return */
@@ -250,12 +213,12 @@ void store_cpu_topology(unsigned int cpuid)
                        /* core performance interdependency */
                        cpuid_topo->thread_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
                        cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
-                       cpuid_topo->socket_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
+                       cpuid_topo->package_id = MPIDR_AFFINITY_LEVEL(mpidr, 2);
                } else {
                        /* largely independent cores */
                        cpuid_topo->thread_id = -1;
                        cpuid_topo->core_id = MPIDR_AFFINITY_LEVEL(mpidr, 0);
-                       cpuid_topo->socket_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
+                       cpuid_topo->package_id = MPIDR_AFFINITY_LEVEL(mpidr, 1);
                }
        } else {
                /*
@@ -265,7 +228,7 @@ void store_cpu_topology(unsigned int cpuid)
                 */
                cpuid_topo->thread_id = -1;
                cpuid_topo->core_id = 0;
-               cpuid_topo->socket_id = -1;
+               cpuid_topo->package_id = -1;
        }
 
        update_siblings_masks(cpuid);
@@ -275,7 +238,7 @@ void store_cpu_topology(unsigned int cpuid)
        pr_info("CPU%u: thread %d, cpu %d, socket %d, mpidr %x\n",
                cpuid, cpu_topology[cpuid].thread_id,
                cpu_topology[cpuid].core_id,
-               cpu_topology[cpuid].socket_id, mpidr);
+               cpu_topology[cpuid].package_id, mpidr);
 }
 
 static inline int cpu_corepower_flags(void)
@@ -298,18 +261,7 @@ static struct sched_domain_topology_level arm_topology[] = {
  */
 void __init init_cpu_topology(void)
 {
-       unsigned int cpu;
-
-       /* init core mask and capacity */
-       for_each_possible_cpu(cpu) {
-               struct cputopo_arm *cpu_topo = &(cpu_topology[cpu]);
-
-               cpu_topo->thread_id = -1;
-               cpu_topo->core_id =  -1;
-               cpu_topo->socket_id = -1;
-               cpumask_clear(&cpu_topo->core_sibling);
-               cpumask_clear(&cpu_topo->thread_sibling);
-       }
+       reset_cpu_topology();
        smp_wmb();
 
        parse_dt_topology();
index 1d5210e..5829252 100644 (file)
@@ -66,7 +66,7 @@ for_each_frame:       tst     frame, mask             @ Check for address exceptions
 
 1003:          ldr     r2, [sv_pc, #-4]        @ if stmfd sp!, {args} exists,
                ldr     r3, .Ldsi+4             @ adjust saved 'pc' back one
-               teq     r3, r2, lsr #10         @ instruction
+               teq     r3, r2, lsr #11         @ instruction
                subne   r0, sv_pc, #4           @ allow for mov
                subeq   r0, sv_pc, #8           @ allow for mov + stmia
 
index a15c3a2..56007b0 100644 (file)
@@ -1,11 +1,10 @@
 # SPDX-License-Identifier: GPL-2.0-only
 menuconfig ARCH_ASPEED
        bool "Aspeed BMC architectures"
-       depends on ARCH_MULTI_V5 || ARCH_MULTI_V6
+       depends on ARCH_MULTI_V5 || ARCH_MULTI_V6 || ARCH_MULTI_V7
        select SRAM
        select WATCHDOG
        select ASPEED_WATCHDOG
-       select FTTMR010_TIMER
        select MFD_SYSCON
        select PINCTRL
        help
@@ -18,6 +17,7 @@ config MACH_ASPEED_G4
        depends on ARCH_MULTI_V5
        select CPU_ARM926T
        select PINCTRL_ASPEED_G4
+       select FTTMR010_TIMER
        help
         Say yes if you intend to run on an Aspeed ast2400 or similar
         fourth generation BMCs, such as those used by OpenPower Power8
@@ -28,8 +28,21 @@ config MACH_ASPEED_G5
        depends on ARCH_MULTI_V6
        select CPU_V6
        select PINCTRL_ASPEED_G5
+       select FTTMR010_TIMER
        help
         Say yes if you intend to run on an Aspeed ast2500 or similar
         fifth generation Aspeed BMCs.
 
+config MACH_ASPEED_G6
+       bool "Aspeed SoC 6th Generation"
+       depends on ARCH_MULTI_V7
+       select CPU_V7
+       select PINCTRL_ASPEED_G6
+       select ARM_GIC
+       select HAVE_ARM_ARCH_TIMER
+       select HAVE_SMP
+       help
+        Say yes if you intend to run on an Aspeed ast2600 or similar
+        sixth generation Aspeed BMCs.
+
 endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
new file mode 100644 (file)
index 0000000..1951b33
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (C) ASPEED Technology Inc.
+# Copyright IBM Corp.
+
+obj-$(CONFIG_SMP) += platsmp.o
diff --git a/arch/arm/mach-aspeed/platsmp.c b/arch/arm/mach-aspeed/platsmp.c
new file mode 100644 (file)
index 0000000..2324bec
--- /dev/null
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// Copyright (C) ASPEED Technology Inc.
+// Copyright IBM Corp.
+
+#include <linux/of_address.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/smp.h>
+
+#define BOOT_ADDR      0x00
+#define BOOT_SIG       0x04
+
+static struct device_node *secboot_node;
+
+static int aspeed_g6_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+       void __iomem *base;
+
+       base = of_iomap(secboot_node, 0);
+       if (!base) {
+               pr_err("could not map the secondary boot base!");
+               return -ENODEV;
+       }
+
+       writel_relaxed(0, base + BOOT_ADDR);
+       writel_relaxed(__pa_symbol(secondary_startup_arm), base + BOOT_ADDR);
+       writel_relaxed((0xABBAAB00 | (cpu & 0xff)), base + BOOT_SIG);
+
+       dsb_sev();
+
+       iounmap(base);
+
+       return 0;
+}
+
+static void __init aspeed_g6_smp_prepare_cpus(unsigned int max_cpus)
+{
+       void __iomem *base;
+
+       secboot_node = of_find_compatible_node(NULL, NULL, "aspeed,ast2600-smpmem");
+       if (!secboot_node) {
+               pr_err("secboot device node found!!\n");
+               return;
+       }
+
+       base = of_iomap(secboot_node, 0);
+       if (!base) {
+               pr_err("could not map the secondary boot base!");
+               return;
+       }
+       __raw_writel(0xBADABABA, base + BOOT_SIG);
+
+       iounmap(base);
+}
+
+static const struct smp_operations aspeed_smp_ops __initconst = {
+       .smp_prepare_cpus       = aspeed_g6_smp_prepare_cpus,
+       .smp_boot_secondary     = aspeed_g6_boot_secondary,
+};
+
+CPU_METHOD_OF_DECLARE(aspeed_smp, "aspeed,ast2600-smp", &aspeed_smp_ops);
diff --git a/arch/arm/mach-at91/.gitignore b/arch/arm/mach-at91/.gitignore
new file mode 100644 (file)
index 0000000..2ecd6f5
--- /dev/null
@@ -0,0 +1 @@
+pm_data-offsets.h
index 31b61f0..de64301 100644 (file)
@@ -19,9 +19,10 @@ ifeq ($(CONFIG_PM_DEBUG),y)
 CFLAGS_pm.o += -DDEBUG
 endif
 
-include/generated/at91_pm_data-offsets.h: arch/arm/mach-at91/pm_data-offsets.s FORCE
+$(obj)/pm_data-offsets.h: $(obj)/pm_data-offsets.s FORCE
        $(call filechk,offsets,__PM_DATA_OFFSETS_H__)
 
-arch/arm/mach-at91/pm_suspend.o: include/generated/at91_pm_data-offsets.h
+$(obj)/pm_suspend.o: $(obj)/pm_data-offsets.h
 
 targets += pm_data-offsets.s
+clean-files += pm_data-offsets.h
index c751f04..ed57c87 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/linkage.h>
 #include <linux/clk/at91_pmc.h>
 #include "pm.h"
-#include "generated/at91_pm_data-offsets.h"
+#include "pm_data-offsets.h"
 
 #define        SRAMC_SELF_FRESH_ACTIVE         0x01
 #define        SRAMC_SELF_FRESH_EXIT           0x00
index 5a59ceb..dd427bd 100644 (file)
@@ -1,11 +1,22 @@
 # SPDX-License-Identifier: GPL-2.0
+
+menuconfig ARCH_DAVINCI
+       bool "TI DaVinci"
+       depends on ARCH_MULTI_V5
+       select DAVINCI_TIMER
+       select ZONE_DMA
+       select ARCH_HAS_HOLES_MEMORYMODEL
+       select PM_GENERIC_DOMAINS if PM
+       select PM_GENERIC_DOMAINS_OF if PM && OF
+       select REGMAP_MMIO
+       select HAVE_IDE
+       select PINCTRL_SINGLE
+
 if ARCH_DAVINCI
 
 config ARCH_DAVINCI_DMx
        bool
 
-menu "TI DaVinci Implementations"
-
 comment "DaVinci Core Type"
 
 config ARCH_DAVINCI_DM644x
@@ -225,6 +236,4 @@ config DAVINCI_MUX_WARNINGS
          to change the pin multiplexing setup. When there are no warnings
          printed, it's safe to deselect DAVINCI_MUX for your product.
 
-endmenu
-
 endif
index f76a848..a03d844 100644 (file)
@@ -4,6 +4,8 @@
 #
 #
 
+ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
+
 # Common objects
 obj-y                                  := time.o serial.o usb.o \
                                           common.o sram.o
index 0628e7d..5b3549f 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/platform_data/ti-aemif.h>
 #include <linux/platform_data/spi-davinci.h>
 #include <linux/platform_data/uio_pruss.h>
+#include <linux/property.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/tps6507x.h>
 #include <linux/regulator/fixed.h>
@@ -802,37 +803,79 @@ static const short da850_evm_mmcsd0_pins[] __initconst = {
        -1
 };
 
-static void da850_panel_power_ctrl(int val)
-{
-       /* lcd backlight */
-       gpio_set_value(DA850_LCD_BL_PIN, val);
+static struct property_entry da850_lcd_backlight_props[] = {
+       PROPERTY_ENTRY_BOOL("default-on"),
+       { }
+};
 
-       /* lcd power */
-       gpio_set_value(DA850_LCD_PWR_PIN, val);
-}
+static struct gpiod_lookup_table da850_lcd_backlight_gpio_table = {
+       .dev_id         = "gpio-backlight",
+       .table = {
+               GPIO_LOOKUP("davinci_gpio", DA850_LCD_BL_PIN, NULL, 0),
+               { }
+       },
+};
+
+static const struct platform_device_info da850_lcd_backlight_info = {
+       .name           = "gpio-backlight",
+       .id             = PLATFORM_DEVID_NONE,
+       .properties     = da850_lcd_backlight_props,
+};
+
+static struct regulator_consumer_supply da850_lcd_supplies[] = {
+       REGULATOR_SUPPLY("lcd", NULL),
+};
+
+static struct regulator_init_data da850_lcd_supply_data = {
+       .consumer_supplies      = da850_lcd_supplies,
+       .num_consumer_supplies  = ARRAY_SIZE(da850_lcd_supplies),
+       .constraints    = {
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+       },
+};
+
+static struct fixed_voltage_config da850_lcd_supply = {
+       .supply_name            = "lcd",
+       .microvolts             = 33000000,
+       .init_data              = &da850_lcd_supply_data,
+};
+
+static struct platform_device da850_lcd_supply_device = {
+       .name                   = "reg-fixed-voltage",
+       .id                     = 1, /* Dummy fixed regulator is 0 */
+       .dev                    = {
+               .platform_data = &da850_lcd_supply,
+       },
+};
+
+static struct gpiod_lookup_table da850_lcd_supply_gpio_table = {
+       .dev_id                 = "reg-fixed-voltage.1",
+       .table = {
+               GPIO_LOOKUP("davinci_gpio", DA850_LCD_PWR_PIN, NULL, 0),
+               { }
+       },
+};
+
+static struct gpiod_lookup_table *da850_lcd_gpio_lookups[] = {
+       &da850_lcd_backlight_gpio_table,
+       &da850_lcd_supply_gpio_table,
+};
 
 static int da850_lcd_hw_init(void)
 {
+       struct platform_device *backlight;
        int status;
 
-       status = gpio_request(DA850_LCD_BL_PIN, "lcd bl");
-       if (status < 0)
-               return status;
-
-       status = gpio_request(DA850_LCD_PWR_PIN, "lcd pwr");
-       if (status < 0) {
-               gpio_free(DA850_LCD_BL_PIN);
-               return status;
-       }
+       gpiod_add_lookup_tables(da850_lcd_gpio_lookups,
+                               ARRAY_SIZE(da850_lcd_gpio_lookups));
 
-       gpio_direction_output(DA850_LCD_BL_PIN, 0);
-       gpio_direction_output(DA850_LCD_PWR_PIN, 0);
+       backlight = platform_device_register_full(&da850_lcd_backlight_info);
+       if (IS_ERR(backlight))
+               return PTR_ERR(backlight);
 
-       /* Switch off panel power and backlight */
-       da850_panel_power_ctrl(0);
-
-       /* Switch on panel power and backlight */
-       da850_panel_power_ctrl(1);
+       status = platform_device_register(&da850_lcd_supply_device);
+       if (status)
+               return status;
 
        return 0;
 }
@@ -1443,7 +1486,6 @@ static __init void da850_evm_init(void)
        if (ret)
                pr_warn("%s: LCD initialization failed: %d\n", __func__, ret);
 
-       sharp_lk043t1dg01_pdata.panel_power_ctrl = da850_panel_power_ctrl,
        ret = da8xx_register_lcdc(&sharp_lk043t1dg01_pdata);
        if (ret)
                pr_warn("%s: LCDC registration failed: %d\n", __func__, ret);
index e6b8ffd..018ab4b 100644 (file)
@@ -21,7 +21,8 @@
 #include <mach/common.h>
 #include <mach/cputype.h>
 #include <mach/da8xx.h>
-#include <mach/time.h>
+
+#include <clocksource/timer-davinci.h>
 
 #include "irqs.h"
 #include "mux.h"
@@ -676,32 +677,17 @@ int __init da830_register_gpio(void)
        return da8xx_register_gpio(&da830_gpio_platform_data);
 }
 
-static struct davinci_timer_instance da830_timer_instance[2] = {
-       {
-               .base           = DA8XX_TIMER64P0_BASE,
-               .bottom_irq     = DAVINCI_INTC_IRQ(IRQ_DA8XX_TINT12_0),
-               .top_irq        = DAVINCI_INTC_IRQ(IRQ_DA8XX_TINT34_0),
-               .cmp_off        = DA830_CMP12_0,
-               .cmp_irq        = DAVINCI_INTC_IRQ(IRQ_DA830_T12CMPINT0_0),
-       },
-       {
-               .base           = DA8XX_TIMER64P1_BASE,
-               .bottom_irq     = DAVINCI_INTC_IRQ(IRQ_DA8XX_TINT12_1),
-               .top_irq        = DAVINCI_INTC_IRQ(IRQ_DA8XX_TINT34_1),
-               .cmp_off        = DA830_CMP12_0,
-               .cmp_irq        = DAVINCI_INTC_IRQ(IRQ_DA830_T12CMPINT0_1),
-       },
-};
-
 /*
- * T0_BOT: Timer 0, bottom             : Used for clock_event & clocksource
- * T0_TOP: Timer 0, top                        : Used by DSP
- * T1_BOT, T1_TOP: Timer 1, bottom & top: Used for watchdog timer
+ * Bottom half of timer0 is used both for clock even and clocksource.
+ * Top half is used by DSP.
  */
-static struct davinci_timer_info da830_timer_info = {
-       .timers         = da830_timer_instance,
-       .clockevent_id  = T0_BOT,
-       .clocksource_id = T0_BOT,
+static const struct davinci_timer_cfg da830_timer_cfg = {
+       .reg = DEFINE_RES_IO(DA8XX_TIMER64P0_BASE, SZ_4K),
+       .irq = {
+               DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_DA830_T12CMPINT0_0)),
+               DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_DA8XX_TINT12_0)),
+       },
+       .cmp_off = DA830_CMP12_0,
 };
 
 static const struct davinci_soc_info davinci_soc_info_da830 = {
@@ -713,7 +699,6 @@ static const struct davinci_soc_info davinci_soc_info_da830 = {
        .pinmux_base            = DA8XX_SYSCFG0_BASE + 0x120,
        .pinmux_pins            = da830_pins,
        .pinmux_pins_num        = ARRAY_SIZE(da830_pins),
-       .timer_info             = &da830_timer_info,
        .emac_pdata             = &da8xx_emac_pdata,
 };
 
@@ -743,6 +728,7 @@ void __init da830_init_time(void)
 {
        void __iomem *pll;
        struct clk *clk;
+       int rv;
 
        clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA830_REF_FREQ);
 
@@ -751,8 +737,13 @@ void __init da830_init_time(void)
        da830_pll_init(NULL, pll, NULL);
 
        clk = clk_get(NULL, "timer0");
+       if (WARN_ON(IS_ERR(clk))) {
+               pr_err("Unable to get the timer clock\n");
+               return;
+       }
 
-       davinci_timer_init(clk);
+       rv = davinci_timer_register(clk, &da830_timer_cfg);
+       WARN(rv, "Unable to register the timer: %d\n", rv);
 }
 
 static struct resource da830_psc0_resources[] = {
index 77bc64d..73b7cc5 100644 (file)
@@ -35,7 +35,8 @@
 #include <mach/cputype.h>
 #include <mach/da8xx.h>
 #include <mach/pm.h>
-#include <mach/time.h>
+
+#include <clocksource/timer-davinci.h>
 
 #include "irqs.h"
 #include "mux.h"
@@ -333,38 +334,16 @@ static struct davinci_id da850_ids[] = {
        },
 };
 
-static struct davinci_timer_instance da850_timer_instance[4] = {
-       {
-               .base           = DA8XX_TIMER64P0_BASE,
-               .bottom_irq     = DAVINCI_INTC_IRQ(IRQ_DA8XX_TINT12_0),
-               .top_irq        = DAVINCI_INTC_IRQ(IRQ_DA8XX_TINT34_0),
-       },
-       {
-               .base           = DA8XX_TIMER64P1_BASE,
-               .bottom_irq     = DAVINCI_INTC_IRQ(IRQ_DA8XX_TINT12_1),
-               .top_irq        = DAVINCI_INTC_IRQ(IRQ_DA8XX_TINT34_1),
-       },
-       {
-               .base           = DA850_TIMER64P2_BASE,
-               .bottom_irq     = DAVINCI_INTC_IRQ(IRQ_DA850_TINT12_2),
-               .top_irq        = DAVINCI_INTC_IRQ(IRQ_DA850_TINT34_2),
-       },
-       {
-               .base           = DA850_TIMER64P3_BASE,
-               .bottom_irq     = DAVINCI_INTC_IRQ(IRQ_DA850_TINT12_3),
-               .top_irq        = DAVINCI_INTC_IRQ(IRQ_DA850_TINT34_3),
-       },
-};
-
 /*
- * T0_BOT: Timer 0, bottom             : Used for clock_event
- * T0_TOP: Timer 0, top                        : Used for clocksource
- * T1_BOT, T1_TOP: Timer 1, bottom & top: Used for watchdog timer
+ * Bottom half of timer 0 is used for clock_event, top half for
+ * clocksource.
  */
-static struct davinci_timer_info da850_timer_info = {
-       .timers         = da850_timer_instance,
-       .clockevent_id  = T0_BOT,
-       .clocksource_id = T0_TOP,
+static const struct davinci_timer_cfg da850_timer_cfg = {
+       .reg = DEFINE_RES_IO(DA8XX_TIMER64P0_BASE, SZ_4K),
+       .irq = {
+               DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_DA8XX_TINT12_0)),
+               DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_DA8XX_TINT34_0)),
+       },
 };
 
 #ifdef CONFIG_CPU_FREQ
@@ -635,7 +614,6 @@ static const struct davinci_soc_info davinci_soc_info_da850 = {
        .pinmux_base            = DA8XX_SYSCFG0_BASE + 0x120,
        .pinmux_pins            = da850_pins,
        .pinmux_pins_num        = ARRAY_SIZE(da850_pins),
-       .timer_info             = &da850_timer_info,
        .emac_pdata             = &da8xx_emac_pdata,
        .sram_dma               = DA8XX_SHARED_RAM_BASE,
        .sram_len               = SZ_128K,
@@ -672,6 +650,7 @@ void __init da850_init_time(void)
        void __iomem *pll0;
        struct regmap *cfgchip;
        struct clk *clk;
+       int rv;
 
        clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DA850_REF_FREQ);
 
@@ -681,8 +660,13 @@ void __init da850_init_time(void)
        da850_pll0_init(NULL, pll0, cfgchip);
 
        clk = clk_get(NULL, "timer0");
+       if (WARN_ON(IS_ERR(clk))) {
+               pr_err("Unable to get the timer clock\n");
+               return;
+       }
 
-       davinci_timer_init(clk);
+       rv = davinci_timer_register(clk, &da850_timer_cfg);
+       WARN(rv, "Unable to register the timer: %d\n", rv);
 }
 
 static struct resource da850_pll1_resources[] = {
index 56c1835..208d7a4 100644 (file)
@@ -60,6 +60,9 @@ void davinci_map_sysmod(void);
 #define DAVINCI_GPIO_BASE 0x01C67000
 int davinci_gpio_register(struct resource *res, int size, void *pdata);
 
+#define DAVINCI_TIMER0_BASE            (IO_PHYS + 0x21400)
+#define DAVINCI_WDOG_BASE              (IO_PHYS + 0x21C00)
+
 /* DM355 base addresses */
 #define DM355_ASYNC_EMIF_CONTROL_BASE  0x01e10000
 #define DM355_ASYNC_EMIF_DATA_CE0_BASE 0x02000000
index c607332..5de72d2 100644 (file)
@@ -30,7 +30,8 @@
 #include <mach/cputype.h>
 #include <mach/mux.h>
 #include <mach/serial.h>
-#include <mach/time.h>
+
+#include <clocksource/timer-davinci.h>
 
 #include "asp.h"
 #include "davinci.h"
@@ -620,15 +621,15 @@ static struct davinci_id dm355_ids[] = {
 };
 
 /*
- * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
- * T0_TOP: Timer 0, top   :  clocksource for generic timekeeping
- * T1_BOT: Timer 1, bottom:  (used by DSP in TI DSPLink code)
- * T1_TOP: Timer 1, top   :  <unused>
+ * Bottom half of timer0 is used for clockevent, top half is used for
+ * clocksource.
  */
-static struct davinci_timer_info dm355_timer_info = {
-       .timers         = davinci_timer_instance,
-       .clockevent_id  = T0_BOT,
-       .clocksource_id = T0_TOP,
+static const struct davinci_timer_cfg dm355_timer_cfg = {
+       .reg = DEFINE_RES_IO(DAVINCI_TIMER0_BASE, SZ_4K),
+       .irq = {
+               DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT12)),
+               DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT34)),
+       },
 };
 
 static struct plat_serial8250_port dm355_serial0_platform_data[] = {
@@ -706,7 +707,6 @@ static const struct davinci_soc_info davinci_soc_info_dm355 = {
        .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm355_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm355_pins),
-       .timer_info             = &dm355_timer_info,
        .sram_dma               = 0x00010000,
        .sram_len               = SZ_32K,
 };
@@ -733,6 +733,7 @@ void __init dm355_init_time(void)
 {
        void __iomem *pll1, *psc;
        struct clk *clk;
+       int rv;
 
        clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM355_REF_FREQ);
 
@@ -743,8 +744,13 @@ void __init dm355_init_time(void)
        dm355_psc_init(NULL, psc);
 
        clk = clk_get(NULL, "timer0");
+       if (WARN_ON(IS_ERR(clk))) {
+               pr_err("Unable to get the timer clock\n");
+               return;
+       }
 
-       davinci_timer_init(clk);
+       rv = davinci_timer_register(clk, &dm355_timer_cfg);
+       WARN(rv, "Unable to register the timer: %d\n", rv);
 }
 
 static struct resource dm355_pll2_resources[] = {
index 2f9ae64..8062412 100644 (file)
@@ -784,6 +784,10 @@ void __init dm365_init_time(void)
        dm365_psc_init(NULL, psc);
 
        clk = clk_get(NULL, "timer0");
+       if (WARN_ON(IS_ERR(clk))) {
+               pr_err("Unable to get the timer clock\n");
+               return;
+       }
 
        davinci_timer_init(clk);
 }
index 1b9e9a6..2498893 100644 (file)
@@ -27,7 +27,8 @@
 #include <mach/cputype.h>
 #include <mach/mux.h>
 #include <mach/serial.h>
-#include <mach/time.h>
+
+#include <clocksource/timer-davinci.h>
 
 #include "asp.h"
 #include "davinci.h"
@@ -561,15 +562,15 @@ static struct davinci_id dm644x_ids[] = {
 };
 
 /*
- * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
- * T0_TOP: Timer 0, top   :  clocksource for generic timekeeping
- * T1_BOT: Timer 1, bottom:  (used by DSP in TI DSPLink code)
- * T1_TOP: Timer 1, top   :  <unused>
+ * Bottom half of timer0 is used for clockevent, top half is used for
+ * clocksource.
  */
-static struct davinci_timer_info dm644x_timer_info = {
-       .timers         = davinci_timer_instance,
-       .clockevent_id  = T0_BOT,
-       .clocksource_id = T0_TOP,
+static const struct davinci_timer_cfg dm644x_timer_cfg = {
+       .reg = DEFINE_RES_IO(DAVINCI_TIMER0_BASE, SZ_4K),
+       .irq = {
+               DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT12)),
+               DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT34)),
+       },
 };
 
 static struct plat_serial8250_port dm644x_serial0_platform_data[] = {
@@ -647,7 +648,6 @@ static const struct davinci_soc_info davinci_soc_info_dm644x = {
        .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm644x_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm644x_pins),
-       .timer_info             = &dm644x_timer_info,
        .emac_pdata             = &dm644x_emac_pdata,
        .sram_dma               = 0x00008000,
        .sram_len               = SZ_16K,
@@ -669,6 +669,7 @@ void __init dm644x_init_time(void)
 {
        void __iomem *pll1, *psc;
        struct clk *clk;
+       int rv;
 
        clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM644X_REF_FREQ);
 
@@ -679,8 +680,13 @@ void __init dm644x_init_time(void)
        dm644x_psc_init(NULL, psc);
 
        clk = clk_get(NULL, "timer0");
+       if (WARN_ON(IS_ERR(clk))) {
+               pr_err("Unable to get the timer clock\n");
+               return;
+       }
 
-       davinci_timer_init(clk);
+       rv = davinci_timer_register(clk, &dm644x_timer_cfg);
+       WARN(rv, "Unable to register the timer: %d\n", rv);
 }
 
 static struct resource dm644x_pll2_resources[] = {
index 62ca952..4ffd028 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * TI DaVinci DM644x chip specific setup
+ * TI DaVinci DM646x chip specific setup
  *
  * Author: Kevin Hilman, Deep Root Systems, LLC
  *
@@ -28,7 +28,8 @@
 #include <mach/cputype.h>
 #include <mach/mux.h>
 #include <mach/serial.h>
-#include <mach/time.h>
+
+#include <clocksource/timer-davinci.h>
 
 #include "asp.h"
 #include "davinci.h"
@@ -501,15 +502,15 @@ static struct davinci_id dm646x_ids[] = {
 };
 
 /*
- * T0_BOT: Timer 0, bottom:  clockevent source for hrtimers
- * T0_TOP: Timer 0, top   :  clocksource for generic timekeeping
- * T1_BOT: Timer 1, bottom:  (used by DSP in TI DSPLink code)
- * T1_TOP: Timer 1, top   :  <unused>
+ * Bottom half of timer0 is used for clockevent, top half is used for
+ * clocksource.
  */
-static struct davinci_timer_info dm646x_timer_info = {
-       .timers         = davinci_timer_instance,
-       .clockevent_id  = T0_BOT,
-       .clocksource_id = T0_TOP,
+static const struct davinci_timer_cfg dm646x_timer_cfg = {
+       .reg = DEFINE_RES_IO(DAVINCI_TIMER0_BASE, SZ_4K),
+       .irq = {
+               DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT12)),
+               DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT34)),
+       },
 };
 
 static struct plat_serial8250_port dm646x_serial0_platform_data[] = {
@@ -587,7 +588,6 @@ static const struct davinci_soc_info davinci_soc_info_dm646x = {
        .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm646x_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm646x_pins),
-       .timer_info             = &dm646x_timer_info,
        .emac_pdata             = &dm646x_emac_pdata,
        .sram_dma               = 0x10010000,
        .sram_len               = SZ_32K,
@@ -652,6 +652,7 @@ void __init dm646x_init_time(unsigned long ref_clk_rate,
 {
        void __iomem *pll1, *psc;
        struct clk *clk;
+       int rv;
 
        clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, ref_clk_rate);
        clk_register_fixed_rate(NULL, "aux_clkin", NULL, 0, aux_clkin_rate);
@@ -663,8 +664,13 @@ void __init dm646x_init_time(unsigned long ref_clk_rate,
        dm646x_psc_init(NULL, psc);
 
        clk = clk_get(NULL, "timer0");
+       if (WARN_ON(IS_ERR(clk))) {
+               pr_err("Unable to get the timer clock\n");
+               return;
+       }
 
-       davinci_timer_init(clk);
+       rv = davinci_timer_register(clk, &dm646x_timer_cfg);
+       WARN(rv, "Unable to register the timer: %d\n", rv);
 }
 
 static struct resource dm646x_pll2_resources[] = {
index 1c971d8..ba91373 100644 (file)
@@ -11,9 +11,7 @@
 #ifndef __ARCH_ARM_MACH_DAVINCI_TIME_H
 #define __ARCH_ARM_MACH_DAVINCI_TIME_H
 
-#define DAVINCI_TIMER0_BASE            (IO_PHYS + 0x21400)
 #define DAVINCI_TIMER1_BASE            (IO_PHYS + 0x21800)
-#define DAVINCI_WDOG_BASE              (IO_PHYS + 0x21C00)
 
 enum {
        T0_BOT,
index 5a6de53..740410a 100644 (file)
@@ -398,17 +398,3 @@ void __init davinci_timer_init(struct clk *timer_clk)
        for (i=0; i< ARRAY_SIZE(timers); i++)
                timer32_config(&timers[i]);
 }
-
-static int __init of_davinci_timer_init(struct device_node *np)
-{
-       struct clk *clk;
-
-       clk = of_clk_get(np, 0);
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
-
-       davinci_timer_init(clk);
-
-       return 0;
-}
-TIMER_OF_DECLARE(davinci_timer, "ti,da830-timer", of_davinci_timer_init);
similarity index 96%
rename from arch/arm/mach-dove/include/mach/bridge-regs.h
rename to arch/arm/mach-dove/bridge-regs.h
index f4a5b34..ace0b0b 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * arch/arm/mach-dove/include/mach/bridge-regs.h
- *
  * Mbus-L to Mbus Bridge Registers
  *
  * This file is licensed under the terms of the GNU General Public
@@ -11,7 +9,7 @@
 #ifndef __ASM_ARCH_BRIDGE_REGS_H
 #define __ASM_ARCH_BRIDGE_REGS_H
 
-#include <mach/dove.h>
+#include "dove.h"
 
 #define CPU_CONFIG             (BRIDGE_VIRT_BASE + 0x0000)
 
index b9a7c33..9f25c99 100644 (file)
@@ -22,8 +22,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
-#include <mach/dove.h>
-
+#include "dove.h"
 #include "common.h"
 
 static struct mv643xx_eth_platform_data cm_a510_ge00_data = {
index d7b826d..01b830a 100644 (file)
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
-#include <mach/bridge-regs.h>
-#include <mach/pm.h>
 #include <plat/common.h>
 #include <plat/irq.h>
 #include <plat/time.h>
+#include "bridge-regs.h"
+#include "pm.h"
 #include "common.h"
 
 /* These can go away once Dove uses the mvebu-mbus DT binding */
index 8971c3c..418ab21 100644 (file)
@@ -24,7 +24,7 @@
 #include <linux/gpio.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
-#include <mach/dove.h>
+#include "dove.h"
 #include "common.h"
 
 static struct mv643xx_eth_platform_data dove_db_ge00_data = {
similarity index 95%
rename from arch/arm/mach-dove/include/mach/dove.h
rename to arch/arm/mach-dove/dove.h
index 00f4545..320ed16 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * arch/arm/mach-dove/include/mach/dove.h
- *
  * Generic definitions for Marvell Dove 88AP510 SoC
  *
  * This file is licensed under the terms of the GNU General Public
@@ -11,7 +9,7 @@
 #ifndef __ASM_ARCH_DOVE_H
 #define __ASM_ARCH_DOVE_H
 
-#include <mach/irqs.h>
+#include "irqs.h"
 
 /*
  * Marvell Dove address maps.
@@ -20,8 +18,8 @@
  * c8000000    fdb00000        1M      Cryptographic SRAM
  * e0000000    @runtime        128M    PCIe-0 Memory space
  * e8000000    @runtime        128M    PCIe-1 Memory space
- * f1000000    fde00000        8M      on-chip south-bridge registers
- * f1800000    fe600000        8M      on-chip north-bridge registers
+ * f1000000    fec00000        1M      on-chip south-bridge registers
+ * f1800000    fe400000        8M      on-chip north-bridge registers
  * f2000000    fee00000        1M      PCIe-0 I/O space
  * f2100000    fef00000        1M      PCIe-1 I/O space
  */
 #define DOVE_SCRATCHPAD_SIZE           SZ_1M
 
 #define DOVE_SB_REGS_PHYS_BASE         0xf1000000
-#define DOVE_SB_REGS_VIRT_BASE         IOMEM(0xfde00000)
-#define DOVE_SB_REGS_SIZE              SZ_8M
+#define DOVE_SB_REGS_VIRT_BASE         IOMEM(0xfec00000)
+#define DOVE_SB_REGS_SIZE              SZ_1M
 
 #define DOVE_NB_REGS_PHYS_BASE         0xf1800000
-#define DOVE_NB_REGS_VIRT_BASE         IOMEM(0xfe600000)
+#define DOVE_NB_REGS_VIRT_BASE         IOMEM(0xfe400000)
 #define DOVE_NB_REGS_SIZE              SZ_8M
 
 #define DOVE_PCIE0_IO_PHYS_BASE                0xf2000000
diff --git a/arch/arm/mach-dove/include/mach/hardware.h b/arch/arm/mach-dove/include/mach/hardware.h
deleted file mode 100644 (file)
index f1368b9..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-dove/include/mach/hardware.h
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include "dove.h"
-
-/* Macros below are required for compatibility with PXA AC'97 driver.  */
-#define __REG(x)       (*((volatile u32 *)((x) - DOVE_SB_REGS_PHYS_BASE + \
-                               DOVE_SB_REGS_VIRT_BASE)))
-#define __PREG(x)      (((u32)&(x)) - DOVE_SB_REGS_VIRT_BASE + \
-               DOVE_SB_REGS_PHYS_BASE)
-#endif
index 5c8ae9b..7a4bd88 100644 (file)
@@ -1,15 +1,13 @@
 /*
- * arch/arm/mach-dove/include/mach/uncompress.h
- *
  * This file is licensed under the terms of the GNU General Public
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
 
-#include <mach/dove.h>
+#define UART0_PHYS_BASE (0xf1000000 + 0x12000)
 
-#define UART_THR ((volatile unsigned char *)(DOVE_UART0_PHYS_BASE + 0x0))
-#define UART_LSR ((volatile unsigned char *)(DOVE_UART0_PHYS_BASE + 0x14))
+#define UART_THR ((volatile unsigned char *)(UART0_PHYS_BASE + 0x0))
+#define UART_LSR ((volatile unsigned char *)(UART0_PHYS_BASE + 0x14))
 
 #define LSR_THRE       0x20
 
index d6627c1..31ccbce 100644 (file)
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <asm/exception.h>
+
 #include <plat/irq.h>
-#include <mach/bridge-regs.h>
 #include <plat/orion-gpio.h>
+
+#include "pm.h"
+#include "bridge-regs.h"
 #include "common.h"
 
 static int __initdata gpio0_irqs[4] = {
similarity index 98%
rename from arch/arm/mach-dove/include/mach/irqs.h
rename to arch/arm/mach-dove/irqs.h
index 8ff0fa8..a074217 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * arch/arm/mach-dove/include/mach/irqs.h
- *
  * IRQ definitions for Marvell Dove 88AP510 SoC
  *
  * This file is licensed under the terms of the GNU General Public
index 8a433a5..6acd848 100644 (file)
@@ -12,8 +12,8 @@
 #include <linux/gpio.h>
 #include <linux/io.h>
 #include <plat/mpp.h>
-#include <mach/dove.h>
 #include <plat/orion-gpio.h>
+#include "dove.h"
 #include "mpp.h"
 
 struct dove_mpp_grp {
index dfb62f3..ee91ac6 100644 (file)
@@ -17,9 +17,9 @@
 #include <asm/setup.h>
 #include <asm/delay.h>
 #include <plat/pcie.h>
-#include <mach/irqs.h>
-#include <mach/bridge-regs.h>
 #include <plat/addr-map.h>
+#include "irqs.h"
+#include "bridge-regs.h"
 #include "common.h"
 
 struct pcie_port {
similarity index 97%
rename from arch/arm/mach-dove/include/mach/pm.h
rename to arch/arm/mach-dove/pm.h
index d22b9b1..0126774 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * arch/arm/mach-dove/include/mach/pm.h
- *
  * This file is licensed under the terms of the GNU General Public
  * License version 2.  This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
@@ -10,7 +8,7 @@
 #define __ASM_ARCH_PM_H
 
 #include <asm/errno.h>
-#include <mach/irqs.h>
+#include "irqs.h"
 
 #define CLOCK_GATING_CONTROL   (DOVE_PMU_VIRT_BASE + 0x38)
 #define  CLOCK_GATING_BIT_USB0         0
index 1f0da76..7b7280c 100644 (file)
@@ -103,7 +103,7 @@ static struct spi_board_info edb93xx_spi_board_info[] __initdata = {
 };
 
 static struct gpiod_lookup_table edb93xx_spi_cs_gpio_table = {
-       .dev_id = "ep93xx-spi.0",
+       .dev_id = "spi0",
        .table = {
                GPIO_LOOKUP("A", 6, "cs", GPIO_ACTIVE_LOW),
                { },
index e2658e2..8a53b74 100644 (file)
@@ -73,7 +73,7 @@ static struct spi_board_info simone_spi_devices[] __initdata = {
  * v1.3 parts will still work, since the signal on SFRMOUT is automatic.
  */
 static struct gpiod_lookup_table simone_spi_cs_gpio_table = {
-       .dev_id = "ep93xx-spi.0",
+       .dev_id = "spi0",
        .table = {
                GPIO_LOOKUP("A", 1, "cs", GPIO_ACTIVE_LOW),
                { },
index 582e06e..e0e1b11 100644 (file)
@@ -267,7 +267,7 @@ static struct spi_board_info bk3_spi_board_info[] __initdata = {
  * goes through CPLD
  */
 static struct gpiod_lookup_table bk3_spi_cs_gpio_table = {
-       .dev_id = "ep93xx-spi.0",
+       .dev_id = "spi0",
        .table = {
                GPIO_LOOKUP("F", 3, "cs", GPIO_ACTIVE_LOW),
                { },
@@ -316,7 +316,7 @@ static struct spi_board_info ts72xx_spi_devices[] __initdata = {
 };
 
 static struct gpiod_lookup_table ts72xx_spi_cs_gpio_table = {
-       .dev_id = "ep93xx-spi.0",
+       .dev_id = "spi0",
        .table = {
                /* DIO_17 */
                GPIO_LOOKUP("F", 2, "cs", GPIO_ACTIVE_LOW),
index a88a1d8..cbcba31 100644 (file)
@@ -242,7 +242,7 @@ static struct spi_board_info vision_spi_board_info[] __initdata = {
 };
 
 static struct gpiod_lookup_table vision_spi_cs_gpio_table = {
-       .dev_id = "ep93xx-spi.0",
+       .dev_id = "spi0",
        .table = {
                GPIO_LOOKUP_IDX("A", 6, "cs", 0, GPIO_ACTIVE_LOW),
                GPIO_LOOKUP_IDX("A", 7, "cs", 1, GPIO_ACTIVE_LOW),
index d742223..f837866 100644 (file)
@@ -13,6 +13,7 @@ menuconfig ARCH_EXYNOS
        select ARM_AMBA
        select ARM_GIC
        select COMMON_CLK_SAMSUNG
+       select EXYNOS_CHIPID
        select EXYNOS_THERMAL
        select EXYNOS_PMU
        select EXYNOS_SROM
index 9571345..ebb2759 100644 (file)
@@ -30,12 +30,6 @@ static int ar8031_phy_fixup(struct phy_device *dev)
        val &= ~(0x1 << 8);
        phy_write(dev, 0xe, val);
 
-       /* introduce tx clock delay */
-       phy_write(dev, 0x1d, 0x5);
-       val = phy_read(dev, 0x1e);
-       val |= 0x0100;
-       phy_write(dev, 0x1e, val);
-
        return 0;
 }
 
diff --git a/arch/arm/mach-iop13xx/Kconfig b/arch/arm/mach-iop13xx/Kconfig
deleted file mode 100644 (file)
index c4f0407..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-if ARCH_IOP13XX
-
-menu "IOP13XX Implementation Options"
-
-comment "IOP13XX Platform Support"
-
-config MACH_IQ81340SC
-       bool "Enable IQ81340SC Hardware Support"
-       help
-         Say Y here if you want to support running on the Intel IQ81340SC
-         evaluation kit.
-
-config MACH_IQ81340MC
-       bool "Enable IQ81340MC Hardware Support"
-       help
-         Say Y here if you want to support running on the Intel IQ81340MC
-         evaluation kit.
-
-endmenu
-endif
diff --git a/arch/arm/mach-iop13xx/Makefile b/arch/arm/mach-iop13xx/Makefile
deleted file mode 100644 (file)
index 5757c8f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_ARCH_IOP13XX) += setup.o
-obj-$(CONFIG_ARCH_IOP13XX) += irq.o
-obj-$(CONFIG_ARCH_IOP13XX) += pci.o
-obj-$(CONFIG_ARCH_IOP13XX) += io.o
-obj-$(CONFIG_ARCH_IOP13XX) += tpmi.o
-obj-$(CONFIG_MACH_IQ81340SC) += iq81340sc.o
-obj-$(CONFIG_MACH_IQ81340MC) += iq81340mc.o
-obj-$(CONFIG_PCI_MSI) += msi.o
diff --git a/arch/arm/mach-iop13xx/Makefile.boot b/arch/arm/mach-iop13xx/Makefile.boot
deleted file mode 100644 (file)
index 4f29554..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-   zreladdr-y   += 0x00008000
-params_phys-y  := 0x00000100
-initrd_phys-y  := 0x00800000
diff --git a/arch/arm/mach-iop13xx/include/mach/adma.h b/arch/arm/mach-iop13xx/include/mach/adma.h
deleted file mode 100644 (file)
index 51d206f..0000000
+++ /dev/null
@@ -1,608 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright(c) 2006, Intel Corporation.
- */
-#ifndef _ADMA_H
-#define _ADMA_H
-#include <linux/types.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <asm/hardware/iop_adma.h>
-
-#define ADMA_ACCR(chan)        (chan->mmr_base + 0x0)
-#define ADMA_ACSR(chan)        (chan->mmr_base + 0x4)
-#define ADMA_ADAR(chan)        (chan->mmr_base + 0x8)
-#define ADMA_IIPCR(chan)       (chan->mmr_base + 0x18)
-#define ADMA_IIPAR(chan)       (chan->mmr_base + 0x1c)
-#define ADMA_IIPUAR(chan)      (chan->mmr_base + 0x20)
-#define ADMA_ANDAR(chan)       (chan->mmr_base + 0x24)
-#define ADMA_ADCR(chan)        (chan->mmr_base + 0x28)
-#define ADMA_CARMD(chan)       (chan->mmr_base + 0x2c)
-#define ADMA_ABCR(chan)        (chan->mmr_base + 0x30)
-#define ADMA_DLADR(chan)       (chan->mmr_base + 0x34)
-#define ADMA_DUADR(chan)       (chan->mmr_base + 0x38)
-#define ADMA_SLAR(src, chan)   (chan->mmr_base + (0x3c + (src << 3)))
-#define ADMA_SUAR(src, chan)   (chan->mmr_base + (0x40 + (src << 3)))
-
-struct iop13xx_adma_src {
-       u32 src_addr;
-       union {
-               u32 upper_src_addr;
-               struct {
-                       unsigned int pq_upper_src_addr:24;
-                       unsigned int pq_dmlt:8;
-               };
-       };
-};
-
-struct iop13xx_adma_desc_ctrl {
-       unsigned int int_en:1;
-       unsigned int xfer_dir:2;
-       unsigned int src_select:4;
-       unsigned int zero_result:1;
-       unsigned int block_fill_en:1;
-       unsigned int crc_gen_en:1;
-       unsigned int crc_xfer_dis:1;
-       unsigned int crc_seed_fetch_dis:1;
-       unsigned int status_write_back_en:1;
-       unsigned int endian_swap_en:1;
-       unsigned int reserved0:2;
-       unsigned int pq_update_xfer_en:1;
-       unsigned int dual_xor_en:1;
-       unsigned int pq_xfer_en:1;
-       unsigned int p_xfer_dis:1;
-       unsigned int reserved1:10;
-       unsigned int relax_order_en:1;
-       unsigned int no_snoop_en:1;
-};
-
-struct iop13xx_adma_byte_count {
-       unsigned int byte_count:24;
-       unsigned int host_if:3;
-       unsigned int reserved:2;
-       unsigned int zero_result_err_q:1;
-       unsigned int zero_result_err:1;
-       unsigned int tx_complete:1;
-};
-
-struct iop13xx_adma_desc_hw {
-       u32 next_desc;
-       union {
-               u32 desc_ctrl;
-               struct iop13xx_adma_desc_ctrl desc_ctrl_field;
-       };
-       union {
-               u32 crc_addr;
-               u32 block_fill_data;
-               u32 q_dest_addr;
-       };
-       union {
-               u32 byte_count;
-               struct iop13xx_adma_byte_count byte_count_field;
-       };
-       union {
-               u32 dest_addr;
-               u32 p_dest_addr;
-       };
-       union {
-               u32 upper_dest_addr;
-               u32 pq_upper_dest_addr;
-       };
-       struct iop13xx_adma_src src[1];
-};
-
-struct iop13xx_adma_desc_dual_xor {
-       u32 next_desc;
-       u32 desc_ctrl;
-       u32 reserved;
-       u32 byte_count;
-       u32 h_dest_addr;
-       u32 h_upper_dest_addr;
-       u32 src0_addr;
-       u32 upper_src0_addr;
-       u32 src1_addr;
-       u32 upper_src1_addr;
-       u32 h_src_addr;
-       u32 h_upper_src_addr;
-       u32 d_src_addr;
-       u32 d_upper_src_addr;
-       u32 d_dest_addr;
-       u32 d_upper_dest_addr;
-};
-
-struct iop13xx_adma_desc_pq_update {
-       u32 next_desc;
-       u32 desc_ctrl;
-       u32 reserved;
-       u32 byte_count;
-       u32 p_dest_addr;
-       u32 p_upper_dest_addr;
-       u32 src0_addr;
-       u32 upper_src0_addr;
-       u32 src1_addr;
-       u32 upper_src1_addr;
-       u32 p_src_addr;
-       u32 p_upper_src_addr;
-       u32 q_src_addr;
-       struct {
-               unsigned int q_upper_src_addr:24;
-               unsigned int q_dmlt:8;
-       };
-       u32 q_dest_addr;
-       u32 q_upper_dest_addr;
-};
-
-static inline int iop_adma_get_max_xor(void)
-{
-       return 16;
-}
-
-#define iop_adma_get_max_pq iop_adma_get_max_xor
-
-static inline u32 iop_chan_get_current_descriptor(struct iop_adma_chan *chan)
-{
-       return __raw_readl(ADMA_ADAR(chan));
-}
-
-static inline void iop_chan_set_next_descriptor(struct iop_adma_chan *chan,
-                                               u32 next_desc_addr)
-{
-       __raw_writel(next_desc_addr, ADMA_ANDAR(chan));
-}
-
-#define ADMA_STATUS_BUSY (1 << 13)
-
-static inline char iop_chan_is_busy(struct iop_adma_chan *chan)
-{
-       if (__raw_readl(ADMA_ACSR(chan)) &
-               ADMA_STATUS_BUSY)
-               return 1;
-       else
-               return 0;
-}
-
-static inline int
-iop_chan_get_desc_align(struct iop_adma_chan *chan, int num_slots)
-{
-       return 1;
-}
-#define iop_desc_is_aligned(x, y) 1
-
-static inline int
-iop_chan_memcpy_slot_count(size_t len, int *slots_per_op)
-{
-       *slots_per_op = 1;
-       return 1;
-}
-
-#define iop_chan_interrupt_slot_count(s, c) iop_chan_memcpy_slot_count(0, s)
-
-static inline int
-iop_chan_memset_slot_count(size_t len, int *slots_per_op)
-{
-       *slots_per_op = 1;
-       return 1;
-}
-
-static inline int
-iop_chan_xor_slot_count(size_t len, int src_cnt, int *slots_per_op)
-{
-       static const char slot_count_table[] = { 1, 2, 2, 2,
-                                                2, 3, 3, 3,
-                                                3, 4, 4, 4,
-                                                4, 5, 5, 5,
-                                               };
-       *slots_per_op = slot_count_table[src_cnt - 1];
-       return *slots_per_op;
-}
-
-#define ADMA_MAX_BYTE_COUNT    (16 * 1024 * 1024)
-#define IOP_ADMA_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT
-#define IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT
-#define IOP_ADMA_XOR_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT
-#define IOP_ADMA_PQ_MAX_BYTE_COUNT ADMA_MAX_BYTE_COUNT
-#define iop_chan_zero_sum_slot_count(l, s, o) iop_chan_xor_slot_count(l, s, o)
-#define iop_chan_pq_slot_count iop_chan_xor_slot_count
-#define iop_chan_pq_zero_sum_slot_count iop_chan_xor_slot_count
-
-static inline u32 iop_desc_get_byte_count(struct iop_adma_desc_slot *desc,
-                                       struct iop_adma_chan *chan)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       return hw_desc->byte_count_field.byte_count;
-}
-
-static inline u32 iop_desc_get_src_addr(struct iop_adma_desc_slot *desc,
-                                       struct iop_adma_chan *chan,
-                                       int src_idx)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       return hw_desc->src[src_idx].src_addr;
-}
-
-static inline u32 iop_desc_get_src_count(struct iop_adma_desc_slot *desc,
-                                       struct iop_adma_chan *chan)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       return hw_desc->desc_ctrl_field.src_select + 1;
-}
-
-static inline void
-iop_desc_init_memcpy(struct iop_adma_desc_slot *desc, unsigned long flags)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       union {
-               u32 value;
-               struct iop13xx_adma_desc_ctrl field;
-       } u_desc_ctrl;
-
-       u_desc_ctrl.value = 0;
-       u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
-       u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
-       hw_desc->desc_ctrl = u_desc_ctrl.value;
-       hw_desc->crc_addr = 0;
-}
-
-static inline void
-iop_desc_init_memset(struct iop_adma_desc_slot *desc, unsigned long flags)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       union {
-               u32 value;
-               struct iop13xx_adma_desc_ctrl field;
-       } u_desc_ctrl;
-
-       u_desc_ctrl.value = 0;
-       u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
-       u_desc_ctrl.field.block_fill_en = 1;
-       u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
-       hw_desc->desc_ctrl = u_desc_ctrl.value;
-       hw_desc->crc_addr = 0;
-}
-
-/* to do: support buffers larger than ADMA_MAX_BYTE_COUNT */
-static inline void
-iop_desc_init_xor(struct iop_adma_desc_slot *desc, int src_cnt,
-                 unsigned long flags)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       union {
-               u32 value;
-               struct iop13xx_adma_desc_ctrl field;
-       } u_desc_ctrl;
-
-       u_desc_ctrl.value = 0;
-       u_desc_ctrl.field.src_select = src_cnt - 1;
-       u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
-       u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
-       hw_desc->desc_ctrl = u_desc_ctrl.value;
-       hw_desc->crc_addr = 0;
-
-}
-#define iop_desc_init_null_xor(d, s, i) iop_desc_init_xor(d, s, i)
-
-/* to do: support buffers larger than ADMA_MAX_BYTE_COUNT */
-static inline int
-iop_desc_init_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
-                      unsigned long flags)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       union {
-               u32 value;
-               struct iop13xx_adma_desc_ctrl field;
-       } u_desc_ctrl;
-
-       u_desc_ctrl.value = 0;
-       u_desc_ctrl.field.src_select = src_cnt - 1;
-       u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
-       u_desc_ctrl.field.zero_result = 1;
-       u_desc_ctrl.field.status_write_back_en = 1;
-       u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
-       hw_desc->desc_ctrl = u_desc_ctrl.value;
-       hw_desc->crc_addr = 0;
-
-       return 1;
-}
-
-static inline void
-iop_desc_init_pq(struct iop_adma_desc_slot *desc, int src_cnt,
-                 unsigned long flags)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       union {
-               u32 value;
-               struct iop13xx_adma_desc_ctrl field;
-       } u_desc_ctrl;
-
-       u_desc_ctrl.value = 0;
-       u_desc_ctrl.field.src_select = src_cnt - 1;
-       u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
-       u_desc_ctrl.field.pq_xfer_en = 1;
-       u_desc_ctrl.field.p_xfer_dis = !!(flags & DMA_PREP_PQ_DISABLE_P);
-       u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
-       hw_desc->desc_ctrl = u_desc_ctrl.value;
-}
-
-static inline void
-iop_desc_init_pq_zero_sum(struct iop_adma_desc_slot *desc, int src_cnt,
-                         unsigned long flags)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       union {
-               u32 value;
-               struct iop13xx_adma_desc_ctrl field;
-       } u_desc_ctrl;
-
-       u_desc_ctrl.value = 0;
-       u_desc_ctrl.field.src_select = src_cnt - 1;
-       u_desc_ctrl.field.xfer_dir = 3; /* local to internal bus */
-       u_desc_ctrl.field.zero_result = 1;
-       u_desc_ctrl.field.status_write_back_en = 1;
-       u_desc_ctrl.field.pq_xfer_en = 1;
-       u_desc_ctrl.field.p_xfer_dis = !!(flags & DMA_PREP_PQ_DISABLE_P);
-       u_desc_ctrl.field.int_en = flags & DMA_PREP_INTERRUPT;
-       hw_desc->desc_ctrl = u_desc_ctrl.value;
-}
-
-static inline void iop_desc_set_byte_count(struct iop_adma_desc_slot *desc,
-                                       struct iop_adma_chan *chan,
-                                       u32 byte_count)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       hw_desc->byte_count = byte_count;
-}
-
-static inline void
-iop_desc_set_zero_sum_byte_count(struct iop_adma_desc_slot *desc, u32 len)
-{
-       int slots_per_op = desc->slots_per_op;
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter;
-       int i = 0;
-
-       if (len <= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT) {
-               hw_desc->byte_count = len;
-       } else {
-               do {
-                       iter = iop_hw_desc_slot_idx(hw_desc, i);
-                       iter->byte_count = IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
-                       len -= IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT;
-                       i += slots_per_op;
-               } while (len > IOP_ADMA_ZERO_SUM_MAX_BYTE_COUNT);
-
-               if (len) {
-                       iter = iop_hw_desc_slot_idx(hw_desc, i);
-                       iter->byte_count = len;
-               }
-       }
-}
-
-#define iop_desc_set_pq_zero_sum_byte_count iop_desc_set_zero_sum_byte_count
-
-static inline void iop_desc_set_dest_addr(struct iop_adma_desc_slot *desc,
-                                       struct iop_adma_chan *chan,
-                                       dma_addr_t addr)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       hw_desc->dest_addr = addr;
-       hw_desc->upper_dest_addr = 0;
-}
-
-static inline void
-iop_desc_set_pq_addr(struct iop_adma_desc_slot *desc, dma_addr_t *addr)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-
-       hw_desc->dest_addr = addr[0];
-       hw_desc->q_dest_addr = addr[1];
-       hw_desc->upper_dest_addr = 0;
-}
-
-static inline void iop_desc_set_memcpy_src_addr(struct iop_adma_desc_slot *desc,
-                                       dma_addr_t addr)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       hw_desc->src[0].src_addr = addr;
-       hw_desc->src[0].upper_src_addr = 0;
-}
-
-static inline void iop_desc_set_xor_src_addr(struct iop_adma_desc_slot *desc,
-                                       int src_idx, dma_addr_t addr)
-{
-       int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter;
-       int i = 0;
-
-       do {
-               iter = iop_hw_desc_slot_idx(hw_desc, i);
-               iter->src[src_idx].src_addr = addr;
-               iter->src[src_idx].upper_src_addr = 0;
-               slot_cnt -= slots_per_op;
-               if (slot_cnt) {
-                       i += slots_per_op;
-                       addr += IOP_ADMA_XOR_MAX_BYTE_COUNT;
-               }
-       } while (slot_cnt);
-}
-
-static inline void
-iop_desc_set_pq_src_addr(struct iop_adma_desc_slot *desc, int src_idx,
-                        dma_addr_t addr, unsigned char coef)
-{
-       int slot_cnt = desc->slot_cnt, slots_per_op = desc->slots_per_op;
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc, *iter;
-       struct iop13xx_adma_src *src;
-       int i = 0;
-
-       do {
-               iter = iop_hw_desc_slot_idx(hw_desc, i);
-               src = &iter->src[src_idx];
-               src->src_addr = addr;
-               src->pq_upper_src_addr = 0;
-               src->pq_dmlt = coef;
-               slot_cnt -= slots_per_op;
-               if (slot_cnt) {
-                       i += slots_per_op;
-                       addr += IOP_ADMA_PQ_MAX_BYTE_COUNT;
-               }
-       } while (slot_cnt);
-}
-
-static inline void
-iop_desc_init_interrupt(struct iop_adma_desc_slot *desc,
-       struct iop_adma_chan *chan)
-{
-       iop_desc_init_memcpy(desc, 1);
-       iop_desc_set_byte_count(desc, chan, 0);
-       iop_desc_set_dest_addr(desc, chan, 0);
-       iop_desc_set_memcpy_src_addr(desc, 0);
-}
-
-#define iop_desc_set_zero_sum_src_addr iop_desc_set_xor_src_addr
-#define iop_desc_set_pq_zero_sum_src_addr iop_desc_set_pq_src_addr
-
-static inline void
-iop_desc_set_pq_zero_sum_addr(struct iop_adma_desc_slot *desc, int pq_idx,
-                             dma_addr_t *src)
-{
-       iop_desc_set_xor_src_addr(desc, pq_idx, src[pq_idx]);
-       iop_desc_set_xor_src_addr(desc, pq_idx+1, src[pq_idx+1]);
-}
-
-static inline void iop_desc_set_next_desc(struct iop_adma_desc_slot *desc,
-                                       u32 next_desc_addr)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-
-       iop_paranoia(hw_desc->next_desc);
-       hw_desc->next_desc = next_desc_addr;
-}
-
-static inline u32 iop_desc_get_next_desc(struct iop_adma_desc_slot *desc)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       return hw_desc->next_desc;
-}
-
-static inline void iop_desc_clear_next_desc(struct iop_adma_desc_slot *desc)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       hw_desc->next_desc = 0;
-}
-
-static inline void iop_desc_set_block_fill_val(struct iop_adma_desc_slot *desc,
-                                               u32 val)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       hw_desc->block_fill_data = val;
-}
-
-static inline enum sum_check_flags
-iop_desc_get_zero_result(struct iop_adma_desc_slot *desc)
-{
-       struct iop13xx_adma_desc_hw *hw_desc = desc->hw_desc;
-       struct iop13xx_adma_desc_ctrl desc_ctrl = hw_desc->desc_ctrl_field;
-       struct iop13xx_adma_byte_count byte_count = hw_desc->byte_count_field;
-       enum sum_check_flags flags;
-
-       BUG_ON(!(byte_count.tx_complete && desc_ctrl.zero_result));
-
-       flags = byte_count.zero_result_err_q << SUM_CHECK_Q;
-       flags |= byte_count.zero_result_err << SUM_CHECK_P;
-
-       return flags;
-}
-
-static inline void iop_chan_append(struct iop_adma_chan *chan)
-{
-       u32 adma_accr;
-
-       adma_accr = __raw_readl(ADMA_ACCR(chan));
-       adma_accr |= 0x2;
-       __raw_writel(adma_accr, ADMA_ACCR(chan));
-}
-
-static inline u32 iop_chan_get_status(struct iop_adma_chan *chan)
-{
-       return __raw_readl(ADMA_ACSR(chan));
-}
-
-static inline void iop_chan_disable(struct iop_adma_chan *chan)
-{
-       u32 adma_chan_ctrl = __raw_readl(ADMA_ACCR(chan));
-       adma_chan_ctrl &= ~0x1;
-       __raw_writel(adma_chan_ctrl, ADMA_ACCR(chan));
-}
-
-static inline void iop_chan_enable(struct iop_adma_chan *chan)
-{
-       u32 adma_chan_ctrl;
-
-       adma_chan_ctrl = __raw_readl(ADMA_ACCR(chan));
-       adma_chan_ctrl |= 0x1;
-       __raw_writel(adma_chan_ctrl, ADMA_ACCR(chan));
-}
-
-static inline void iop_adma_device_clear_eot_status(struct iop_adma_chan *chan)
-{
-       u32 status = __raw_readl(ADMA_ACSR(chan));
-       status &= (1 << 12);
-       __raw_writel(status, ADMA_ACSR(chan));
-}
-
-static inline void iop_adma_device_clear_eoc_status(struct iop_adma_chan *chan)
-{
-       u32 status = __raw_readl(ADMA_ACSR(chan));
-       status &= (1 << 11);
-       __raw_writel(status, ADMA_ACSR(chan));
-}
-
-static inline void iop_adma_device_clear_err_status(struct iop_adma_chan *chan)
-{
-       u32 status = __raw_readl(ADMA_ACSR(chan));
-       status &= (1 << 9) | (1 << 5) | (1 << 4) | (1 << 3);
-       __raw_writel(status, ADMA_ACSR(chan));
-}
-
-static inline int
-iop_is_err_int_parity(unsigned long status, struct iop_adma_chan *chan)
-{
-       return test_bit(9, &status);
-}
-
-static inline int
-iop_is_err_mcu_abort(unsigned long status, struct iop_adma_chan *chan)
-{
-       return test_bit(5, &status);
-}
-
-static inline int
-iop_is_err_int_tabort(unsigned long status, struct iop_adma_chan *chan)
-{
-       return test_bit(4, &status);
-}
-
-static inline int
-iop_is_err_int_mabort(unsigned long status, struct iop_adma_chan *chan)
-{
-       return test_bit(3, &status);
-}
-
-static inline int
-iop_is_err_pci_tabort(unsigned long status, struct iop_adma_chan *chan)
-{
-       return 0;
-}
-
-static inline int
-iop_is_err_pci_mabort(unsigned long status, struct iop_adma_chan *chan)
-{
-       return 0;
-}
-
-static inline int
-iop_is_err_split_tx(unsigned long status, struct iop_adma_chan *chan)
-{
-       return 0;
-}
-
-#endif /* _ADMA_H */
diff --git a/arch/arm/mach-iop13xx/include/mach/entry-macro.S b/arch/arm/mach-iop13xx/include/mach/entry-macro.S
deleted file mode 100644 (file)
index 9f4ecb8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * iop13xx low level irq macros
- * Copyright (c) 2005-2006, Intel Corporation.
- */
-       .macro get_irqnr_preamble, base, tmp
-       mrc     p15, 0, \tmp, c15, c1, 0
-       orr     \tmp, \tmp, #(1 << 6)
-       mcr     p15, 0, \tmp, c15, c1, 0        @ Enable cp6 access
-       .endm
-
-       /*
-        * Note: a 1-cycle window exists where iintvec will return the value
-        * of iintbase, so we explicitly check for "bad zeros"
-        */
-       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-       mrc     p6, 0, \irqnr, c3, c2, 0        @ Read IINTVEC
-       cmp     \irqnr, #0
-       mrceq   p6, 0, \irqnr, c3, c2, 0        @ Re-read on potentially bad zero
-       adds    \irqstat, \irqnr, #1            @ Check for 0xffffffff
-       movne   \irqnr, \irqnr, lsr #2          @ Convert to irqnr
-       .endm
-
-       .macro arch_ret_to_user, tmp1, tmp2
-       mrc     p15, 0, \tmp1, c15, c1, 0
-       ands    \tmp2, \tmp1, #(1 << 6)
-       bicne   \tmp1, \tmp1, #(1 << 6)
-       mcrne   p15, 0, \tmp1, c15, c1, 0       @ Disable cp6 access
-       .endm
diff --git a/arch/arm/mach-iop13xx/include/mach/hardware.h b/arch/arm/mach-iop13xx/include/mach/hardware.h
deleted file mode 100644 (file)
index 8c943fa..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-#include <asm/types.h>
-
-#ifndef __ASSEMBLY__
-extern u16 iop13xx_dev_id(void);
-extern void iop13xx_set_atu_mmr_bases(void);
-#endif
-
-/*
- * Generic chipset bits
- *
- */
-#include "iop13xx.h"
-
-/*
- * Board specific bits
- */
-#include "iq81340.h"
-
-#endif  /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-iop13xx/include/mach/iop13xx.h b/arch/arm/mach-iop13xx/include/mach/iop13xx.h
deleted file mode 100644 (file)
index 04bb6ac..0000000
+++ /dev/null
@@ -1,508 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _IOP13XX_HW_H_
-#define _IOP13XX_HW_H_
-
-#ifndef __ASSEMBLY__
-
-enum reboot_mode;
-
-/* The ATU offsets can change based on the strapping */
-extern u32 iop13xx_atux_pmmr_offset;
-extern u32 iop13xx_atue_pmmr_offset;
-void iop13xx_init_early(void);
-void iop13xx_init_irq(void);
-void iop13xx_map_io(void);
-void iop13xx_platform_init(void);
-void iop13xx_add_tpmi_devices(void);
-void iop13xx_init_irq(void);
-void iop13xx_restart(enum reboot_mode, const char *);
-
-/* CPUID CP6 R0 Page 0 */
-static inline int iop13xx_cpu_id(void)
-{
-       int id;
-       asm volatile("mrc p6, 0, %0, c0, c0, 0":"=r" (id));
-       return id;
-}
-
-/* WDTCR CP6 R7 Page 9 */
-static inline u32 read_wdtcr(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c7, c9, 0":"=r" (val));
-       return val;
-}
-static inline void write_wdtcr(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c7, c9, 0"::"r" (val));
-}
-
-/* WDTSR CP6 R8 Page 9 */
-static inline u32 read_wdtsr(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c8, c9, 0":"=r" (val));
-       return val;
-}
-static inline void write_wdtsr(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c8, c9, 0"::"r" (val));
-}
-
-/* RCSR - Reset Cause Status Register  */
-static inline u32 read_rcsr(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c0, c1, 0":"=r" (val));
-       return val;
-}
-
-extern unsigned long get_iop_tick_rate(void);
-#endif
-
-/*
- * IOP13XX I/O and Mem space regions for PCI autoconfiguration
- */
-#define IOP13XX_MAX_RAM_SIZE    0x80000000UL  /* 2GB */
-#define IOP13XX_PCI_OFFSET      IOP13XX_MAX_RAM_SIZE
-
-/* PCI MAP
- * bus range           cpu phys        cpu virt        note
- * 0x0000.0000 + 2GB   (n/a)           (n/a)           inbound, 1:1 mapping with Physical RAM
- * 0x8000.0000 + 928M  0x1.8000.0000   (ioremap)       PCIX outbound memory window
- * 0x8000.0000 + 928M  0x2.8000.0000   (ioremap)       PCIE outbound memory window
- *
- * IO MAP
- * 0x00000 + 64K       0x0.fffb.0000   0xfee0.0000     PCIX outbound i/o window
- * 0x10000 + 64K       0x0.fffd.0000   0xfee1.0000     PCIE outbound i/o window
- */
-#define IOP13XX_PCIX_LOWER_IO_PA      0xfffb0000UL
-#define IOP13XX_PCIX_LOWER_IO_BA      0x0UL /* OIOTVR */
-
-#define IOP13XX_PCIX_MEM_PHYS_OFFSET  0x100000000ULL
-#define IOP13XX_PCIX_MEM_WINDOW_SIZE  0x3a000000UL
-#define IOP13XX_PCIX_LOWER_MEM_BA     (PHYS_OFFSET + IOP13XX_PCI_OFFSET)
-#define IOP13XX_PCIX_LOWER_MEM_PA     (IOP13XX_PCIX_MEM_PHYS_OFFSET +\
-                                      IOP13XX_PCIX_LOWER_MEM_BA)
-#define IOP13XX_PCIX_UPPER_MEM_PA     (IOP13XX_PCIX_LOWER_MEM_PA +\
-                                      IOP13XX_PCIX_MEM_WINDOW_SIZE - 1)
-#define IOP13XX_PCIX_UPPER_MEM_BA     (IOP13XX_PCIX_LOWER_MEM_BA +\
-                                      IOP13XX_PCIX_MEM_WINDOW_SIZE - 1)
-
-#define IOP13XX_PCIX_MEM_COOKIE        0x80000000UL
-#define IOP13XX_PCIX_LOWER_MEM_RA      IOP13XX_PCIX_MEM_COOKIE
-#define IOP13XX_PCIX_UPPER_MEM_RA      (IOP13XX_PCIX_LOWER_MEM_RA +\
-                                       IOP13XX_PCIX_MEM_WINDOW_SIZE - 1)
-#define IOP13XX_PCIX_MEM_OFFSET        (IOP13XX_PCIX_MEM_COOKIE -\
-                                       IOP13XX_PCIX_LOWER_MEM_BA)
-
-/* PCI-E ranges */
-#define IOP13XX_PCIE_LOWER_IO_PA        0xfffd0000UL
-#define IOP13XX_PCIE_LOWER_IO_BA        0x10000UL  /* OIOTVR */
-
-#define IOP13XX_PCIE_MEM_PHYS_OFFSET    0x200000000ULL
-#define IOP13XX_PCIE_MEM_WINDOW_SIZE    0x3a000000UL
-#define IOP13XX_PCIE_LOWER_MEM_BA       (PHYS_OFFSET + IOP13XX_PCI_OFFSET)
-#define IOP13XX_PCIE_LOWER_MEM_PA       (IOP13XX_PCIE_MEM_PHYS_OFFSET +\
-                                        IOP13XX_PCIE_LOWER_MEM_BA)
-#define IOP13XX_PCIE_UPPER_MEM_PA       (IOP13XX_PCIE_LOWER_MEM_PA +\
-                                        IOP13XX_PCIE_MEM_WINDOW_SIZE - 1)
-#define IOP13XX_PCIE_UPPER_MEM_BA       (IOP13XX_PCIE_LOWER_MEM_BA +\
-                                        IOP13XX_PCIE_MEM_WINDOW_SIZE - 1)
-
-/* All 0xc000.0000 - 0xfdff.ffff addresses belong to PCIe */
-#define IOP13XX_PCIE_MEM_COOKIE         0xc0000000UL
-#define IOP13XX_PCIE_LOWER_MEM_RA       IOP13XX_PCIE_MEM_COOKIE
-#define IOP13XX_PCIE_UPPER_MEM_RA       (IOP13XX_PCIE_LOWER_MEM_RA +\
-                                        IOP13XX_PCIE_MEM_WINDOW_SIZE - 1)
-#define IOP13XX_PCIE_MEM_OFFSET         (IOP13XX_PCIE_MEM_COOKIE -\
-                                        IOP13XX_PCIE_LOWER_MEM_BA)
-
-/* PBI Ranges */
-#define IOP13XX_PBI_LOWER_MEM_PA         0xf0000000UL
-#define IOP13XX_PBI_MEM_WINDOW_SIZE      0x04000000UL
-#define IOP13XX_PBI_MEM_COOKIE           0xfa000000UL
-#define IOP13XX_PBI_LOWER_MEM_RA         IOP13XX_PBI_MEM_COOKIE
-#define IOP13XX_PBI_UPPER_MEM_RA         (IOP13XX_PBI_LOWER_MEM_RA +\
-                                         IOP13XX_PBI_MEM_WINDOW_SIZE - 1)
-
-/*
- * IOP13XX chipset registers
- */
-#define IOP13XX_PMMR_PHYS_MEM_BASE        0xffd80000UL  /* PMMR phys. address */
-#define IOP13XX_PMMR_VIRT_MEM_BASE        (void __iomem *)(0xfee80000UL)  /* PMMR phys. address */
-#define IOP13XX_PMMR_MEM_WINDOW_SIZE      0x80000
-#define IOP13XX_PMMR_UPPER_MEM_VA         (IOP13XX_PMMR_VIRT_MEM_BASE +\
-                                          IOP13XX_PMMR_MEM_WINDOW_SIZE - 1)
-#define IOP13XX_PMMR_UPPER_MEM_PA         (IOP13XX_PMMR_PHYS_MEM_BASE +\
-                                          IOP13XX_PMMR_MEM_WINDOW_SIZE - 1)
-#define IOP13XX_PMMR_VIRT_TO_PHYS(addr)   (((addr) - IOP13XX_PMMR_VIRT_MEM_BASE)\
-                                          + IOP13XX_PMMR_PHYS_MEM_BASE)
-#define IOP13XX_PMMR_PHYS_TO_VIRT(addr)   (((addr) - IOP13XX_PMMR_PHYS_MEM_BASE)\
-                                          + IOP13XX_PMMR_VIRT_MEM_BASE)
-#define IOP13XX_REG_ADDR32(reg)           (IOP13XX_PMMR_VIRT_MEM_BASE + (reg))
-#define IOP13XX_REG_ADDR16(reg)           (IOP13XX_PMMR_VIRT_MEM_BASE + (reg))
-#define IOP13XX_REG_ADDR8(reg)            (IOP13XX_PMMR_VIRT_MEM_BASE + (reg))
-#define IOP13XX_REG_ADDR32_PHYS(reg)      (IOP13XX_PMMR_PHYS_MEM_BASE + (reg))
-#define IOP13XX_REG_ADDR16_PHYS(reg)      (IOP13XX_PMMR_PHYS_MEM_BASE + (reg))
-#define IOP13XX_REG_ADDR8_PHYS(reg)       (IOP13XX_PMMR_PHYS_MEM_BASE + (reg))
-#define IOP13XX_PMMR_SIZE                 0x00080000
-
-/*=================== Defines for Platform Devices =====================*/
-#define IOP13XX_UART0_PHYS  (IOP13XX_PMMR_PHYS_MEM_BASE + 0x00002300)
-#define IOP13XX_UART1_PHYS  (IOP13XX_PMMR_PHYS_MEM_BASE + 0x00002340)
-#define IOP13XX_UART0_VIRT  (IOP13XX_PMMR_VIRT_MEM_BASE + 0x00002300)
-#define IOP13XX_UART1_VIRT  (IOP13XX_PMMR_VIRT_MEM_BASE + 0x00002340)
-
-#define IOP13XX_I2C0_PHYS   (IOP13XX_PMMR_PHYS_MEM_BASE | 0x00002500)
-#define IOP13XX_I2C1_PHYS   (IOP13XX_PMMR_PHYS_MEM_BASE | 0x00002520)
-#define IOP13XX_I2C2_PHYS   (IOP13XX_PMMR_PHYS_MEM_BASE | 0x00002540)
-#define IOP13XX_I2C0_VIRT   (IOP13XX_PMMR_VIRT_MEM_BASE | 0x00002500)
-#define IOP13XX_I2C1_VIRT   (IOP13XX_PMMR_VIRT_MEM_BASE | 0x00002520)
-#define IOP13XX_I2C2_VIRT   (IOP13XX_PMMR_VIRT_MEM_BASE | 0x00002540)
-
-/* ATU selection flags */
-/* IOP13XX_INIT_ATU_DEFAULT = Rely on CONFIG_IOP13XX_ATU* */
-#define IOP13XX_INIT_ATU_DEFAULT     (0)
-#define IOP13XX_INIT_ATU_ATUX        (1 << 0)
-#define IOP13XX_INIT_ATU_ATUE        (1 << 1)
-#define IOP13XX_INIT_ATU_NONE        (1 << 2)
-
-/* UART selection flags */
-/* IOP13XX_INIT_UART_DEFAULT = Rely on CONFIG_IOP13XX_UART* */
-#define IOP13XX_INIT_UART_DEFAULT    (0)
-#define IOP13XX_INIT_UART_0          (1 << 0)
-#define IOP13XX_INIT_UART_1          (1 << 1)
-
-/* I2C selection flags */
-/* IOP13XX_INIT_I2C_DEFAULT = Rely on CONFIG_IOP13XX_I2C* */
-#define IOP13XX_INIT_I2C_DEFAULT     (0)
-#define IOP13XX_INIT_I2C_0           (1 << 0)
-#define IOP13XX_INIT_I2C_1           (1 << 1)
-#define IOP13XX_INIT_I2C_2           (1 << 2)
-
-/* ADMA selection flags */
-/* INIT_ADMA_DEFAULT = Rely on CONFIG_IOP13XX_ADMA* */
-#define IOP13XX_INIT_ADMA_DEFAULT     (0)
-#define IOP13XX_INIT_ADMA_0           (1 << 0)
-#define IOP13XX_INIT_ADMA_1           (1 << 1)
-#define IOP13XX_INIT_ADMA_2           (1 << 2)
-
-/* Platform devices */
-#define IQ81340_NUM_UART               2
-#define IQ81340_NUM_I2C                3
-#define IQ81340_NUM_PHYS_MAP_FLASH     1
-#define IQ81340_NUM_ADMA               3
-#define IQ81340_MAX_PLAT_DEVICES (IQ81340_NUM_UART + \
-                               IQ81340_NUM_I2C + \
-                               IQ81340_NUM_PHYS_MAP_FLASH + \
-                               IQ81340_NUM_ADMA)
-
-/*========================== PMMR offsets for key registers ============*/
-#define IOP13XX_ATU0_PMMR_OFFSET       0x00048000
-#define IOP13XX_ATU1_PMMR_OFFSET       0x0004c000
-#define IOP13XX_ATU2_PMMR_OFFSET       0x0004d000
-#define IOP13XX_ADMA0_PMMR_OFFSET      0x00000000
-#define IOP13XX_ADMA1_PMMR_OFFSET      0x00000200
-#define IOP13XX_ADMA2_PMMR_OFFSET      0x00000400
-#define IOP13XX_PBI_PMMR_OFFSET        0x00001580
-#define IOP13XX_MU_PMMR_OFFSET         0x00004000
-#define IOP13XX_ESSR0_PMMR_OFFSET      0x00002188
-#define IOP13XX_ESSR0                  IOP13XX_REG_ADDR32(0x00002188)
-
-#define IOP13XX_ESSR0_IFACE_MASK       0x00004000  /* Interface PCI-X / PCI-E */
-#define IOP13XX_CONTROLLER_ONLY        (1 << 14)
-#define IOP13XX_INTERFACE_SEL_PCIX     (1 << 15)
-
-#define IOP13XX_PMON_PMMR_OFFSET       0x0001A000
-#define IOP13XX_PMON_BASE              (IOP13XX_PMMR_VIRT_MEM_BASE +\
-                                       IOP13XX_PMON_PMMR_OFFSET)
-#define IOP13XX_PMON_PHYSBASE          (IOP13XX_PMMR_PHYS_MEM_BASE +\
-                                       IOP13XX_PMON_PMMR_OFFSET)
-
-#define IOP13XX_PMON_CMD0              (IOP13XX_PMON_BASE + 0x0)
-#define IOP13XX_PMON_EVR0              (IOP13XX_PMON_BASE + 0x4)
-#define IOP13XX_PMON_STS0              (IOP13XX_PMON_BASE + 0x8)
-#define IOP13XX_PMON_DATA0             (IOP13XX_PMON_BASE + 0xC)
-
-#define IOP13XX_PMON_CMD3              (IOP13XX_PMON_BASE + 0x30)
-#define IOP13XX_PMON_EVR3              (IOP13XX_PMON_BASE + 0x34)
-#define IOP13XX_PMON_STS3              (IOP13XX_PMON_BASE + 0x38)
-#define IOP13XX_PMON_DATA3             (IOP13XX_PMON_BASE + 0x3C)
-
-#define IOP13XX_PMON_CMD7              (IOP13XX_PMON_BASE + 0x70)
-#define IOP13XX_PMON_EVR7              (IOP13XX_PMON_BASE + 0x74)
-#define IOP13XX_PMON_STS7              (IOP13XX_PMON_BASE + 0x78)
-#define IOP13XX_PMON_DATA7             (IOP13XX_PMON_BASE + 0x7C)
-
-#define IOP13XX_PMONEN                 (IOP13XX_PMMR_VIRT_MEM_BASE + 0x4E040)
-#define IOP13XX_PMONSTAT               (IOP13XX_PMMR_VIRT_MEM_BASE + 0x4E044)
-
-/*================================ATU===================================*/
-#define IOP13XX_ATUX_OFFSET(ofs)       IOP13XX_REG_ADDR32(\
-                                       iop13xx_atux_pmmr_offset + (ofs))
-
-#define IOP13XX_ATUX_DID               IOP13XX_REG_ADDR16(\
-                                       iop13xx_atux_pmmr_offset + 0x2)
-
-#define IOP13XX_ATUX_ATUCMD            IOP13XX_REG_ADDR16(\
-                                       iop13xx_atux_pmmr_offset + 0x4)
-#define IOP13XX_ATUX_ATUSR             IOP13XX_REG_ADDR16(\
-                                       iop13xx_atux_pmmr_offset + 0x6)
-
-#define IOP13XX_ATUX_IABAR0            IOP13XX_ATUX_OFFSET(0x10)
-#define IOP13XX_ATUX_IAUBAR0           IOP13XX_ATUX_OFFSET(0x14)
-#define IOP13XX_ATUX_IABAR1            IOP13XX_ATUX_OFFSET(0x18)
-#define IOP13XX_ATUX_IAUBAR1           IOP13XX_ATUX_OFFSET(0x1c)
-#define IOP13XX_ATUX_IABAR2            IOP13XX_ATUX_OFFSET(0x20)
-#define IOP13XX_ATUX_IAUBAR2           IOP13XX_ATUX_OFFSET(0x24)
-#define IOP13XX_ATUX_IALR0             IOP13XX_ATUX_OFFSET(0x40)
-#define IOP13XX_ATUX_IATVR0            IOP13XX_ATUX_OFFSET(0x44)
-#define IOP13XX_ATUX_IAUTVR0           IOP13XX_ATUX_OFFSET(0x48)
-#define IOP13XX_ATUX_IALR1             IOP13XX_ATUX_OFFSET(0x4c)
-#define IOP13XX_ATUX_IATVR1            IOP13XX_ATUX_OFFSET(0x50)
-#define IOP13XX_ATUX_IAUTVR1           IOP13XX_ATUX_OFFSET(0x54)
-#define IOP13XX_ATUX_IALR2             IOP13XX_ATUX_OFFSET(0x58)
-#define IOP13XX_ATUX_IATVR2            IOP13XX_ATUX_OFFSET(0x5c)
-#define IOP13XX_ATUX_IAUTVR2           IOP13XX_ATUX_OFFSET(0x60)
-#define IOP13XX_ATUX_ATUCR             IOP13XX_ATUX_OFFSET(0x70)
-#define IOP13XX_ATUX_PCSR              IOP13XX_ATUX_OFFSET(0x74)
-#define IOP13XX_ATUX_ATUISR            IOP13XX_ATUX_OFFSET(0x78)
-#define IOP13XX_ATUX_PCIXSR            IOP13XX_ATUX_OFFSET(0xD4)
-#define IOP13XX_ATUX_IABAR3            IOP13XX_ATUX_OFFSET(0x200)
-#define IOP13XX_ATUX_IAUBAR3           IOP13XX_ATUX_OFFSET(0x204)
-#define IOP13XX_ATUX_IALR3             IOP13XX_ATUX_OFFSET(0x208)
-#define IOP13XX_ATUX_IATVR3            IOP13XX_ATUX_OFFSET(0x20c)
-#define IOP13XX_ATUX_IAUTVR3           IOP13XX_ATUX_OFFSET(0x210)
-
-#define IOP13XX_ATUX_OIOBAR            IOP13XX_ATUX_OFFSET(0x300)
-#define IOP13XX_ATUX_OIOWTVR           IOP13XX_ATUX_OFFSET(0x304)
-#define IOP13XX_ATUX_OUMBAR0           IOP13XX_ATUX_OFFSET(0x308)
-#define IOP13XX_ATUX_OUMWTVR0          IOP13XX_ATUX_OFFSET(0x30c)
-#define IOP13XX_ATUX_OUMBAR1           IOP13XX_ATUX_OFFSET(0x310)
-#define IOP13XX_ATUX_OUMWTVR1          IOP13XX_ATUX_OFFSET(0x314)
-#define IOP13XX_ATUX_OUMBAR2           IOP13XX_ATUX_OFFSET(0x318)
-#define IOP13XX_ATUX_OUMWTVR2          IOP13XX_ATUX_OFFSET(0x31c)
-#define IOP13XX_ATUX_OUMBAR3           IOP13XX_ATUX_OFFSET(0x320)
-#define IOP13XX_ATUX_OUMWTVR3          IOP13XX_ATUX_OFFSET(0x324)
-#define IOP13XX_ATUX_OUDMABAR          IOP13XX_ATUX_OFFSET(0x328)
-#define IOP13XX_ATUX_OUMSIBAR          IOP13XX_ATUX_OFFSET(0x32c)
-#define IOP13XX_ATUX_OCCAR             IOP13XX_ATUX_OFFSET(0x330)
-#define IOP13XX_ATUX_OCCDR             IOP13XX_ATUX_OFFSET(0x334)
-
-#define IOP13XX_ATUX_ATUCR_OUT_EN              (1 << 1)
-#define IOP13XX_ATUX_PCSR_CENTRAL_RES          (1 << 25)
-#define IOP13XX_ATUX_PCSR_P_RSTOUT             (1 << 21)
-#define IOP13XX_ATUX_PCSR_OUT_Q_BUSY           (1 << 15)
-#define IOP13XX_ATUX_PCSR_IN_Q_BUSY            (1 << 14)
-#define IOP13XX_ATUX_PCSR_FREQ_OFFSET          (16)
-
-#define IOP13XX_ATUX_STAT_PCI_IFACE_ERR        (1 << 18)
-#define IOP13XX_ATUX_STAT_VPD_ADDR             (1 << 17)
-#define IOP13XX_ATUX_STAT_INT_PAR_ERR          (1 << 16)
-#define IOP13XX_ATUX_STAT_CFG_WRITE            (1 << 15)
-#define IOP13XX_ATUX_STAT_ERR_COR              (1 << 14)
-#define IOP13XX_ATUX_STAT_TX_SCEM              (1 << 13)
-#define IOP13XX_ATUX_STAT_REC_SCEM             (1 << 12)
-#define IOP13XX_ATUX_STAT_POWER_TRAN           (1 << 11)
-#define IOP13XX_ATUX_STAT_TX_SERR              (1 << 10)
-#define IOP13XX_ATUX_STAT_DET_PAR_ERR          (1 << 9 )
-#define IOP13XX_ATUX_STAT_BIST                 (1 << 8 )
-#define IOP13XX_ATUX_STAT_INT_REC_MABORT       (1 << 7 )
-#define IOP13XX_ATUX_STAT_REC_SERR             (1 << 4 )
-#define IOP13XX_ATUX_STAT_EXT_REC_MABORT       (1 << 3 )
-#define IOP13XX_ATUX_STAT_EXT_REC_TABORT       (1 << 2 )
-#define IOP13XX_ATUX_STAT_EXT_SIG_TABORT       (1 << 1 )
-#define IOP13XX_ATUX_STAT_MASTER_DATA_PAR      (1 << 0 )
-
-#define IOP13XX_ATUX_PCIXSR_BUS_NUM    (8)
-#define IOP13XX_ATUX_PCIXSR_DEV_NUM    (3)
-#define IOP13XX_ATUX_PCIXSR_FUNC_NUM   (0)
-
-#define IOP13XX_ATUX_IALR_DISABLE      0x00000001
-#define IOP13XX_ATUX_OUMBAR_ENABLE     0x80000000
-
-#define IOP13XX_ATUE_OFFSET(ofs)       IOP13XX_REG_ADDR32(\
-                                       iop13xx_atue_pmmr_offset + (ofs))
-
-#define IOP13XX_ATUE_DID               IOP13XX_REG_ADDR16(\
-                                       iop13xx_atue_pmmr_offset + 0x2)
-#define IOP13XX_ATUE_ATUCMD            IOP13XX_REG_ADDR16(\
-                                       iop13xx_atue_pmmr_offset + 0x4)
-#define IOP13XX_ATUE_ATUSR             IOP13XX_REG_ADDR16(\
-                                       iop13xx_atue_pmmr_offset + 0x6)
-
-#define IOP13XX_ATUE_IABAR0            IOP13XX_ATUE_OFFSET(0x10)
-#define IOP13XX_ATUE_IAUBAR0           IOP13XX_ATUE_OFFSET(0x14)
-#define IOP13XX_ATUE_IABAR1            IOP13XX_ATUE_OFFSET(0x18)
-#define IOP13XX_ATUE_IAUBAR1           IOP13XX_ATUE_OFFSET(0x1c)
-#define IOP13XX_ATUE_IABAR2            IOP13XX_ATUE_OFFSET(0x20)
-#define IOP13XX_ATUE_IAUBAR2           IOP13XX_ATUE_OFFSET(0x24)
-#define IOP13XX_ATUE_IALR0             IOP13XX_ATUE_OFFSET(0x40)
-#define IOP13XX_ATUE_IATVR0            IOP13XX_ATUE_OFFSET(0x44)
-#define IOP13XX_ATUE_IAUTVR0           IOP13XX_ATUE_OFFSET(0x48)
-#define IOP13XX_ATUE_IALR1             IOP13XX_ATUE_OFFSET(0x4c)
-#define IOP13XX_ATUE_IATVR1            IOP13XX_ATUE_OFFSET(0x50)
-#define IOP13XX_ATUE_IAUTVR1           IOP13XX_ATUE_OFFSET(0x54)
-#define IOP13XX_ATUE_IALR2             IOP13XX_ATUE_OFFSET(0x58)
-#define IOP13XX_ATUE_IATVR2            IOP13XX_ATUE_OFFSET(0x5c)
-#define IOP13XX_ATUE_IAUTVR2           IOP13XX_ATUE_OFFSET(0x60)
-#define IOP13XX_ATUE_PE_LSTS           IOP13XX_REG_ADDR16(\
-                                       iop13xx_atue_pmmr_offset + 0xe2)
-#define IOP13XX_ATUE_OIOWTVR           IOP13XX_ATUE_OFFSET(0x304)
-#define IOP13XX_ATUE_OUMBAR0           IOP13XX_ATUE_OFFSET(0x308)
-#define IOP13XX_ATUE_OUMWTVR0          IOP13XX_ATUE_OFFSET(0x30c)
-#define IOP13XX_ATUE_OUMBAR1           IOP13XX_ATUE_OFFSET(0x310)
-#define IOP13XX_ATUE_OUMWTVR1          IOP13XX_ATUE_OFFSET(0x314)
-#define IOP13XX_ATUE_OUMBAR2           IOP13XX_ATUE_OFFSET(0x318)
-#define IOP13XX_ATUE_OUMWTVR2          IOP13XX_ATUE_OFFSET(0x31c)
-#define IOP13XX_ATUE_OUMBAR3           IOP13XX_ATUE_OFFSET(0x320)
-#define IOP13XX_ATUE_OUMWTVR3          IOP13XX_ATUE_OFFSET(0x324)
-
-#define IOP13XX_ATUE_ATUCR             IOP13XX_ATUE_OFFSET(0x70)
-#define IOP13XX_ATUE_PCSR              IOP13XX_ATUE_OFFSET(0x74)
-#define IOP13XX_ATUE_ATUISR            IOP13XX_ATUE_OFFSET(0x78)
-#define IOP13XX_ATUE_OIOBAR            IOP13XX_ATUE_OFFSET(0x300)
-#define IOP13XX_ATUE_OCCAR             IOP13XX_ATUE_OFFSET(0x32c)
-#define IOP13XX_ATUE_OCCDR             IOP13XX_ATUE_OFFSET(0x330)
-
-#define IOP13XX_ATUE_PIE_STS           IOP13XX_ATUE_OFFSET(0x384)
-#define IOP13XX_ATUE_PIE_MSK           IOP13XX_ATUE_OFFSET(0x388)
-
-#define IOP13XX_ATUE_ATUCR_IVM         (1 << 6)
-#define IOP13XX_ATUE_ATUCR_OUT_EN      (1 << 1)
-#define IOP13XX_ATUE_OCCAR_BUS_NUM     (24)
-#define IOP13XX_ATUE_OCCAR_DEV_NUM     (19)
-#define IOP13XX_ATUE_OCCAR_FUNC_NUM    (16)
-#define IOP13XX_ATUE_OCCAR_EXT_REG     (8)
-#define IOP13XX_ATUE_OCCAR_REG         (2)
-
-#define IOP13XX_ATUE_PCSR_BUS_NUM      (24)
-#define IOP13XX_ATUE_PCSR_DEV_NUM      (19)
-#define IOP13XX_ATUE_PCSR_FUNC_NUM     (16)
-#define IOP13XX_ATUE_PCSR_OUT_Q_BUSY   (1 << 15)
-#define IOP13XX_ATUE_PCSR_IN_Q_BUSY    (1 << 14)
-#define IOP13XX_ATUE_PCSR_END_POINT    (1 << 13)
-#define IOP13XX_ATUE_PCSR_LLRB_BUSY    (1 << 12)
-
-#define IOP13XX_ATUE_PCSR_BUS_NUM_MASK         (0xff)
-#define IOP13XX_ATUE_PCSR_DEV_NUM_MASK         (0x1f)
-#define IOP13XX_ATUE_PCSR_FUNC_NUM_MASK        (0x7)
-
-#define IOP13XX_ATUE_PCSR_CORE_RESET           (8)
-#define IOP13XX_ATUE_PCSR_FUNC_NUM             (16)
-
-#define IOP13XX_ATUE_LSTS_TRAINING             (1 << 11)
-#define IOP13XX_ATUE_STAT_SLOT_PWR_MSG         (1 << 28)
-#define IOP13XX_ATUE_STAT_PME                  (1 << 27)
-#define IOP13XX_ATUE_STAT_HOT_PLUG_MSG         (1 << 26)
-#define IOP13XX_ATUE_STAT_IVM                  (1 << 25)
-#define IOP13XX_ATUE_STAT_BIST                 (1 << 24)
-#define IOP13XX_ATUE_STAT_CFG_WRITE            (1 << 18)
-#define IOP13XX_ATUE_STAT_VPD_ADDR             (1 << 17)
-#define IOP13XX_ATUE_STAT_POWER_TRAN           (1 << 16)
-#define IOP13XX_ATUE_STAT_HALT_ON_ERROR        (1 << 13)
-#define IOP13XX_ATUE_STAT_ROOT_SYS_ERR         (1 << 12)
-#define IOP13XX_ATUE_STAT_ROOT_ERR_MSG         (1 << 11)
-#define IOP13XX_ATUE_STAT_PCI_IFACE_ERR        (1 << 10)
-#define IOP13XX_ATUE_STAT_ERR_COR              (1 << 9 )
-#define IOP13XX_ATUE_STAT_ERR_UNCOR            (1 << 8 )
-#define IOP13XX_ATUE_STAT_CRS                  (1 << 7 )
-#define IOP13XX_ATUE_STAT_LNK_DWN              (1 << 6 )
-#define IOP13XX_ATUE_STAT_INT_REC_MABORT       (1 << 5 )
-#define IOP13XX_ATUE_STAT_DET_PAR_ERR          (1 << 4 )
-#define IOP13XX_ATUE_STAT_EXT_REC_MABORT       (1 << 3 )
-#define IOP13XX_ATUE_STAT_SIG_TABORT           (1 << 2 )
-#define IOP13XX_ATUE_STAT_EXT_REC_TABORT       (1 << 1 )
-#define IOP13XX_ATUE_STAT_MASTER_DATA_PAR      (1 << 0 )
-
-#define IOP13XX_ATUE_ESTAT_REC_UNSUPPORTED_COMP_REQ    (1 << 31)
-#define IOP13XX_ATUE_ESTAT_REC_COMPLETER_ABORT         (1 << 30)
-#define IOP13XX_ATUE_ESTAT_TX_POISONED_TLP             (1 << 29)
-#define IOP13XX_ATUE_ESTAT_TX_PAR_ERR                  (1 << 28)
-#define IOP13XX_ATUE_ESTAT_REC_UNSUPPORTED_REQ         (1 << 20)
-#define IOP13XX_ATUE_ESTAT_REC_ECRC_ERR                (1 << 19)
-#define IOP13XX_ATUE_ESTAT_REC_MALFORMED_TLP           (1 << 18)
-#define IOP13XX_ATUE_ESTAT_TX_RECEIVER_OVERFLOW        (1 << 17)
-#define IOP13XX_ATUE_ESTAT_REC_UNEXPECTED_COMP         (1 << 16)
-#define IOP13XX_ATUE_ESTAT_INT_COMP_ABORT              (1 << 15)
-#define IOP13XX_ATUE_ESTAT_COMP_TIMEOUT                (1 << 14)
-#define IOP13XX_ATUE_ESTAT_FLOW_CONTROL_ERR            (1 << 13)
-#define IOP13XX_ATUE_ESTAT_REC_POISONED_TLP            (1 << 12)
-#define IOP13XX_ATUE_ESTAT_DATA_LNK_ERR                (1 << 4 )
-#define IOP13XX_ATUE_ESTAT_TRAINING_ERR                (1 << 0 )
-
-#define IOP13XX_ATUE_IALR_DISABLE              (0x00000001)
-#define IOP13XX_ATUE_OUMBAR_ENABLE             (0x80000000)
-#define IOP13XX_ATU_OUMBAR_FUNC_NUM            (28)
-#define IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK       (0x7)
-/*=======================================================================*/
-
-/*============================MESSAGING UNIT=============================*/
-#define IOP13XX_MU_OFFSET(ofs) IOP13XX_REG_ADDR32(IOP13XX_MU_PMMR_OFFSET +\
-                                                       (ofs))
-
-#define IOP13XX_MU_IMR0        IOP13XX_MU_OFFSET(0x10)
-#define IOP13XX_MU_IMR1        IOP13XX_MU_OFFSET(0x14)
-#define IOP13XX_MU_OMR0        IOP13XX_MU_OFFSET(0x18)
-#define IOP13XX_MU_OMR1        IOP13XX_MU_OFFSET(0x1C)
-#define IOP13XX_MU_IDR         IOP13XX_MU_OFFSET(0x20)
-#define IOP13XX_MU_IISR        IOP13XX_MU_OFFSET(0x24)
-#define IOP13XX_MU_IIMR        IOP13XX_MU_OFFSET(0x28)
-#define IOP13XX_MU_ODR         IOP13XX_MU_OFFSET(0x2C)
-#define IOP13XX_MU_OISR        IOP13XX_MU_OFFSET(0x30)
-#define IOP13XX_MU_OIMR        IOP13XX_MU_OFFSET(0x34)
-#define IOP13XX_MU_IRCSR       IOP13XX_MU_OFFSET(0x38)
-#define IOP13XX_MU_ORCSR       IOP13XX_MU_OFFSET(0x3C)
-#define IOP13XX_MU_MIMR        IOP13XX_MU_OFFSET(0x48)
-#define IOP13XX_MU_MUCR        IOP13XX_MU_OFFSET(0x50)
-#define IOP13XX_MU_QBAR        IOP13XX_MU_OFFSET(0x54)
-#define IOP13XX_MU_MUBAR       IOP13XX_MU_OFFSET(0x84)
-
-#define IOP13XX_MU_WINDOW_SIZE (8 * 1024)
-#define IOP13XX_MU_BASE_PHYS   (0xff000000)
-#define IOP13XX_MU_BASE_PCI    (0xff000000)
-#define IOP13XX_MU_MIMR_PCI    (IOP13XX_MU_BASE_PCI + 0x48)
-#define IOP13XX_MU_MIMR_CORE_SELECT (15)
-/*=======================================================================*/
-
-/*==============================ADMA UNITS===============================*/
-#define IOP13XX_ADMA_PHYS_BASE(chan)   IOP13XX_REG_ADDR32_PHYS((chan << 9))
-#define IOP13XX_ADMA_UPPER_PA(chan)    (IOP13XX_ADMA_PHYS_BASE(chan) + 0xc0)
-
-/*==============================XSI BRIDGE===============================*/
-#define IOP13XX_XBG_BECSR              IOP13XX_REG_ADDR32(0x178c)
-#define IOP13XX_XBG_BERAR              IOP13XX_REG_ADDR32(0x1790)
-#define IOP13XX_XBG_BERUAR             IOP13XX_REG_ADDR32(0x1794)
-#define is_atue_occdr_error(x)         ((__raw_readl(IOP13XX_XBG_BERAR) == \
-                                       IOP13XX_PMMR_VIRT_TO_PHYS(\
-                                       IOP13XX_ATUE_OCCDR))\
-                                       && (__raw_readl(IOP13XX_XBG_BECSR) & 1))
-#define is_atux_occdr_error(x)         ((__raw_readl(IOP13XX_XBG_BERAR) == \
-                                       IOP13XX_PMMR_VIRT_TO_PHYS(\
-                                       IOP13XX_ATUX_OCCDR))\
-                                       && (__raw_readl(IOP13XX_XBG_BECSR) & 1))
-/*=======================================================================*/
-
-#define IOP13XX_PBI_OFFSET(ofs) IOP13XX_REG_ADDR32(IOP13XX_PBI_PMMR_OFFSET +\
-                                                       (ofs))
-
-#define IOP13XX_PBI_CR                 IOP13XX_PBI_OFFSET(0x0)
-#define IOP13XX_PBI_SR                 IOP13XX_PBI_OFFSET(0x4)
-#define IOP13XX_PBI_BAR0               IOP13XX_PBI_OFFSET(0x8)
-#define IOP13XX_PBI_LR0                IOP13XX_PBI_OFFSET(0xc)
-#define IOP13XX_PBI_BAR1               IOP13XX_PBI_OFFSET(0x10)
-#define IOP13XX_PBI_LR1                IOP13XX_PBI_OFFSET(0x14)
-
-#define IOP13XX_PROCESSOR_FREQ         IOP13XX_REG_ADDR32(0x2180)
-
-/* Watchdog timer definitions */
-#define IOP_WDTCR_EN_ARM       0x1e1e1e1e
-#define IOP_WDTCR_EN           0xe1e1e1e1
-#define IOP_WDTCR_DIS_ARM      0x1f1f1f1f
-#define IOP_WDTCR_DIS          0xf1f1f1f1
-#define IOP_RCSR_WDT           (1 << 5) /* reset caused by watchdog timer */
-#define IOP13XX_WDTSR_WRITE_EN (1 << 31) /* used to speed up reset requests */
-#define IOP13XX_WDTCR_IB_RESET (1 << 0)
-
-#endif /* _IOP13XX_HW_H_ */
diff --git a/arch/arm/mach-iop13xx/include/mach/iq81340.h b/arch/arm/mach-iop13xx/include/mach/iq81340.h
deleted file mode 100644 (file)
index d7ad27a..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _IQ81340_H_
-#define _IQ81340_H_
-
-#define IQ81340_PCE_BAR0    IOP13XX_PBI_LOWER_MEM_RA
-#define IQ81340_PCE_BAR1    (IQ81340_PCE_BAR0 + 0x02000000)
-
-#define IQ81340_FLASHBASE   IQ81340_PCE_BAR0   /* Flash */
-
-#define IQ81340_PCE_BAR1_OFFSET(a) (IQ81340_PCE_BAR1 + (a))
-
-#define IQ81340_PRD_CODE    IQ81340_PCE_BAR1_OFFSET(0)
-#define IQ81340_BRD_STEP    IQ81340_PCE_BAR1_OFFSET(0x10000)
-#define IQ81340_CPLD_REV    IQ81340_PCE_BAR1_OFFSET(0x20000)
-#define IQ81340_LED         IQ81340_PCE_BAR1_OFFSET(0x30000)
-#define IQ81340_LHEX        IQ81340_PCE_BAR1_OFFSET(0x40000)
-#define IQ81340_RHEX        IQ81340_PCE_BAR1_OFFSET(0x50000)
-#define IQ81340_BUZZER      IQ81340_PCE_BAR1_OFFSET(0x60000)
-#define IQ81340_32K_NVRAM   IQ81340_PCE_BAR1_OFFSET(0x70000)
-#define IQ81340_256K_NVRAM  IQ81340_PCE_BAR1_OFFSET(0x80000)
-#define IQ81340_ROTARY_SW   IQ81340_PCE_BAR1_OFFSET(0xd0000)
-#define IQ81340_BATT_STAT   IQ81340_PCE_BAR1_OFFSET(0xf0000)
-#define IQ81340_CMP_FLSH    IQ81340_PCE_BAR1_OFFSET(0x1000000) /* 16MB */
-
-#define PBI_CF_IDE_BASE     (IQ81340_CMP_FLSH)
-#define PBI_CF_BAR_ADDR     (IOP13XX_PBI_BAR1)
-
-
-#endif /* _IQ81340_H_ */
diff --git a/arch/arm/mach-iop13xx/include/mach/irqs.h b/arch/arm/mach-iop13xx/include/mach/irqs.h
deleted file mode 100644 (file)
index cd6b637..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _IOP13XX_IRQS_H_
-#define _IOP13XX_IRQS_H_
-
-#ifndef __ASSEMBLER__
-#include <linux/types.h>
-
-/* INTPND0 CP6 R0 Page 3
- */
-static inline u32 read_intpnd_0(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c0, c3, 0":"=r" (val));
-       return val;
-}
-
-/* INTPND1 CP6 R1 Page 3
- */
-static inline u32 read_intpnd_1(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c1, c3, 0":"=r" (val));
-       return val;
-}
-
-/* INTPND2 CP6 R2 Page 3
- */
-static inline u32 read_intpnd_2(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c2, c3, 0":"=r" (val));
-       return val;
-}
-
-/* INTPND3 CP6 R3 Page 3
- */
-static inline u32 read_intpnd_3(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c3, c3, 0":"=r" (val));
-       return val;
-}
-#endif
-
-#define INTBASE 0
-#define INTSIZE_4 1
-
-/*
- * iop34x chipset interrupts
- */
-#define IOP13XX_IRQ(x)         (IOP13XX_IRQ_OFS + (x))
-
-/*
- * On IRQ or FIQ register
- */
-#define IRQ_IOP13XX_ADMA0_EOT  (0)
-#define IRQ_IOP13XX_ADMA0_EOC  (1)
-#define IRQ_IOP13XX_ADMA1_EOT  (2)
-#define IRQ_IOP13XX_ADMA1_EOC  (3)
-#define IRQ_IOP13XX_ADMA2_EOT  (4)
-#define IRQ_IOP13XX_ADMA2_EOC  (5)
-#define IRQ_IOP134_WATCHDOG    (6)
-#define IRQ_IOP13XX_RSVD_7     (7)
-#define IRQ_IOP13XX_TIMER0     (8)
-#define IRQ_IOP13XX_TIMER1     (9)
-#define IRQ_IOP13XX_I2C_0      (10)
-#define IRQ_IOP13XX_I2C_1      (11)
-#define IRQ_IOP13XX_MSG        (12)
-#define IRQ_IOP13XX_MSGIBQ     (13)
-#define IRQ_IOP13XX_ATU_IM     (14)
-#define IRQ_IOP13XX_ATU_BIST   (15)
-#define IRQ_IOP13XX_PPMU       (16)
-#define IRQ_IOP13XX_COREPMU    (17)
-#define IRQ_IOP13XX_CORECACHE  (18)
-#define IRQ_IOP13XX_RSVD_19    (19)
-#define IRQ_IOP13XX_RSVD_20    (20)
-#define IRQ_IOP13XX_RSVD_21    (21)
-#define IRQ_IOP13XX_RSVD_22    (22)
-#define IRQ_IOP13XX_RSVD_23    (23)
-#define IRQ_IOP13XX_XINT0      (24)
-#define IRQ_IOP13XX_XINT1      (25)
-#define IRQ_IOP13XX_XINT2      (26)
-#define IRQ_IOP13XX_XINT3      (27)
-#define IRQ_IOP13XX_XINT4      (28)
-#define IRQ_IOP13XX_XINT5      (29)
-#define IRQ_IOP13XX_XINT6      (30)
-#define IRQ_IOP13XX_XINT7      (31)
-                                     /* IINTSRC1 bit */
-#define IRQ_IOP13XX_XINT8      (32)  /* 0  */
-#define IRQ_IOP13XX_XINT9      (33)  /* 1  */
-#define IRQ_IOP13XX_XINT10     (34)  /* 2  */
-#define IRQ_IOP13XX_XINT11     (35)  /* 3  */
-#define IRQ_IOP13XX_XINT12     (36)  /* 4  */
-#define IRQ_IOP13XX_XINT13     (37)  /* 5  */
-#define IRQ_IOP13XX_XINT14     (38)  /* 6  */
-#define IRQ_IOP13XX_XINT15     (39)  /* 7  */
-#define IRQ_IOP13XX_RSVD_40    (40)  /* 8  */
-#define IRQ_IOP13XX_RSVD_41    (41)  /* 9  */
-#define IRQ_IOP13XX_RSVD_42    (42)  /* 10 */
-#define IRQ_IOP13XX_RSVD_43    (43)  /* 11 */
-#define IRQ_IOP13XX_RSVD_44    (44)  /* 12 */
-#define IRQ_IOP13XX_RSVD_45    (45)  /* 13 */
-#define IRQ_IOP13XX_RSVD_46    (46)  /* 14 */
-#define IRQ_IOP13XX_RSVD_47    (47)  /* 15 */
-#define IRQ_IOP13XX_RSVD_48    (48)  /* 16 */
-#define IRQ_IOP13XX_RSVD_49    (49)  /* 17 */
-#define IRQ_IOP13XX_RSVD_50    (50)  /* 18 */
-#define IRQ_IOP13XX_UART0      (51)  /* 19 */
-#define IRQ_IOP13XX_UART1      (52)  /* 20 */
-#define IRQ_IOP13XX_PBIE       (53)  /* 21 */
-#define IRQ_IOP13XX_ATU_CRW    (54)  /* 22 */
-#define IRQ_IOP13XX_ATU_ERR    (55)  /* 23 */
-#define IRQ_IOP13XX_MCU_ERR    (56)  /* 24 */
-#define IRQ_IOP13XX_ADMA0_ERR  (57)  /* 25 */
-#define IRQ_IOP13XX_ADMA1_ERR  (58)  /* 26 */
-#define IRQ_IOP13XX_ADMA2_ERR  (59)  /* 27 */
-#define IRQ_IOP13XX_RSVD_60    (60)  /* 28 */
-#define IRQ_IOP13XX_RSVD_61    (61)  /* 29 */
-#define IRQ_IOP13XX_MSG_ERR    (62)  /* 30 */
-#define IRQ_IOP13XX_RSVD_63    (63)  /* 31 */
-                                     /* IINTSRC2 bit */
-#define IRQ_IOP13XX_INTERPROC  (64)  /* 0  */
-#define IRQ_IOP13XX_RSVD_65    (65)  /* 1  */
-#define IRQ_IOP13XX_RSVD_66    (66)  /* 2  */
-#define IRQ_IOP13XX_RSVD_67    (67)  /* 3  */
-#define IRQ_IOP13XX_RSVD_68    (68)  /* 4  */
-#define IRQ_IOP13XX_RSVD_69    (69)  /* 5  */
-#define IRQ_IOP13XX_RSVD_70    (70)  /* 6  */
-#define IRQ_IOP13XX_RSVD_71    (71)  /* 7  */
-#define IRQ_IOP13XX_RSVD_72    (72)  /* 8  */
-#define IRQ_IOP13XX_RSVD_73    (73)  /* 9  */
-#define IRQ_IOP13XX_RSVD_74    (74)  /* 10 */
-#define IRQ_IOP13XX_RSVD_75    (75)  /* 11 */
-#define IRQ_IOP13XX_RSVD_76    (76)  /* 12 */
-#define IRQ_IOP13XX_RSVD_77    (77)  /* 13 */
-#define IRQ_IOP13XX_RSVD_78    (78)  /* 14 */
-#define IRQ_IOP13XX_RSVD_79    (79)  /* 15 */
-#define IRQ_IOP13XX_RSVD_80    (80)  /* 16 */
-#define IRQ_IOP13XX_RSVD_81    (81)  /* 17 */
-#define IRQ_IOP13XX_RSVD_82    (82)  /* 18 */
-#define IRQ_IOP13XX_RSVD_83    (83)  /* 19 */
-#define IRQ_IOP13XX_RSVD_84    (84)  /* 20 */
-#define IRQ_IOP13XX_RSVD_85    (85)  /* 21 */
-#define IRQ_IOP13XX_RSVD_86    (86)  /* 22 */
-#define IRQ_IOP13XX_RSVD_87    (87)  /* 23 */
-#define IRQ_IOP13XX_RSVD_88    (88)  /* 24 */
-#define IRQ_IOP13XX_RSVD_89    (89)  /* 25 */
-#define IRQ_IOP13XX_RSVD_90    (90)  /* 26 */
-#define IRQ_IOP13XX_RSVD_91    (91)  /* 27 */
-#define IRQ_IOP13XX_RSVD_92    (92)  /* 28 */
-#define IRQ_IOP13XX_RSVD_93    (93)  /* 29 */
-#define IRQ_IOP13XX_SIB_ERR    (94)  /* 30 */
-#define IRQ_IOP13XX_SRAM_ERR   (95)  /* 31 */
-                                     /* IINTSRC3 bit */
-#define IRQ_IOP13XX_I2C_2      (96)  /* 0  */
-#define IRQ_IOP13XX_ATUE_BIST  (97)  /* 1  */
-#define IRQ_IOP13XX_ATUE_CRW   (98)  /* 2  */
-#define IRQ_IOP13XX_ATUE_ERR   (99)  /* 3  */
-#define IRQ_IOP13XX_IMU        (100) /* 4  */
-#define IRQ_IOP13XX_RSVD_101   (101) /* 5  */
-#define IRQ_IOP13XX_RSVD_102   (102) /* 6  */
-#define IRQ_IOP13XX_TPMI0_OUT  (103) /* 7  */
-#define IRQ_IOP13XX_TPMI1_OUT  (104) /* 8  */
-#define IRQ_IOP13XX_TPMI2_OUT  (105) /* 9  */
-#define IRQ_IOP13XX_TPMI3_OUT  (106) /* 10 */
-#define IRQ_IOP13XX_ATUE_IMA   (107) /* 11 */
-#define IRQ_IOP13XX_ATUE_IMB   (108) /* 12 */
-#define IRQ_IOP13XX_ATUE_IMC   (109) /* 13 */
-#define IRQ_IOP13XX_ATUE_IMD   (110) /* 14 */
-#define IRQ_IOP13XX_MU_MSI_TB  (111) /* 15 */
-#define IRQ_IOP13XX_RSVD_112   (112) /* 16 */
-#define IRQ_IOP13XX_INBD_MSI   (113) /* 17 */
-#define IRQ_IOP13XX_RSVD_114   (114) /* 18 */
-#define IRQ_IOP13XX_RSVD_115   (115) /* 19 */
-#define IRQ_IOP13XX_RSVD_116   (116) /* 20 */
-#define IRQ_IOP13XX_RSVD_117   (117) /* 21 */
-#define IRQ_IOP13XX_RSVD_118   (118) /* 22 */
-#define IRQ_IOP13XX_RSVD_119   (119) /* 23 */
-#define IRQ_IOP13XX_RSVD_120   (120) /* 24 */
-#define IRQ_IOP13XX_RSVD_121   (121) /* 25 */
-#define IRQ_IOP13XX_RSVD_122   (122) /* 26 */
-#define IRQ_IOP13XX_RSVD_123   (123) /* 27 */
-#define IRQ_IOP13XX_RSVD_124   (124) /* 28 */
-#define IRQ_IOP13XX_RSVD_125   (125) /* 29 */
-#define IRQ_IOP13XX_RSVD_126   (126) /* 30 */
-#define IRQ_IOP13XX_HPI        (127) /* 31 */
-
-#ifdef CONFIG_PCI_MSI
-#define IRQ_IOP13XX_MSI_0      (IRQ_IOP13XX_HPI + 1)
-#define NR_IOP13XX_IRQS        (IRQ_IOP13XX_MSI_0 + 128)
-#else
-#define NR_IOP13XX_IRQS        (IRQ_IOP13XX_HPI + 1)
-#endif
-
-#endif /* _IOP13XX_IRQ_H_ */
diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h
deleted file mode 100644 (file)
index 32da0e0..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-#include <mach/hardware.h>
-
-#ifndef __ASSEMBLY__
-
-#if defined(CONFIG_ARCH_IOP13XX)
-#define IOP13XX_PMMR_V_START (IOP13XX_PMMR_VIRT_MEM_BASE)
-#define IOP13XX_PMMR_V_END   (IOP13XX_PMMR_VIRT_MEM_BASE + IOP13XX_PMMR_SIZE)
-#define IOP13XX_PMMR_P_START (IOP13XX_PMMR_PHYS_MEM_BASE)
-#define IOP13XX_PMMR_P_END   (IOP13XX_PMMR_PHYS_MEM_BASE + IOP13XX_PMMR_SIZE)
-
-static inline dma_addr_t __virt_to_lbus(void __iomem *x)
-{
-       return x + IOP13XX_PMMR_PHYS_MEM_BASE - IOP13XX_PMMR_VIRT_MEM_BASE;
-}
-
-static inline void __iomem *__lbus_to_virt(dma_addr_t x)
-{
-       return x + IOP13XX_PMMR_VIRT_MEM_BASE - IOP13XX_PMMR_PHYS_MEM_BASE;
-}
-
-#define __is_lbus_dma(a)                               \
-       ((a) >= IOP13XX_PMMR_P_START && (a) < IOP13XX_PMMR_P_END)
-
-#define __is_lbus_virt(a)                              \
-       ((a) >= IOP13XX_PMMR_V_START && (a) < IOP13XX_PMMR_V_END)
-
-/* Device is an lbus device if it is on the platform bus of the IOP13XX */
-#define is_lbus_device(dev)                            \
-       (dev && strncmp(dev->bus->name, "platform", 8) == 0)
-
-#define __arch_dma_to_virt(dev, addr)                                  \
-       ({                                                              \
-               void * __virt;                                          \
-               dma_addr_t __dma = addr;                                \
-               if (is_lbus_device(dev) && __is_lbus_dma(__dma))        \
-                       __virt = __lbus_to_virt(__dma);                 \
-               else                                                    \
-                       __virt = (void *)__phys_to_virt(__dma);         \
-               __virt;                                                 \
-       })
-
-#define __arch_virt_to_dma(dev, addr)                                  \
-       ({                                                              \
-               void * __virt = addr;                                   \
-               dma_addr_t __dma;                                       \
-               if (is_lbus_device(dev) && __is_lbus_virt(__virt))      \
-                       __dma = __virt_to_lbus(__virt);                 \
-               else                                                    \
-                       __dma = __virt_to_phys((unsigned long)__virt);  \
-               __dma;                                                  \
-       })
-
-#define __arch_pfn_to_dma(dev, pfn)                                    \
-       ({                                                              \
-               /* __is_lbus_virt() can never be true for RAM pages */  \
-               (dma_addr_t)__pfn_to_phys(pfn);                         \
-       })
-
-#define __arch_dma_to_pfn(dev, addr)   __phys_to_pfn(addr)
-
-#endif /* CONFIG_ARCH_IOP13XX */
-#endif /* !ASSEMBLY */
-
-#endif
diff --git a/arch/arm/mach-iop13xx/include/mach/time.h b/arch/arm/mach-iop13xx/include/mach/time.h
deleted file mode 100644 (file)
index 2c2d753..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _IOP13XX_TIME_H_
-#define _IOP13XX_TIME_H_
-
-#include <mach/irqs.h>
-
-#define IRQ_IOP_TIMER0 IRQ_IOP13XX_TIMER0
-
-#define IOP_TMR_EN         0x02
-#define IOP_TMR_RELOAD     0x04
-#define IOP_TMR_PRIVILEGED 0x08
-#define IOP_TMR_RATIO_1_1  0x00
-
-#define IOP13XX_XSI_FREQ_RATIO_MASK    (3 << 19)
-#define IOP13XX_XSI_FREQ_RATIO_2       (0 << 19)
-#define IOP13XX_XSI_FREQ_RATIO_3       (1 << 19)
-#define IOP13XX_XSI_FREQ_RATIO_4       (2 << 19)
-#define IOP13XX_CORE_FREQ_MASK         (7 << 16)
-#define IOP13XX_CORE_FREQ_600          (0 << 16)
-#define IOP13XX_CORE_FREQ_667          (1 << 16)
-#define IOP13XX_CORE_FREQ_800          (2 << 16)
-#define IOP13XX_CORE_FREQ_933          (3 << 16)
-#define IOP13XX_CORE_FREQ_1000         (4 << 16)
-#define IOP13XX_CORE_FREQ_1200         (5 << 16)
-
-void iop_init_time(unsigned long tickrate);
-
-static inline unsigned long iop13xx_core_freq(void)
-{
-       unsigned long freq = __raw_readl(IOP13XX_PROCESSOR_FREQ);
-       freq &= IOP13XX_CORE_FREQ_MASK;
-       switch (freq) {
-       case IOP13XX_CORE_FREQ_600:
-               return 600000000;
-       case IOP13XX_CORE_FREQ_667:
-               return 667000000;
-       case IOP13XX_CORE_FREQ_800:
-               return 800000000;
-       case IOP13XX_CORE_FREQ_933:
-               return 933000000;
-       case IOP13XX_CORE_FREQ_1000:
-               return 1000000000;
-       case IOP13XX_CORE_FREQ_1200:
-               return 1200000000;
-       default:
-               printk("%s: warning unknown frequency, defaulting to 800MHz\n",
-                       __func__);
-       }
-
-       return 800000000;
-}
-
-static inline unsigned long iop13xx_xsi_bus_ratio(void)
-{
-       unsigned long  ratio = __raw_readl(IOP13XX_PROCESSOR_FREQ);
-       ratio &= IOP13XX_XSI_FREQ_RATIO_MASK;
-       switch (ratio) {
-       case IOP13XX_XSI_FREQ_RATIO_2:
-               return 2;
-       case IOP13XX_XSI_FREQ_RATIO_3:
-               return 3;
-       case IOP13XX_XSI_FREQ_RATIO_4:
-               return 4;
-       default:
-               printk("%s: warning unknown ratio, defaulting to 2\n",
-                       __func__);
-       }
-
-       return 2;
-}
-
-static inline u32 read_tmr0(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c0, c9, 0" : "=r" (val));
-       return val;
-}
-
-static inline void write_tmr0(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c0, c9, 0" : : "r" (val));
-}
-
-static inline void write_tmr1(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c1, c9, 0" : : "r" (val));
-}
-
-static inline u32 read_tcr0(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c2, c9, 0" : "=r" (val));
-       return val;
-}
-
-static inline void write_tcr0(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c2, c9, 0" : : "r" (val));
-}
-
-static inline u32 read_tcr1(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c3, c9, 0" : "=r" (val));
-       return val;
-}
-
-static inline void write_tcr1(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c3, c9, 0" : : "r" (val));
-}
-
-static inline void write_trr0(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c4, c9, 0" : : "r" (val));
-}
-
-static inline void write_trr1(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c5, c9, 0" : : "r" (val));
-}
-
-static inline void write_tisr(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c6, c9, 0" : : "r" (val));
-}
-#endif
diff --git a/arch/arm/mach-iop13xx/include/mach/uncompress.h b/arch/arm/mach-iop13xx/include/mach/uncompress.h
deleted file mode 100644 (file)
index c629030..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/types.h>
-#include <linux/serial_reg.h>
-#include <mach/hardware.h>
-
-#define UART_BASE ((volatile u32 *)IOP13XX_UART1_PHYS)
-#define TX_DONE (UART_LSR_TEMT | UART_LSR_THRE)
-
-static inline void putc(char c)
-{
-       while ((UART_BASE[UART_LSR] & TX_DONE) != TX_DONE)
-               barrier();
-       UART_BASE[UART_TX] = c;
-}
-
-static inline void flush(void)
-{
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
diff --git a/arch/arm/mach-iop13xx/io.c b/arch/arm/mach-iop13xx/io.c
deleted file mode 100644 (file)
index 253d446..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * iop13xx custom ioremap implementation
- * Copyright (c) 2005-2006, Intel Corporation.
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-
-#include "pci.h"
-
-static void __iomem *__iop13xx_ioremap_caller(phys_addr_t cookie,
-       size_t size, unsigned int mtype, void *caller)
-{
-       void __iomem * retval;
-
-       switch (cookie) {
-       case IOP13XX_PCIX_LOWER_MEM_RA ... IOP13XX_PCIX_UPPER_MEM_RA:
-               if (unlikely(!iop13xx_atux_mem_base))
-                       retval = NULL;
-               else
-                       retval = (iop13xx_atux_mem_base +
-                                (cookie - IOP13XX_PCIX_LOWER_MEM_RA));
-               break;
-       case IOP13XX_PCIE_LOWER_MEM_RA ... IOP13XX_PCIE_UPPER_MEM_RA:
-               if (unlikely(!iop13xx_atue_mem_base))
-                       retval = NULL;
-               else
-                       retval = (iop13xx_atue_mem_base +
-                                (cookie - IOP13XX_PCIE_LOWER_MEM_RA));
-               break;
-       case IOP13XX_PBI_LOWER_MEM_RA ... IOP13XX_PBI_UPPER_MEM_RA:
-               retval = __arm_ioremap_caller(IOP13XX_PBI_LOWER_MEM_PA +
-                                      (cookie - IOP13XX_PBI_LOWER_MEM_RA),
-                                      size, mtype, __builtin_return_address(0));
-               break;
-       case IOP13XX_PMMR_PHYS_MEM_BASE ... IOP13XX_PMMR_UPPER_MEM_PA:
-               retval = IOP13XX_PMMR_PHYS_TO_VIRT(cookie);
-               break;
-       default:
-               retval = __arm_ioremap_caller(cookie, size, mtype,
-                               caller);
-       }
-
-       return retval;
-}
-
-static void __iop13xx_iounmap(volatile void __iomem *addr)
-{
-       if (iop13xx_atue_mem_base)
-               if (addr >= (void __iomem *) iop13xx_atue_mem_base &&
-                   addr < (void __iomem *) (iop13xx_atue_mem_base +
-                                            iop13xx_atue_mem_size))
-                   goto skip;
-
-       if (iop13xx_atux_mem_base)
-               if (addr >= (void __iomem *) iop13xx_atux_mem_base &&
-                   addr < (void __iomem *) (iop13xx_atux_mem_base +
-                                            iop13xx_atux_mem_size))
-                   goto skip;
-
-       switch ((u32) addr) {
-       case (u32)IOP13XX_PMMR_VIRT_MEM_BASE ... (u32)IOP13XX_PMMR_UPPER_MEM_VA:
-               goto skip;
-       }
-       __iounmap(addr);
-
-skip:
-       return;
-}
-
-void __init iop13xx_init_early(void)
-{
-       arch_ioremap_caller = __iop13xx_ioremap_caller;
-       arch_iounmap = __iop13xx_iounmap;
-}
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c
deleted file mode 100644 (file)
index b3ce5cb..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * iq81340mc board support
- * Copyright (c) 2005-2006, Intel Corporation.
- */
-#include <linux/pci.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/pci.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include "pci.h"
-#include <asm/mach/time.h>
-#include <mach/time.h>
-
-extern int init_atu; /* Flag to select which ATU(s) to initialize / disable */
-
-static int __init
-iq81340mc_pcix_map_irq(const struct pci_dev *dev, u8 idsel, u8 pin)
-{
-       switch (idsel) {
-       case 1:
-               switch (pin) {
-               case 1: return ATUX_INTB;
-               case 2: return ATUX_INTC;
-               case 3: return ATUX_INTD;
-               case 4: return ATUX_INTA;
-               default: return -1;
-               }
-       case 2:
-               switch (pin) {
-               case 1: return ATUX_INTC;
-               case 2: return ATUX_INTD;
-               case 3: return ATUX_INTC;
-               case 4: return ATUX_INTD;
-               default: return -1;
-               }
-       default: return -1;
-       }
-}
-
-static struct hw_pci iq81340mc_pci __initdata = {
-       .nr_controllers = 0,
-       .setup          = iop13xx_pci_setup,
-       .map_irq        = iq81340mc_pcix_map_irq,
-       .scan           = iop13xx_scan_bus,
-       .preinit        = iop13xx_pci_init,
-};
-
-static int __init iq81340mc_pci_init(void)
-{
-       iop13xx_atu_select(&iq81340mc_pci);
-       pci_common_init(&iq81340mc_pci);
-       iop13xx_map_pci_memory();
-
-       return 0;
-}
-
-static void __init iq81340mc_init(void)
-{
-       iop13xx_platform_init();
-       iq81340mc_pci_init();
-       iop13xx_add_tpmi_devices();
-}
-
-static void __init iq81340mc_timer_init(void)
-{
-       unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio();
-       printk(KERN_DEBUG "%s: bus frequency: %lu\n", __func__, bus_freq);
-       iop_init_time(bus_freq);
-}
-
-MACHINE_START(IQ81340MC, "Intel IQ81340MC")
-       /* Maintainer: Dan Williams <dan.j.williams@intel.com> */
-       .atag_offset    = 0x100,
-       .init_early     = iop13xx_init_early,
-       .map_io         = iop13xx_map_io,
-       .init_irq       = iop13xx_init_irq,
-       .init_time      = iq81340mc_timer_init,
-       .init_machine   = iq81340mc_init,
-       .restart        = iop13xx_restart,
-       .nr_irqs        = NR_IOP13XX_IRQS,
-MACHINE_END
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c
deleted file mode 100644 (file)
index 123845d..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * iq81340sc board support
- * Copyright (c) 2005-2006, Intel Corporation.
- */
-#include <linux/pci.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/pci.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include "pci.h"
-#include <asm/mach/time.h>
-#include <mach/time.h>
-
-extern int init_atu;
-
-static int __init
-iq81340sc_atux_map_irq(const struct pci_dev *dev, u8 idsel, u8 pin)
-{
-       WARN_ON(idsel < 1 || idsel > 2);
-
-       switch (idsel) {
-       case 1:
-               switch (pin) {
-               case 1: return ATUX_INTB;
-               case 2: return ATUX_INTC;
-               case 3: return ATUX_INTD;
-               case 4: return ATUX_INTA;
-               default: return -1;
-               }
-       case 2:
-               switch (pin) {
-               case 1: return ATUX_INTC;
-               case 2: return ATUX_INTC;
-               case 3: return ATUX_INTC;
-               case 4: return ATUX_INTC;
-               default: return -1;
-               }
-       default: return -1;
-       }
-}
-
-static struct hw_pci iq81340sc_pci __initdata = {
-       .nr_controllers = 0,
-       .setup          = iop13xx_pci_setup,
-       .scan           = iop13xx_scan_bus,
-       .map_irq        = iq81340sc_atux_map_irq,
-       .preinit        = iop13xx_pci_init
-};
-
-static int __init iq81340sc_pci_init(void)
-{
-       iop13xx_atu_select(&iq81340sc_pci);
-       pci_common_init(&iq81340sc_pci);
-       iop13xx_map_pci_memory();
-
-       return 0;
-}
-
-static void __init iq81340sc_init(void)
-{
-       iop13xx_platform_init();
-       iq81340sc_pci_init();
-       iop13xx_add_tpmi_devices();
-}
-
-static void __init iq81340sc_timer_init(void)
-{
-       unsigned long bus_freq = iop13xx_core_freq() / iop13xx_xsi_bus_ratio();
-       printk(KERN_DEBUG "%s: bus frequency: %lu\n", __func__, bus_freq);
-       iop_init_time(bus_freq);
-}
-
-MACHINE_START(IQ81340SC, "Intel IQ81340SC")
-       /* Maintainer: Dan Williams <dan.j.williams@intel.com> */
-       .atag_offset    = 0x100,
-       .init_early     = iop13xx_init_early,
-       .map_io         = iop13xx_map_io,
-       .init_irq       = iop13xx_init_irq,
-       .init_time      = iq81340sc_timer_init,
-       .init_machine   = iq81340sc_init,
-       .restart        = iop13xx_restart,
-       .nr_irqs        = NR_IOP13XX_IRQS,
-MACHINE_END
diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c
deleted file mode 100644 (file)
index 0e24ba7..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * iop13xx IRQ handling / support functions
- * Copyright (c) 2005-2006, Intel Corporation.
- */
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/sysctl.h>
-#include <linux/uaccess.h>
-#include <asm/mach/irq.h>
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-#include "msi.h"
-
-/* INTCTL0 CP6 R0 Page 4
- */
-static u32 read_intctl_0(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c0, c4, 0":"=r" (val));
-       return val;
-}
-static void write_intctl_0(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c0, c4, 0"::"r" (val));
-}
-
-/* INTCTL1 CP6 R1 Page 4
- */
-static u32 read_intctl_1(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c1, c4, 0":"=r" (val));
-       return val;
-}
-static void write_intctl_1(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c1, c4, 0"::"r" (val));
-}
-
-/* INTCTL2 CP6 R2 Page 4
- */
-static u32 read_intctl_2(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c2, c4, 0":"=r" (val));
-       return val;
-}
-static void write_intctl_2(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c2, c4, 0"::"r" (val));
-}
-
-/* INTCTL3 CP6 R3 Page 4
- */
-static u32 read_intctl_3(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c3, c4, 0":"=r" (val));
-       return val;
-}
-static void write_intctl_3(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c3, c4, 0"::"r" (val));
-}
-
-/* INTSTR0 CP6 R0 Page 5
- */
-static void write_intstr_0(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c0, c5, 0"::"r" (val));
-}
-
-/* INTSTR1 CP6 R1 Page 5
- */
-static void write_intstr_1(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c1, c5, 0"::"r" (val));
-}
-
-/* INTSTR2 CP6 R2 Page 5
- */
-static void write_intstr_2(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c2, c5, 0"::"r" (val));
-}
-
-/* INTSTR3 CP6 R3 Page 5
- */
-static void write_intstr_3(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c3, c5, 0"::"r" (val));
-}
-
-/* INTBASE CP6 R0 Page 2
- */
-static void write_intbase(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c0, c2, 0"::"r" (val));
-}
-
-/* INTSIZE CP6 R2 Page 2
- */
-static void write_intsize(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c2, c2, 0"::"r" (val));
-}
-
-/* 0 = Interrupt Masked and 1 = Interrupt not masked */
-static void
-iop13xx_irq_mask0 (struct irq_data *d)
-{
-       write_intctl_0(read_intctl_0() & ~(1 << (d->irq - 0)));
-}
-
-static void
-iop13xx_irq_mask1 (struct irq_data *d)
-{
-       write_intctl_1(read_intctl_1() & ~(1 << (d->irq - 32)));
-}
-
-static void
-iop13xx_irq_mask2 (struct irq_data *d)
-{
-       write_intctl_2(read_intctl_2() & ~(1 << (d->irq - 64)));
-}
-
-static void
-iop13xx_irq_mask3 (struct irq_data *d)
-{
-       write_intctl_3(read_intctl_3() & ~(1 << (d->irq - 96)));
-}
-
-static void
-iop13xx_irq_unmask0(struct irq_data *d)
-{
-       write_intctl_0(read_intctl_0() | (1 << (d->irq - 0)));
-}
-
-static void
-iop13xx_irq_unmask1(struct irq_data *d)
-{
-       write_intctl_1(read_intctl_1() | (1 << (d->irq - 32)));
-}
-
-static void
-iop13xx_irq_unmask2(struct irq_data *d)
-{
-       write_intctl_2(read_intctl_2() | (1 << (d->irq - 64)));
-}
-
-static void
-iop13xx_irq_unmask3(struct irq_data *d)
-{
-       write_intctl_3(read_intctl_3() | (1 << (d->irq - 96)));
-}
-
-static struct irq_chip iop13xx_irqchip1 = {
-       .name       = "IOP13xx-1",
-       .irq_ack    = iop13xx_irq_mask0,
-       .irq_mask   = iop13xx_irq_mask0,
-       .irq_unmask = iop13xx_irq_unmask0,
-};
-
-static struct irq_chip iop13xx_irqchip2 = {
-       .name       = "IOP13xx-2",
-       .irq_ack    = iop13xx_irq_mask1,
-       .irq_mask   = iop13xx_irq_mask1,
-       .irq_unmask = iop13xx_irq_unmask1,
-};
-
-static struct irq_chip iop13xx_irqchip3 = {
-       .name       = "IOP13xx-3",
-       .irq_ack    = iop13xx_irq_mask2,
-       .irq_mask   = iop13xx_irq_mask2,
-       .irq_unmask = iop13xx_irq_unmask2,
-};
-
-static struct irq_chip iop13xx_irqchip4 = {
-       .name       = "IOP13xx-4",
-       .irq_ack    = iop13xx_irq_mask3,
-       .irq_mask   = iop13xx_irq_mask3,
-       .irq_unmask = iop13xx_irq_unmask3,
-};
-
-extern void iop_init_cp6_handler(void);
-
-void __init iop13xx_init_irq(void)
-{
-       unsigned int i;
-
-       iop_init_cp6_handler();
-
-       /* disable all interrupts */
-       write_intctl_0(0);
-       write_intctl_1(0);
-       write_intctl_2(0);
-       write_intctl_3(0);
-
-       /* treat all as IRQ */
-       write_intstr_0(0);
-       write_intstr_1(0);
-       write_intstr_2(0);
-       write_intstr_3(0);
-
-       /* initialize the interrupt vector generator */
-       write_intbase(INTBASE);
-       write_intsize(INTSIZE_4);
-
-       for(i = 0; i <= IRQ_IOP13XX_HPI; i++) {
-               if (i < 32)
-                       irq_set_chip(i, &iop13xx_irqchip1);
-               else if (i < 64)
-                       irq_set_chip(i, &iop13xx_irqchip2);
-               else if (i < 96)
-                       irq_set_chip(i, &iop13xx_irqchip3);
-               else
-                       irq_set_chip(i, &iop13xx_irqchip4);
-
-               irq_set_handler(i, handle_level_irq);
-               irq_clear_status_flags(i, IRQ_NOREQUEST | IRQ_NOPROBE);
-       }
-
-       iop13xx_msi_init();
-}
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
deleted file mode 100644 (file)
index f4d70cb..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mach-iop13xx/msi.c
- *
- * PCI MSI support for the iop13xx processor
- *
- * Copyright (c) 2006, Intel Corporation.
- */
-#include <linux/pci.h>
-#include <linux/msi.h>
-#include <asm/mach/irq.h>
-#include <asm/irq.h>
-#include <mach/irqs.h>
-
-/* IMIPR0 CP6 R8 Page 1
- */
-static u32 read_imipr_0(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c8, c1, 0":"=r" (val));
-       return val;
-}
-static void write_imipr_0(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c8, c1, 0"::"r" (val));
-}
-
-/* IMIPR1 CP6 R9 Page 1
- */
-static u32 read_imipr_1(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c9, c1, 0":"=r" (val));
-       return val;
-}
-static void write_imipr_1(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c9, c1, 0"::"r" (val));
-}
-
-/* IMIPR2 CP6 R10 Page 1
- */
-static u32 read_imipr_2(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c10, c1, 0":"=r" (val));
-       return val;
-}
-static void write_imipr_2(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c10, c1, 0"::"r" (val));
-}
-
-/* IMIPR3 CP6 R11 Page 1
- */
-static u32 read_imipr_3(void)
-{
-       u32 val;
-       asm volatile("mrc p6, 0, %0, c11, c1, 0":"=r" (val));
-       return val;
-}
-static void write_imipr_3(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c11, c1, 0"::"r" (val));
-}
-
-static u32 (*read_imipr[])(void) = {
-       read_imipr_0,
-       read_imipr_1,
-       read_imipr_2,
-       read_imipr_3,
-};
-
-static void (*write_imipr[])(u32) = {
-       write_imipr_0,
-       write_imipr_1,
-       write_imipr_2,
-       write_imipr_3,
-};
-
-static void iop13xx_msi_handler(struct irq_desc *desc)
-{
-       int i, j;
-       unsigned long status;
-
-       /* read IMIPR registers and find any active interrupts,
-        * then call ISR for each active interrupt
-        */
-       for (i = 0; i < ARRAY_SIZE(read_imipr); i++) {
-               status = (read_imipr[i])();
-               if (!status)
-                       continue;
-
-               do {
-                       j = find_first_bit(&status, 32);
-                       (write_imipr[i])(1 << j); /* write back to clear bit */
-                       generic_handle_irq(IRQ_IOP13XX_MSI_0 + j + (32*i));
-                       status = (read_imipr[i])();
-               } while (status);
-       }
-}
-
-void __init iop13xx_msi_init(void)
-{
-       irq_set_chained_handler(IRQ_IOP13XX_INBD_MSI, iop13xx_msi_handler);
-}
-
-static void iop13xx_msi_nop(struct irq_data *d)
-{
-       return;
-}
-
-static struct irq_chip iop13xx_msi_chip = {
-       .name = "PCI-MSI",
-       .irq_ack = iop13xx_msi_nop,
-       .irq_enable = pci_msi_unmask_irq,
-       .irq_disable = pci_msi_mask_irq,
-       .irq_mask = pci_msi_mask_irq,
-       .irq_unmask = pci_msi_unmask_irq,
-};
-
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
-{
-       int id, irq = irq_alloc_desc_from(IRQ_IOP13XX_MSI_0, -1);
-       struct msi_msg msg;
-
-       if (irq < 0)
-               return irq;
-
-       if (irq >= NR_IOP13XX_IRQS) {
-               irq_free_desc(irq);
-               return -ENOSPC;
-       }
-
-       irq_set_msi_desc(irq, desc);
-
-       msg.address_hi = 0x0;
-       msg.address_lo = IOP13XX_MU_MIMR_PCI;
-
-       id = iop13xx_cpu_id();
-       msg.data = (id << IOP13XX_MU_MIMR_CORE_SELECT) | (irq & 0x7f);
-
-       pci_write_msi_msg(irq, &msg);
-       irq_set_chip_and_handler(irq, &iop13xx_msi_chip, handle_simple_irq);
-
-       return 0;
-}
-
-void arch_teardown_msi_irq(unsigned int irq)
-{
-       irq_free_desc(irq);
-}
diff --git a/arch/arm/mach-iop13xx/msi.h b/arch/arm/mach-iop13xx/msi.h
deleted file mode 100644 (file)
index 766dcfa..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _IOP13XX_MSI_H_
-#define _IOP13XX_MSI_H_
-#ifdef CONFIG_PCI_MSI
-void iop13xx_msi_init(void);
-#else
-static inline void iop13xx_msi_init(void)
-{
-       return;
-}
-#endif
-#endif
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
deleted file mode 100644 (file)
index 46ea06e..0000000
+++ /dev/null
@@ -1,1115 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * iop13xx PCI support
- * Copyright (c) 2005-2006, Intel Corporation.
- */
-
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/jiffies.h>
-#include <linux/export.h>
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <linux/sizes.h>
-#include <asm/signal.h>
-#include <asm/mach/pci.h>
-#include "pci.h"
-
-#define IOP13XX_PCI_DEBUG 0
-#define PRINTK(x...) ((void)(IOP13XX_PCI_DEBUG && printk(x)))
-
-u32 iop13xx_atux_pmmr_offset; /* This offset can change based on strapping */
-u32 iop13xx_atue_pmmr_offset; /* This offset can change based on strapping */
-static struct pci_bus *pci_bus_atux = 0;
-static struct pci_bus *pci_bus_atue = 0;
-void __iomem *iop13xx_atue_mem_base;
-void __iomem *iop13xx_atux_mem_base;
-size_t iop13xx_atue_mem_size;
-size_t iop13xx_atux_mem_size;
-
-EXPORT_SYMBOL(iop13xx_atue_mem_base);
-EXPORT_SYMBOL(iop13xx_atux_mem_base);
-EXPORT_SYMBOL(iop13xx_atue_mem_size);
-EXPORT_SYMBOL(iop13xx_atux_mem_size);
-
-int init_atu = 0; /* Flag to select which ATU(s) to initialize / disable */
-static unsigned long atux_trhfa_timeout = 0; /* Trhfa = RST# high to first
-                                                access */
-
-/* Scan the initialized busses and ioremap the requested memory range
- */
-void iop13xx_map_pci_memory(void)
-{
-       int atu;
-       struct pci_bus *bus;
-       struct pci_dev *dev;
-       resource_size_t end = 0;
-
-       for (atu = 0; atu < 2; atu++) {
-               bus = atu ? pci_bus_atue : pci_bus_atux;
-               if (bus) {
-                       list_for_each_entry(dev, &bus->devices, bus_list) {
-                               int i;
-                               int max = 7;
-
-                               if (dev->subordinate)
-                                       max = DEVICE_COUNT_RESOURCE;
-
-                               for (i = 0; i < max; i++) {
-                                       struct resource *res = &dev->resource[i];
-                                       if (res->flags & IORESOURCE_MEM)
-                                               end = max(res->end, end);
-                               }
-                       }
-
-                       switch(atu) {
-                       case 0:
-                               iop13xx_atux_mem_size =
-                                       (end - IOP13XX_PCIX_LOWER_MEM_RA) + 1;
-
-                               /* 16MB align the request */
-                               if (iop13xx_atux_mem_size & (SZ_16M - 1)) {
-                                       iop13xx_atux_mem_size &= ~(SZ_16M - 1);
-                                       iop13xx_atux_mem_size += SZ_16M;
-                               }
-
-                               if (end) {
-                                       iop13xx_atux_mem_base = __arm_ioremap_pfn(
-                                       __phys_to_pfn(IOP13XX_PCIX_LOWER_MEM_PA)
-                                       , 0, iop13xx_atux_mem_size, MT_DEVICE);
-                                       if (!iop13xx_atux_mem_base) {
-                                               printk("%s: atux allocation "
-                                                      "failed\n", __func__);
-                                               BUG();
-                                       }
-                               } else
-                                       iop13xx_atux_mem_size = 0;
-                               PRINTK("%s: atu: %d bus_size: %d mem_base: %p\n",
-                               __func__, atu, iop13xx_atux_mem_size,
-                               iop13xx_atux_mem_base);
-                               break;
-                       case 1:
-                               iop13xx_atue_mem_size =
-                                       (end - IOP13XX_PCIE_LOWER_MEM_RA) + 1;
-
-                               /* 16MB align the request */
-                               if (iop13xx_atue_mem_size & (SZ_16M - 1)) {
-                                       iop13xx_atue_mem_size &= ~(SZ_16M - 1);
-                                       iop13xx_atue_mem_size += SZ_16M;
-                               }
-
-                               if (end) {
-                                       iop13xx_atue_mem_base = __arm_ioremap_pfn(
-                                       __phys_to_pfn(IOP13XX_PCIE_LOWER_MEM_PA)
-                                       , 0, iop13xx_atue_mem_size, MT_DEVICE);
-                                       if (!iop13xx_atue_mem_base) {
-                                               printk("%s: atue allocation "
-                                                      "failed\n", __func__);
-                                               BUG();
-                                       }
-                               } else
-                                       iop13xx_atue_mem_size = 0;
-                               PRINTK("%s: atu: %d bus_size: %d mem_base: %p\n",
-                               __func__, atu, iop13xx_atue_mem_size,
-                               iop13xx_atue_mem_base);
-                               break;
-                       }
-
-                       printk("%s: Initialized (%uM @ resource/virtual: %08lx/%p)\n",
-                       atu ? "ATUE" : "ATUX",
-                       (atu ? iop13xx_atue_mem_size : iop13xx_atux_mem_size) /
-                       SZ_1M,
-                       atu ? IOP13XX_PCIE_LOWER_MEM_RA :
-                       IOP13XX_PCIX_LOWER_MEM_RA,
-                       atu ? iop13xx_atue_mem_base :
-                       iop13xx_atux_mem_base);
-                       end = 0;
-               }
-
-       }
-}
-
-static int iop13xx_atu_function(int atu)
-{
-       int func = 0;
-       /* the function number depends on the value of the
-        * IOP13XX_INTERFACE_SEL_PCIX reset strap
-        * see C-Spec section 3.17
-        */
-       switch(atu) {
-       case IOP13XX_INIT_ATU_ATUX:
-               if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
-                       func = 5;
-               else
-                       func = 0;
-               break;
-       case IOP13XX_INIT_ATU_ATUE:
-               if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
-                       func = 0;
-               else
-                       func = 5;
-               break;
-       default:
-               BUG();
-       }
-
-       return func;
-}
-
-/* iop13xx_atux_cfg_address - format a configuration address for atux
- * @bus: Target bus to access
- * @devfn: Combined device number and function number
- * @where: Desired register's address offset
- *
- * Convert the parameters to a configuration address formatted
- * according the PCI-X 2.0 specification
- */
-static u32 iop13xx_atux_cfg_address(struct pci_bus *bus, int devfn, int where)
-{
-       struct pci_sys_data *sys = bus->sysdata;
-       u32 addr;
-
-       if (sys->busnr == bus->number)
-               addr = 1 << (PCI_SLOT(devfn) + 16) | (PCI_SLOT(devfn) << 11);
-       else
-               addr = bus->number << 16 | PCI_SLOT(devfn) << 11 | 1;
-
-       addr |= PCI_FUNC(devfn) << 8 | ((where & 0xff) & ~3);
-       addr |= ((where & 0xf00) >> 8) << 24; /* upper register number */
-
-       return addr;
-}
-
-/* iop13xx_atue_cfg_address - format a configuration address for atue
- * @bus: Target bus to access
- * @devfn: Combined device number and function number
- * @where: Desired register's address offset
- *
- * Convert the parameters to an address usable by the ATUE_OCCAR
- */
-static u32 iop13xx_atue_cfg_address(struct pci_bus *bus, int devfn, int where)
-{
-       struct pci_sys_data *sys = bus->sysdata;
-       u32 addr;
-
-       PRINTK("iop13xx_atue_cfg_address: bus: %d dev: %d func: %d",
-               bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
-       addr = ((u32) bus->number)     << IOP13XX_ATUE_OCCAR_BUS_NUM |
-                  ((u32) PCI_SLOT(devfn)) << IOP13XX_ATUE_OCCAR_DEV_NUM |
-                  ((u32) PCI_FUNC(devfn)) << IOP13XX_ATUE_OCCAR_FUNC_NUM |
-                  (where & ~0x3);
-
-       if (sys->busnr != bus->number)
-               addr |= 1; /* type 1 access */
-
-       return addr;
-}
-
-/* This routine checks the status of the last configuration cycle.  If an error
- * was detected it returns >0, else it returns a 0.  The errors being checked
- * are parity, master abort, target abort (master and target).  These types of
- * errors occur during a config cycle where there is no device, like during
- * the discovery stage.
- */
-static int iop13xx_atux_pci_status(int clear)
-{
-       unsigned int status;
-       int err = 0;
-
-       /*
-        * Check the status registers.
-        */
-       status = __raw_readw(IOP13XX_ATUX_ATUSR);
-       if (status & IOP_PCI_STATUS_ERROR)
-       {
-               PRINTK("\t\t\tPCI error: ATUSR %#08x", status);
-               if(clear)
-                       __raw_writew(status & IOP_PCI_STATUS_ERROR,
-                               IOP13XX_ATUX_ATUSR);
-               err = 1;
-       }
-       status = __raw_readl(IOP13XX_ATUX_ATUISR);
-       if (status & IOP13XX_ATUX_ATUISR_ERROR)
-       {
-               PRINTK("\t\t\tPCI error interrupt:  ATUISR %#08x", status);
-               if(clear)
-                       __raw_writel(status & IOP13XX_ATUX_ATUISR_ERROR,
-                               IOP13XX_ATUX_ATUISR);
-               err = 1;
-       }
-       return err;
-}
-
-/* Simply write the address register and read the configuration
- * data.  Note that the data dependency on %0 encourages an abort
- * to be detected before we return.
- */
-static u32 iop13xx_atux_read(unsigned long addr)
-{
-       u32 val;
-
-       __asm__ __volatile__(
-               "str    %1, [%2]\n\t"
-               "ldr    %0, [%3]\n\t"
-               "mov    %0, %0\n\t"
-               : "=r" (val)
-               : "r" (addr), "r" (IOP13XX_ATUX_OCCAR), "r" (IOP13XX_ATUX_OCCDR));
-
-       return val;
-}
-
-/* The read routines must check the error status of the last configuration
- * cycle.  If there was an error, the routine returns all hex f's.
- */
-static int
-iop13xx_atux_read_config(struct pci_bus *bus, unsigned int devfn, int where,
-               int size, u32 *value)
-{
-       unsigned long addr = iop13xx_atux_cfg_address(bus, devfn, where);
-       u32 val = iop13xx_atux_read(addr) >> ((where & 3) * 8);
-
-       if (iop13xx_atux_pci_status(1) || is_atux_occdr_error()) {
-               __raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3,
-                       IOP13XX_XBG_BECSR);
-               val = 0xffffffff;
-       }
-
-       *value = val;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-iop13xx_atux_write_config(struct pci_bus *bus, unsigned int devfn, int where,
-               int size, u32 value)
-{
-       unsigned long addr = iop13xx_atux_cfg_address(bus, devfn, where);
-       u32 val;
-
-       if (size != 4) {
-               val = iop13xx_atux_read(addr);
-               if (!iop13xx_atux_pci_status(1) == 0)
-                       return PCIBIOS_SUCCESSFUL;
-
-               where = (where & 3) * 8;
-
-               if (size == 1)
-                       val &= ~(0xff << where);
-               else
-                       val &= ~(0xffff << where);
-
-               __raw_writel(val | value << where, IOP13XX_ATUX_OCCDR);
-       } else {
-               __raw_writel(addr, IOP13XX_ATUX_OCCAR);
-               __raw_writel(value, IOP13XX_ATUX_OCCDR);
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops iop13xx_atux_ops = {
-       .read   = iop13xx_atux_read_config,
-       .write  = iop13xx_atux_write_config,
-};
-
-/* This routine checks the status of the last configuration cycle.  If an error
- * was detected it returns >0, else it returns a 0.  The errors being checked
- * are parity, master abort, target abort (master and target).  These types of
- * errors occur during a config cycle where there is no device, like during
- * the discovery stage.
- */
-static int iop13xx_atue_pci_status(int clear)
-{
-       unsigned int status;
-       int err = 0;
-
-       /*
-        * Check the status registers.
-        */
-
-       /* standard pci status register */
-       status = __raw_readw(IOP13XX_ATUE_ATUSR);
-       if (status & IOP_PCI_STATUS_ERROR) {
-               PRINTK("\t\t\tPCI error: ATUSR %#08x", status);
-               if(clear)
-                       __raw_writew(status & IOP_PCI_STATUS_ERROR,
-                               IOP13XX_ATUE_ATUSR);
-               err++;
-       }
-
-       /* check the normal status bits in the ATUISR */
-       status = __raw_readl(IOP13XX_ATUE_ATUISR);
-       if (status & IOP13XX_ATUE_ATUISR_ERROR) {
-               PRINTK("\t\t\tPCI error: ATUISR %#08x", status);
-               if (clear)
-                       __raw_writew(status & IOP13XX_ATUE_ATUISR_ERROR,
-                               IOP13XX_ATUE_ATUISR);
-               err++;
-
-               /* check the PCI-E status if the ATUISR reports an interface error */
-               if (status & IOP13XX_ATUE_STAT_PCI_IFACE_ERR) {
-                       /* get the unmasked errors */
-                       status = __raw_readl(IOP13XX_ATUE_PIE_STS) &
-                                       ~(__raw_readl(IOP13XX_ATUE_PIE_MSK));
-
-                       if (status) {
-                               PRINTK("\t\t\tPCI-E error: ATUE_PIE_STS %#08x",
-                                       __raw_readl(IOP13XX_ATUE_PIE_STS));
-                               err++;
-                       } else {
-                               PRINTK("\t\t\tPCI-E error: ATUE_PIE_STS %#08x",
-                                       __raw_readl(IOP13XX_ATUE_PIE_STS));
-                               PRINTK("\t\t\tPCI-E error: ATUE_PIE_MSK %#08x",
-                                       __raw_readl(IOP13XX_ATUE_PIE_MSK));
-                               BUG();
-                       }
-
-                       if(clear)
-                               __raw_writel(status, IOP13XX_ATUE_PIE_STS);
-               }
-       }
-
-       return err;
-}
-
-static int
-iop13xx_pcie_map_irq(const struct pci_dev *dev, u8 idsel, u8 pin)
-{
-       WARN_ON(idsel != 0);
-
-       switch (pin) {
-       case 1: return ATUE_INTA;
-       case 2: return ATUE_INTB;
-       case 3: return ATUE_INTC;
-       case 4: return ATUE_INTD;
-       default: return -1;
-       }
-}
-
-static u32 iop13xx_atue_read(unsigned long addr)
-{
-       u32 val;
-
-       __raw_writel(addr, IOP13XX_ATUE_OCCAR);
-       val = __raw_readl(IOP13XX_ATUE_OCCDR);
-
-       rmb();
-
-       return val;
-}
-
-/* The read routines must check the error status of the last configuration
- * cycle.  If there was an error, the routine returns all hex f's.
- */
-static int
-iop13xx_atue_read_config(struct pci_bus *bus, unsigned int devfn, int where,
-               int size, u32 *value)
-{
-       u32 val;
-       unsigned long addr = iop13xx_atue_cfg_address(bus, devfn, where);
-
-       /* Hide device numbers > 0 on the local PCI-E bus (Type 0 access) */
-       if (!PCI_SLOT(devfn) || (addr & 1)) {
-               val = iop13xx_atue_read(addr) >> ((where & 3) * 8);
-               if( iop13xx_atue_pci_status(1) || is_atue_occdr_error() ) {
-                       __raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3,
-                               IOP13XX_XBG_BECSR);
-                       val = 0xffffffff;
-               }
-
-               PRINTK("addr=%#0lx, val=%#010x", addr, val);
-       } else
-               val = 0xffffffff;
-
-       *value = val;
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-iop13xx_atue_write_config(struct pci_bus *bus, unsigned int devfn, int where,
-               int size, u32 value)
-{
-       unsigned long addr = iop13xx_atue_cfg_address(bus, devfn, where);
-       u32 val;
-
-       if (size != 4) {
-               val = iop13xx_atue_read(addr);
-               if (!iop13xx_atue_pci_status(1) == 0)
-                       return PCIBIOS_SUCCESSFUL;
-
-               where = (where & 3) * 8;
-
-               if (size == 1)
-                       val &= ~(0xff << where);
-               else
-                       val &= ~(0xffff << where);
-
-               __raw_writel(val | value << where, IOP13XX_ATUE_OCCDR);
-       } else {
-               __raw_writel(addr, IOP13XX_ATUE_OCCAR);
-               __raw_writel(value, IOP13XX_ATUE_OCCDR);
-       }
-
-       return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops iop13xx_atue_ops = {
-       .read   = iop13xx_atue_read_config,
-       .write  = iop13xx_atue_write_config,
-};
-
-/* When a PCI device does not exist during config cycles, the XScale gets a
- * bus error instead of returning 0xffffffff.  We can't rely on the ATU status
- * bits to tell us that it was indeed a configuration cycle that caused this
- * error especially in the case when the ATUE link is down.  Instead we rely
- * on data from the south XSI bridge to validate the abort
- */
-int
-iop13xx_pci_abort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
-{
-       PRINTK("Data abort: address = 0x%08lx "
-                   "fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx",
-               addr, fsr, regs->ARM_pc, regs->ARM_lr);
-
-       PRINTK("IOP13XX_XBG_BECSR: %#10x", __raw_readl(IOP13XX_XBG_BECSR));
-       PRINTK("IOP13XX_XBG_BERAR: %#10x", __raw_readl(IOP13XX_XBG_BERAR));
-       PRINTK("IOP13XX_XBG_BERUAR: %#10x", __raw_readl(IOP13XX_XBG_BERUAR));
-
-       /*  If it was an imprecise abort, then we need to correct the
-        *  return address to be _after_ the instruction.
-        */
-       if (fsr & (1 << 10))
-               regs->ARM_pc += 4;
-
-       if (is_atue_occdr_error() || is_atux_occdr_error())
-               return 0;
-       else
-               return 1;
-}
-
-/* Scan an IOP13XX PCI bus.  nr selects which ATU we use.
- */
-int iop13xx_scan_bus(int nr, struct pci_host_bridge *bridge)
-{
-       int which_atu, ret;
-       struct pci_sys_data *sys = pci_host_bridge_priv(bridge);
-
-       switch (init_atu) {
-       case IOP13XX_INIT_ATU_ATUX:
-               which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUX;
-               break;
-       case IOP13XX_INIT_ATU_ATUE:
-               which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUE;
-               break;
-       case (IOP13XX_INIT_ATU_ATUX | IOP13XX_INIT_ATU_ATUE):
-               which_atu = nr ? IOP13XX_INIT_ATU_ATUE : IOP13XX_INIT_ATU_ATUX;
-               break;
-       default:
-               which_atu = 0;
-       }
-
-       if (!which_atu) {
-               BUG();
-               return -ENODEV;
-       }
-
-       list_splice_init(&sys->resources, &bridge->windows);
-       bridge->dev.parent = NULL;
-       bridge->sysdata = sys;
-       bridge->busnr = sys->busnr;
-
-       switch (which_atu) {
-       case IOP13XX_INIT_ATU_ATUX:
-               if (time_after_eq(jiffies + msecs_to_jiffies(1000),
-                                 atux_trhfa_timeout))  /* ensure not wrap */
-                       while(time_before(jiffies, atux_trhfa_timeout))
-                               udelay(100);
-
-               bridge->ops = &iop13xx_atux_ops;
-               ret = pci_scan_root_bus_bridge(bridge);
-               if (!ret)
-                       pci_bus_atux = bridge->bus;
-               break;
-       case IOP13XX_INIT_ATU_ATUE:
-               bridge->ops = &iop13xx_atue_ops;
-               ret = pci_scan_root_bus_bridge(bridge);
-               if (!ret)
-                       pci_bus_atue = bridge->bus;
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-/* This function is called from iop13xx_pci_init() after assigning valid
- * values to iop13xx_atue_pmmr_offset.  This is the location for common
- * setup of ATUE for all IOP13XX implementations.
- */
-void __init iop13xx_atue_setup(void)
-{
-       int func = iop13xx_atu_function(IOP13XX_INIT_ATU_ATUE);
-       u32 reg_val;
-
-#ifdef CONFIG_PCI_MSI
-       /* BAR 0 (inbound msi window) */
-       __raw_writel(IOP13XX_MU_BASE_PHYS, IOP13XX_MU_MUBAR);
-       __raw_writel(~(IOP13XX_MU_WINDOW_SIZE - 1), IOP13XX_ATUE_IALR0);
-       __raw_writel(IOP13XX_MU_BASE_PHYS, IOP13XX_ATUE_IATVR0);
-       __raw_writel(IOP13XX_MU_BASE_PCI, IOP13XX_ATUE_IABAR0);
-#endif
-
-       /* BAR 1 (1:1 mapping with Physical RAM) */
-       /* Set limit and enable */
-       __raw_writel(~(IOP13XX_MAX_RAM_SIZE - PHYS_OFFSET - 1) & ~0x1,
-                       IOP13XX_ATUE_IALR1);
-       __raw_writel(0x0, IOP13XX_ATUE_IAUBAR1);
-
-       /* Set base at the top of the reserved address space */
-       __raw_writel(PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_TYPE_64 |
-                       PCI_BASE_ADDRESS_MEM_PREFETCH, IOP13XX_ATUE_IABAR1);
-
-       /* 1:1 mapping with physical ram
-        * (leave big endian byte swap disabled)
-        */
-        __raw_writel(0x0, IOP13XX_ATUE_IAUTVR1);
-        __raw_writel(PHYS_OFFSET, IOP13XX_ATUE_IATVR1);
-
-       /* Outbound window 1 (PCIX/PCIE memory window) */
-       /* 32 bit Address Space */
-       __raw_writel(0x0, IOP13XX_ATUE_OUMWTVR1);
-       /* PA[35:32] */
-       __raw_writel(IOP13XX_ATUE_OUMBAR_ENABLE |
-                       (IOP13XX_PCIE_MEM_PHYS_OFFSET >> 32),
-                       IOP13XX_ATUE_OUMBAR1);
-
-       /* Setup the I/O Bar
-        * A[35-16] in 31-12
-        */
-       __raw_writel(((IOP13XX_PCIE_LOWER_IO_PA >> 0x4) & 0xfffff000),
-               IOP13XX_ATUE_OIOBAR);
-       __raw_writel(IOP13XX_PCIE_LOWER_IO_BA, IOP13XX_ATUE_OIOWTVR);
-
-       /* clear startup errors */
-       iop13xx_atue_pci_status(1);
-
-       /* OIOBAR function number
-        */
-       reg_val = __raw_readl(IOP13XX_ATUE_OIOBAR);
-       reg_val &= ~0x7;
-       reg_val |= func;
-       __raw_writel(reg_val, IOP13XX_ATUE_OIOBAR);
-
-       /* OUMBAR function numbers
-        */
-       reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR0);
-       reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
-                       IOP13XX_ATU_OUMBAR_FUNC_NUM);
-       reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
-       __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR0);
-
-       reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR1);
-       reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
-                       IOP13XX_ATU_OUMBAR_FUNC_NUM);
-       reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
-       __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR1);
-
-       reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR2);
-       reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
-                       IOP13XX_ATU_OUMBAR_FUNC_NUM);
-       reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
-       __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR2);
-
-       reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR3);
-       reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
-                       IOP13XX_ATU_OUMBAR_FUNC_NUM);
-       reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
-       __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR3);
-
-       /* Enable inbound and outbound cycles
-        */
-       reg_val = __raw_readw(IOP13XX_ATUE_ATUCMD);
-       reg_val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
-                       PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
-       __raw_writew(reg_val, IOP13XX_ATUE_ATUCMD);
-
-       reg_val = __raw_readl(IOP13XX_ATUE_ATUCR);
-       reg_val |= IOP13XX_ATUE_ATUCR_OUT_EN |
-                       IOP13XX_ATUE_ATUCR_IVM;
-       __raw_writel(reg_val, IOP13XX_ATUE_ATUCR);
-}
-
-void __init iop13xx_atue_disable(void)
-{
-       u32 reg_val;
-
-       __raw_writew(0x0, IOP13XX_ATUE_ATUCMD);
-       __raw_writel(IOP13XX_ATUE_ATUCR_IVM, IOP13XX_ATUE_ATUCR);
-
-       /* wait for cycles to quiesce */
-       while (__raw_readl(IOP13XX_ATUE_PCSR) & (IOP13XX_ATUE_PCSR_OUT_Q_BUSY |
-                                            IOP13XX_ATUE_PCSR_IN_Q_BUSY |
-                                            IOP13XX_ATUE_PCSR_LLRB_BUSY))
-               cpu_relax();
-
-       /* BAR 0 ( Disabled ) */
-       __raw_writel(0x0, IOP13XX_ATUE_IAUBAR0);
-       __raw_writel(0x0, IOP13XX_ATUE_IABAR0);
-       __raw_writel(0x0, IOP13XX_ATUE_IAUTVR0);
-       __raw_writel(0x0, IOP13XX_ATUE_IATVR0);
-       __raw_writel(0x0, IOP13XX_ATUE_IALR0);
-       reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR0);
-       reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE;
-       __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR0);
-
-       /* BAR 1 ( Disabled ) */
-       __raw_writel(0x0, IOP13XX_ATUE_IAUBAR1);
-       __raw_writel(0x0, IOP13XX_ATUE_IABAR1);
-       __raw_writel(0x0, IOP13XX_ATUE_IAUTVR1);
-       __raw_writel(0x0, IOP13XX_ATUE_IATVR1);
-       __raw_writel(0x0, IOP13XX_ATUE_IALR1);
-       reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR1);
-       reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE;
-       __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR1);
-
-       /* BAR 2 ( Disabled ) */
-       __raw_writel(0x0, IOP13XX_ATUE_IAUBAR2);
-       __raw_writel(0x0, IOP13XX_ATUE_IABAR2);
-       __raw_writel(0x0, IOP13XX_ATUE_IAUTVR2);
-       __raw_writel(0x0, IOP13XX_ATUE_IATVR2);
-       __raw_writel(0x0, IOP13XX_ATUE_IALR2);
-       reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR2);
-       reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE;
-       __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR2);
-
-       /* BAR 3 ( Disabled ) */
-       reg_val = __raw_readl(IOP13XX_ATUE_OUMBAR3);
-       reg_val &= ~IOP13XX_ATUE_OUMBAR_ENABLE;
-       __raw_writel(reg_val, IOP13XX_ATUE_OUMBAR3);
-
-       /* Setup the I/O Bar
-        * A[35-16] in 31-12
-        */
-       __raw_writel((IOP13XX_PCIE_LOWER_IO_PA >> 0x4) & 0xfffff000,
-                       IOP13XX_ATUE_OIOBAR);
-       __raw_writel(IOP13XX_PCIE_LOWER_IO_BA, IOP13XX_ATUE_OIOWTVR);
-}
-
-/* This function is called from iop13xx_pci_init() after assigning valid
- * values to iop13xx_atux_pmmr_offset.  This is the location for common
- * setup of ATUX for all IOP13XX implementations.
- */
-void __init iop13xx_atux_setup(void)
-{
-       u32 reg_val;
-       int func = iop13xx_atu_function(IOP13XX_INIT_ATU_ATUX);
-
-       /* Take PCI-X bus out of reset if bootloader hasn't already.
-        * According to spec, we should wait for 2^25 PCI clocks to meet
-        * the PCI timing parameter Trhfa (RST# high to first access).
-        * This is rarely necessary and often ignored.
-        */
-       reg_val = __raw_readl(IOP13XX_ATUX_PCSR);
-       if (reg_val & IOP13XX_ATUX_PCSR_P_RSTOUT) {
-               int msec = (reg_val >> IOP13XX_ATUX_PCSR_FREQ_OFFSET) & 0x7;
-               msec = 1000 / (8-msec); /* bits 100=133MHz, 111=>33MHz */
-               __raw_writel(reg_val & ~IOP13XX_ATUX_PCSR_P_RSTOUT,
-                               IOP13XX_ATUX_PCSR);
-               atux_trhfa_timeout = jiffies + msecs_to_jiffies(msec);
-       }
-       else
-               atux_trhfa_timeout = jiffies;
-
-#ifdef CONFIG_PCI_MSI
-       /* BAR 0 (inbound msi window) */
-       __raw_writel(IOP13XX_MU_BASE_PHYS, IOP13XX_MU_MUBAR);
-       __raw_writel(~(IOP13XX_MU_WINDOW_SIZE - 1), IOP13XX_ATUX_IALR0);
-       __raw_writel(IOP13XX_MU_BASE_PHYS, IOP13XX_ATUX_IATVR0);
-       __raw_writel(IOP13XX_MU_BASE_PCI, IOP13XX_ATUX_IABAR0);
-#endif
-
-       /* BAR 1 (1:1 mapping with Physical RAM) */
-       /* Set limit and enable */
-       __raw_writel(~(IOP13XX_MAX_RAM_SIZE - PHYS_OFFSET - 1) & ~0x1,
-                       IOP13XX_ATUX_IALR1);
-       __raw_writel(0x0, IOP13XX_ATUX_IAUBAR1);
-
-       /* Set base at the top of the reserved address space */
-       __raw_writel(PHYS_OFFSET | PCI_BASE_ADDRESS_MEM_TYPE_64 |
-                       PCI_BASE_ADDRESS_MEM_PREFETCH, IOP13XX_ATUX_IABAR1);
-
-       /* 1:1 mapping with physical ram
-        * (leave big endian byte swap disabled)
-        */
-       __raw_writel(0x0, IOP13XX_ATUX_IAUTVR1);
-       __raw_writel(PHYS_OFFSET, IOP13XX_ATUX_IATVR1);
-
-       /* Outbound window 1 (PCIX/PCIE memory window) */
-       /* 32 bit Address Space */
-       __raw_writel(0x0, IOP13XX_ATUX_OUMWTVR1);
-       /* PA[35:32] */
-       __raw_writel(IOP13XX_ATUX_OUMBAR_ENABLE |
-                       IOP13XX_PCIX_MEM_PHYS_OFFSET >> 32,
-                       IOP13XX_ATUX_OUMBAR1);
-
-       /* Setup the I/O Bar
-        * A[35-16] in 31-12
-        */
-       __raw_writel((IOP13XX_PCIX_LOWER_IO_PA >> 0x4) & 0xfffff000,
-               IOP13XX_ATUX_OIOBAR);
-       __raw_writel(IOP13XX_PCIX_LOWER_IO_BA, IOP13XX_ATUX_OIOWTVR);
-
-       /* clear startup errors */
-       iop13xx_atux_pci_status(1);
-
-       /* OIOBAR function number
-        */
-       reg_val = __raw_readl(IOP13XX_ATUX_OIOBAR);
-       reg_val &= ~0x7;
-       reg_val |= func;
-       __raw_writel(reg_val, IOP13XX_ATUX_OIOBAR);
-
-       /* OUMBAR function numbers
-        */
-       reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR0);
-       reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
-                       IOP13XX_ATU_OUMBAR_FUNC_NUM);
-       reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
-       __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR0);
-
-       reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR1);
-       reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
-                       IOP13XX_ATU_OUMBAR_FUNC_NUM);
-       reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
-       __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR1);
-
-       reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR2);
-       reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
-                       IOP13XX_ATU_OUMBAR_FUNC_NUM);
-       reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
-       __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR2);
-
-       reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR3);
-       reg_val &= ~(IOP13XX_ATU_OUMBAR_FUNC_NUM_MASK <<
-                       IOP13XX_ATU_OUMBAR_FUNC_NUM);
-       reg_val |= func << IOP13XX_ATU_OUMBAR_FUNC_NUM;
-       __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR3);
-
-       /* Enable inbound and outbound cycles
-        */
-       reg_val = __raw_readw(IOP13XX_ATUX_ATUCMD);
-       reg_val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
-                       PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
-       __raw_writew(reg_val, IOP13XX_ATUX_ATUCMD);
-
-       reg_val = __raw_readl(IOP13XX_ATUX_ATUCR);
-       reg_val |= IOP13XX_ATUX_ATUCR_OUT_EN;
-       __raw_writel(reg_val, IOP13XX_ATUX_ATUCR);
-}
-
-void __init iop13xx_atux_disable(void)
-{
-       u32 reg_val;
-
-       __raw_writew(0x0, IOP13XX_ATUX_ATUCMD);
-       __raw_writel(0x0, IOP13XX_ATUX_ATUCR);
-
-       /* wait for cycles to quiesce */
-       while (__raw_readl(IOP13XX_ATUX_PCSR) & (IOP13XX_ATUX_PCSR_OUT_Q_BUSY |
-                                    IOP13XX_ATUX_PCSR_IN_Q_BUSY))
-               cpu_relax();
-
-       /* BAR 0 ( Disabled ) */
-       __raw_writel(0x0, IOP13XX_ATUX_IAUBAR0);
-       __raw_writel(0x0, IOP13XX_ATUX_IABAR0);
-       __raw_writel(0x0, IOP13XX_ATUX_IAUTVR0);
-       __raw_writel(0x0, IOP13XX_ATUX_IATVR0);
-       __raw_writel(0x0, IOP13XX_ATUX_IALR0);
-       reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR0);
-       reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE;
-       __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR0);
-
-       /* BAR 1 ( Disabled ) */
-       __raw_writel(0x0, IOP13XX_ATUX_IAUBAR1);
-       __raw_writel(0x0, IOP13XX_ATUX_IABAR1);
-       __raw_writel(0x0, IOP13XX_ATUX_IAUTVR1);
-       __raw_writel(0x0, IOP13XX_ATUX_IATVR1);
-       __raw_writel(0x0, IOP13XX_ATUX_IALR1);
-       reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR1);
-       reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE;
-       __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR1);
-
-       /* BAR 2 ( Disabled ) */
-       __raw_writel(0x0, IOP13XX_ATUX_IAUBAR2);
-       __raw_writel(0x0, IOP13XX_ATUX_IABAR2);
-       __raw_writel(0x0, IOP13XX_ATUX_IAUTVR2);
-       __raw_writel(0x0, IOP13XX_ATUX_IATVR2);
-       __raw_writel(0x0, IOP13XX_ATUX_IALR2);
-       reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR2);
-       reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE;
-       __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR2);
-
-       /* BAR 3 ( Disabled ) */
-       __raw_writel(0x0, IOP13XX_ATUX_IAUBAR3);
-       __raw_writel(0x0, IOP13XX_ATUX_IABAR3);
-       __raw_writel(0x0, IOP13XX_ATUX_IAUTVR3);
-       __raw_writel(0x0, IOP13XX_ATUX_IATVR3);
-       __raw_writel(0x0, IOP13XX_ATUX_IALR3);
-       reg_val = __raw_readl(IOP13XX_ATUX_OUMBAR3);
-       reg_val &= ~IOP13XX_ATUX_OUMBAR_ENABLE;
-       __raw_writel(reg_val, IOP13XX_ATUX_OUMBAR3);
-
-       /* Setup the I/O Bar
-       * A[35-16] in 31-12
-       */
-       __raw_writel((IOP13XX_PCIX_LOWER_IO_PA >> 0x4) & 0xfffff000,
-                       IOP13XX_ATUX_OIOBAR);
-       __raw_writel(IOP13XX_PCIX_LOWER_IO_BA, IOP13XX_ATUX_OIOWTVR);
-}
-
-void __init iop13xx_set_atu_mmr_bases(void)
-{
-       /* Based on ESSR0, determine the ATU X/E offsets */
-       switch(__raw_readl(IOP13XX_ESSR0) &
-               (IOP13XX_CONTROLLER_ONLY | IOP13XX_INTERFACE_SEL_PCIX)) {
-       /* both asserted */
-       case 0:
-               iop13xx_atux_pmmr_offset = IOP13XX_ATU1_PMMR_OFFSET;
-               iop13xx_atue_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET;
-               break;
-       /* IOP13XX_CONTROLLER_ONLY = deasserted
-        * IOP13XX_INTERFACE_SEL_PCIX = asserted
-        */
-       case IOP13XX_CONTROLLER_ONLY:
-               iop13xx_atux_pmmr_offset = IOP13XX_ATU0_PMMR_OFFSET;
-               iop13xx_atue_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET;
-               break;
-       /* IOP13XX_CONTROLLER_ONLY = asserted
-        * IOP13XX_INTERFACE_SEL_PCIX = deasserted
-        */
-       case IOP13XX_INTERFACE_SEL_PCIX:
-               iop13xx_atux_pmmr_offset = IOP13XX_ATU1_PMMR_OFFSET;
-               iop13xx_atue_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET;
-               break;
-       /* both deasserted */
-       case IOP13XX_CONTROLLER_ONLY | IOP13XX_INTERFACE_SEL_PCIX:
-               iop13xx_atux_pmmr_offset = IOP13XX_ATU2_PMMR_OFFSET;
-               iop13xx_atue_pmmr_offset = IOP13XX_ATU0_PMMR_OFFSET;
-               break;
-       default:
-               BUG();
-       }
-}
-
-void __init iop13xx_atu_select(struct hw_pci *plat_pci)
-{
-       int i;
-
-       /* set system defaults
-        * note: if "iop13xx_init_atu=" is specified this autodetect
-        * sequence will be bypassed
-        */
-       if (init_atu == IOP13XX_INIT_ATU_DEFAULT) {
-               /* check for single/dual interface */
-               if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX) {
-                       /* ATUE must be present check the device id
-                        * to see if ATUX is present.
-                        */
-                       init_atu |= IOP13XX_INIT_ATU_ATUE;
-                       switch (__raw_readw(IOP13XX_ATUE_DID) & 0xf0) {
-                       case 0x70:
-                       case 0x80:
-                       case 0xc0:
-                               init_atu |= IOP13XX_INIT_ATU_ATUX;
-                               break;
-                       }
-               } else {
-                       /* ATUX must be present check the device id
-                        * to see if ATUE is present.
-                        */
-                       init_atu |= IOP13XX_INIT_ATU_ATUX;
-                       switch (__raw_readw(IOP13XX_ATUX_DID) & 0xf0) {
-                       case 0x70:
-                       case 0x80:
-                       case 0xc0:
-                               init_atu |= IOP13XX_INIT_ATU_ATUE;
-                               break;
-                       }
-               }
-
-               /* check central resource and root complex capability */
-               if (init_atu & IOP13XX_INIT_ATU_ATUX)
-                       if (!(__raw_readl(IOP13XX_ATUX_PCSR) &
-                               IOP13XX_ATUX_PCSR_CENTRAL_RES))
-                               init_atu &= ~IOP13XX_INIT_ATU_ATUX;
-
-               if (init_atu & IOP13XX_INIT_ATU_ATUE)
-                       if (__raw_readl(IOP13XX_ATUE_PCSR) &
-                               IOP13XX_ATUE_PCSR_END_POINT)
-                               init_atu &= ~IOP13XX_INIT_ATU_ATUE;
-       }
-
-       for (i = 0; i < 2; i++) {
-               if((init_atu & (1 << i)) == (1 << i))
-                       plat_pci->nr_controllers++;
-       }
-}
-
-void __init iop13xx_pci_init(void)
-{
-       /* clear pre-existing south bridge errors */
-       __raw_writel(__raw_readl(IOP13XX_XBG_BECSR) & 3, IOP13XX_XBG_BECSR);
-
-       /* Setup the Min Address for PCI memory... */
-       pcibios_min_mem = IOP13XX_PCIX_LOWER_MEM_BA;
-
-       /* if Linux is given control of an ATU
-        * clear out its prior configuration,
-        * otherwise do not touch the registers
-        */
-       if (init_atu & IOP13XX_INIT_ATU_ATUE) {
-               iop13xx_atue_disable();
-               iop13xx_atue_setup();
-       }
-
-       if (init_atu & IOP13XX_INIT_ATU_ATUX) {
-               iop13xx_atux_disable();
-               iop13xx_atux_setup();
-       }
-
-       hook_fault_code(16+6, iop13xx_pci_abort, SIGBUS, 0,
-                       "imprecise external abort");
-}
-
-/* initialize the pci memory space.  handle any combination of
- * atue and atux enabled/disabled
- */
-int iop13xx_pci_setup(int nr, struct pci_sys_data *sys)
-{
-       struct resource *res;
-       int which_atu;
-       u32 pcixsr, pcsr;
-
-       if (nr > 1)
-               return 0;
-
-       res = kzalloc(sizeof(struct resource), GFP_KERNEL);
-       if (!res)
-               panic("PCI: unable to alloc resources");
-
-
-       /* 'nr' assumptions:
-        * ATUX is always 0
-        * ATUE is 1 when ATUX is also enabled
-        * ATUE is 0 when ATUX is disabled
-        */
-       switch(init_atu) {
-       case IOP13XX_INIT_ATU_ATUX:
-               which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUX;
-               break;
-       case IOP13XX_INIT_ATU_ATUE:
-               which_atu = nr ? 0 : IOP13XX_INIT_ATU_ATUE;
-               break;
-       case (IOP13XX_INIT_ATU_ATUX | IOP13XX_INIT_ATU_ATUE):
-               which_atu = nr ? IOP13XX_INIT_ATU_ATUE : IOP13XX_INIT_ATU_ATUX;
-               break;
-       default:
-               which_atu = 0;
-       }
-
-       if (!which_atu) {
-               kfree(res);
-               return 0;
-       }
-
-       switch(which_atu) {
-       case IOP13XX_INIT_ATU_ATUX:
-               pcixsr = __raw_readl(IOP13XX_ATUX_PCIXSR);
-               pcixsr &= ~0xffff;
-               pcixsr |= sys->busnr << IOP13XX_ATUX_PCIXSR_BUS_NUM |
-                         0 << IOP13XX_ATUX_PCIXSR_DEV_NUM |
-                         iop13xx_atu_function(IOP13XX_INIT_ATU_ATUX)
-                                 << IOP13XX_ATUX_PCIXSR_FUNC_NUM;
-               __raw_writel(pcixsr, IOP13XX_ATUX_PCIXSR);
-
-               pci_ioremap_io(0, IOP13XX_PCIX_LOWER_IO_PA);
-
-               res->start = IOP13XX_PCIX_LOWER_MEM_RA;
-               res->end   = IOP13XX_PCIX_UPPER_MEM_RA;
-               res->name  = "IQ81340 ATUX PCI Memory Space";
-               res->flags = IORESOURCE_MEM;
-               sys->mem_offset = IOP13XX_PCIX_MEM_OFFSET;
-               break;
-       case IOP13XX_INIT_ATU_ATUE:
-               /* Note: the function number field in the PCSR is ro */
-               pcsr = __raw_readl(IOP13XX_ATUE_PCSR);
-               pcsr &= ~(0xfff8 << 16);
-               pcsr |= sys->busnr << IOP13XX_ATUE_PCSR_BUS_NUM |
-                               0 << IOP13XX_ATUE_PCSR_DEV_NUM;
-
-               __raw_writel(pcsr, IOP13XX_ATUE_PCSR);
-
-               pci_ioremap_io(SZ_64K, IOP13XX_PCIE_LOWER_IO_PA);
-
-               res->start = IOP13XX_PCIE_LOWER_MEM_RA;
-               res->end   = IOP13XX_PCIE_UPPER_MEM_RA;
-               res->name  = "IQ81340 ATUE PCI Memory Space";
-               res->flags = IORESOURCE_MEM;
-               sys->mem_offset = IOP13XX_PCIE_MEM_OFFSET;
-               sys->map_irq = iop13xx_pcie_map_irq;
-               break;
-       default:
-               kfree(res);
-               return 0;
-       }
-
-       request_resource(&iomem_resource, res);
-
-       pci_add_resource_offset(&sys->resources, res, sys->mem_offset);
-
-       return 1;
-}
-
-u16 iop13xx_dev_id(void)
-{
-       if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
-               return __raw_readw(IOP13XX_ATUE_DID);
-       else
-               return __raw_readw(IOP13XX_ATUX_DID);
-}
-
-static int __init iop13xx_init_atu_setup(char *str)
-{
-        init_atu = IOP13XX_INIT_ATU_NONE;
-        if (str) {
-                while (*str != '\0') {
-                        switch (*str) {
-                        case 'x':
-                        case 'X':
-                                init_atu |= IOP13XX_INIT_ATU_ATUX;
-                                init_atu &= ~IOP13XX_INIT_ATU_NONE;
-                                break;
-                        case 'e':
-                        case 'E':
-                                init_atu |= IOP13XX_INIT_ATU_ATUE;
-                                init_atu &= ~IOP13XX_INIT_ATU_NONE;
-                                break;
-                        case ',':
-                        case '=':
-                                break;
-                        default:
-                                PRINTK("\"iop13xx_init_atu\" malformed at "
-                                            "character: \'%c\'", *str);
-                                *(str + 1) = '\0';
-                                init_atu = IOP13XX_INIT_ATU_DEFAULT;
-                        }
-                        str++;
-                }
-        }
-        return 1;
-}
-
-__setup("iop13xx_init_atu", iop13xx_init_atu_setup);
diff --git a/arch/arm/mach-iop13xx/pci.h b/arch/arm/mach-iop13xx/pci.h
deleted file mode 100644 (file)
index 736168d..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _IOP13XX_PCI_H_
-#define _IOP13XX_PCI_H_
-#include <linux/io.h>
-#include <mach/irqs.h>
-
-#include <linux/types.h>
-
-extern void __iomem *iop13xx_atue_mem_base;
-extern void __iomem *iop13xx_atux_mem_base;
-extern size_t iop13xx_atue_mem_size;
-extern size_t iop13xx_atux_mem_size;
-
-struct pci_sys_data;
-struct pci_host_bridge;
-struct hw_pci;
-int iop13xx_pci_setup(int nr, struct pci_sys_data *sys);
-int iop13xx_scan_bus(int nr, struct pci_host_bridge *bridge);
-void iop13xx_atu_select(struct hw_pci *plat_pci);
-void iop13xx_pci_init(void);
-void iop13xx_map_pci_memory(void);
-
-#define IOP_PCI_STATUS_ERROR (PCI_STATUS_PARITY |           \
-                              PCI_STATUS_SIG_TARGET_ABORT | \
-                              PCI_STATUS_REC_TARGET_ABORT | \
-                              PCI_STATUS_REC_TARGET_ABORT | \
-                              PCI_STATUS_REC_MASTER_ABORT | \
-                              PCI_STATUS_SIG_SYSTEM_ERROR | \
-                              PCI_STATUS_DETECTED_PARITY)
-
-#define IOP13XX_ATUE_ATUISR_ERROR (IOP13XX_ATUE_STAT_HALT_ON_ERROR |  \
-                                   IOP13XX_ATUE_STAT_ROOT_SYS_ERR |   \
-                                   IOP13XX_ATUE_STAT_PCI_IFACE_ERR |  \
-                                   IOP13XX_ATUE_STAT_ERR_COR |        \
-                                   IOP13XX_ATUE_STAT_ERR_UNCOR |      \
-                                   IOP13XX_ATUE_STAT_CRS |            \
-                                   IOP13XX_ATUE_STAT_DET_PAR_ERR |    \
-                                   IOP13XX_ATUE_STAT_EXT_REC_MABORT | \
-                                   IOP13XX_ATUE_STAT_SIG_TABORT |     \
-                                   IOP13XX_ATUE_STAT_EXT_REC_TABORT | \
-                                   IOP13XX_ATUE_STAT_MASTER_DATA_PAR)
-
-#define IOP13XX_ATUX_ATUISR_ERROR (IOP13XX_ATUX_STAT_TX_SCEM |        \
-                                   IOP13XX_ATUX_STAT_REC_SCEM |       \
-                                   IOP13XX_ATUX_STAT_TX_SERR |        \
-                                   IOP13XX_ATUX_STAT_DET_PAR_ERR |    \
-                                   IOP13XX_ATUX_STAT_INT_REC_MABORT | \
-                                   IOP13XX_ATUX_STAT_REC_SERR |       \
-                                   IOP13XX_ATUX_STAT_EXT_REC_MABORT | \
-                                   IOP13XX_ATUX_STAT_EXT_REC_TABORT | \
-                                   IOP13XX_ATUX_STAT_EXT_SIG_TABORT | \
-                                   IOP13XX_ATUX_STAT_MASTER_DATA_PAR)
-
-/* PCI interrupts
- */
-#define ATUX_INTA IRQ_IOP13XX_XINT0
-#define ATUX_INTB IRQ_IOP13XX_XINT1
-#define ATUX_INTC IRQ_IOP13XX_XINT2
-#define ATUX_INTD IRQ_IOP13XX_XINT3
-
-#define ATUE_INTA IRQ_IOP13XX_ATUE_IMA
-#define ATUE_INTB IRQ_IOP13XX_ATUE_IMB
-#define ATUE_INTC IRQ_IOP13XX_ATUE_IMC
-#define ATUE_INTD IRQ_IOP13XX_ATUE_IMD
-
-#endif /* _IOP13XX_PCI_H_ */
diff --git a/arch/arm/mach-iop13xx/setup.c b/arch/arm/mach-iop13xx/setup.c
deleted file mode 100644 (file)
index c5c84c9..0000000
+++ /dev/null
@@ -1,595 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * iop13xx platform Initialization
- * Copyright (c) 2005-2006, Intel Corporation.
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/serial_8250.h>
-#include <linux/io.h>
-#include <linux/reboot.h>
-#ifdef CONFIG_MTD_PHYSMAP
-#include <linux/mtd/physmap.h>
-#endif
-#include <asm/mach/map.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/hardware/iop_adma.h>
-#include <mach/irqs.h>
-
-#define IOP13XX_UART_XTAL 33334000
-#define IOP13XX_SETUP_DEBUG 0
-#define PRINTK(x...) ((void)(IOP13XX_SETUP_DEBUG && printk(x)))
-
-/* Standard IO mapping for all IOP13XX based systems
- */
-static struct map_desc iop13xx_std_desc[] __initdata = {
-       {    /* mem mapped registers */
-               .virtual = (unsigned long)IOP13XX_PMMR_VIRT_MEM_BASE,
-               .pfn     = __phys_to_pfn(IOP13XX_PMMR_PHYS_MEM_BASE),
-               .length  = IOP13XX_PMMR_SIZE,
-               .type    = MT_DEVICE,
-       },
-};
-
-static struct resource iop13xx_uart0_resources[] = {
-       [0] = {
-               .start = IOP13XX_UART0_PHYS,
-               .end = IOP13XX_UART0_PHYS + 0x3f,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP13XX_UART0,
-               .end = IRQ_IOP13XX_UART0,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct resource iop13xx_uart1_resources[] = {
-       [0] = {
-               .start = IOP13XX_UART1_PHYS,
-               .end = IOP13XX_UART1_PHYS + 0x3f,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP13XX_UART1,
-               .end = IRQ_IOP13XX_UART1,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct plat_serial8250_port iop13xx_uart0_data[] = {
-       {
-       .membase     = IOP13XX_UART0_VIRT,
-       .mapbase     = IOP13XX_UART0_PHYS,
-       .irq         = IRQ_IOP13XX_UART0,
-       .uartclk     = IOP13XX_UART_XTAL,
-       .regshift    = 2,
-       .iotype      = UPIO_MEM,
-       .flags       = UPF_SKIP_TEST,
-       },
-       {  },
-};
-
-static struct plat_serial8250_port iop13xx_uart1_data[] = {
-       {
-       .membase     = IOP13XX_UART1_VIRT,
-       .mapbase     = IOP13XX_UART1_PHYS,
-       .irq         = IRQ_IOP13XX_UART1,
-       .uartclk     = IOP13XX_UART_XTAL,
-       .regshift    = 2,
-       .iotype      = UPIO_MEM,
-       .flags       = UPF_SKIP_TEST,
-       },
-       {  },
-};
-
-/* The ids are fixed up later in iop13xx_platform_init */
-static struct platform_device iop13xx_uart0 = {
-       .name = "serial8250",
-       .id = 0,
-       .dev.platform_data = iop13xx_uart0_data,
-       .num_resources = 2,
-       .resource = iop13xx_uart0_resources,
-};
-
-static struct platform_device iop13xx_uart1 = {
-       .name = "serial8250",
-       .id = 0,
-       .dev.platform_data = iop13xx_uart1_data,
-       .num_resources = 2,
-       .resource = iop13xx_uart1_resources
-};
-
-static struct resource iop13xx_i2c_0_resources[] = {
-       [0] = {
-               .start = IOP13XX_I2C0_PHYS,
-               .end = IOP13XX_I2C0_PHYS + 0x18,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP13XX_I2C_0,
-               .end = IRQ_IOP13XX_I2C_0,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct resource iop13xx_i2c_1_resources[] = {
-       [0] = {
-               .start = IOP13XX_I2C1_PHYS,
-               .end = IOP13XX_I2C1_PHYS + 0x18,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP13XX_I2C_1,
-               .end = IRQ_IOP13XX_I2C_1,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct resource iop13xx_i2c_2_resources[] = {
-       [0] = {
-               .start = IOP13XX_I2C2_PHYS,
-               .end = IOP13XX_I2C2_PHYS + 0x18,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP13XX_I2C_2,
-               .end = IRQ_IOP13XX_I2C_2,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-/* I2C controllers. The IOP13XX uses the same block as the IOP3xx, so
- * we just use the same device name.
- */
-
-/* The ids are fixed up later in iop13xx_platform_init */
-static struct platform_device iop13xx_i2c_0_controller = {
-       .name = "IOP3xx-I2C",
-       .id = 0,
-       .num_resources = 2,
-       .resource = iop13xx_i2c_0_resources
-};
-
-static struct platform_device iop13xx_i2c_1_controller = {
-       .name = "IOP3xx-I2C",
-       .id = 0,
-       .num_resources = 2,
-       .resource = iop13xx_i2c_1_resources
-};
-
-static struct platform_device iop13xx_i2c_2_controller = {
-       .name = "IOP3xx-I2C",
-       .id = 0,
-       .num_resources = 2,
-       .resource = iop13xx_i2c_2_resources
-};
-
-#ifdef CONFIG_MTD_PHYSMAP
-/* PBI Flash Device
- */
-static struct physmap_flash_data iq8134x_flash_data = {
-       .width = 2,
-};
-
-static struct resource iq8134x_flash_resource = {
-       .start = IQ81340_FLASHBASE,
-       .end   = 0,
-       .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device iq8134x_flash = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = { .platform_data  = &iq8134x_flash_data, },
-       .num_resources  = 1,
-       .resource       = &iq8134x_flash_resource,
-};
-
-static unsigned long iq8134x_probe_flash_size(void)
-{
-       uint8_t __iomem *flash_addr = ioremap(IQ81340_FLASHBASE, PAGE_SIZE);
-       int i;
-       char query[3];
-       unsigned long size = 0;
-       int width = iq8134x_flash_data.width;
-
-       if (flash_addr) {
-               /* send CFI 'query' command */
-               writew(0x98, flash_addr);
-
-               /* check for CFI compliance */
-               for (i = 0; i < 3 * width; i += width)
-                       query[i / width] = readb(flash_addr + (0x10 * width) + i);
-
-               /* read the size */
-               if (memcmp(query, "QRY", 3) == 0)
-                       size = 1 << readb(flash_addr + (0x27 * width));
-
-               /* send CFI 'read array' command */
-               writew(0xff, flash_addr);
-
-               iounmap(flash_addr);
-       }
-
-       return size;
-}
-#endif
-
-/* ADMA Channels */
-static struct resource iop13xx_adma_0_resources[] = {
-       [0] = {
-               .start = IOP13XX_ADMA_PHYS_BASE(0),
-               .end = IOP13XX_ADMA_UPPER_PA(0),
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP13XX_ADMA0_EOT,
-               .end = IRQ_IOP13XX_ADMA0_EOT,
-               .flags = IORESOURCE_IRQ
-       },
-       [2] = {
-               .start = IRQ_IOP13XX_ADMA0_EOC,
-               .end = IRQ_IOP13XX_ADMA0_EOC,
-               .flags = IORESOURCE_IRQ
-       },
-       [3] = {
-               .start = IRQ_IOP13XX_ADMA0_ERR,
-               .end = IRQ_IOP13XX_ADMA0_ERR,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct resource iop13xx_adma_1_resources[] = {
-       [0] = {
-               .start = IOP13XX_ADMA_PHYS_BASE(1),
-               .end = IOP13XX_ADMA_UPPER_PA(1),
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP13XX_ADMA1_EOT,
-               .end = IRQ_IOP13XX_ADMA1_EOT,
-               .flags = IORESOURCE_IRQ
-       },
-       [2] = {
-               .start = IRQ_IOP13XX_ADMA1_EOC,
-               .end = IRQ_IOP13XX_ADMA1_EOC,
-               .flags = IORESOURCE_IRQ
-       },
-       [3] = {
-               .start = IRQ_IOP13XX_ADMA1_ERR,
-               .end = IRQ_IOP13XX_ADMA1_ERR,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct resource iop13xx_adma_2_resources[] = {
-       [0] = {
-               .start = IOP13XX_ADMA_PHYS_BASE(2),
-               .end = IOP13XX_ADMA_UPPER_PA(2),
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_IOP13XX_ADMA2_EOT,
-               .end = IRQ_IOP13XX_ADMA2_EOT,
-               .flags = IORESOURCE_IRQ
-       },
-       [2] = {
-               .start = IRQ_IOP13XX_ADMA2_EOC,
-               .end = IRQ_IOP13XX_ADMA2_EOC,
-               .flags = IORESOURCE_IRQ
-       },
-       [3] = {
-               .start = IRQ_IOP13XX_ADMA2_ERR,
-               .end = IRQ_IOP13XX_ADMA2_ERR,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static u64 iop13xx_adma_dmamask = DMA_BIT_MASK(32);
-static struct iop_adma_platform_data iop13xx_adma_0_data = {
-       .hw_id = 0,
-       .pool_size = PAGE_SIZE,
-};
-
-static struct iop_adma_platform_data iop13xx_adma_1_data = {
-       .hw_id = 1,
-       .pool_size = PAGE_SIZE,
-};
-
-static struct iop_adma_platform_data iop13xx_adma_2_data = {
-       .hw_id = 2,
-       .pool_size = PAGE_SIZE,
-};
-
-/* The ids are fixed up later in iop13xx_platform_init */
-static struct platform_device iop13xx_adma_0_channel = {
-       .name = "iop-adma",
-       .id = 0,
-       .num_resources = 4,
-       .resource = iop13xx_adma_0_resources,
-       .dev = {
-               .dma_mask = &iop13xx_adma_dmamask,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-               .platform_data = (void *) &iop13xx_adma_0_data,
-       },
-};
-
-static struct platform_device iop13xx_adma_1_channel = {
-       .name = "iop-adma",
-       .id = 0,
-       .num_resources = 4,
-       .resource = iop13xx_adma_1_resources,
-       .dev = {
-               .dma_mask = &iop13xx_adma_dmamask,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-               .platform_data = (void *) &iop13xx_adma_1_data,
-       },
-};
-
-static struct platform_device iop13xx_adma_2_channel = {
-       .name = "iop-adma",
-       .id = 0,
-       .num_resources = 4,
-       .resource = iop13xx_adma_2_resources,
-       .dev = {
-               .dma_mask = &iop13xx_adma_dmamask,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-               .platform_data = (void *) &iop13xx_adma_2_data,
-       },
-};
-
-void __init iop13xx_map_io(void)
-{
-       /* Initialize the Static Page Table maps */
-       iotable_init(iop13xx_std_desc, ARRAY_SIZE(iop13xx_std_desc));
-}
-
-static int init_uart;
-static int init_i2c;
-static int init_adma;
-
-void __init iop13xx_platform_init(void)
-{
-       int i;
-       u32 uart_idx, i2c_idx, adma_idx, plat_idx;
-       struct platform_device *iop13xx_devices[IQ81340_MAX_PLAT_DEVICES];
-
-       /* set the bases so we can read the device id */
-       iop13xx_set_atu_mmr_bases();
-
-       memset(iop13xx_devices, 0, sizeof(iop13xx_devices));
-
-       if (init_uart == IOP13XX_INIT_UART_DEFAULT) {
-               switch (iop13xx_dev_id()) {
-               /* enable both uarts on iop341 */
-               case 0x3380:
-               case 0x3384:
-               case 0x3388:
-               case 0x338c:
-                       init_uart |= IOP13XX_INIT_UART_0;
-                       init_uart |= IOP13XX_INIT_UART_1;
-                       break;
-               /* only enable uart 1 */
-               default:
-                       init_uart |= IOP13XX_INIT_UART_1;
-               }
-       }
-
-       if (init_i2c == IOP13XX_INIT_I2C_DEFAULT) {
-               switch (iop13xx_dev_id()) {
-               /* enable all i2c units on iop341 and iop342 */
-               case 0x3380:
-               case 0x3384:
-               case 0x3388:
-               case 0x338c:
-               case 0x3382:
-               case 0x3386:
-               case 0x338a:
-               case 0x338e:
-                       init_i2c |= IOP13XX_INIT_I2C_0;
-                       init_i2c |= IOP13XX_INIT_I2C_1;
-                       init_i2c |= IOP13XX_INIT_I2C_2;
-                       break;
-               /* only enable i2c 1 and 2 */
-               default:
-                       init_i2c |= IOP13XX_INIT_I2C_1;
-                       init_i2c |= IOP13XX_INIT_I2C_2;
-               }
-       }
-
-       if (init_adma == IOP13XX_INIT_ADMA_DEFAULT) {
-               init_adma |= IOP13XX_INIT_ADMA_0;
-               init_adma |= IOP13XX_INIT_ADMA_1;
-               init_adma |= IOP13XX_INIT_ADMA_2;
-       }
-
-       plat_idx = 0;
-       uart_idx = 0;
-       i2c_idx = 0;
-
-       /* uart 1 (if enabled) is ttyS0 */
-       if (init_uart & IOP13XX_INIT_UART_1) {
-               PRINTK("Adding uart1 to platform device list\n");
-               iop13xx_uart1.id = uart_idx++;
-               iop13xx_devices[plat_idx++] = &iop13xx_uart1;
-       }
-       if (init_uart & IOP13XX_INIT_UART_0) {
-               PRINTK("Adding uart0 to platform device list\n");
-               iop13xx_uart0.id = uart_idx++;
-               iop13xx_devices[plat_idx++] = &iop13xx_uart0;
-       }
-
-       for(i = 0; i < IQ81340_NUM_I2C; i++) {
-               if ((init_i2c & (1 << i)) && IOP13XX_SETUP_DEBUG)
-                       printk("Adding i2c%d to platform device list\n", i);
-               switch(init_i2c & (1 << i)) {
-               case IOP13XX_INIT_I2C_0:
-                       iop13xx_i2c_0_controller.id = i2c_idx++;
-                       iop13xx_devices[plat_idx++] =
-                               &iop13xx_i2c_0_controller;
-                       break;
-               case IOP13XX_INIT_I2C_1:
-                       iop13xx_i2c_1_controller.id = i2c_idx++;
-                       iop13xx_devices[plat_idx++] =
-                               &iop13xx_i2c_1_controller;
-                       break;
-               case IOP13XX_INIT_I2C_2:
-                       iop13xx_i2c_2_controller.id = i2c_idx++;
-                       iop13xx_devices[plat_idx++] =
-                               &iop13xx_i2c_2_controller;
-                       break;
-               }
-       }
-
-       /* initialize adma channel ids and capabilities */
-       adma_idx = 0;
-       for (i = 0; i < IQ81340_NUM_ADMA; i++) {
-               struct iop_adma_platform_data *plat_data;
-               if ((init_adma & (1 << i)) && IOP13XX_SETUP_DEBUG)
-                       printk(KERN_INFO
-                               "Adding adma%d to platform device list\n", i);
-               switch (init_adma & (1 << i)) {
-               case IOP13XX_INIT_ADMA_0:
-                       iop13xx_adma_0_channel.id = adma_idx++;
-                       iop13xx_devices[plat_idx++] = &iop13xx_adma_0_channel;
-                       plat_data = &iop13xx_adma_0_data;
-                       dma_cap_set(DMA_MEMCPY, plat_data->cap_mask);
-                       dma_cap_set(DMA_XOR, plat_data->cap_mask);
-                       dma_cap_set(DMA_XOR_VAL, plat_data->cap_mask);
-                       dma_cap_set(DMA_INTERRUPT, plat_data->cap_mask);
-                       break;
-               case IOP13XX_INIT_ADMA_1:
-                       iop13xx_adma_1_channel.id = adma_idx++;
-                       iop13xx_devices[plat_idx++] = &iop13xx_adma_1_channel;
-                       plat_data = &iop13xx_adma_1_data;
-                       dma_cap_set(DMA_MEMCPY, plat_data->cap_mask);
-                       dma_cap_set(DMA_XOR, plat_data->cap_mask);
-                       dma_cap_set(DMA_XOR_VAL, plat_data->cap_mask);
-                       dma_cap_set(DMA_INTERRUPT, plat_data->cap_mask);
-                       break;
-               case IOP13XX_INIT_ADMA_2:
-                       iop13xx_adma_2_channel.id = adma_idx++;
-                       iop13xx_devices[plat_idx++] = &iop13xx_adma_2_channel;
-                       plat_data = &iop13xx_adma_2_data;
-                       dma_cap_set(DMA_MEMCPY, plat_data->cap_mask);
-                       dma_cap_set(DMA_XOR, plat_data->cap_mask);
-                       dma_cap_set(DMA_XOR_VAL, plat_data->cap_mask);
-                       dma_cap_set(DMA_INTERRUPT, plat_data->cap_mask);
-                       dma_cap_set(DMA_PQ, plat_data->cap_mask);
-                       dma_cap_set(DMA_PQ_VAL, plat_data->cap_mask);
-                       break;
-               }
-       }
-
-#ifdef CONFIG_MTD_PHYSMAP
-       iq8134x_flash_resource.end = iq8134x_flash_resource.start +
-                               iq8134x_probe_flash_size() - 1;
-       if (iq8134x_flash_resource.end > iq8134x_flash_resource.start)
-               iop13xx_devices[plat_idx++] = &iq8134x_flash;
-       else
-               printk(KERN_ERR "%s: Failed to probe flash size\n", __func__);
-#endif
-
-       platform_add_devices(iop13xx_devices, plat_idx);
-}
-
-static int __init iop13xx_init_uart_setup(char *str)
-{
-       if (str) {
-               while (*str != '\0') {
-                       switch(*str) {
-                       case '0':
-                               init_uart |= IOP13XX_INIT_UART_0;
-                               break;
-                       case '1':
-                               init_uart |= IOP13XX_INIT_UART_1;
-                               break;
-                       case ',':
-                       case '=':
-                               break;
-                       default:
-                               PRINTK("\"iop13xx_init_uart\" malformed"
-                                           " at character: \'%c\'", *str);
-                               *(str + 1) = '\0';
-                               init_uart = IOP13XX_INIT_UART_DEFAULT;
-                       }
-                       str++;
-               }
-       }
-       return 1;
-}
-
-static int __init iop13xx_init_i2c_setup(char *str)
-{
-       if (str) {
-               while (*str != '\0') {
-                       switch(*str) {
-                       case '0':
-                               init_i2c |= IOP13XX_INIT_I2C_0;
-                               break;
-                       case '1':
-                               init_i2c |= IOP13XX_INIT_I2C_1;
-                               break;
-                       case '2':
-                               init_i2c |= IOP13XX_INIT_I2C_2;
-                               break;
-                       case ',':
-                       case '=':
-                               break;
-                       default:
-                               PRINTK("\"iop13xx_init_i2c\" malformed"
-                                           " at character: \'%c\'", *str);
-                               *(str + 1) = '\0';
-                               init_i2c = IOP13XX_INIT_I2C_DEFAULT;
-                       }
-                       str++;
-               }
-       }
-       return 1;
-}
-
-static int __init iop13xx_init_adma_setup(char *str)
-{
-       if (str)        {
-               while (*str != '\0') {
-                       switch (*str) {
-                       case '0':
-                               init_adma |= IOP13XX_INIT_ADMA_0;
-                               break;
-                       case '1':
-                               init_adma |= IOP13XX_INIT_ADMA_1;
-                               break;
-                       case '2':
-                               init_adma |= IOP13XX_INIT_ADMA_2;
-                               break;
-                       case ',':
-                       case '=':
-                               break;
-                       default:
-                               PRINTK("\"iop13xx_init_adma\" malformed"
-                                           " at character: \'%c\'", *str);
-                               *(str + 1) = '\0';
-                               init_adma = IOP13XX_INIT_ADMA_DEFAULT;
-                       }
-                       str++;
-               }
-       }
-       return 1;
-}
-
-__setup("iop13xx_init_adma", iop13xx_init_adma_setup);
-__setup("iop13xx_init_uart", iop13xx_init_uart_setup);
-__setup("iop13xx_init_i2c", iop13xx_init_i2c_setup);
-
-void iop13xx_restart(enum reboot_mode mode, const char *cmd)
-{
-       /*
-        * Reset the internal bus (warning both cores are reset)
-        */
-       write_wdtcr(IOP_WDTCR_EN_ARM);
-       write_wdtcr(IOP_WDTCR_EN);
-       write_wdtsr(IOP13XX_WDTSR_WRITE_EN | IOP13XX_WDTCR_IB_RESET);
-       write_wdtcr(0x1000);
-}
diff --git a/arch/arm/mach-iop13xx/tpmi.c b/arch/arm/mach-iop13xx/tpmi.c
deleted file mode 100644 (file)
index 4f91654..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * iop13xx tpmi device resources
- * Copyright (c) 2005-2006, Intel Corporation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/io.h>
-#include <asm/irq.h>
-#include <linux/sizes.h>
-#include <mach/irqs.h>
-
-/* assumes CONTROLLER_ONLY# is never asserted in the ESSR register */
-#define IOP13XX_TPMI_MMR(dev)  IOP13XX_REG_ADDR32_PHYS(0x48000 + (dev << 12))
-#define IOP13XX_TPMI_MEM(dev)  IOP13XX_REG_ADDR32_PHYS(0x60000 + (dev << 13))
-#define IOP13XX_TPMI_CTRL(dev) IOP13XX_REG_ADDR32_PHYS(0x50000 + (dev << 10))
-#define IOP13XX_TPMI_IOP_CTRL(dev) (IOP13XX_TPMI_CTRL(dev) + 0x2000)
-#define IOP13XX_TPMI_MMR_SIZE      (SZ_4K - 1)
-#define IOP13XX_TPMI_MEM_SIZE      (255)
-#define IOP13XX_TPMI_MEM_CTRL      (SZ_1K - 1)
-#define IOP13XX_TPMI_RESOURCE_MMR  0
-#define IOP13XX_TPMI_RESOURCE_MEM  1
-#define IOP13XX_TPMI_RESOURCE_CTRL 2
-#define IOP13XX_TPMI_RESOURCE_IOP_CTRL 3
-#define IOP13XX_TPMI_RESOURCE_IRQ  4
-
-static struct resource iop13xx_tpmi_0_resources[] = {
-       [IOP13XX_TPMI_RESOURCE_MMR] = {
-               .start = IOP13XX_TPMI_MMR(4), /* tpmi0 starts at dev == 4 */
-               .end = IOP13XX_TPMI_MMR(4) + IOP13XX_TPMI_MMR_SIZE,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_MEM] = {
-               .start = IOP13XX_TPMI_MEM(0),
-               .end = IOP13XX_TPMI_MEM(0) + IOP13XX_TPMI_MEM_SIZE,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_CTRL] = {
-               .start = IOP13XX_TPMI_CTRL(0),
-               .end = IOP13XX_TPMI_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
-               .start = IOP13XX_TPMI_IOP_CTRL(0),
-               .end = IOP13XX_TPMI_IOP_CTRL(0) + IOP13XX_TPMI_MEM_CTRL,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_IRQ] = {
-               .start = IRQ_IOP13XX_TPMI0_OUT,
-               .end = IRQ_IOP13XX_TPMI0_OUT,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct resource iop13xx_tpmi_1_resources[] = {
-       [IOP13XX_TPMI_RESOURCE_MMR] = {
-               .start = IOP13XX_TPMI_MMR(1),
-               .end = IOP13XX_TPMI_MMR(1) + IOP13XX_TPMI_MMR_SIZE,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_MEM] = {
-               .start = IOP13XX_TPMI_MEM(1),
-               .end = IOP13XX_TPMI_MEM(1) + IOP13XX_TPMI_MEM_SIZE,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_CTRL] = {
-               .start = IOP13XX_TPMI_CTRL(1),
-               .end = IOP13XX_TPMI_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
-               .start = IOP13XX_TPMI_IOP_CTRL(1),
-               .end = IOP13XX_TPMI_IOP_CTRL(1) + IOP13XX_TPMI_MEM_CTRL,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_IRQ] = {
-               .start = IRQ_IOP13XX_TPMI1_OUT,
-               .end = IRQ_IOP13XX_TPMI1_OUT,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct resource iop13xx_tpmi_2_resources[] = {
-       [IOP13XX_TPMI_RESOURCE_MMR] = {
-               .start = IOP13XX_TPMI_MMR(2),
-               .end = IOP13XX_TPMI_MMR(2) + IOP13XX_TPMI_MMR_SIZE,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_MEM] = {
-               .start = IOP13XX_TPMI_MEM(2),
-               .end = IOP13XX_TPMI_MEM(2) + IOP13XX_TPMI_MEM_SIZE,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_CTRL] = {
-               .start = IOP13XX_TPMI_CTRL(2),
-               .end = IOP13XX_TPMI_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
-               .start = IOP13XX_TPMI_IOP_CTRL(2),
-               .end = IOP13XX_TPMI_IOP_CTRL(2) + IOP13XX_TPMI_MEM_CTRL,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_IRQ] = {
-               .start = IRQ_IOP13XX_TPMI2_OUT,
-               .end = IRQ_IOP13XX_TPMI2_OUT,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-static struct resource iop13xx_tpmi_3_resources[] = {
-       [IOP13XX_TPMI_RESOURCE_MMR] = {
-               .start = IOP13XX_TPMI_MMR(3),
-               .end = IOP13XX_TPMI_MMR(3) + IOP13XX_TPMI_MMR_SIZE,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_MEM] = {
-               .start = IOP13XX_TPMI_MEM(3),
-               .end = IOP13XX_TPMI_MEM(3) + IOP13XX_TPMI_MEM_SIZE,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_CTRL] = {
-               .start = IOP13XX_TPMI_CTRL(3),
-               .end = IOP13XX_TPMI_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_IOP_CTRL] = {
-               .start = IOP13XX_TPMI_IOP_CTRL(3),
-               .end = IOP13XX_TPMI_IOP_CTRL(3) + IOP13XX_TPMI_MEM_CTRL,
-               .flags = IORESOURCE_MEM,
-       },
-       [IOP13XX_TPMI_RESOURCE_IRQ] = {
-               .start = IRQ_IOP13XX_TPMI3_OUT,
-               .end = IRQ_IOP13XX_TPMI3_OUT,
-               .flags = IORESOURCE_IRQ
-       }
-};
-
-u64 iop13xx_tpmi_mask = DMA_BIT_MASK(32);
-static struct platform_device iop13xx_tpmi_0_device = {
-       .name = "iop-tpmi",
-       .id = 0,
-       .num_resources = ARRAY_SIZE(iop13xx_tpmi_0_resources),
-       .resource = iop13xx_tpmi_0_resources,
-       .dev = {
-               .dma_mask          = &iop13xx_tpmi_mask,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-       },
-};
-
-static struct platform_device iop13xx_tpmi_1_device = {
-       .name = "iop-tpmi",
-       .id = 1,
-       .num_resources = ARRAY_SIZE(iop13xx_tpmi_1_resources),
-       .resource = iop13xx_tpmi_1_resources,
-       .dev = {
-               .dma_mask          = &iop13xx_tpmi_mask,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-       },
-};
-
-static struct platform_device iop13xx_tpmi_2_device = {
-       .name = "iop-tpmi",
-       .id = 2,
-       .num_resources = ARRAY_SIZE(iop13xx_tpmi_2_resources),
-       .resource = iop13xx_tpmi_2_resources,
-       .dev = {
-               .dma_mask          = &iop13xx_tpmi_mask,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-       },
-};
-
-static struct platform_device iop13xx_tpmi_3_device = {
-       .name = "iop-tpmi",
-       .id = 3,
-       .num_resources = ARRAY_SIZE(iop13xx_tpmi_3_resources),
-       .resource = iop13xx_tpmi_3_resources,
-       .dev = {
-               .dma_mask          = &iop13xx_tpmi_mask,
-               .coherent_dma_mask = DMA_BIT_MASK(32),
-       },
-};
-
-__init void iop13xx_add_tpmi_devices(void)
-{
-       unsigned short device_id;
-
-       /* tpmi's not present on iop341 or iop342 */
-       if (__raw_readl(IOP13XX_ESSR0) & IOP13XX_INTERFACE_SEL_PCIX)
-               /* ATUE must be present */
-               device_id = __raw_readw(IOP13XX_ATUE_DID);
-       else
-               /* ATUX must be present */
-               device_id = __raw_readw(IOP13XX_ATUX_DID);
-
-       switch (device_id) {
-       /* iop34[1|2] 0-tpmi */
-       case 0x3380:
-       case 0x3384:
-       case 0x3388:
-       case 0x338c:
-       case 0x3382:
-       case 0x3386:
-       case 0x338a:
-       case 0x338e:
-               return;
-       /* iop348 1-tpmi */
-       case 0x3310:
-       case 0x3312:
-       case 0x3314:
-       case 0x3318:
-       case 0x331a:
-       case 0x331c:
-       case 0x33c0:
-       case 0x33c2:
-       case 0x33c4:
-       case 0x33c8:
-       case 0x33ca:
-       case 0x33cc:
-       case 0x33b0:
-       case 0x33b2:
-       case 0x33b4:
-       case 0x33b8:
-       case 0x33ba:
-       case 0x33bc:
-       case 0x3320:
-       case 0x3322:
-       case 0x3324:
-       case 0x3328:
-       case 0x332a:
-       case 0x332c:
-               platform_device_register(&iop13xx_tpmi_0_device);
-               return;
-       default:
-               platform_device_register(&iop13xx_tpmi_0_device);
-               platform_device_register(&iop13xx_tpmi_1_device);
-               platform_device_register(&iop13xx_tpmi_2_device);
-               platform_device_register(&iop13xx_tpmi_3_device);
-               return;
-       }
-}
index 71d6244..c8018ef 100644 (file)
@@ -3,7 +3,15 @@
 # Makefile for the linux kernel.
 #
 
-obj-y                  := irq.o
+obj-$(CONFIG_ARCH_IOP32X) += irq.o
+obj-$(CONFIG_ARCH_IOP32X) += i2c.o
+obj-$(CONFIG_ARCH_IOP32X) += pci.o
+obj-$(CONFIG_ARCH_IOP32X) += setup.o
+obj-$(CONFIG_ARCH_IOP32X) += time.o
+obj-$(CONFIG_ARCH_IOP32X) += cp6.o
+obj-$(CONFIG_ARCH_IOP32X) += adma.o
+obj-$(CONFIG_ARCH_IOP32X) += pmu.o
+obj-$(CONFIG_ARCH_IOP32X) += restart.o
 
 obj-$(CONFIG_MACH_GLANTANK) += glantank.o
 obj-$(CONFIG_ARCH_IQ80321) += iq80321.o
similarity index 75%
rename from arch/arm/plat-iop/adma.c
rename to arch/arm/mach-iop32x/adma.c
index b8e3602..764bcbf 100644 (file)
@@ -4,12 +4,12 @@
  * Copyright © 2006, Intel Corporation.
  */
 #include <linux/platform_device.h>
-#include <asm/hardware/iop3xx.h>
 #include <linux/dma-mapping.h>
-#include <mach/adma.h>
-#include <asm/hardware/iop_adma.h>
+#include <linux/platform_data/dma-iop32x.h>
+
+#include "iop3xx.h"
+#include "irqs.h"
 
-#ifdef CONFIG_ARCH_IOP32X
 #define IRQ_DMA0_EOT IRQ_IOP32X_DMA0_EOT
 #define IRQ_DMA0_EOC IRQ_IOP32X_DMA0_EOC
 #define IRQ_DMA0_ERR IRQ_IOP32X_DMA0_ERR
 #define IRQ_AA_EOT IRQ_IOP32X_AA_EOT
 #define IRQ_AA_EOC IRQ_IOP32X_AA_EOC
 #define IRQ_AA_ERR IRQ_IOP32X_AA_ERR
-#endif
-#ifdef CONFIG_ARCH_IOP33X
-#define IRQ_DMA0_EOT IRQ_IOP33X_DMA0_EOT
-#define IRQ_DMA0_EOC IRQ_IOP33X_DMA0_EOC
-#define IRQ_DMA0_ERR IRQ_IOP33X_DMA0_ERR
-
-#define IRQ_DMA1_EOT IRQ_IOP33X_DMA1_EOT
-#define IRQ_DMA1_EOC IRQ_IOP33X_DMA1_EOC
-#define IRQ_DMA1_ERR IRQ_IOP33X_DMA1_ERR
-
-#define IRQ_AA_EOT IRQ_IOP33X_AA_EOT
-#define IRQ_AA_EOC IRQ_IOP33X_AA_EOC
-#define IRQ_AA_ERR IRQ_IOP33X_AA_ERR
-#endif
+
 /* AAU and DMA Channels */
 static struct resource iop3xx_dma_0_resources[] = {
        [0] = {
@@ -161,30 +148,14 @@ struct platform_device iop3xx_aau_channel = {
 
 static int __init iop3xx_adma_cap_init(void)
 {
-       #ifdef CONFIG_ARCH_IOP32X /* the 32x DMA does not perform CRC32C */
-       dma_cap_set(DMA_MEMCPY, iop3xx_dma_0_data.cap_mask);
-       dma_cap_set(DMA_INTERRUPT, iop3xx_dma_0_data.cap_mask);
-       #else
        dma_cap_set(DMA_MEMCPY, iop3xx_dma_0_data.cap_mask);
        dma_cap_set(DMA_INTERRUPT, iop3xx_dma_0_data.cap_mask);
-       #endif
 
-       #ifdef CONFIG_ARCH_IOP32X /* the 32x DMA does not perform CRC32C */
        dma_cap_set(DMA_MEMCPY, iop3xx_dma_1_data.cap_mask);
        dma_cap_set(DMA_INTERRUPT, iop3xx_dma_1_data.cap_mask);
-       #else
-       dma_cap_set(DMA_MEMCPY, iop3xx_dma_1_data.cap_mask);
-       dma_cap_set(DMA_INTERRUPT, iop3xx_dma_1_data.cap_mask);
-       #endif
 
-       #ifdef CONFIG_ARCH_IOP32X /* the 32x AAU does not perform zero sum */
-       dma_cap_set(DMA_XOR, iop3xx_aau_data.cap_mask);
-       dma_cap_set(DMA_INTERRUPT, iop3xx_aau_data.cap_mask);
-       #else
        dma_cap_set(DMA_XOR, iop3xx_aau_data.cap_mask);
-       dma_cap_set(DMA_XOR_VAL, iop3xx_aau_data.cap_mask);
        dma_cap_set(DMA_INTERRUPT, iop3xx_aau_data.cap_mask);
-       #endif
 
        return 0;
 }
index 61a1e59..d43ced3 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/i2c.h>
 #include <linux/gpio.h>
 #include <linux/gpio/machine.h>
-#include <mach/hardware.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
 #include <asm/mach/time.h>
 #include <asm/mach-types.h>
-#include <mach/time.h>
+
+#include "hardware.h"
 #include "gpio-iop32x.h"
+#include "irqs.h"
 
 static void __init em7210_timer_init(void)
 {
index 5a45d61..2fe0f77 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio/machine.h>
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <asm/mach-types.h>
 #include <asm/page.h>
-#include <mach/time.h>
+
+#include "hardware.h"
 #include "gpio-iop32x.h"
+#include "irqs.h"
 
 /*
  * GLAN Tank timer tick configuration.
similarity index 78%
rename from arch/arm/mach-iop32x/include/mach/glantank.h
rename to arch/arm/mach-iop32x/glantank.h
index b9df2e4..f38e86b 100644 (file)
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * arch/arm/mach-iop32x/include/mach/glantank.h
- *
  * IO-Data GLAN Tank board registers
  */
 
similarity index 90%
rename from arch/arm/mach-iop32x/include/mach/hardware.h
rename to arch/arm/mach-iop32x/hardware.h
index 6e5303e..43ab4fb 100644 (file)
@@ -1,8 +1,4 @@
 /* SPDX-License-Identifier: GPL-2.0 */
-/*
- * arch/arm/mach-iop32x/include/mach/hardware.h
- */
-
 #ifndef __HARDWARE_H
 #define __HARDWARE_H
 
@@ -28,7 +24,7 @@ void iop32x_init_irq(void);
 /*
  * Generic chipset bits
  */
-#include "iop32x.h"
+#include "iop3xx.h"
 
 /*
  * Board specific bits
similarity index 81%
rename from arch/arm/plat-iop/i2c.c
rename to arch/arm/mach-iop32x/i2c.c
index dfbd7c3..dc9f6a1 100644 (file)
 #include <asm/mach/map.h>
 #include <asm/setup.h>
 #include <asm/memory.h>
-#include <mach/hardware.h>
-#include <asm/hardware/iop3xx.h>
 #include <asm/mach/arch.h>
 
-#ifdef CONFIG_ARCH_IOP32X
-#define IRQ_IOP3XX_I2C_0       IRQ_IOP32X_I2C_0
-#define IRQ_IOP3XX_I2C_1       IRQ_IOP32X_I2C_1
-#endif
-#ifdef CONFIG_ARCH_IOP33X
-#define IRQ_IOP3XX_I2C_0       IRQ_IOP33X_I2C_0
-#define IRQ_IOP3XX_I2C_1       IRQ_IOP33X_I2C_1
-#endif
+#include "hardware.h"
+#include "iop3xx.h"
+#include "irqs.h"
 
 /*
  * Each of the I2C busses have corresponding GPIO lines, and the driver
@@ -65,8 +58,8 @@ static struct resource iop3xx_i2c0_resources[] = {
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = IRQ_IOP3XX_I2C_0,
-               .end    = IRQ_IOP3XX_I2C_0,
+               .start  = IRQ_IOP32X_I2C_0,
+               .end    = IRQ_IOP32X_I2C_0,
                .flags  = IORESOURCE_IRQ,
        },
 };
@@ -86,8 +79,8 @@ static struct resource iop3xx_i2c1_resources[] = {
                .flags  = IORESOURCE_MEM,
        },
        [1] = {
-               .start  = IRQ_IOP3XX_I2C_1,
-               .end    = IRQ_IOP3XX_I2C_1,
+               .start  = IRQ_IOP32X_I2C_1,
+               .end    = IRQ_IOP32X_I2C_1,
                .flags  = IORESOURCE_IRQ,
        }
 };
diff --git a/arch/arm/mach-iop32x/include/mach/adma.h b/arch/arm/mach-iop32x/include/mach/adma.h
deleted file mode 100644 (file)
index 2b20063..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef IOP32X_ADMA_H
-#define IOP32X_ADMA_H
-#include <asm/hardware/iop3xx-adma.h>
-#endif
-
index ea13ae0..8e6766d 100644 (file)
@@ -7,8 +7,6 @@
  * License version 2. This program is licensed "as is" without any
  * warranty of any kind, whether express or implied.
  */
-#include <mach/iop32x.h>
-
        .macro get_irqnr_preamble, base, tmp
        mrc     p15, 0, \tmp, c15, c1, 0
        orr     \tmp, \tmp, #(1 << 6)
diff --git a/arch/arm/mach-iop32x/include/mach/iop32x.h b/arch/arm/mach-iop32x/include/mach/iop32x.h
deleted file mode 100644 (file)
index 84223f8..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-iop32x/include/mach/iop32x.h
- *
- * Intel IOP32X Chip definitions
- *
- * Author: Rory Bolt <rorybolt@pacbell.net>
- * Copyright (C) 2002 Rory Bolt
- * Copyright (C) 2004 Intel Corp.
- */
-
-#ifndef __IOP32X_H
-#define __IOP32X_H
-
-/*
- * Peripherals that are shared between the iop32x and iop33x but
- * located at different addresses.
- */
-#define IOP3XX_TIMER_REG(reg)  (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg))
-
-#include <asm/hardware/iop3xx.h>
-
-/* ATU Parameters
- * set up a 1:1 bus to physical ram relationship
- * w/ physical ram on top of pci in the memory map
- */
-#define IOP32X_MAX_RAM_SIZE            0x40000000UL
-#define IOP3XX_MAX_RAM_SIZE            IOP32X_MAX_RAM_SIZE
-#define IOP3XX_PCI_LOWER_MEM_BA        0x80000000
-
-#endif
index 82b1174..c4e78df 100644 (file)
@@ -9,39 +9,6 @@
 #ifndef __IRQS_H
 #define __IRQS_H
 
-/*
- * IOP80321 chipset interrupts
- */
-#define IRQ_IOP32X_DMA0_EOT    0
-#define IRQ_IOP32X_DMA0_EOC    1
-#define IRQ_IOP32X_DMA1_EOT    2
-#define IRQ_IOP32X_DMA1_EOC    3
-#define IRQ_IOP32X_AA_EOT      6
-#define IRQ_IOP32X_AA_EOC      7
-#define IRQ_IOP32X_CORE_PMON   8
-#define IRQ_IOP32X_TIMER0      9
-#define IRQ_IOP32X_TIMER1      10
-#define IRQ_IOP32X_I2C_0       11
-#define IRQ_IOP32X_I2C_1       12
-#define IRQ_IOP32X_MESSAGING   13
-#define IRQ_IOP32X_ATU_BIST    14
-#define IRQ_IOP32X_PERFMON     15
-#define IRQ_IOP32X_CORE_PMU    16
-#define IRQ_IOP32X_BIU_ERR     17
-#define IRQ_IOP32X_ATU_ERR     18
-#define IRQ_IOP32X_MCU_ERR     19
-#define IRQ_IOP32X_DMA0_ERR    20
-#define IRQ_IOP32X_DMA1_ERR    21
-#define IRQ_IOP32X_AA_ERR      23
-#define IRQ_IOP32X_MSG_ERR     24
-#define IRQ_IOP32X_SSP         25
-#define IRQ_IOP32X_XINT0       27
-#define IRQ_IOP32X_XINT1       28
-#define IRQ_IOP32X_XINT2       29
-#define IRQ_IOP32X_XINT3       30
-#define IRQ_IOP32X_HPI         31
-
 #define NR_IRQS                        32
 
-
 #endif
diff --git a/arch/arm/mach-iop32x/include/mach/time.h b/arch/arm/mach-iop32x/include/mach/time.h
deleted file mode 100644 (file)
index d08950c..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _IOP32X_TIME_H_
-#define _IOP32X_TIME_H_
-#define IRQ_IOP_TIMER0 IRQ_IOP32X_TIMER0
-#endif
index ed4ac3e..c854887 100644 (file)
@@ -6,9 +6,8 @@
 #include <asm/types.h>
 #include <asm/mach-types.h>
 #include <linux/serial_reg.h>
-#include <mach/hardware.h>
 
-volatile u8 *uart_base;
+#define uart_base ((volatile u8 *)0xfe800000)
 
 #define TX_DONE                (UART_LSR_TEMT | UART_LSR_THRE)
 
@@ -23,17 +22,4 @@ static inline void flush(void)
 {
 }
 
-static __inline__ void __arch_decomp_setup(unsigned long arch_id)
-{
-       if (machine_is_iq80321())
-               uart_base = (volatile u8 *)IQ80321_UART;
-       else if (machine_is_iq31244() || machine_is_em7210())
-               uart_base = (volatile u8 *)IQ31244_UART;
-       else
-               uart_base = (volatile u8 *)0xfe800000;
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()    __arch_decomp_setup(arch_id)
+#define arch_decomp_setup() do { } while (0)
similarity index 96%
rename from arch/arm/include/asm/hardware/iop3xx.h
rename to arch/arm/mach-iop32x/iop3xx.h
index 3cb6f22..46b4b34 100644 (file)
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * arch/arm/include/asm/hardware/iop3xx.h
- *
  * Intel IOP32X and IOP33X register definitions
  *
  * Author: Rory Bolt <rorybolt@pacbell.net>
 #define __IOP3XX_H
 
 /*
+ * Peripherals that are shared between the iop32x and iop33x but
+ * located at different addresses.
+ */
+#define IOP3XX_TIMER_REG(reg)  (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07e0 + (reg))
+
+#include "iop3xx.h"
+
+/* ATU Parameters
+ * set up a 1:1 bus to physical ram relationship
+ * w/ physical ram on top of pci in the memory map
+ */
+#define IOP32X_MAX_RAM_SIZE            0x40000000UL
+#define IOP3XX_MAX_RAM_SIZE            IOP32X_MAX_RAM_SIZE
+#define IOP3XX_PCI_LOWER_MEM_BA        0x80000000
+
+/*
  * IOP3XX GPIO handling
  */
 #define IOP3XX_GPIO_LINE(x)    (x)
index 8755aa8..04a7d38 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio/machine.h>
-#include <mach/hardware.h>
 #include <asm/cputype.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
@@ -33,7 +32,9 @@
 #include <asm/mach-types.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <mach/time.h>
+
+#include "hardware.h"
+#include "irqs.h"
 #include "gpio-iop32x.h"
 
 /*
similarity index 89%
rename from arch/arm/mach-iop32x/include/mach/iq31244.h
rename to arch/arm/mach-iop32x/iq31244.h
index e62da5d..a7ac691 100644 (file)
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * arch/arm/mach-iop32x/include/mach/iq31244.h
- *
  * Intel IQ31244 evaluation board registers
  */
 
index e12699d..4bd596d 100644 (file)
@@ -20,7 +20,6 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/gpio/machine.h>
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -29,7 +28,9 @@
 #include <asm/mach-types.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <mach/time.h>
+
+#include "hardware.h"
+#include "irqs.h"
 #include "gpio-iop32x.h"
 
 /*
similarity index 89%
rename from arch/arm/mach-iop32x/include/mach/iq80321.h
rename to arch/arm/mach-iop32x/iq80321.h
index faf62c2..3a5d106 100644 (file)
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * arch/arm/mach-iop32x/include/mach/iq80321.h
- *
  * Intel IQ80321 evaluation board registers
  */
 
index 2f5d4ec..2d48bf1 100644 (file)
 #include <linux/list.h>
 #include <asm/mach/irq.h>
 #include <asm/irq.h>
-#include <mach/hardware.h>
 #include <asm/mach-types.h>
 
+#include "hardware.h"
+
 static u32 iop32x_mask;
 
 static void intctl_write(u32 val)
diff --git a/arch/arm/mach-iop32x/irqs.h b/arch/arm/mach-iop32x/irqs.h
new file mode 100644 (file)
index 0000000..69858e4
--- /dev/null
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Author:     Rory Bolt <rorybolt@pacbell.net>
+ * Copyright:  (C) 2002 Rory Bolt
+ */
+
+#ifndef __IOP32X_IRQS_H
+#define __IOP32X_IRQS_H
+
+/*
+ * IOP80321 chipset interrupts
+ */
+#define IRQ_IOP32X_DMA0_EOT    0
+#define IRQ_IOP32X_DMA0_EOC    1
+#define IRQ_IOP32X_DMA1_EOT    2
+#define IRQ_IOP32X_DMA1_EOC    3
+#define IRQ_IOP32X_AA_EOT      6
+#define IRQ_IOP32X_AA_EOC      7
+#define IRQ_IOP32X_CORE_PMON   8
+#define IRQ_IOP32X_TIMER0      9
+#define IRQ_IOP32X_TIMER1      10
+#define IRQ_IOP32X_I2C_0       11
+#define IRQ_IOP32X_I2C_1       12
+#define IRQ_IOP32X_MESSAGING   13
+#define IRQ_IOP32X_ATU_BIST    14
+#define IRQ_IOP32X_PERFMON     15
+#define IRQ_IOP32X_CORE_PMU    16
+#define IRQ_IOP32X_BIU_ERR     17
+#define IRQ_IOP32X_ATU_ERR     18
+#define IRQ_IOP32X_MCU_ERR     19
+#define IRQ_IOP32X_DMA0_ERR    20
+#define IRQ_IOP32X_DMA1_ERR    21
+#define IRQ_IOP32X_AA_ERR      23
+#define IRQ_IOP32X_MSG_ERR     24
+#define IRQ_IOP32X_SSP         25
+#define IRQ_IOP32X_XINT0       27
+#define IRQ_IOP32X_XINT1       28
+#define IRQ_IOP32X_XINT2       29
+#define IRQ_IOP32X_XINT3       30
+#define IRQ_IOP32X_HPI         31
+
+#endif
index 26d76b3..5382a93 100644 (file)
@@ -28,7 +28,6 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/gpio/machine.h>
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -37,7 +36,9 @@
 #include <asm/mach-types.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
-#include <mach/time.h>
+
+#include "hardware.h"
+#include "irqs.h"
 #include "gpio-iop32x.h"
 
 /*
similarity index 89%
rename from arch/arm/mach-iop32x/include/mach/n2100.h
rename to arch/arm/mach-iop32x/n2100.h
index 70bb660..0b97b94 100644 (file)
@@ -1,7 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * arch/arm/mach-iop32x/include/mach/n2100.h
- *
  * Thecus N2100 board registers
  */
 
similarity index 99%
rename from arch/arm/plat-iop/pci.c
rename to arch/arm/mach-iop32x/pci.c
index 4c42c95..ab0010d 100644 (file)
@@ -17,9 +17,9 @@
 #include <linux/io.h>
 #include <asm/irq.h>
 #include <asm/signal.h>
-#include <mach/hardware.h>
 #include <asm/mach/pci.h>
-#include <asm/hardware/iop3xx.h>
+#include "hardware.h"
+#include "iop3xx.h"
 
 // #define DEBUG
 
similarity index 79%
rename from arch/arm/plat-iop/pmu.c
rename to arch/arm/mach-iop32x/pmu.c
index 04c44a8..bdbc7a3 100644 (file)
@@ -5,17 +5,11 @@
  */
 
 #include <linux/platform_device.h>
-#include <mach/irqs.h>
+#include "irqs.h"
 
 static struct resource pmu_resource = {
-#ifdef CONFIG_ARCH_IOP32X
        .start  = IRQ_IOP32X_CORE_PMU,
        .end    = IRQ_IOP32X_CORE_PMU,
-#endif
-#ifdef CONFIG_ARCH_IOP33X
-       .start  = IRQ_IOP33X_CORE_PMU,
-       .end    = IRQ_IOP33X_CORE_PMU,
-#endif
        .flags  = IORESOURCE_IRQ,
 };
 
similarity index 82%
rename from arch/arm/plat-iop/restart.c
rename to arch/arm/mach-iop32x/restart.c
index cf6d3d9..3dfa54d 100644 (file)
@@ -4,9 +4,9 @@
  *
  * Copyright (C) 2001 MontaVista Software, Inc.
  */
-#include <asm/hardware/iop3xx.h>
 #include <asm/system_misc.h>
-#include <mach/hardware.h>
+#include "hardware.h"
+#include "iop3xx.h"
 
 void iop3xx_restart(enum reboot_mode mode, const char *cmd)
 {
similarity index 95%
rename from arch/arm/plat-iop/setup.c
rename to arch/arm/mach-iop32x/setup.c
index d10e010..a0a81c2 100644 (file)
@@ -10,7 +10,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <asm/mach/map.h>
-#include <asm/hardware/iop3xx.h>
+#include "iop3xx.h"
 
 /*
  * Standard IO mapping for all IOP3xx based systems.  Note that
similarity index 97%
rename from arch/arm/plat-iop/time.c
rename to arch/arm/mach-iop32x/time.c
index f9dd1f5..18a4df5 100644 (file)
 #include <linux/clockchips.h>
 #include <linux/export.h>
 #include <linux/sched_clock.h>
-#include <mach/hardware.h>
 #include <asm/irq.h>
 #include <linux/uaccess.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
-#include <mach/time.h>
+
+#include "hardware.h"
+#include "irqs.h"
 
 /*
  * Minimum clocksource/clockevent timer range in seconds
@@ -167,7 +168,7 @@ void __init iop_init_time(unsigned long tick_rate)
         */
        write_tmr0(timer_ctl & ~IOP_TMR_EN);
        write_tisr(1);
-       setup_irq(IRQ_IOP_TIMER0, &iop_timer_irq);
+       setup_irq(IRQ_IOP32X_TIMER0, &iop_timer_irq);
        iop_clockevent.cpumask = cpumask_of(0);
        clockevents_config_and_register(&iop_clockevent, tick_rate,
                                        0xf, 0xfffffffe);
diff --git a/arch/arm/mach-iop33x/Kconfig b/arch/arm/mach-iop33x/Kconfig
deleted file mode 100644 (file)
index cd6069c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-if ARCH_IOP33X
-
-menu "IOP33x Implementation Options"
-
-comment "IOP33x Platform Types"
-
-config ARCH_IQ80331
-       bool "Enable support for IQ80331"
-       help
-         Say Y here if you want to run your kernel on the Intel IQ80331
-         evaluation kit for the IOP331 chipset.
-
-config MACH_IQ80332
-       bool "Enable support for IQ80332"
-       help
-         Say Y here if you want to run your kernel on the Intel IQ80332
-         evaluation kit for the IOP332 chipset.
-
-endmenu
-
-endif
diff --git a/arch/arm/mach-iop33x/Makefile b/arch/arm/mach-iop33x/Makefile
deleted file mode 100644 (file)
index 320ecde..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the linux kernel.
-#
-
-obj-y                  := irq.o uart.o
-
-obj-$(CONFIG_ARCH_IQ80331) += iq80331.o
-obj-$(CONFIG_MACH_IQ80332) += iq80332.o
diff --git a/arch/arm/mach-iop33x/Makefile.boot b/arch/arm/mach-iop33x/Makefile.boot
deleted file mode 100644 (file)
index e4dd1d2..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-   zreladdr-y  += 0x00008000
-params_phys-y  := 0x00000100
-initrd_phys-y  := 0x00800000
diff --git a/arch/arm/mach-iop33x/include/mach/adma.h b/arch/arm/mach-iop33x/include/mach/adma.h
deleted file mode 100644 (file)
index 8aa7159..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef IOP33X_ADMA_H
-#define IOP33X_ADMA_H
-#include <asm/hardware/iop3xx-adma.h>
-#endif
-
diff --git a/arch/arm/mach-iop33x/include/mach/entry-macro.S b/arch/arm/mach-iop33x/include/mach/entry-macro.S
deleted file mode 100644 (file)
index 0a398fe..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * arch/arm/mach-iop33x/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for IOP33x-based platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <mach/iop33x.h>
-
-       .macro get_irqnr_preamble, base, tmp
-       mrc     p15, 0, \tmp, c15, c1, 0
-       orr     \tmp, \tmp, #(1 << 6)
-       mcr     p15, 0, \tmp, c15, c1, 0        @ Enable cp6 access
-       mrc     p15, 0, \tmp, c15, c1, 0
-       mov     \tmp, \tmp
-       sub     pc, pc, #4                      @ cp_wait
-       .endm
-
-       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-       mrc     p6, 0, \irqstat, c14, c0, 0     @ Read IINTVEC
-       cmp     \irqstat, #0
-       mrceq   p6, 0, \irqstat, c14, c0, 0     @ erratum 63 workaround
-       adds    \irqnr, \irqstat, #1
-       movne   \irqnr, \irqstat, lsr #2
-       .endm
-
-       .macro arch_ret_to_user, tmp1, tmp2
-       mrc     p15, 0, \tmp1, c15, c1, 0
-       ands    \tmp2, \tmp1, #(1 << 6)
-       bicne   \tmp1, \tmp1, #(1 << 6)
-       mcrne   p15, 0, \tmp1, c15, c1, 0       @ Disable cp6 access
-       .endm
diff --git a/arch/arm/mach-iop33x/include/mach/hardware.h b/arch/arm/mach-iop33x/include/mach/hardware.h
deleted file mode 100644 (file)
index 020bafb..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * arch/arm/mach-iop33x/include/mach/hardware.h
- */
-
-#ifndef __HARDWARE_H
-#define __HARDWARE_H
-
-#include <asm/types.h>
-
-/*
- * Note about PCI IO space mappings
- *
- * To make IO space accesses efficient, we store virtual addresses in
- * the IO resources.
- *
- * The PCI IO space is located at virtual 0xfe000000 from physical
- * 0x90000000.  The PCI BARs must be programmed with physical addresses,
- * but when we read them, we convert them to virtual addresses.  See
- * arch/arm/mach-iop3xx/iop3xx-pci.c
- */
-
-#ifndef __ASSEMBLY__
-void iop33x_init_irq(void);
-
-extern struct platform_device iop33x_uart0_device;
-extern struct platform_device iop33x_uart1_device;
-#endif
-
-
-/*
- * Generic chipset bits
- *
- */
-#include "iop33x.h"
-
-/*
- * Board specific bits
- */
-#include "iq80331.h"
-#include "iq80332.h"
-
-
-#endif
diff --git a/arch/arm/mach-iop33x/include/mach/iop33x.h b/arch/arm/mach-iop33x/include/mach/iop33x.h
deleted file mode 100644 (file)
index 0c7041e..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-iop33x/include/mach/iop33x.h
- *
- * Intel IOP33X Chip definitions
- *
- * Author: Dave Jiang (dave.jiang@intel.com)
- * Copyright (C) 2003, 2004 Intel Corp.
- */
-
-#ifndef __IOP33X_H
-#define __IOP33X_H
-
-/*
- * Peripherals that are shared between the iop32x and iop33x but
- * located at different addresses.
- */
-#define IOP3XX_TIMER_REG(reg)  (IOP3XX_PERIPHERAL_VIRT_BASE + 0x07d0 + (reg))
-
-#include <asm/hardware/iop3xx.h>
-
-/* UARTs  */
-#define IOP33X_UART0_PHYS      (IOP3XX_PERIPHERAL_PHYS_BASE + 0x1700)
-#define IOP33X_UART0_VIRT      (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1700)
-#define IOP33X_UART1_PHYS      (IOP3XX_PERIPHERAL_PHYS_BASE + 0x1740)
-#define IOP33X_UART1_VIRT      (IOP3XX_PERIPHERAL_VIRT_BASE + 0x1740)
-
-/* ATU Parameters
- * set up a 1:1 bus to physical ram relationship
- * w/ pci on top of physical ram in memory map
- */
-#define IOP33X_MAX_RAM_SIZE            0x80000000UL
-#define IOP3XX_MAX_RAM_SIZE            IOP33X_MAX_RAM_SIZE
-#define IOP3XX_PCI_LOWER_MEM_BA        (PHYS_OFFSET + IOP33X_MAX_RAM_SIZE)
-
-
-#endif
diff --git a/arch/arm/mach-iop33x/include/mach/iq80331.h b/arch/arm/mach-iop33x/include/mach/iq80331.h
deleted file mode 100644 (file)
index c7e68d8..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * arch/arm/mach-iop33x/include/mach/iq80331.h
- *
- * Intel IQ80331 evaluation board registers
- */
-
-#ifndef __IQ80331_H
-#define __IQ80331_H
-
-#define IQ80331_7SEG_1         0xce840000      /* 7-Segment MSB */
-#define IQ80331_7SEG_0         0xce850000      /* 7-Segment LSB (WO) */
-#define IQ80331_ROTARY_SW      0xce8d0000      /* Rotary Switch */
-#define IQ80331_BATT_STAT      0xce8f0000      /* Battery Status */
-
-
-#endif
diff --git a/arch/arm/mach-iop33x/include/mach/iq80332.h b/arch/arm/mach-iop33x/include/mach/iq80332.h
deleted file mode 100644 (file)
index 749b44b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * arch/arm/mach-iop33x/include/mach/iq80332.h
- *
- * Intel IQ80332 evaluation board registers
- */
-
-#ifndef __IQ80332_H
-#define __IQ80332_H
-
-#define IQ80332_7SEG_1         0xce840000      /* 7-Segment MSB */
-#define IQ80332_7SEG_0         0xce850000      /* 7-Segment LSB (WO) */
-#define IQ80332_ROTARY_SW      0xce8d0000      /* Rotary Switch */
-#define IQ80332_BATT_STAT      0xce8f0000      /* Battery Status */
-
-
-#endif
diff --git a/arch/arm/mach-iop33x/include/mach/irqs.h b/arch/arm/mach-iop33x/include/mach/irqs.h
deleted file mode 100644 (file)
index cc3dce0..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-iop33x/include/mach/irqs.h
- *
- * Author:     Dave Jiang (dave.jiang@intel.com)
- * Copyright:  (C) 2003 Intel Corp.
- */
-
-#ifndef __IRQS_H
-#define __IRQS_H
-
-/*
- * IOP80331 chipset interrupts
- */
-#define IRQ_IOP33X_DMA0_EOT    0
-#define IRQ_IOP33X_DMA0_EOC    1
-#define IRQ_IOP33X_DMA1_EOT    2
-#define IRQ_IOP33X_DMA1_EOC    3
-#define IRQ_IOP33X_AA_EOT      6
-#define IRQ_IOP33X_AA_EOC      7
-#define IRQ_IOP33X_TIMER0      8
-#define IRQ_IOP33X_TIMER1      9
-#define IRQ_IOP33X_I2C_0       10
-#define IRQ_IOP33X_I2C_1       11
-#define IRQ_IOP33X_MSG         12
-#define IRQ_IOP33X_MSGIBQ      13
-#define IRQ_IOP33X_ATU_BIST    14
-#define IRQ_IOP33X_PERFMON     15
-#define IRQ_IOP33X_CORE_PMU    16
-#define IRQ_IOP33X_XINT0       24
-#define IRQ_IOP33X_XINT1       25
-#define IRQ_IOP33X_XINT2       26
-#define IRQ_IOP33X_XINT3       27
-#define IRQ_IOP33X_XINT8       32
-#define IRQ_IOP33X_XINT9       33
-#define IRQ_IOP33X_XINT10      34
-#define IRQ_IOP33X_XINT11      35
-#define IRQ_IOP33X_XINT12      36
-#define IRQ_IOP33X_XINT13      37
-#define IRQ_IOP33X_XINT14      38
-#define IRQ_IOP33X_XINT15      39
-#define IRQ_IOP33X_UART0       51
-#define IRQ_IOP33X_UART1       52
-#define IRQ_IOP33X_PBIE                53
-#define IRQ_IOP33X_ATU_CRW     54
-#define IRQ_IOP33X_ATU_ERR     55
-#define IRQ_IOP33X_MCU_ERR     56
-#define IRQ_IOP33X_DMA0_ERR    57
-#define IRQ_IOP33X_DMA1_ERR    58
-#define IRQ_IOP33X_AA_ERR      60
-#define IRQ_IOP33X_MSG_ERR     62
-#define IRQ_IOP33X_HPI         63
-
-#define NR_IRQS                        64
-
-
-#endif
diff --git a/arch/arm/mach-iop33x/include/mach/time.h b/arch/arm/mach-iop33x/include/mach/time.h
deleted file mode 100644 (file)
index 801f8fd..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _IOP33X_TIME_H_
-#define _IOP33X_TIME_H_
-#define IRQ_IOP_TIMER0 IRQ_IOP33X_TIMER0
-#endif
diff --git a/arch/arm/mach-iop33x/include/mach/uncompress.h b/arch/arm/mach-iop33x/include/mach/uncompress.h
deleted file mode 100644 (file)
index 62b71cd..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * arch/arm/mach-iop33x/include/mach/uncompress.h
- */
-
-#include <asm/types.h>
-#include <asm/mach-types.h>
-#include <linux/serial_reg.h>
-#include <mach/hardware.h>
-
-volatile u32 *uart_base;
-
-#define TX_DONE                (UART_LSR_TEMT | UART_LSR_THRE)
-
-static inline void putc(char c)
-{
-       while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
-               barrier();
-       uart_base[UART_TX] = c;
-}
-
-static inline void flush(void)
-{
-}
-
-static __inline__ void __arch_decomp_setup(unsigned long arch_id)
-{
-       if (machine_is_iq80331() || machine_is_iq80332())
-               uart_base = (volatile u32 *)IOP33X_UART0_PHYS;
-       else
-               uart_base = (volatile u32 *)0xfe800000;
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()    __arch_decomp_setup(arch_id)
diff --git a/arch/arm/mach-iop33x/iq80331.c b/arch/arm/mach-iop33x/iq80331.c
deleted file mode 100644 (file)
index ab74fba..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * arch/arm/mach-iop33x/iq80331.c
- *
- * Board support code for the Intel IQ80331 platform.
- *
- * Author: Dave Jiang <dave.jiang@intel.com>
- * Copyright (C) 2003 Intel Corp.
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-#include <linux/serial_core.h>
-#include <linux/serial_8250.h>
-#include <linux/mtd/physmap.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/pci.h>
-#include <asm/mach/time.h>
-#include <asm/mach-types.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <mach/time.h>
-
-/*
- * IQ80331 timer tick configuration.
- */
-static void __init iq80331_timer_init(void)
-{
-       /* D-Step parts run at a higher internal bus frequency */
-       if (*IOP3XX_ATURID >= 0xa)
-               iop_init_time(333000000);
-       else
-               iop_init_time(266000000);
-}
-
-
-/*
- * IQ80331 PCI.
- */
-static int __init
-iq80331_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       int irq;
-
-       if (slot == 1 && pin == 1) {
-               /* PCI-X Slot INTA */
-               irq = IRQ_IOP33X_XINT1;
-       } else if (slot == 1 && pin == 2) {
-               /* PCI-X Slot INTB */
-               irq = IRQ_IOP33X_XINT2;
-       } else if (slot == 1 && pin == 3) {
-               /* PCI-X Slot INTC */
-               irq = IRQ_IOP33X_XINT3;
-       } else if (slot == 1 && pin == 4) {
-               /* PCI-X Slot INTD */
-               irq = IRQ_IOP33X_XINT0;
-       } else if (slot == 2) {
-               /* GigE */
-               irq = IRQ_IOP33X_XINT2;
-       } else {
-               printk(KERN_ERR "iq80331_pci_map_irq() called for unknown "
-                       "device PCI:%d:%d:%d\n", dev->bus->number,
-                       PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-               irq = -1;
-       }
-
-       return irq;
-}
-
-static struct hw_pci iq80331_pci __initdata = {
-       .nr_controllers = 1,
-       .ops            = &iop3xx_ops,
-       .setup          = iop3xx_pci_setup,
-       .preinit        = iop3xx_pci_preinit_cond,
-       .map_irq        = iq80331_pci_map_irq,
-};
-
-static int __init iq80331_pci_init(void)
-{
-       if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
-               machine_is_iq80331())
-               pci_common_init(&iq80331_pci);
-
-       return 0;
-}
-
-subsys_initcall(iq80331_pci_init);
-
-
-/*
- * IQ80331 machine initialisation.
- */
-static struct physmap_flash_data iq80331_flash_data = {
-       .width          = 1,
-};
-
-static struct resource iq80331_flash_resource = {
-       .start          = 0xc0000000,
-       .end            = 0xc07fffff,
-       .flags          = IORESOURCE_MEM,
-};
-
-static struct platform_device iq80331_flash_device = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-               .platform_data  = &iq80331_flash_data,
-       },
-       .num_resources  = 1,
-       .resource       = &iq80331_flash_resource,
-};
-
-static struct resource iq80331_gpio_res[] = {
-       DEFINE_RES_MEM((IOP3XX_PERIPHERAL_PHYS_BASE + 0x1780), 0x10),
-};
-
-static void __init iq80331_init_machine(void)
-{
-       platform_device_register_simple("gpio-iop", 0,
-                                       iq80331_gpio_res,
-                                       ARRAY_SIZE(iq80331_gpio_res));
-       platform_device_register(&iop3xx_i2c0_device);
-       platform_device_register(&iop3xx_i2c1_device);
-       platform_device_register(&iop33x_uart0_device);
-       platform_device_register(&iop33x_uart1_device);
-       platform_device_register(&iq80331_flash_device);
-       platform_device_register(&iop3xx_dma_0_channel);
-       platform_device_register(&iop3xx_dma_1_channel);
-       platform_device_register(&iop3xx_aau_channel);
-}
-
-MACHINE_START(IQ80331, "Intel IQ80331")
-       /* Maintainer: Intel Corp. */
-       .atag_offset    = 0x100,
-       .map_io         = iop3xx_map_io,
-       .init_irq       = iop33x_init_irq,
-       .init_time      = iq80331_timer_init,
-       .init_machine   = iq80331_init_machine,
-       .restart        = iop3xx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-iop33x/iq80332.c b/arch/arm/mach-iop33x/iq80332.c
deleted file mode 100644 (file)
index 2e309b1..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * arch/arm/mach-iop33x/iq80332.c
- *
- * Board support code for the Intel IQ80332 platform.
- *
- * Author: Dave Jiang <dave.jiang@intel.com>
- * Copyright (C) 2004 Intel Corp.
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/string.h>
-#include <linux/serial_core.h>
-#include <linux/serial_8250.h>
-#include <linux/mtd/physmap.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/pci.h>
-#include <asm/mach/time.h>
-#include <asm/mach-types.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <mach/time.h>
-
-/*
- * IQ80332 timer tick configuration.
- */
-static void __init iq80332_timer_init(void)
-{
-       /* D-Step parts and the iop333 run at a higher internal bus frequency */
-       if (*IOP3XX_ATURID >= 0xa || *IOP3XX_ATUDID == 0x374)
-               iop_init_time(333000000);
-       else
-               iop_init_time(266000000);
-}
-
-
-/*
- * IQ80332 PCI.
- */
-static int __init
-iq80332_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       int irq;
-
-       if (slot == 4 && pin == 1) {
-               /* PCI-X Slot INTA */
-               irq = IRQ_IOP33X_XINT0;
-       } else if (slot == 4 && pin == 2) {
-               /* PCI-X Slot INTB */
-               irq = IRQ_IOP33X_XINT1;
-       } else if (slot == 4 && pin == 3) {
-               /* PCI-X Slot INTC */
-               irq = IRQ_IOP33X_XINT2;
-       } else if (slot == 4 && pin == 4) {
-               /* PCI-X Slot INTD */
-               irq = IRQ_IOP33X_XINT3;
-       } else if (slot == 6) {
-               /* GigE */
-               irq = IRQ_IOP33X_XINT2;
-       } else {
-               printk(KERN_ERR "iq80332_pci_map_irq() called for unknown "
-                       "device PCI:%d:%d:%d\n", dev->bus->number,
-                       PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-               irq = -1;
-       }
-
-       return irq;
-}
-
-static struct hw_pci iq80332_pci __initdata = {
-       .nr_controllers = 1,
-       .ops            = &iop3xx_ops,
-       .setup          = iop3xx_pci_setup,
-       .preinit        = iop3xx_pci_preinit_cond,
-       .map_irq        = iq80332_pci_map_irq,
-};
-
-static int __init iq80332_pci_init(void)
-{
-       if ((iop3xx_get_init_atu() == IOP3XX_INIT_ATU_ENABLE) &&
-               machine_is_iq80332())
-               pci_common_init(&iq80332_pci);
-
-       return 0;
-}
-
-subsys_initcall(iq80332_pci_init);
-
-
-/*
- * IQ80332 machine initialisation.
- */
-static struct physmap_flash_data iq80332_flash_data = {
-       .width          = 1,
-};
-
-static struct resource iq80332_flash_resource = {
-       .start          = 0xc0000000,
-       .end            = 0xc07fffff,
-       .flags          = IORESOURCE_MEM,
-};
-
-static struct platform_device iq80332_flash_device = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .dev            = {
-               .platform_data  = &iq80332_flash_data,
-       },
-       .num_resources  = 1,
-       .resource       = &iq80332_flash_resource,
-};
-
-static struct resource iq80332_gpio_res[] = {
-       DEFINE_RES_MEM((IOP3XX_PERIPHERAL_PHYS_BASE + 0x1780), 0x10),
-};
-
-static void __init iq80332_init_machine(void)
-{
-       platform_device_register_simple("gpio-iop", 0,
-                                       iq80332_gpio_res,
-                                       ARRAY_SIZE(iq80332_gpio_res));
-       platform_device_register(&iop3xx_i2c0_device);
-       platform_device_register(&iop3xx_i2c1_device);
-       platform_device_register(&iop33x_uart0_device);
-       platform_device_register(&iop33x_uart1_device);
-       platform_device_register(&iq80332_flash_device);
-       platform_device_register(&iop3xx_dma_0_channel);
-       platform_device_register(&iop3xx_dma_1_channel);
-       platform_device_register(&iop3xx_aau_channel);
-}
-
-MACHINE_START(IQ80332, "Intel IQ80332")
-       /* Maintainer: Intel Corp. */
-       .atag_offset    = 0x100,
-       .map_io         = iop3xx_map_io,
-       .init_irq       = iop33x_init_irq,
-       .init_time      = iq80332_timer_init,
-       .init_machine   = iq80332_init_machine,
-       .restart        = iop3xx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c
deleted file mode 100644 (file)
index 03ad7d3..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mach-iop33x/irq.c
- *
- * Generic IOP331 IRQ handling functionality
- *
- * Author: Dave Jiang <dave.jiang@intel.com>
- * Copyright (C) 2003 Intel Corp.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <asm/mach/irq.h>
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-
-static u32 iop33x_mask0;
-static u32 iop33x_mask1;
-
-static void intctl0_write(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c0, c0, 0" : : "r" (val));
-}
-
-static void intctl1_write(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c1, c0, 0" : : "r" (val));
-}
-
-static void intstr0_write(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c2, c0, 0" : : "r" (val));
-}
-
-static void intstr1_write(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c3, c0, 0" : : "r" (val));
-}
-
-static void intbase_write(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c12, c0, 0" : : "r" (val));
-}
-
-static void intsize_write(u32 val)
-{
-       asm volatile("mcr p6, 0, %0, c13, c0, 0" : : "r" (val));
-}
-
-static void
-iop33x_irq_mask1 (struct irq_data *d)
-{
-       iop33x_mask0 &= ~(1 << d->irq);
-       intctl0_write(iop33x_mask0);
-}
-
-static void
-iop33x_irq_mask2 (struct irq_data *d)
-{
-       iop33x_mask1 &= ~(1 << (d->irq - 32));
-       intctl1_write(iop33x_mask1);
-}
-
-static void
-iop33x_irq_unmask1(struct irq_data *d)
-{
-       iop33x_mask0 |= 1 << d->irq;
-       intctl0_write(iop33x_mask0);
-}
-
-static void
-iop33x_irq_unmask2(struct irq_data *d)
-{
-       iop33x_mask1 |= (1 << (d->irq - 32));
-       intctl1_write(iop33x_mask1);
-}
-
-struct irq_chip iop33x_irqchip1 = {
-       .name           = "IOP33x-1",
-       .irq_ack        = iop33x_irq_mask1,
-       .irq_mask       = iop33x_irq_mask1,
-       .irq_unmask     = iop33x_irq_unmask1,
-};
-
-struct irq_chip iop33x_irqchip2 = {
-       .name           = "IOP33x-2",
-       .irq_ack        = iop33x_irq_mask2,
-       .irq_mask       = iop33x_irq_mask2,
-       .irq_unmask     = iop33x_irq_unmask2,
-};
-
-void __init iop33x_init_irq(void)
-{
-       int i;
-
-       iop_init_cp6_handler();
-
-       intctl0_write(0);
-       intctl1_write(0);
-       intstr0_write(0);
-       intstr1_write(0);
-       intbase_write(0);
-       intsize_write(1);
-       if (machine_is_iq80331())
-               *IOP3XX_PCIIRSR = 0x0f;
-
-       for (i = 0; i < NR_IRQS; i++) {
-               irq_set_chip_and_handler(i,
-                                        (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2,
-                                        handle_level_irq);
-               irq_clear_status_flags(i, IRQ_NOREQUEST | IRQ_NOPROBE);
-       }
-}
diff --git a/arch/arm/mach-iop33x/uart.c b/arch/arm/mach-iop33x/uart.c
deleted file mode 100644 (file)
index 8fa079d..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mach-iop33x/uart.c
- *
- * Author: Dave Jiang (dave.jiang@intel.com)
- * Copyright (C) 2004 Intel Corporation.
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/major.h>
-#include <linux/fs.h>
-#include <linux/platform_device.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/serial_8250.h>
-#include <linux/io.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/mach/map.h>
-#include <asm/setup.h>
-#include <asm/memory.h>
-#include <mach/hardware.h>
-#include <asm/hardware/iop3xx.h>
-#include <asm/mach/arch.h>
-
-#define IOP33X_UART_XTAL 33334000
-
-static struct plat_serial8250_port iop33x_uart0_data[] = {
-       {
-               .membase        = (char *)IOP33X_UART0_VIRT,
-               .mapbase        = IOP33X_UART0_PHYS,
-               .irq            = IRQ_IOP33X_UART0,
-               .uartclk        = IOP33X_UART_XTAL,
-               .regshift       = 2,
-               .iotype         = UPIO_MEM,
-               .flags          = UPF_SKIP_TEST,
-       },
-       { },
-};
-
-static struct resource iop33x_uart0_resources[] = {
-       [0] = {
-               .start  = IOP33X_UART0_PHYS,
-               .end    = IOP33X_UART0_PHYS + 0x3f,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_IOP33X_UART0,
-               .end    = IRQ_IOP33X_UART0,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device iop33x_uart0_device = {
-       .name           = "serial8250",
-       .id             = PLAT8250_DEV_PLATFORM,
-       .dev            = {
-               .platform_data          = iop33x_uart0_data,
-       },
-       .num_resources  = 2,
-       .resource       = iop33x_uart0_resources,
-};
-
-
-static struct resource iop33x_uart1_resources[] = {
-       [0] = {
-               .start  = IOP33X_UART1_PHYS,
-               .end    = IOP33X_UART1_PHYS + 0x3f,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start  = IRQ_IOP33X_UART1,
-               .end    = IRQ_IOP33X_UART1,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct plat_serial8250_port iop33x_uart1_data[] = {
-       {
-               .membase        = (char *)IOP33X_UART1_VIRT,
-               .mapbase        = IOP33X_UART1_PHYS,
-               .irq            = IRQ_IOP33X_UART1,
-               .uartclk        = IOP33X_UART_XTAL,
-               .regshift       = 2,
-               .iotype         = UPIO_MEM,
-               .flags          = UPF_SKIP_TEST,
-       },
-       { },
-};
-
-struct platform_device iop33x_uart1_device = {
-       .name           = "serial8250",
-       .id             = PLAT8250_DEV_PLATFORM1,
-       .dev            = {
-               .platform_data          = iop33x_uart1_data,
-       },
-       .num_resources  = 2,
-       .resource       = iop33x_uart1_resources,
-};
diff --git a/arch/arm/mach-ks8695/Kconfig b/arch/arm/mach-ks8695/Kconfig
deleted file mode 100644 (file)
index 724d7d0..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-if ARCH_KS8695
-
-menu "Kendin/Micrel KS8695 Implementations"
-
-config MACH_KS8695
-       bool "KS8695 development board"
-       select HAVE_PCI
-       help
-         Say 'Y' here if you want your kernel to run on the original
-         Kendin-Micrel KS8695 development board.
-
-config MACH_DSM320
-       bool "DSM-320 Wireless Media Player"
-       help
-         Say 'Y' here if you want your kernel to run on the D-Link
-         DSM-320 Wireless Media Player.
-
-config MACH_ACS5K
-       bool "Brivo Systems LLC, ACS-5000 Master board"
-       help
-         say 'Y' here if you want your kernel to run on the Brivo
-         Systems LLC, ACS-5000 Master board.
-
-config MACH_LITE300
-       bool "SecureComputing SG300"
-       help
-         Say 'Y' here if you want your kernel to support the
-         SecureComputing / SnapGear SG300 VPN Internet Router.
-         See http://www.securecomputing.com for more details.
-
-config MACH_SG310
-       bool "McAfee SG310"
-       help
-         Say 'Y' here if you want your kernel to support the
-         McAfee / SnapGear SG310 VPN Internet Router.
-         See http://www.mcafee.com for more details.
-
-config MACH_SE4200
-       bool "SecureComputing SE4200"
-       help
-         Say 'Y' here if you want your kernel to support the
-         SecureComputing / SnapGear SE4200 Secure Wireless VPN
-         Internet Router.
-         See http://www.securecomputing.com for more details.
-
-config MACH_CM4002
-       bool "OpenGear CM4002"
-       help
-         Say 'Y' here if you want your kernel to support the OpenGear
-         CM4002 Secure Access Server. See http://www.opengear.com for
-         more details.
-
-config MACH_CM4008
-       bool "OpenGear CM4008"
-       select HAVE_PCI
-       help
-         Say 'Y' here if you want your kernel to support the OpenGear
-         CM4008 Console Server. See http://www.opengear.com for more
-         details.
-
-config MACH_CM41xx
-       bool "OpenGear CM41xx"
-       select HAVE_PCI
-       help
-         Say 'Y' here if you want your kernel to support the OpenGear
-         CM4016 or CM4048 Console Servers. See http://www.opengear.com for
-         more details.
-
-config MACH_IM4004
-       bool "OpenGear IM4004"
-       select HAVE_PCI
-       help
-         Say 'Y' here if you want your kernel to support the OpenGear
-         IM4004 Secure Access Server. See http://www.opengear.com for
-         more details.
-
-config MACH_IM42xx
-       bool "OpenGear IM42xx"
-       select HAVE_PCI
-       help
-         Say 'Y' here if you want your kernel to support the OpenGear
-         IM4216 or IM4248 Console Servers. See http://www.opengear.com for
-         more details.
-
-endmenu
-
-endif
diff --git a/arch/arm/mach-ks8695/Makefile b/arch/arm/mach-ks8695/Makefile
deleted file mode 100644 (file)
index 439b222..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-# arch/arm/mach-ks8695/Makefile
-#
-# Makefile for KS8695 architecture support
-#
-
-obj-y                          := cpu.o irq.o time.o devices.o
-
-# PCI support is optional
-obj-$(CONFIG_PCI)              += pci.o
-
-# Board-specific support
-obj-$(CONFIG_MACH_KS8695)      += board-micrel.o
-obj-$(CONFIG_MACH_DSM320)      += board-dsm320.o
-obj-$(CONFIG_MACH_ACS5K)       += board-acs5k.o
-obj-$(CONFIG_MACH_LITE300)     += board-sg.o
-obj-$(CONFIG_MACH_SG310)       += board-sg.o
-obj-$(CONFIG_MACH_SE4200)      += board-sg.o
-obj-$(CONFIG_MACH_CM4002)      += board-og.o
-obj-$(CONFIG_MACH_CM4008)      += board-og.o
-obj-$(CONFIG_MACH_CM41xx)      += board-og.o
-obj-$(CONFIG_MACH_IM4004)      += board-og.o
-obj-$(CONFIG_MACH_IM42xx)      += board-og.o
diff --git a/arch/arm/mach-ks8695/Makefile.boot b/arch/arm/mach-ks8695/Makefile.boot
deleted file mode 100644 (file)
index cf32eb6..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-# Note: the following conditions must always be true:
-#   ZRELADDR == virt_to_phys(TEXTADDR)
-#   PARAMS_PHYS must be within 4MB of ZRELADDR
-#   INITRD_PHYS must be in RAM
-
-   zreladdr-y  += 0x00008000
-params_phys-y  := 0x00000100
-initrd_phys-y  := 0x00800000
diff --git a/arch/arm/mach-ks8695/board-acs5k.c b/arch/arm/mach-ks8695/board-acs5k.c
deleted file mode 100644 (file)
index f319258..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mach-ks8695/board-acs5k.c
- *
- * Brivo Systems LLC, ACS-5000 Master Board
- *
- * Copyright 2008 Simtec Electronics
- *               Daniel Silverstone <dsilvers@simtec.co.uk>
- */
-#include <linux/gpio.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/gpio/machine.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/platform_data/i2c-gpio.h>
-#include <linux/platform_data/pca953x.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include "devices.h"
-#include <mach/gpio-ks8695.h>
-
-#include "generic.h"
-
-static struct gpiod_lookup_table acs5k_i2c_gpiod_table = {
-       .dev_id         = "i2c-gpio",
-       .table          = {
-               GPIO_LOOKUP_IDX("KS8695", 4, NULL, 0,
-                               GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
-               GPIO_LOOKUP_IDX("KS8695", 5, NULL, 1,
-                               GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
-       },
-};
-
-static struct i2c_gpio_platform_data acs5k_i2c_device_platdata = {
-       .udelay         = 10,
-};
-
-static struct platform_device acs5k_i2c_device = {
-       .name           = "i2c-gpio",
-       .id             = -1,
-       .num_resources  = 0,
-       .resource       = NULL,
-       .dev            = {
-               .platform_data  = &acs5k_i2c_device_platdata,
-       },
-};
-
-static int acs5k_pca9555_setup(struct i2c_client *client,
-                              unsigned gpio_base, unsigned ngpio,
-                              void *context)
-{
-       static int acs5k_gpio_value[] = {
-               -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, -1, 0, 1, 0, -1, -1
-       };
-       int n;
-
-       for (n = 0; n < ARRAY_SIZE(acs5k_gpio_value); ++n) {
-               gpio_request(gpio_base + n, "ACS-5000 GPIO Expander");
-               if (acs5k_gpio_value[n] < 0)
-                       gpio_direction_input(gpio_base + n);
-               else
-                       gpio_direction_output(gpio_base + n,
-                                             acs5k_gpio_value[n]);
-               gpio_export(gpio_base + n, 0); /* Export, direction locked down */
-       }
-
-       return 0;
-}
-
-static struct pca953x_platform_data acs5k_i2c_pca9555_platdata = {
-       .gpio_base      = 16, /* Start directly after the CPU's GPIO */
-       .invert         = 0, /* Do not invert */
-       .setup          = acs5k_pca9555_setup,
-};
-
-static struct i2c_board_info acs5k_i2c_devs[] __initdata = {
-       {
-               I2C_BOARD_INFO("pcf8563", 0x51),
-       },
-       {
-               I2C_BOARD_INFO("pca9555", 0x20),
-               .platform_data = &acs5k_i2c_pca9555_platdata,
-       },
-};
-
-static void __init acs5k_i2c_init(void)
-{
-       /* The gpio interface */
-       gpiod_add_lookup_table(&acs5k_i2c_gpiod_table);
-       platform_device_register(&acs5k_i2c_device);
-       /* I2C devices */
-       i2c_register_board_info(0, acs5k_i2c_devs,
-                               ARRAY_SIZE(acs5k_i2c_devs));
-}
-
-static struct mtd_partition acs5k_nor_partitions[] = {
-       [0] = {
-               .name   = "Boot Agent and config",
-               .size   = SZ_256K,
-               .offset = 0,
-               .mask_flags = MTD_WRITEABLE,
-       },
-       [1] = {
-               .name   = "Kernel",
-               .size   = SZ_1M,
-               .offset = SZ_256K,
-       },
-       [2] = {
-               .name   = "SquashFS1",
-               .size   = SZ_2M,
-               .offset = SZ_256K + SZ_1M,
-       },
-       [3] = {
-               .name   = "SquashFS2",
-               .size   = SZ_4M + SZ_2M,
-               .offset = SZ_256K + SZ_1M + SZ_2M,
-       },
-       [4] = {
-               .name   = "Data",
-               .size   = SZ_16M + SZ_4M + SZ_2M + SZ_512K, /* 22.5 MB */
-               .offset = SZ_256K + SZ_8M + SZ_1M,
-       }
-};
-
-static struct physmap_flash_data acs5k_nor_pdata = {
-       .width          = 4,
-       .nr_parts       = ARRAY_SIZE(acs5k_nor_partitions),
-       .parts          = acs5k_nor_partitions,
-};
-
-static struct resource acs5k_nor_resource[] = {
-       [0] = {
-               .start = SZ_32M, /* We expect the bootloader to map
-                                 * the flash here.
-                                 */
-               .end   = SZ_32M + SZ_16M - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = SZ_32M + SZ_16M,
-               .end   = SZ_32M + SZ_32M - SZ_256K - 1,
-               .flags = IORESOURCE_MEM,
-       }
-};
-
-static struct platform_device acs5k_device_nor = {
-       .name           = "physmap-flash",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(acs5k_nor_resource),
-       .resource       = acs5k_nor_resource,
-       .dev            = {
-               .platform_data = &acs5k_nor_pdata,
-       },
-};
-
-static void __init acs5k_register_nor(void)
-{
-       int ret;
-
-       if (acs5k_nor_partitions[0].mask_flags == 0)
-               printk(KERN_WARNING "Warning: Unprotecting bootloader and configuration partition\n");
-
-       ret = platform_device_register(&acs5k_device_nor);
-       if (ret < 0)
-               printk(KERN_ERR "failed to register physmap-flash device\n");
-}
-
-static int __init acs5k_protection_setup(char *s)
-{
-       /* We can't allocate anything here but we should be able
-        * to trivially parse s and decide if we can protect the
-        * bootloader partition or not
-        */
-       if (strcmp(s, "no") == 0)
-               acs5k_nor_partitions[0].mask_flags = 0;
-
-       return 1;
-}
-
-__setup("protect_bootloader=", acs5k_protection_setup);
-
-static void __init acs5k_init_gpio(void)
-{
-       int i;
-
-       ks8695_register_gpios();
-       for (i = 0; i < 4; ++i)
-               gpio_request(i, "ACS5K IRQ");
-       gpio_request(7, "ACS5K KS_FRDY");
-       for (i = 8; i < 16; ++i)
-               gpio_request(i, "ACS5K Unused");
-
-       gpio_request(3, "ACS5K CAN Control");
-       gpio_request(6, "ACS5K Heartbeat");
-       gpio_direction_output(3, 1); /* Default CAN_RESET high */
-       gpio_direction_output(6, 0); /* Default KS8695_ACTIVE low */
-       gpio_export(3, 0); /* export CAN_RESET as output only */
-       gpio_export(6, 0); /* export KS8695_ACTIVE as output only */
-}
-
-static void __init acs5k_init(void)
-{
-       acs5k_init_gpio();
-
-       /* Network device */
-       ks8695_add_device_lan();        /* eth0 = LAN */
-       ks8695_add_device_wan();        /* ethX = WAN */
-
-       /* NOR devices */
-       acs5k_register_nor();
-
-       /* I2C bus */
-       acs5k_i2c_init();
-}
-
-MACHINE_START(ACS5K, "Brivo Systems LLC ACS-5000 Master board")
-       /* Maintainer: Simtec Electronics. */
-       .atag_offset    = 0x100,
-       .map_io         = ks8695_map_io,
-       .init_irq       = ks8695_init_irq,
-       .init_machine   = acs5k_init,
-       .init_time      = ks8695_timer_init,
-       .restart        = ks8695_restart,
-MACHINE_END
diff --git a/arch/arm/mach-ks8695/board-dsm320.c b/arch/arm/mach-ks8695/board-dsm320.c
deleted file mode 100644 (file)
index d5f435c..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mach-ks8695/board-dsm320.c
- *
- * DSM-320 D-Link Wireless Media Player, board support.
- *
- * Copyright 2008 Simtec Electronics
- *               Daniel Silverstone <dsilvers@simtec.co.uk>
- */
-#include <linux/gpio.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/partitions.h>
-
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include "devices.h"
-#include <mach/gpio-ks8695.h>
-
-#include "generic.h"
-
-#ifdef CONFIG_PCI
-static int dsm320_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       switch (slot) {
-       case 0:
-               /* PCI-AHB bridge? */
-               return KS8695_IRQ_EXTERN0;
-       case 18:
-               /* Mini PCI slot */
-               return KS8695_IRQ_EXTERN2;
-       case 20:
-               /* RealMAGIC chip */
-               return KS8695_IRQ_EXTERN0;
-       }
-       BUG();
-}
-
-static struct ks8695_pci_cfg __initdata dsm320_pci = {
-       .mode           = KS8695_MODE_MINIPCI,
-       .map_irq        = dsm320_pci_map_irq,
-};
-
-static void __init dsm320_register_pci(void)
-{
-       /* Initialise the GPIO lines for interrupt mode */
-       /* RealMAGIC */
-       ks8695_gpio_interrupt(KS8695_GPIO_0, IRQ_TYPE_LEVEL_LOW);
-       /* MiniPCI Slot */
-       ks8695_gpio_interrupt(KS8695_GPIO_2, IRQ_TYPE_LEVEL_LOW);
-
-       ks8695_init_pci(&dsm320_pci);
-}
-
-#else
-static inline void __init dsm320_register_pci(void) { }
-#endif
-
-static struct physmap_flash_data dsm320_nor_pdata = {
-       .width          = 4,
-       .nr_parts       = 0,
-};
-
-static struct resource dsm320_nor_resource[] = {
-       [0] = {
-               .start = SZ_32M, /* We expect the bootloader to map
-                                 * the flash here.
-                                 */
-               .end   = SZ_32M + SZ_4M - 1,
-               .flags = IORESOURCE_MEM,
-       }
-};
-
-static struct platform_device dsm320_device_nor = {
-       .name           = "physmap-flash",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(dsm320_nor_resource),
-       .resource       = dsm320_nor_resource,
-       .dev            = {
-               .platform_data = &dsm320_nor_pdata,
-       },
-};
-
-void __init dsm320_register_nor(void)
-{
-       int ret;
-
-       ret = platform_device_register(&dsm320_device_nor);
-       if (ret < 0)
-               printk(KERN_ERR "failed to register physmap-flash device\n");
-}
-
-static void __init dsm320_init(void)
-{
-       /* GPIO registration */
-       ks8695_register_gpios();
-
-       /* PCI registration */
-       dsm320_register_pci();
-
-       /* Network device */
-       ks8695_add_device_lan();        /* eth0 = LAN */
-
-       /* NOR devices */
-       dsm320_register_nor();
-}
-
-MACHINE_START(DSM320, "D-Link DSM-320 Wireless Media Player")
-       /* Maintainer: Simtec Electronics. */
-       .atag_offset    = 0x100,
-       .map_io         = ks8695_map_io,
-       .init_irq       = ks8695_init_irq,
-       .init_machine   = dsm320_init,
-       .init_time      = ks8695_timer_init,
-       .restart        = ks8695_restart,
-MACHINE_END
diff --git a/arch/arm/mach-ks8695/board-micrel.c b/arch/arm/mach-ks8695/board-micrel.c
deleted file mode 100644 (file)
index bf8856c..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mach-ks8695/board-micrel.c
- */
-#include <linux/gpio.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <mach/gpio-ks8695.h>
-#include "devices.h"
-
-#include "generic.h"
-
-#ifdef CONFIG_PCI
-static int micrel_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       return KS8695_IRQ_EXTERN0;
-}
-
-static struct ks8695_pci_cfg __initdata micrel_pci = {
-       .mode           = KS8695_MODE_MINIPCI,
-       .map_irq        = micrel_pci_map_irq,
-};
-#endif
-
-
-static void __init micrel_init(void)
-{
-       printk(KERN_INFO "Micrel KS8695 Development Board initializing\n");
-
-       ks8695_register_gpios();
-
-#ifdef CONFIG_PCI
-       ks8695_init_pci(&micrel_pci);
-#endif
-
-       /* Add devices */
-       ks8695_add_device_wan();        /* eth0 = WAN */
-       ks8695_add_device_lan();        /* eth1 = LAN */
-}
-
-MACHINE_START(KS8695, "KS8695 Centaur Development Board")
-       /* Maintainer: Micrel Semiconductor Inc. */
-       .atag_offset    = 0x100,
-       .map_io         = ks8695_map_io,
-       .init_irq       = ks8695_init_irq,
-       .init_machine   = micrel_init,
-       .init_time      = ks8695_timer_init,
-       .restart        = ks8695_restart,
-MACHINE_END
diff --git a/arch/arm/mach-ks8695/board-og.c b/arch/arm/mach-ks8695/board-og.c
deleted file mode 100644 (file)
index 12ffe92..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * board-og.c -- support for the OpenGear KS8695 based boards.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/serial_8250.h>
-#include <linux/gpio.h>
-#include <linux/irq.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include "devices.h"
-#include <mach/regs-gpio.h>
-#include <mach/gpio-ks8695.h>
-#include "generic.h"
-
-static int og_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       if (machine_is_im4004() && (slot == 8))
-               return KS8695_IRQ_EXTERN1;
-       return KS8695_IRQ_EXTERN0;
-}
-
-static struct ks8695_pci_cfg __initdata og_pci = {
-       .mode           = KS8695_MODE_PCI,
-       .map_irq        = og_pci_map_irq,
-};
-
-static void __init og_register_pci(void)
-{
-       /* Initialize the GPIO lines for interrupt mode */
-       ks8695_gpio_interrupt(KS8695_GPIO_0, IRQ_TYPE_LEVEL_LOW);
-
-       /* Cardbus Slot */
-       if (machine_is_im4004())
-               ks8695_gpio_interrupt(KS8695_GPIO_1, IRQ_TYPE_LEVEL_LOW);
-
-       if (IS_ENABLED(CONFIG_PCI))
-               ks8695_init_pci(&og_pci);
-}
-
-/*
- * The PCI bus reset is driven by a dedicated GPIO line. Toggle it here
- * and bring the PCI bus out of reset.
- */
-static void __init og_pci_bus_reset(void)
-{
-       unsigned int rstline = 1;
-
-       /* Some boards use a different GPIO as the PCI reset line */
-       if (machine_is_im4004())
-               rstline = 2;
-       else if (machine_is_im42xx())
-               rstline = 0;
-
-       gpio_request(rstline, "PCI reset");
-       gpio_direction_output(rstline, 0);
-
-       /* Drive a reset on the PCI reset line */
-       gpio_set_value(rstline, 1);
-       gpio_set_value(rstline, 0);
-       mdelay(100);
-       gpio_set_value(rstline, 1);
-       mdelay(100);
-}
-
-/*
- * Direct connect serial ports (non-PCI that is).
- */
-#define        S8250_PHYS      0x03800000
-#define        S8250_VIRT      0xf4000000
-#define        S8250_SIZE      0x00100000
-
-static struct map_desc og_io_desc[] __initdata = {
-       {
-               .virtual        = S8250_VIRT,
-               .pfn            = __phys_to_pfn(S8250_PHYS),
-               .length         = S8250_SIZE,
-               .type           = MT_DEVICE,
-       }
-};
-
-static struct resource og_uart_resources[] = {
-       {
-               .start          = S8250_VIRT,
-               .end            = S8250_VIRT + S8250_SIZE,
-               .flags          = IORESOURCE_MEM
-       },
-};
-
-static struct plat_serial8250_port og_uart_data[] = {
-       {
-               .mapbase        = S8250_VIRT,
-               .membase        = (char *) S8250_VIRT,
-               .irq            = 3,
-               .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
-               .iotype         = UPIO_MEM,
-               .regshift       = 2,
-               .uartclk        = 115200 * 16,
-       },
-       { },
-};
-
-static struct platform_device og_uart = {
-       .name                   = "serial8250",
-       .id                     = 0,
-       .dev.platform_data      = og_uart_data,
-       .num_resources          = 1,
-       .resource               = og_uart_resources
-};
-
-static struct platform_device *og_devices[] __initdata = {
-       &og_uart
-};
-
-static void __init og_init(void)
-{
-       ks8695_register_gpios();
-
-       if (machine_is_cm4002()) {
-               ks8695_gpio_interrupt(KS8695_GPIO_1, IRQ_TYPE_LEVEL_HIGH);
-               iotable_init(og_io_desc, ARRAY_SIZE(og_io_desc));
-               platform_add_devices(og_devices, ARRAY_SIZE(og_devices));
-       } else {
-               og_pci_bus_reset();
-               og_register_pci();
-       }
-
-       ks8695_add_device_lan();
-       ks8695_add_device_wan();
-}
-
-#ifdef CONFIG_MACH_CM4002
-MACHINE_START(CM4002, "OpenGear/CM4002")
-       /* OpenGear Inc. */
-       .atag_offset    = 0x100,
-       .map_io         = ks8695_map_io,
-       .init_irq       = ks8695_init_irq,
-       .init_machine   = og_init,
-       .init_time      = ks8695_timer_init,
-       .restart        = ks8695_restart,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_CM4008
-MACHINE_START(CM4008, "OpenGear/CM4008")
-       /* OpenGear Inc. */
-       .atag_offset    = 0x100,
-       .map_io         = ks8695_map_io,
-       .init_irq       = ks8695_init_irq,
-       .init_machine   = og_init,
-       .init_time      = ks8695_timer_init,
-       .restart        = ks8695_restart,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_CM41xx
-MACHINE_START(CM41XX, "OpenGear/CM41xx")
-       /* OpenGear Inc. */
-       .atag_offset    = 0x100,
-       .map_io         = ks8695_map_io,
-       .init_irq       = ks8695_init_irq,
-       .init_machine   = og_init,
-       .init_time      = ks8695_timer_init,
-       .restart        = ks8695_restart,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_IM4004
-MACHINE_START(IM4004, "OpenGear/IM4004")
-       /* OpenGear Inc. */
-       .atag_offset    = 0x100,
-       .map_io         = ks8695_map_io,
-       .init_irq       = ks8695_init_irq,
-       .init_machine   = og_init,
-       .init_time      = ks8695_timer_init,
-       .restart        = ks8695_restart,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_IM42xx
-MACHINE_START(IM42XX, "OpenGear/IM42xx")
-       /* OpenGear Inc. */
-       .atag_offset    = 0x100,
-       .map_io         = ks8695_map_io,
-       .init_irq       = ks8695_init_irq,
-       .init_machine   = og_init,
-       .init_time      = ks8695_timer_init,
-       .restart        = ks8695_restart,
-MACHINE_END
-#endif
diff --git a/arch/arm/mach-ks8695/board-sg.c b/arch/arm/mach-ks8695/board-sg.c
deleted file mode 100644 (file)
index d5ec85a..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * board-sg.c -- support for the SnapGear KS8695 based boards
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/partitions.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include "devices.h"
-#include "generic.h"
-
-/*
- * The SG310 machine type is fitted with a conventional 8MB Strataflash
- * device. Define its partitioning.
- */
-#define        FL_BASE         0x02000000
-#define        FL_SIZE         SZ_8M
-
-static struct mtd_partition sg_mtd_partitions[] = {
-       [0] = {
-               .name   = "SnapGear Boot Loader",
-               .size   = SZ_128K,
-       },
-       [1] = {
-               .name   = "SnapGear non-volatile configuration",
-               .size   = SZ_512K,
-               .offset = SZ_256K,
-       },
-       [2] = {
-               .name   = "SnapGear image",
-               .offset = SZ_512K + SZ_256K,
-       },
-       [3] = {
-               .name   = "SnapGear StrataFlash",
-       },
-       [4] = {
-               .name   = "SnapGear Boot Tags",
-               .size   = SZ_128K,
-               .offset = SZ_128K,
-       },
-};
-
-static struct physmap_flash_data sg_mtd_pdata = {
-       .width          = 1,
-       .nr_parts       = ARRAY_SIZE(sg_mtd_partitions),
-       .parts          = sg_mtd_partitions,
-};
-
-
-static struct resource sg_mtd_resource[] = {
-       [0] = {
-               .start = FL_BASE,
-               .end   = FL_BASE + FL_SIZE - 1,
-               .flags = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device sg_mtd_device = {
-       .name           = "physmap-flash",
-       .id             = 0,
-       .num_resources  = ARRAY_SIZE(sg_mtd_resource),
-       .resource       = sg_mtd_resource,
-       .dev            = {
-               .platform_data = &sg_mtd_pdata,
-       },
-};
-
-static void __init sg_init(void)
-{
-       ks8695_add_device_lan();
-       ks8695_add_device_wan();
-
-       if (machine_is_sg310())
-               platform_device_register(&sg_mtd_device);
-}
-
-#ifdef CONFIG_MACH_LITE300
-MACHINE_START(LITE300, "SecureComputing/SG300")
-       /* SnapGear */
-       .atag_offset    = 0x100,
-       .map_io         = ks8695_map_io,
-       .init_irq       = ks8695_init_irq,
-       .init_machine   = sg_init,
-       .init_time      = ks8695_timer_init,
-       .restart        = ks8695_restart,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_SG310
-MACHINE_START(SG310, "McAfee/SG310")
-       /* SnapGear */
-       .atag_offset    = 0x100,
-       .map_io         = ks8695_map_io,
-       .init_irq       = ks8695_init_irq,
-       .init_machine   = sg_init,
-       .init_time      = ks8695_timer_init,
-       .restart        = ks8695_restart,
-MACHINE_END
-#endif
-
-#ifdef CONFIG_MACH_SE4200
-MACHINE_START(SE4200, "SecureComputing/SE4200")
-       /* SnapGear */
-       .atag_offset    = 0x100,
-       .map_io         = ks8695_map_io,
-       .init_irq       = ks8695_init_irq,
-       .init_machine   = sg_init,
-       .init_time      = ks8695_timer_init,
-       .restart        = ks8695_restart,
-MACHINE_END
-#endif
diff --git a/arch/arm/mach-ks8695/cpu.c b/arch/arm/mach-ks8695/cpu.c
deleted file mode 100644 (file)
index aa6bb0c..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * arch/arm/mach-ks8695/cpu.c
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- *
- * KS8695 CPU support
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "regs-sys.h"
-#include <mach/regs-misc.h>
-
-
-static struct map_desc ks8695_io_desc[] __initdata = {
-       {
-               .virtual        = (unsigned long)KS8695_IO_VA,
-               .pfn            = __phys_to_pfn(KS8695_IO_PA),
-               .length         = KS8695_IO_SIZE,
-               .type           = MT_DEVICE,
-       }
-};
-
-static void __init ks8695_processor_info(void)
-{
-       unsigned long id, rev;
-
-       id = __raw_readl(KS8695_MISC_VA + KS8695_DID);
-       rev = __raw_readl(KS8695_MISC_VA + KS8695_RID);
-
-       printk("KS8695 ID=%04lx  SubID=%02lx  Revision=%02lx\n", (id & DID_ID), (rev & RID_SUBID), (rev & RID_REVISION));
-}
-
-static unsigned int sysclk[8] = { 125000000, 100000000, 62500000, 50000000, 41700000, 33300000, 31300000, 25000000 };
-static unsigned int cpuclk[8] = { 166000000, 166000000, 83000000, 83000000, 55300000, 55300000, 41500000, 41500000 };
-
-static void __init ks8695_clock_info(void)
-{
-       unsigned int scdc = __raw_readl(KS8695_SYS_VA + KS8695_CLKCON) & CLKCON_SCDC;
-
-       printk("Clocks: System %u MHz, CPU %u MHz\n",
-                       sysclk[scdc] / 1000000, cpuclk[scdc] / 1000000);
-}
-
-void __init ks8695_map_io(void)
-{
-       iotable_init(ks8695_io_desc, ARRAY_SIZE(ks8695_io_desc));
-
-       ks8695_processor_info();
-       ks8695_clock_info();
-}
diff --git a/arch/arm/mach-ks8695/devices.c b/arch/arm/mach-ks8695/devices.c
deleted file mode 100644 (file)
index 61cf20b..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * arch/arm/mach-ks8695/devices.c
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-
-#include <mach/irqs.h>
-#include "regs-wan.h"
-#include "regs-lan.h"
-#include "regs-hpna.h"
-#include <mach/regs-switch.h>
-#include <mach/regs-misc.h>
-
-
-/* --------------------------------------------------------------------
- *  Ethernet
- * -------------------------------------------------------------------- */
-
-static u64 eth_dmamask = 0xffffffffUL;
-
-static struct resource ks8695_wan_resources[] = {
-       [0] = {
-               .start  = KS8695_WAN_PA,
-               .end    = KS8695_WAN_PA + 0x00ff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .name   = "WAN RX",
-               .start  = KS8695_IRQ_WAN_RX_STATUS,
-               .end    = KS8695_IRQ_WAN_RX_STATUS,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .name   = "WAN TX",
-               .start  = KS8695_IRQ_WAN_TX_STATUS,
-               .end    = KS8695_IRQ_WAN_TX_STATUS,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [3] = {
-               .name   = "WAN Link",
-               .start  = KS8695_IRQ_WAN_LINK,
-               .end    = KS8695_IRQ_WAN_LINK,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [4] = {
-               .name   = "WAN PHY",
-               .start  = KS8695_MISC_PA,
-               .end    = KS8695_MISC_PA + 0x1f,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device ks8695_wan_device = {
-       .name           = "ks8695_ether",
-       .id             = 0,
-       .dev            = {
-                               .dma_mask               = &eth_dmamask,
-                               .coherent_dma_mask      = 0xffffffff,
-       },
-       .resource       = ks8695_wan_resources,
-       .num_resources  = ARRAY_SIZE(ks8695_wan_resources),
-};
-
-
-static struct resource ks8695_lan_resources[] = {
-       [0] = {
-               .start  = KS8695_LAN_PA,
-               .end    = KS8695_LAN_PA + 0x00ff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .name   = "LAN RX",
-               .start  = KS8695_IRQ_LAN_RX_STATUS,
-               .end    = KS8695_IRQ_LAN_RX_STATUS,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .name   = "LAN TX",
-               .start  = KS8695_IRQ_LAN_TX_STATUS,
-               .end    = KS8695_IRQ_LAN_TX_STATUS,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [3] = {
-               .name   = "LAN SWITCH",
-               .start  = KS8695_SWITCH_PA,
-               .end    = KS8695_SWITCH_PA + 0x4f,
-               .flags  = IORESOURCE_MEM,
-       },
-};
-
-static struct platform_device ks8695_lan_device = {
-       .name           = "ks8695_ether",
-       .id             = 1,
-       .dev            = {
-                               .dma_mask               = &eth_dmamask,
-                               .coherent_dma_mask      = 0xffffffff,
-       },
-       .resource       = ks8695_lan_resources,
-       .num_resources  = ARRAY_SIZE(ks8695_lan_resources),
-};
-
-
-static struct resource ks8695_hpna_resources[] = {
-       [0] = {
-               .start  = KS8695_HPNA_PA,
-               .end    = KS8695_HPNA_PA + 0x00ff,
-               .flags  = IORESOURCE_MEM,
-       },
-       [1] = {
-               .name   = "HPNA RX",
-               .start  = KS8695_IRQ_HPNA_RX_STATUS,
-               .end    = KS8695_IRQ_HPNA_RX_STATUS,
-               .flags  = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .name   = "HPNA TX",
-               .start  = KS8695_IRQ_HPNA_TX_STATUS,
-               .end    = KS8695_IRQ_HPNA_TX_STATUS,
-               .flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct platform_device ks8695_hpna_device = {
-       .name           = "ks8695_ether",
-       .id             = 2,
-       .dev            = {
-                               .dma_mask               = &eth_dmamask,
-                               .coherent_dma_mask      = 0xffffffff,
-       },
-       .resource       = ks8695_hpna_resources,
-       .num_resources  = ARRAY_SIZE(ks8695_hpna_resources),
-};
-
-void __init ks8695_add_device_wan(void)
-{
-       platform_device_register(&ks8695_wan_device);
-}
-
-void __init ks8695_add_device_lan(void)
-{
-       platform_device_register(&ks8695_lan_device);
-}
-
-void __init ks8696_add_device_hpna(void)
-{
-       platform_device_register(&ks8695_hpna_device);
-}
-
-
-/* --------------------------------------------------------------------
- *  Watchdog
- * -------------------------------------------------------------------- */
-
-static struct platform_device ks8695_wdt_device = {
-       .name           = "ks8695_wdt",
-       .id             = -1,
-       .num_resources  = 0,
-};
-
-static void __init ks8695_add_device_watchdog(void)
-{
-       platform_device_register(&ks8695_wdt_device);
-}
-
-
-/* -------------------------------------------------------------------- */
-
-/*
- * These devices are always present and don't need any board-specific
- * setup.
- */
-static int __init ks8695_add_standard_devices(void)
-{
-       ks8695_add_device_watchdog();
-       return 0;
-}
-
-arch_initcall(ks8695_add_standard_devices);
diff --git a/arch/arm/mach-ks8695/devices.h b/arch/arm/mach-ks8695/devices.h
deleted file mode 100644 (file)
index cc23ee3..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ks8695/include/mach/devices.h
- *
- * Copyright (C) 2006 Andrew Victor
- */
-
-#ifndef __ASM_ARCH_DEVICES_H
-#define __ASM_ARCH_DEVICES_H
-
-#include <linux/pci.h>
-
- /* Ethernet */
-extern void __init ks8695_add_device_wan(void);
-extern void __init ks8695_add_device_lan(void);
-extern void __init ks8695_add_device_hpna(void);
-
- /* PCI */
-#define KS8695_MODE_PCI                0
-#define KS8695_MODE_MINIPCI    1
-#define KS8695_MODE_CARDBUS    2
-
-struct ks8695_pci_cfg {
-       short mode;
-       int (*map_irq)(const struct pci_dev *, u8, u8);
-};
-extern __init void ks8695_init_pci(struct ks8695_pci_cfg *);
-
-#endif
diff --git a/arch/arm/mach-ks8695/generic.h b/arch/arm/mach-ks8695/generic.h
deleted file mode 100644 (file)
index 9e9cbdd..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-ks8695/generic.h
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
-*/
-
-extern __init void ks8695_map_io(void);
-extern __init void ks8695_init_irq(void);
-extern void ks8695_restart(enum reboot_mode, const char *);
-extern void ks8695_timer_init(void);
diff --git a/arch/arm/mach-ks8695/include/mach/entry-macro.S b/arch/arm/mach-ks8695/include/mach/entry-macro.S
deleted file mode 100644 (file)
index 7ff812c..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/entry-macro.S
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- *
- * Low-level IRQ helper macros for KS8695
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
-*/
-
-#include <mach/hardware.h>
-#include <mach/regs-irq.h>
-
-       .macro  get_irqnr_preamble, base, tmp
-               ldr     \base, =KS8695_IRQ_VA                   @ Base address of interrupt controller
-       .endm
-
-       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-               ldr     \irqstat, [\base, #KS8695_INTMS]        @ Mask Status register
-
-               teq     \irqstat, #0
-               beq     1001f
-
-               mov     \irqnr, #0
-
-               tst     \irqstat, #0xff
-               moveq   \irqstat, \irqstat, lsr #8
-               addeq   \irqnr, \irqnr, #8
-               tsteq   \irqstat, #0xff
-               moveq   \irqstat, \irqstat, lsr #8
-               addeq   \irqnr, \irqnr, #8
-               tsteq   \irqstat, #0xff
-               moveq   \irqstat, \irqstat, lsr #8
-               addeq   \irqnr, \irqnr, #8
-               tst     \irqstat, #0x0f
-               moveq   \irqstat, \irqstat, lsr #4
-               addeq   \irqnr, \irqnr, #4
-               tst     \irqstat, #0x03
-               moveq   \irqstat, \irqstat, lsr #2
-               addeq   \irqnr, \irqnr, #2
-               tst     \irqstat, #0x01
-               addseq  \irqnr, \irqnr, #1
-1001:
-       .endm
diff --git a/arch/arm/mach-ks8695/include/mach/gpio-ks8695.h b/arch/arm/mach-ks8695/include/mach/gpio-ks8695.h
deleted file mode 100644 (file)
index 600115f..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) 2006 Andrew Victor
- */
-
-#ifndef __MACH_KS8659_GPIO_H
-#define __MACH_KS8659_GPIO_H
-
-#include <linux/kernel.h>
-
-#define KS8695_GPIO_0          0
-#define KS8695_GPIO_1          1
-#define KS8695_GPIO_2          2
-#define KS8695_GPIO_3          3
-#define KS8695_GPIO_4          4
-#define KS8695_GPIO_5          5
-#define KS8695_GPIO_6          6
-#define KS8695_GPIO_7          7
-#define KS8695_GPIO_8          8
-#define KS8695_GPIO_9          9
-#define KS8695_GPIO_10         10
-#define KS8695_GPIO_11         11
-#define KS8695_GPIO_12         12
-#define KS8695_GPIO_13         13
-#define KS8695_GPIO_14         14
-#define KS8695_GPIO_15         15
-
-/*
- * Configure GPIO pin as external interrupt source.
- */
-extern int ks8695_gpio_interrupt(unsigned int pin, unsigned int type);
-
-/* Register the GPIOs */
-extern void ks8695_register_gpios(void);
-
-#endif /* __MACH_KS8659_GPIO_H */
diff --git a/arch/arm/mach-ks8695/include/mach/hardware.h b/arch/arm/mach-ks8695/include/mach/hardware.h
deleted file mode 100644 (file)
index 0fb889b..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ks8695/include/mach/hardware.h
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- *
- * KS8695 - Memory Map definitions
-*/
-
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include <linux/sizes.h>
-
-/*
- * Clocks are derived from MCLK, which is 25MHz
- */
-#define KS8695_CLOCK_RATE      25000000
-
-/*
- * Physical RAM address.
- */
-#define KS8695_SDRAM_PA                0x00000000
-
-
-/*
- * We map an entire MiB with the System Configuration Registers in even
- * though only 64KiB is needed. This makes it easier for use with the
- * head debug code as the initial MMU setup only deals in L1 sections.
- */
-#define KS8695_IO_PA           0x03F00000
-#define KS8695_IO_VA           IOMEM(0xF0000000)
-#define KS8695_IO_SIZE         SZ_1M
-
-#define KS8695_PCIMEM_PA       0x60000000
-#define KS8695_PCIMEM_SIZE     SZ_512M
-
-#define KS8695_PCIIO_PA                0x80000000
-#define KS8695_PCIIO_SIZE      SZ_64K
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/irqs.h b/arch/arm/mach-ks8695/include/mach/irqs.h
deleted file mode 100644 (file)
index 0cbb306..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ks8695/include/mach/irqs.h
- *
- * Copyright (C) 2006 Simtec Electronics
- *   Ben Dooks <ben@simtec.co.uk>
- */
-
-#ifndef __ASM_ARCH_IRQS_H
-#define __ASM_ARCH_IRQS_H
-
-
-#define NR_IRQS                                32
-
-/*
- * IRQ definitions
- */
-#define KS8695_IRQ_COMM_RX             0
-#define KS8695_IRQ_COMM_TX             1
-#define KS8695_IRQ_EXTERN0             2
-#define KS8695_IRQ_EXTERN1             3
-#define KS8695_IRQ_EXTERN2             4
-#define KS8695_IRQ_EXTERN3             5
-#define KS8695_IRQ_TIMER0              6
-#define KS8695_IRQ_TIMER1              7
-#define KS8695_IRQ_UART_TX             8
-#define KS8695_IRQ_UART_RX             9
-#define KS8695_IRQ_UART_LINE_STATUS    10
-#define KS8695_IRQ_UART_MODEM_STATUS   11
-#define KS8695_IRQ_LAN_RX_STOP         12
-#define KS8695_IRQ_LAN_TX_STOP         13
-#define KS8695_IRQ_LAN_RX_BUF          14
-#define KS8695_IRQ_LAN_TX_BUF          15
-#define KS8695_IRQ_LAN_RX_STATUS       16
-#define KS8695_IRQ_LAN_TX_STATUS       17
-#define KS8695_IRQ_HPNA_RX_STOP                18
-#define KS8695_IRQ_HPNA_TX_STOP                19
-#define KS8695_IRQ_HPNA_RX_BUF         20
-#define KS8695_IRQ_HPNA_TX_BUF         21
-#define KS8695_IRQ_HPNA_RX_STATUS      22
-#define KS8695_IRQ_HPNA_TX_STATUS      23
-#define KS8695_IRQ_BUS_ERROR           24
-#define KS8695_IRQ_WAN_RX_STOP         25
-#define KS8695_IRQ_WAN_TX_STOP         26
-#define KS8695_IRQ_WAN_RX_BUF          27
-#define KS8695_IRQ_WAN_TX_BUF          28
-#define KS8695_IRQ_WAN_RX_STATUS       29
-#define KS8695_IRQ_WAN_TX_STATUS       30
-#define KS8695_IRQ_WAN_LINK            31
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/memory.h b/arch/arm/mach-ks8695/include/mach/memory.h
deleted file mode 100644 (file)
index ab0d27f..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/memory.h
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * KS8695 Memory definitions
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-#include <mach/hardware.h>
-
-#ifndef __ASSEMBLY__
-
-#ifdef CONFIG_PCI
-
-/* PCI mappings */
-#define __virt_to_bus(x)       ((x) - PAGE_OFFSET + KS8695_PCIMEM_PA)
-#define __bus_to_virt(x)       ((x) - KS8695_PCIMEM_PA + PAGE_OFFSET)
-
-/* Platform-bus mapping */
-extern struct bus_type platform_bus_type;
-#define is_lbus_device(dev)            (dev && dev->bus == &platform_bus_type)
-#define __arch_dma_to_virt(dev, x)     ({ (void *) (is_lbus_device(dev) ? \
-                                       __phys_to_virt(x) : __bus_to_virt(x)); })
-#define __arch_virt_to_dma(dev, x)     ({ is_lbus_device(dev) ? \
-                                       (dma_addr_t)__virt_to_phys((unsigned long)x) \
-                                       : (dma_addr_t)__virt_to_bus(x); })
-#define __arch_pfn_to_dma(dev, pfn)    \
-       ({ dma_addr_t __dma = __pfn_to_phys(pfn); \
-          if (!is_lbus_device(dev)) \
-               __dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \
-          __dma; })
-
-#define __arch_dma_to_pfn(dev, x)      \
-       ({ dma_addr_t __dma = x;                                \
-          if (!is_lbus_device(dev))                            \
-               __dma += PHYS_OFFSET - KS8695_PCIMEM_PA;        \
-          __phys_to_pfn(__dma);                                \
-       })
-
-#endif
-
-#endif
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-gpio.h b/arch/arm/mach-ks8695/include/mach/regs-gpio.h
deleted file mode 100644 (file)
index 90614a7..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-gpio.h
- *
- * Copyright (C) 2007 Andrew Victor
- *
- * KS8695 - GPIO control registers and bit definitions.
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef KS8695_GPIO_H
-#define KS8695_GPIO_H
-
-#define KS8695_GPIO_OFFSET     (0xF0000 + 0xE600)
-#define KS8695_GPIO_VA         (KS8695_IO_VA + KS8695_GPIO_OFFSET)
-#define KS8695_GPIO_PA         (KS8695_IO_PA + KS8695_GPIO_OFFSET)
-
-
-#define KS8695_IOPM            (0x00)          /* I/O Port Mode Register */
-#define KS8695_IOPC            (0x04)          /* I/O Port Control Register */
-#define KS8695_IOPD            (0x08)          /* I/O Port Data Register */
-
-
-/* Port Mode Register */
-#define IOPM(x)                        (1 << (x))      /* Mode for GPIO Pin x */
-
-/* Port Control Register */
-#define IOPC_IOTIM1EN          (1 << 17)       /* GPIO Pin for Timer1 Enable */
-#define IOPC_IOTIM0EN          (1 << 16)       /* GPIO Pin for Timer0 Enable */
-#define IOPC_IOEINT3EN         (1 << 15)       /* GPIO Pin for External/Soft Interrupt 3 Enable */
-#define IOPC_IOEINT3TM         (7 << 12)       /* GPIO Pin for External/Soft Interrupt 3 Trigger Mode */
-#define IOPC_IOEINT3_MODE(x)   ((x) << 12)
-#define IOPC_IOEINT2EN         (1 << 11)       /* GPIO Pin for External/Soft Interrupt 2 Enable */
-#define IOPC_IOEINT2TM         (7 << 8)        /* GPIO Pin for External/Soft Interrupt 2 Trigger Mode */
-#define IOPC_IOEINT2_MODE(x)   ((x) << 8)
-#define IOPC_IOEINT1EN         (1 << 7)        /* GPIO Pin for External/Soft Interrupt 1 Enable */
-#define IOPC_IOEINT1TM         (7 << 4)        /* GPIO Pin for External/Soft Interrupt 1 Trigger Mode */
-#define IOPC_IOEINT1_MODE(x)   ((x) << 4)
-#define IOPC_IOEINT0EN         (1 << 3)        /* GPIO Pin for External/Soft Interrupt 0 Enable */
-#define IOPC_IOEINT0TM         (7 << 0)        /* GPIO Pin for External/Soft Interrupt 0 Trigger Mode */
-#define IOPC_IOEINT0_MODE(x)   ((x) << 0)
-
- /* Trigger Modes */
-#define IOPC_TM_LOW            (0)             /* Level Detection (Active Low) */
-#define IOPC_TM_HIGH           (1)             /* Level Detection (Active High) */
-#define IOPC_TM_RISING         (2)             /* Rising Edge Detection */
-#define IOPC_TM_FALLING                (4)             /* Falling Edge Detection */
-#define IOPC_TM_EDGE           (6)             /* Both Edge Detection */
-
-/* Port Data Register */
-#define IOPD(x)                        (1 << (x))      /* Signal Level of GPIO Pin x */
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-irq.h b/arch/arm/mach-ks8695/include/mach/regs-irq.h
deleted file mode 100644 (file)
index 352b7e8..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-irq.h
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- *
- * KS8695 - IRQ registers and bit definitions
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef KS8695_IRQ_H
-#define KS8695_IRQ_H
-
-#define KS8695_IRQ_OFFSET      (0xF0000 + 0xE200)
-#define KS8695_IRQ_VA          (KS8695_IO_VA + KS8695_IRQ_OFFSET)
-#define KS8695_IRQ_PA          (KS8695_IO_PA + KS8695_IRQ_OFFSET)
-
-
-/*
- * Interrupt Controller registers
- */
-#define KS8695_INTMC           (0x00)          /* Mode Control Register */
-#define KS8695_INTEN           (0x04)          /* Interrupt Enable Register */
-#define KS8695_INTST           (0x08)          /* Interrupt Status Register */
-#define KS8695_INTPW           (0x0c)          /* Interrupt Priority (WAN MAC) */
-#define KS8695_INTPH           (0x10)          /* Interrupt Priority (HPNA) [KS8695 only] */
-#define KS8695_INTPL           (0x14)          /* Interrupt Priority (LAN MAC) */
-#define KS8695_INTPT           (0x18)          /* Interrupt Priority (Timer) */
-#define KS8695_INTPU           (0x1c)          /* Interrupt Priority (UART) */
-#define KS8695_INTPE           (0x20)          /* Interrupt Priority (External Interrupt) */
-#define KS8695_INTPC           (0x24)          /* Interrupt Priority (Communications Channel) */
-#define KS8695_INTPBE          (0x28)          /* Interrupt Priority (Bus Error Response) */
-#define KS8695_INTMS           (0x2c)          /* Interrupt Mask Status Register */
-#define KS8695_INTHPF          (0x30)          /* Interrupt Pending Highest Priority (FIQ) */
-#define KS8695_INTHPI          (0x34)          /* Interrupt Pending Highest Priority (IRQ) */
-
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-misc.h b/arch/arm/mach-ks8695/include/mach/regs-misc.h
deleted file mode 100644 (file)
index 2740c52..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-misc.h
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * KS8695 - Miscellaneous Registers
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef KS8695_MISC_H
-#define KS8695_MISC_H
-
-#define KS8695_MISC_OFFSET     (0xF0000 + 0xEA00)
-#define KS8695_MISC_VA         (KS8695_IO_VA + KS8695_MISC_OFFSET)
-#define KS8695_MISC_PA         (KS8695_IO_PA + KS8695_MISC_OFFSET)
-
-
-/*
- * Miscellaneous registers
- */
-#define KS8695_DID             (0x00)          /* Device ID */
-#define KS8695_RID             (0x04)          /* Revision ID */
-#define KS8695_HMC             (0x08)          /* HPNA Miscellaneous Control [KS8695 only] */
-#define KS8695_WMC             (0x0c)          /* WAN Miscellaneous Control */
-#define KS8695_WPPM            (0x10)          /* WAN PHY Power Management */
-#define KS8695_PPS             (0x1c)          /* PHY PowerSave */
-
-/* Device ID Register */
-#define DID_ID                 (0xffff << 0)   /* Device ID */
-
-/* Revision ID Register */
-#define RID_SUBID              (0xf << 4)      /* Sub-Device ID */
-#define RID_REVISION           (0xf << 0)      /* Revision ID */
-
-/* HPNA Miscellaneous Control Register */
-#define HMC_HSS                        (1 << 1)        /* Speed */
-#define HMC_HDS                        (1 << 0)        /* Duplex */
-
-/* WAN Miscellaneous Control Register */
-#define WMC_WANC               (1 << 30)       /* Auto-negotiation complete */
-#define WMC_WANR               (1 << 29)       /* Auto-negotiation restart */
-#define WMC_WANAP              (1 << 28)       /* Advertise Pause */
-#define WMC_WANA100F           (1 << 27)       /* Advertise 100 FDX */
-#define WMC_WANA100H           (1 << 26)       /* Advertise 100 HDX */
-#define WMC_WANA10F            (1 << 25)       /* Advertise 10 FDX */
-#define WMC_WANA10H            (1 << 24)       /* Advertise 10 HDX */
-#define WMC_WLS                        (1 << 23)       /* Link status */
-#define WMC_WDS                        (1 << 22)       /* Duplex status */
-#define WMC_WSS                        (1 << 21)       /* Speed status */
-#define WMC_WLPP               (1 << 20)       /* Link Partner Pause */
-#define WMC_WLP100F            (1 << 19)       /* Link Partner 100 FDX */
-#define WMC_WLP100H            (1 << 18)       /* Link Partner 100 HDX */
-#define WMC_WLP10F             (1 << 17)       /* Link Partner 10 FDX */
-#define WMC_WLP10H             (1 << 16)       /* Link Partner 10 HDX */
-#define WMC_WAND               (1 << 15)       /* Auto-negotiation disable */
-#define WMC_WANF100            (1 << 14)       /* Force 100 */
-#define WMC_WANFF              (1 << 13)       /* Force FDX */
-#define WMC_WLED1S             (7 <<  4)       /* LED1 Select */
-#define                WLED1S_SPEED            (0 << 4)
-#define                WLED1S_LINK             (1 << 4)
-#define                WLED1S_DUPLEX           (2 << 4)
-#define                WLED1S_COLLISION        (3 << 4)
-#define                WLED1S_ACTIVITY         (4 << 4)
-#define                WLED1S_FDX_COLLISION    (5 << 4)
-#define                WLED1S_LINK_ACTIVITY    (6 << 4)
-#define WMC_WLED0S             (7 << 0)        /* LED0 Select */
-#define                WLED0S_SPEED            (0 << 0)
-#define                WLED0S_LINK             (1 << 0)
-#define                WLED0S_DUPLEX           (2 << 0)
-#define                WLED0S_COLLISION        (3 << 0)
-#define                WLED0S_ACTIVITY         (4 << 0)
-#define                WLED0S_FDX_COLLISION    (5 << 0)
-#define                WLED0S_LINK_ACTIVITY    (6 << 0)
-
-/* WAN PHY Power Management Register */
-#define WPPM_WLPBK             (1 << 14)       /* Local Loopback */
-#define WPPM_WRLPKB            (1 << 13)       /* Remove Loopback */
-#define WPPM_WPI               (1 << 12)       /* PHY isolate */
-#define WPPM_WFL               (1 << 10)       /* Force link */
-#define WPPM_MDIXS             (1 << 9)        /* MDIX Status */
-#define WPPM_FEF               (1 << 8)        /* Far End Fault */
-#define WPPM_AMDIXP            (1 << 7)        /* Auto MDIX Parameter */
-#define WPPM_TXDIS             (1 << 6)        /* Disable transmitter */
-#define WPPM_DFEF              (1 << 5)        /* Disable Far End Fault */
-#define WPPM_PD                        (1 << 4)        /* Power Down */
-#define WPPM_DMDX              (1 << 3)        /* Disable Auto MDI/MDIX */
-#define WPPM_FMDX              (1 << 2)        /* Force MDIX */
-#define WPPM_LPBK              (1 << 1)        /* MAX Loopback */
-
-/* PHY Power Save Register */
-#define PPS_PPSM               (1 << 0)        /* PHY Power Save Mode */
-
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-switch.h b/arch/arm/mach-ks8695/include/mach/regs-switch.h
deleted file mode 100644 (file)
index 97e8acb..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-switch.h
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * KS8695 - Switch Registers and bit definitions.
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef KS8695_SWITCH_H
-#define KS8695_SWITCH_H
-
-#define KS8695_SWITCH_OFFSET   (0xF0000 + 0xe800)
-#define KS8695_SWITCH_VA       (KS8695_IO_VA + KS8695_SWITCH_OFFSET)
-#define KS8695_SWITCH_PA       (KS8695_IO_PA + KS8695_SWITCH_OFFSET)
-
-
-/*
- * Switch registers
- */
-#define KS8695_SEC0            (0x00)          /* Switch Engine Control 0 */
-#define KS8695_SEC1            (0x04)          /* Switch Engine Control 1 */
-#define KS8695_SEC2            (0x08)          /* Switch Engine Control 2 */
-
-#define KS8695_SEPXCZ(x,z)     (0x0c + (((x)-1)*3 + ((z)-1))*4)        /* Port Configuration Registers */
-
-#define KS8695_SEP12AN         (0x48)          /* Port 1 & 2 Auto-Negotiation */
-#define KS8695_SEP34AN         (0x4c)          /* Port 3 & 4 Auto-Negotiation */
-#define KS8695_SEIAC           (0x50)          /* Indirect Access Control */
-#define KS8695_SEIADH2         (0x54)          /* Indirect Access Data High 2 */
-#define KS8695_SEIADH1         (0x58)          /* Indirect Access Data High 1 */
-#define KS8695_SEIADL          (0x5c)          /* Indirect Access Data Low */
-#define KS8695_SEAFC           (0x60)          /* Advance Feature Control */
-#define KS8695_SEDSCPH         (0x64)          /* TOS Priority High */
-#define KS8695_SEDSCPL         (0x68)          /* TOS Priority Low */
-#define KS8695_SEMAH           (0x6c)          /* Switch Engine MAC Address High */
-#define KS8695_SEMAL           (0x70)          /* Switch Engine MAC Address Low */
-#define KS8695_LPPM12          (0x74)          /* Port 1 & 2 PHY Power Management */
-#define KS8695_LPPM34          (0x78)          /* Port 3 & 4 PHY Power Management */
-
-
-/* Switch Engine Control 0 */
-#define SEC0_LLED1S            (7 << 25)       /* LED1 Select */
-#define                LLED1S_SPEED            (0 << 25)
-#define                LLED1S_LINK             (1 << 25)
-#define                LLED1S_DUPLEX           (2 << 25)
-#define                LLED1S_COLLISION        (3 << 25)
-#define                LLED1S_ACTIVITY         (4 << 25)
-#define                LLED1S_FDX_COLLISION    (5 << 25)
-#define                LLED1S_LINK_ACTIVITY    (6 << 25)
-#define SEC0_LLED0S            (7 << 22)       /* LED0 Select */
-#define                LLED0S_SPEED            (0 << 22)
-#define                LLED0S_LINK             (1 << 22)
-#define                LLED0S_DUPLEX           (2 << 22)
-#define                LLED0S_COLLISION        (3 << 22)
-#define                LLED0S_ACTIVITY         (4 << 22)
-#define                LLED0S_FDX_COLLISION    (5 << 22)
-#define                LLED0S_LINK_ACTIVITY    (6 << 22)
-#define SEC0_ENABLE            (1 << 0)        /* Enable Switch */
-
-
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/regs-uart.h b/arch/arm/mach-ks8695/include/mach/regs-uart.h
deleted file mode 100644 (file)
index 941a542..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ks8695/include/mach/regs-uart.h
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- *
- * KS8695 - UART register and bit definitions.
- */
-
-#ifndef KS8695_UART_H
-#define KS8695_UART_H
-
-#define KS8695_UART_OFFSET     (0xF0000 + 0xE000)
-#define KS8695_UART_VA         (KS8695_IO_VA + KS8695_UART_OFFSET)
-#define KS8695_UART_PA         (KS8695_IO_PA + KS8695_UART_OFFSET)
-
-
-/*
- * UART registers
- */
-#define KS8695_URRB    (0x00)          /* Receive Buffer Register */
-#define KS8695_URTH    (0x04)          /* Transmit Holding Register */
-#define KS8695_URFC    (0x08)          /* FIFO Control Register */
-#define KS8695_URLC    (0x0C)          /* Line Control Register */
-#define KS8695_URMC    (0x10)          /* Modem Control Register */
-#define KS8695_URLS    (0x14)          /* Line Status Register */
-#define KS8695_URMS    (0x18)          /* Modem Status Register */
-#define KS8695_URBD    (0x1C)          /* Baud Rate Divisor Register */
-#define KS8695_USR     (0x20)          /* Status Register */
-
-
-/* FIFO Control Register */
-#define URFC_URFRT     (3 << 6)        /* Receive FIFO Trigger Level */
-#define                URFC_URFRT_1    (0 << 6)
-#define                URFC_URFRT_4    (1 << 6)
-#define                URFC_URFRT_8    (2 << 6)
-#define                URFC_URFRT_14   (3 << 6)
-#define URFC_URTFR     (1 << 2)        /* Transmit FIFO Reset */
-#define URFC_URRFR     (1 << 1)        /* Receive FIFO Reset */
-#define URFC_URFE      (1 << 0)        /* FIFO Enable */
-
-/* Line Control Register */
-#define URLC_URSBC     (1 << 6)        /* Set Break Condition */
-#define URLC_PARITY    (7 << 3)        /* Parity */
-#define                URPE_NONE       (0 << 3)
-#define                URPE_ODD        (1 << 3)
-#define                URPE_EVEN       (3 << 3)
-#define                URPE_MARK       (5 << 3)
-#define                URPE_SPACE      (7 << 3)
-#define URLC_URSB      (1 << 2)        /* Stop Bits */
-#define URLC_URCL      (3 << 0)        /* Character Length */
-#define                URCL_5          (0 << 0)
-#define                URCL_6          (1 << 0)
-#define                URCL_7          (2 << 0)
-#define                URCL_8          (3 << 0)
-
-/* Modem Control Register */
-#define URMC_URLB      (1 << 4)        /* Loop-back mode */
-#define URMC_UROUT2    (1 << 3)        /* OUT2 signal */
-#define URMC_UROUT1    (1 << 2)        /* OUT1 signal */
-#define URMC_URRTS     (1 << 1)        /* Request to Send */
-#define URMC_URDTR     (1 << 0)        /* Data Terminal Ready */
-
-/* Line Status Register */
-#define URLS_URRFE     (1 << 7)        /* Receive FIFO Error */
-#define URLS_URTE      (1 << 6)        /* Transmit Empty */
-#define URLS_URTHRE    (1 << 5)        /* Transmit Holding Register Empty */
-#define URLS_URBI      (1 << 4)        /* Break Interrupt */
-#define URLS_URFE      (1 << 3)        /* Framing Error */
-#define URLS_URPE      (1 << 2)        /* Parity Error */
-#define URLS_URROE     (1 << 1)        /* Receive Overrun Error */
-#define URLS_URDR      (1 << 0)        /* Receive Data Ready */
-
-/* Modem Status Register */
-#define URMS_URDCD     (1 << 7)        /* Data Carrier Detect */
-#define URMS_URRI      (1 << 6)        /* Ring Indicator */
-#define URMS_URDSR     (1 << 5)        /* Data Set Ready */
-#define URMS_URCTS     (1 << 4)        /* Clear to Send */
-#define URMS_URDDCD    (1 << 3)        /* Delta Data Carrier Detect */
-#define URMS_URTERI    (1 << 2)        /* Trailing Edge Ring Indicator */
-#define URMS_URDDST    (1 << 1)        /* Delta Data Set Ready */
-#define URMS_URDCTS    (1 << 0)        /* Delta Clear to Send */
-
-/* Status Register */
-#define USR_UTI                (1 << 0)        /* Timeout Indication */
-
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/uncompress.h b/arch/arm/mach-ks8695/include/mach/uncompress.h
deleted file mode 100644 (file)
index dc78a29..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-ks8695/include/mach/uncompress.h
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- *
- * KS8695 - Kernel uncompressor
- */
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H
-
-#include <linux/io.h>
-#include <mach/regs-uart.h>
-
-static inline void putc(char c)
-{
-       while (!(__raw_readl((void __iomem*)KS8695_UART_PA + KS8695_URLS) & URLS_URTHRE))
-               barrier();
-
-       __raw_writel(c, (void __iomem*)KS8695_UART_PA + KS8695_URTH);
-}
-
-static inline void flush(void)
-{
-       while (!(__raw_readl((void __iomem*)KS8695_UART_PA + KS8695_URLS) & URLS_URTE))
-               barrier();
-}
-
-#define arch_decomp_setup()
-
-#endif
diff --git a/arch/arm/mach-ks8695/irq.c b/arch/arm/mach-ks8695/irq.c
deleted file mode 100644 (file)
index 4b7ec8d..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * arch/arm/mach-ks8695/irq.c
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-
-#include <asm/mach/irq.h>
-
-#include <mach/regs-irq.h>
-#include <mach/regs-gpio.h>
-
-static void ks8695_irq_mask(struct irq_data *d)
-{
-       unsigned long inten;
-
-       inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
-       inten &= ~(1 << d->irq);
-
-       __raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
-}
-
-static void ks8695_irq_unmask(struct irq_data *d)
-{
-       unsigned long inten;
-
-       inten = __raw_readl(KS8695_IRQ_VA + KS8695_INTEN);
-       inten |= (1 << d->irq);
-
-       __raw_writel(inten, KS8695_IRQ_VA + KS8695_INTEN);
-}
-
-static void ks8695_irq_ack(struct irq_data *d)
-{
-       __raw_writel((1 << d->irq), KS8695_IRQ_VA + KS8695_INTST);
-}
-
-
-static struct irq_chip ks8695_irq_level_chip;
-static struct irq_chip ks8695_irq_edge_chip;
-
-
-static int ks8695_irq_set_type(struct irq_data *d, unsigned int type)
-{
-       unsigned long ctrl, mode;
-       unsigned short level_triggered = 0;
-
-       ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
-
-       switch (type) {
-               case IRQ_TYPE_LEVEL_HIGH:
-                       mode = IOPC_TM_HIGH;
-                       level_triggered = 1;
-                       break;
-               case IRQ_TYPE_LEVEL_LOW:
-                       mode = IOPC_TM_LOW;
-                       level_triggered = 1;
-                       break;
-               case IRQ_TYPE_EDGE_RISING:
-                       mode = IOPC_TM_RISING;
-                       break;
-               case IRQ_TYPE_EDGE_FALLING:
-                       mode = IOPC_TM_FALLING;
-                       break;
-               case IRQ_TYPE_EDGE_BOTH:
-                       mode = IOPC_TM_EDGE;
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-       switch (d->irq) {
-               case KS8695_IRQ_EXTERN0:
-                       ctrl &= ~IOPC_IOEINT0TM;
-                       ctrl |= IOPC_IOEINT0_MODE(mode);
-                       break;
-               case KS8695_IRQ_EXTERN1:
-                       ctrl &= ~IOPC_IOEINT1TM;
-                       ctrl |= IOPC_IOEINT1_MODE(mode);
-                       break;
-               case KS8695_IRQ_EXTERN2:
-                       ctrl &= ~IOPC_IOEINT2TM;
-                       ctrl |= IOPC_IOEINT2_MODE(mode);
-                       break;
-               case KS8695_IRQ_EXTERN3:
-                       ctrl &= ~IOPC_IOEINT3TM;
-                       ctrl |= IOPC_IOEINT3_MODE(mode);
-                       break;
-               default:
-                       return -EINVAL;
-       }
-
-       if (level_triggered) {
-               irq_set_chip_and_handler(d->irq, &ks8695_irq_level_chip,
-                                        handle_level_irq);
-       }
-       else {
-               irq_set_chip_and_handler(d->irq, &ks8695_irq_edge_chip,
-                                        handle_edge_irq);
-       }
-
-       __raw_writel(ctrl, KS8695_GPIO_VA + KS8695_IOPC);
-       return 0;
-}
-
-static struct irq_chip ks8695_irq_level_chip = {
-       .irq_ack        = ks8695_irq_mask,
-       .irq_mask       = ks8695_irq_mask,
-       .irq_unmask     = ks8695_irq_unmask,
-       .irq_set_type   = ks8695_irq_set_type,
-};
-
-static struct irq_chip ks8695_irq_edge_chip = {
-       .irq_ack        = ks8695_irq_ack,
-       .irq_mask       = ks8695_irq_mask,
-       .irq_unmask     = ks8695_irq_unmask,
-       .irq_set_type   = ks8695_irq_set_type,
-};
-
-void __init ks8695_init_irq(void)
-{
-       unsigned int irq;
-
-       /* Disable all interrupts initially */
-       __raw_writel(0, KS8695_IRQ_VA + KS8695_INTMC);
-       __raw_writel(0, KS8695_IRQ_VA + KS8695_INTEN);
-
-       for (irq = 0; irq < NR_IRQS; irq++) {
-               switch (irq) {
-                       /* Level-triggered interrupts */
-                       case KS8695_IRQ_BUS_ERROR:
-                       case KS8695_IRQ_UART_MODEM_STATUS:
-                       case KS8695_IRQ_UART_LINE_STATUS:
-                       case KS8695_IRQ_UART_RX:
-                       case KS8695_IRQ_COMM_TX:
-                       case KS8695_IRQ_COMM_RX:
-                               irq_set_chip_and_handler(irq,
-                                                        &ks8695_irq_level_chip,
-                                                        handle_level_irq);
-                               break;
-
-                       /* Edge-triggered interrupts */
-                       default:
-                               /* clear pending bit */
-                               ks8695_irq_ack(irq_get_irq_data(irq));
-                               irq_set_chip_and_handler(irq,
-                                                        &ks8695_irq_edge_chip,
-                                                        handle_edge_irq);
-               }
-
-               irq_clear_status_flags(irq, IRQ_NOREQUEST);
-       }
-}
diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c
deleted file mode 100644 (file)
index 83f330b..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * arch/arm/mach-ks8695/pci.c
- *
- *  Copyright (C) 2003, Micrel Semiconductors
- *  Copyright (C) 2006, Greg Ungerer <gerg@snapgear.com>
- *  Copyright (C) 2006, Ben Dooks
- *  Copyright (C) 2007, Andrew Victor
- */
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-
-#include <asm/signal.h>
-#include <asm/mach/pci.h>
-#include <mach/hardware.h>
-
-#include "devices.h"
-#include "regs-pci.h"
-
-
-static int pci_dbg;
-
-static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsigned int where)
-{
-       unsigned long pbca;
-
-       pbca = PBCA_ENABLE | (where & ~3);
-       pbca |= PCI_SLOT(devfn) << 11 ;
-       pbca |= PCI_FUNC(devfn) << 8;
-       pbca |= bus_nr << 16;
-
-       if (bus_nr == 0) {
-               /* use Type-0 transaction */
-               __raw_writel(pbca, KS8695_PCI_VA + KS8695_PBCA);
-       } else {
-               /* use Type-1 transaction */
-               __raw_writel(pbca | PBCA_TYPE1, KS8695_PCI_VA + KS8695_PBCA);
-       }
-}
-
-static void __iomem *ks8695_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
-                                       int where)
-{
-       ks8695_pci_setupconfig(bus->number, devfn, where);
-       return KS8695_PCI_VA +  KS8695_PBCD;
-}
-
-static void ks8695_local_writeconfig(int where, u32 value)
-{
-       ks8695_pci_setupconfig(0, 0, where);
-       __raw_writel(value, KS8695_PCI_VA + KS8695_PBCD);
-}
-
-static struct pci_ops ks8695_pci_ops = {
-       .map_bus = ks8695_pci_map_bus,
-       .read   = pci_generic_config_read32,
-       .write  = pci_generic_config_write32,
-};
-
-static struct resource pci_mem = {
-       .name   = "PCI Memory space",
-       .start  = KS8695_PCIMEM_PA,
-       .end    = KS8695_PCIMEM_PA + (KS8695_PCIMEM_SIZE - 1),
-       .flags  = IORESOURCE_MEM,
-};
-
-static struct resource pci_io = {
-       .name   = "PCI IO space",
-       .start  = KS8695_PCIIO_PA,
-       .end    = KS8695_PCIIO_PA + (KS8695_PCIIO_SIZE - 1),
-       .flags  = IORESOURCE_IO,
-};
-
-static int __init ks8695_pci_setup(int nr, struct pci_sys_data *sys)
-{
-       if (nr > 0)
-               return 0;
-
-       request_resource(&iomem_resource, &pci_mem);
-       request_resource(&ioport_resource, &pci_io);
-
-       pci_add_resource_offset(&sys->resources, &pci_io, sys->io_offset);
-       pci_add_resource_offset(&sys->resources, &pci_mem, sys->mem_offset);
-
-       /* Assign and enable processor bridge */
-       ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA);
-
-       /* Enable bus-master & Memory Space access */
-       ks8695_local_writeconfig(PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
-
-       /* Set cache-line size & latency. */
-       ks8695_local_writeconfig(PCI_CACHE_LINE_SIZE, (32 << 8) | (L1_CACHE_BYTES / sizeof(u32)));
-
-       /* Reserve PCI memory space for PCI-AHB resources */
-       if (!request_mem_region(KS8695_PCIMEM_PA, SZ_64M, "PCI-AHB Bridge")) {
-               printk(KERN_ERR "Cannot allocate PCI-AHB Bridge memory.\n");
-               return -EBUSY;
-       }
-
-       return 1;
-}
-
-static inline unsigned int size_mask(unsigned long size)
-{
-       return (~size) + 1;
-}
-
-static int ks8695_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
-{
-       unsigned long pc = instruction_pointer(regs);
-       unsigned long instr = *(unsigned long *)pc;
-       unsigned long cmdstat;
-
-       cmdstat = __raw_readl(KS8695_PCI_VA + KS8695_CRCFCS);
-
-       printk(KERN_ERR "PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx [%s%s%s%s%s]\n",
-               addr, fsr, regs->ARM_pc, regs->ARM_lr,
-               cmdstat & (PCI_STATUS_SIG_TARGET_ABORT << 16) ? "GenTarget" : " ",
-               cmdstat & (PCI_STATUS_REC_TARGET_ABORT << 16) ? "RecvTarget" : " ",
-               cmdstat & (PCI_STATUS_REC_MASTER_ABORT << 16) ? "MasterAbort" : " ",
-               cmdstat & (PCI_STATUS_SIG_SYSTEM_ERROR << 16) ? "SysError" : " ",
-               cmdstat & (PCI_STATUS_DETECTED_PARITY << 16)  ? "Parity" : " "
-       );
-
-       __raw_writel(cmdstat, KS8695_PCI_VA + KS8695_CRCFCS);
-
-       /*
-        * If the instruction being executed was a read,
-        * make it look like it read all-ones.
-        */
-       if ((instr & 0x0c100000) == 0x04100000) {
-               int reg = (instr >> 12) & 15;
-               unsigned long val;
-
-               if (instr & 0x00400000)
-                       val = 255;
-               else
-                       val = -1;
-
-               regs->uregs[reg] = val;
-               regs->ARM_pc += 4;
-               return 0;
-       }
-
-       if ((instr & 0x0e100090) == 0x00100090) {
-               int reg = (instr >> 12) & 15;
-
-               regs->uregs[reg] = -1;
-               regs->ARM_pc += 4;
-               return 0;
-       }
-
-       return 1;
-}
-
-static void __init ks8695_pci_preinit(void)
-{
-       /* make software reset to avoid freeze if PCI bus was messed up */
-       __raw_writel(0x80000000, KS8695_PCI_VA + KS8695_PBCS);
-
-       /* stage 1 initialization, subid, subdevice = 0x0001 */
-       __raw_writel(0x00010001, KS8695_PCI_VA + KS8695_CRCSID);
-
-       /* stage 2 initialization */
-       /* prefetch limits with 16 words, retry enable */
-       __raw_writel(0x40000000, KS8695_PCI_VA + KS8695_PBCS);
-
-       /* configure memory mapping */
-       __raw_writel(KS8695_PCIMEM_PA, KS8695_PCI_VA + KS8695_PMBA);
-       __raw_writel(size_mask(KS8695_PCIMEM_SIZE), KS8695_PCI_VA + KS8695_PMBAM);
-       __raw_writel(KS8695_PCIMEM_PA, KS8695_PCI_VA + KS8695_PMBAT);
-       __raw_writel(0, KS8695_PCI_VA + KS8695_PMBAC);
-
-       /* configure IO mapping */
-       __raw_writel(KS8695_PCIIO_PA, KS8695_PCI_VA + KS8695_PIOBA);
-       __raw_writel(size_mask(KS8695_PCIIO_SIZE), KS8695_PCI_VA + KS8695_PIOBAM);
-       __raw_writel(KS8695_PCIIO_PA, KS8695_PCI_VA + KS8695_PIOBAT);
-       __raw_writel(0, KS8695_PCI_VA + KS8695_PIOBAC);
-
-       /* hook in fault handlers */
-       hook_fault_code(8, ks8695_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
-       hook_fault_code(10, ks8695_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
-}
-
-static void ks8695_show_pciregs(void)
-{
-       if (!pci_dbg)
-               return;
-
-       printk(KERN_INFO "PCI: CRCFID = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFID));
-       printk(KERN_INFO "PCI: CRCFCS = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFCS));
-       printk(KERN_INFO "PCI: CRCFRV = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFRV));
-       printk(KERN_INFO "PCI: CRCFLT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFLT));
-       printk(KERN_INFO "PCI: CRCBMA = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCBMA));
-       printk(KERN_INFO "PCI: CRCSID = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCSID));
-       printk(KERN_INFO "PCI: CRCFIT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_CRCFIT));
-
-       printk(KERN_INFO "PCI: PBM    = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PBM));
-       printk(KERN_INFO "PCI: PBCS   = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PBCS));
-
-       printk(KERN_INFO "PCI: PMBA   = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBA));
-       printk(KERN_INFO "PCI: PMBAC  = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAC));
-       printk(KERN_INFO "PCI: PMBAM  = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAM));
-       printk(KERN_INFO "PCI: PMBAT  = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PMBAT));
-
-       printk(KERN_INFO "PCI: PIOBA  = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBA));
-       printk(KERN_INFO "PCI: PIOBAC = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAC));
-       printk(KERN_INFO "PCI: PIOBAM = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAM));
-       printk(KERN_INFO "PCI: PIOBAT = %08x\n", __raw_readl(KS8695_PCI_VA + KS8695_PIOBAT));
-}
-
-
-static struct hw_pci ks8695_pci __initdata = {
-       .nr_controllers = 1,
-       .ops            = &ks8695_pci_ops,
-       .preinit        = ks8695_pci_preinit,
-       .setup          = ks8695_pci_setup,
-       .postinit       = NULL,
-       .map_irq        = NULL,
-};
-
-void __init ks8695_init_pci(struct ks8695_pci_cfg *cfg)
-{
-       if (__raw_readl(KS8695_PCI_VA + KS8695_CRCFRV) & CFRV_GUEST) {
-               printk("PCI: KS8695 in guest mode, not initialising\n");
-               return;
-       }
-
-       pcibios_min_io = 0;
-       pcibios_min_mem = 0;
-
-       printk(KERN_INFO "PCI: Initialising\n");
-       ks8695_show_pciregs();
-
-       /* set Mode */
-       __raw_writel(cfg->mode << 29, KS8695_PCI_VA + KS8695_PBM);
-
-       ks8695_pci.map_irq = cfg->map_irq;      /* board-specific map_irq method */
-
-       pci_common_init(&ks8695_pci);
-}
diff --git a/arch/arm/mach-ks8695/regs-hpna.h b/arch/arm/mach-ks8695/regs-hpna.h
deleted file mode 100644 (file)
index 815ce5c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-wan.h
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * KS8695 - HPNA Registers and bit definitions.
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef KS8695_HPNA_H
-#define KS8695_HPNA_H
-
-#define KS8695_HPNA_OFFSET     (0xF0000 + 0xA000)
-#define KS8695_HPNA_VA         (KS8695_IO_VA + KS8695_HPNA_OFFSET)
-#define KS8695_HPNA_PA         (KS8695_IO_PA + KS8695_HPNA_OFFSET)
-
-
-/*
- * HPNA registers
- */
-
-#endif
diff --git a/arch/arm/mach-ks8695/regs-lan.h b/arch/arm/mach-ks8695/regs-lan.h
deleted file mode 100644 (file)
index 82c5f37..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-lan.h
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * KS8695 - LAN Registers and bit definitions.
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef KS8695_LAN_H
-#define KS8695_LAN_H
-
-#define KS8695_LAN_OFFSET      (0xF0000 + 0x8000)
-#define KS8695_LAN_VA          (KS8695_IO_VA + KS8695_LAN_OFFSET)
-#define KS8695_LAN_PA          (KS8695_IO_PA + KS8695_LAN_OFFSET)
-
-
-/*
- * LAN registers
- */
-#define KS8695_LMDTXC          (0x00)          /* DMA Transmit Control */
-#define KS8695_LMDRXC          (0x04)          /* DMA Receive Control */
-#define KS8695_LMDTSC          (0x08)          /* DMA Transmit Start Command */
-#define KS8695_LMDRSC          (0x0c)          /* DMA Receive Start Command */
-#define KS8695_LTDLB           (0x10)          /* Transmit Descriptor List Base Address */
-#define KS8695_LRDLB           (0x14)          /* Receive Descriptor List Base Address */
-#define KS8695_LMAL            (0x18)          /* MAC Station Address Low */
-#define KS8695_LMAH            (0x1c)          /* MAC Station Address High */
-#define KS8695_LMAAL(n)                (0x80 + ((n)*8))        /* MAC Additional Station Address (0..15) Low */
-#define KS8695_LMAAH(n)                (0x84 + ((n)*8))        /* MAC Additional Station Address (0..15) High */
-
-
-/* DMA Transmit Control Register */
-#define LMDTXC_LMTRST          (1    << 31)    /* Soft Reset */
-#define LMDTXC_LMTBS           (0x3f << 24)    /* Transmit Burst Size */
-#define LMDTXC_LMTUCG          (1    << 18)    /* Transmit UDP Checksum Generate */
-#define LMDTXC_LMTTCG          (1    << 17)    /* Transmit TCP Checksum Generate */
-#define LMDTXC_LMTICG          (1    << 16)    /* Transmit IP Checksum Generate */
-#define LMDTXC_LMTFCE          (1    <<  9)    /* Transmit Flow Control Enable */
-#define LMDTXC_LMTLB           (1    <<  8)    /* Loopback mode */
-#define LMDTXC_LMTEP           (1    <<  2)    /* Transmit Enable Padding */
-#define LMDTXC_LMTAC           (1    <<  1)    /* Transmit Add CRC */
-#define LMDTXC_LMTE            (1    <<  0)    /* TX Enable */
-
-/* DMA Receive Control Register */
-#define LMDRXC_LMRBS           (0x3f << 24)    /* Receive Burst Size */
-#define LMDRXC_LMRUCC          (1    << 18)    /* Receive UDP Checksum check */
-#define LMDRXC_LMRTCG          (1    << 17)    /* Receive TCP Checksum check */
-#define LMDRXC_LMRICG          (1    << 16)    /* Receive IP Checksum check */
-#define LMDRXC_LMRFCE          (1    <<  9)    /* Receive Flow Control Enable */
-#define LMDRXC_LMRB            (1    <<  6)    /* Receive Broadcast */
-#define LMDRXC_LMRM            (1    <<  5)    /* Receive Multicast */
-#define LMDRXC_LMRU            (1    <<  4)    /* Receive Unicast */
-#define LMDRXC_LMRERR          (1    <<  3)    /* Receive Error Frame */
-#define LMDRXC_LMRA            (1    <<  2)    /* Receive All */
-#define LMDRXC_LMRE            (1    <<  1)    /* RX Enable */
-
-/* Additional Station Address High */
-#define LMAAH_E                        (1    << 31)    /* Address Enabled */
-
-
-#endif
diff --git a/arch/arm/mach-ks8695/regs-mem.h b/arch/arm/mach-ks8695/regs-mem.h
deleted file mode 100644 (file)
index 55806bc..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-mem.h
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * KS8695 - Memory Controller registers and bit definitions
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef KS8695_MEM_H
-#define KS8695_MEM_H
-
-#define KS8695_MEM_OFFSET      (0xF0000 + 0x4000)
-#define KS8695_MEM_VA          (KS8695_IO_VA + KS8695_MEM_OFFSET)
-#define KS8695_MEM_PA          (KS8695_IO_PA + KS8695_MEM_OFFSET)
-
-
-/*
- * Memory Controller Registers
- */
-#define KS8695_EXTACON0                (0x00)          /* External I/O 0 Access Control */
-#define KS8695_EXTACON1                (0x04)          /* External I/O 1 Access Control */
-#define KS8695_EXTACON2                (0x08)          /* External I/O 2 Access Control */
-#define KS8695_ROMCON0         (0x10)          /* ROM/SRAM/Flash 1 Control Register */
-#define KS8695_ROMCON1         (0x14)          /* ROM/SRAM/Flash 2 Control Register */
-#define KS8695_ERGCON          (0x20)          /* External I/O and ROM/SRAM/Flash General Register */
-#define KS8695_SDCON0          (0x30)          /* SDRAM Control Register 0 */
-#define KS8695_SDCON1          (0x34)          /* SDRAM Control Register 1 */
-#define KS8695_SDGCON          (0x38)          /* SDRAM General Control */
-#define KS8695_SDBCON          (0x3c)          /* SDRAM Buffer Control */
-#define KS8695_REFTIM          (0x40)          /* SDRAM Refresh Timer */
-
-
-/* External I/O Access Control Registers */
-#define EXTACON_EBNPTR         (0x3ff << 22)           /* Last Address Pointer */
-#define EXTACON_EBBPTR         (0x3ff << 12)           /* Base Pointer */
-#define EXTACON_EBTACT         (7     <<  9)           /* Write Enable/Output Enable Active Time */
-#define EXTACON_EBTCOH         (7     <<  6)           /* Chip Select Hold Time */
-#define EXTACON_EBTACS         (7     <<  3)           /* Address Setup Time before ECSN */
-#define EXTACON_EBTCOS         (7     <<  0)           /* Chip Select Time before OEN */
-
-/* ROM/SRAM/Flash Control Register */
-#define ROMCON_RBNPTR          (0x3ff << 22)           /* Next Pointer */
-#define ROMCON_RBBPTR          (0x3ff << 12)           /* Base Pointer */
-#define ROMCON_RBTACC          (7     <<  4)           /* Access Cycle Time */
-#define ROMCON_RBTPA           (3     <<  2)           /* Page Address Access Time */
-#define ROMCON_PMC             (3     <<  0)           /* Page Mode Configuration */
-#define                PMC_NORMAL              (0 << 0)
-#define                PMC_4WORD               (1 << 0)
-#define                PMC_8WORD               (2 << 0)
-#define                PMC_16WORD              (3 << 0)
-
-/* External I/O and ROM/SRAM/Flash General Register */
-#define ERGCON_TMULT           (3 << 28)               /* Time Multiplier */
-#define ERGCON_DSX2            (3 << 20)               /* Data Width (External I/O Bank 2) */
-#define ERGCON_DSX1            (3 << 18)               /* Data Width (External I/O Bank 1) */
-#define ERGCON_DSX0            (3 << 16)               /* Data Width (External I/O Bank 0) */
-#define ERGCON_DSR1            (3 <<  2)               /* Data Width (ROM/SRAM/Flash Bank 1) */
-#define ERGCON_DSR0            (3 <<  0)               /* Data Width (ROM/SRAM/Flash Bank 0) */
-
-/* SDRAM Control Register */
-#define SDCON_DBNPTR           (0x3ff << 22)           /* Last Address Pointer */
-#define SDCON_DBBPTR           (0x3ff << 12)           /* Base Pointer */
-#define SDCON_DBCAB            (3     <<  8)           /* Column Address Bits */
-#define SDCON_DBBNUM           (1     <<  3)           /* Number of Banks */
-#define SDCON_DBDBW            (3     <<  1)           /* Data Bus Width */
-
-/* SDRAM General Control Register */
-#define SDGCON_SDTRC           (3 << 2)                /* RAS to CAS latency */
-#define SDGCON_SDCAS           (3 << 0)                /* CAS latency */
-
-/* SDRAM Buffer Control Register */
-#define SDBCON_SDESTA          (1 << 31)               /* SDRAM Engine Status */
-#define SDBCON_RBUFBDIS                (1 << 24)               /* Read Buffer Burst Enable */
-#define SDBCON_WFIFOEN         (1 << 23)               /* Write FIFO Enable */
-#define SDBCON_RBUFEN          (1 << 22)               /* Read Buffer Enable */
-#define SDBCON_FLUSHWFIFO      (1 << 21)               /* Flush Write FIFO */
-#define SDBCON_RBUFINV         (1 << 20)               /* Read Buffer Invalidate */
-#define SDBCON_SDINI           (3 << 16)               /* SDRAM Initialization Control */
-#define SDBCON_SDMODE          (0x3fff << 0)           /* SDRAM Mode Register Value Program */
-
-/* SDRAM Refresh Timer Register */
-#define REFTIM_REFTIM          (0xffff << 0)           /* Refresh Timer Value */
-
-
-#endif
diff --git a/arch/arm/mach-ks8695/regs-pci.h b/arch/arm/mach-ks8695/regs-pci.h
deleted file mode 100644 (file)
index 75a9db6..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-pci.h
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- *
- * KS8695 - PCI bridge registers and bit definitions.
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#define KS8695_PCI_OFFSET      (0xF0000 + 0x2000)
-#define KS8695_PCI_VA          (KS8695_IO_VA + KS8695_PCI_OFFSET)
-#define KS8695_PCI_PA          (KS8695_IO_PA + KS8695_PCI_OFFSET)
-
-
-#define KS8695_CRCFID          (0x000)         /* Configuration: Identification */
-#define KS8695_CRCFCS          (0x004)         /* Configuration: Command and Status */
-#define KS8695_CRCFRV          (0x008)         /* Configuration: Revision */
-#define KS8695_CRCFLT          (0x00C)         /* Configuration: Latency Timer */
-#define KS8695_CRCBMA          (0x010)         /* Configuration: Base Memory Address */
-#define KS8695_CRCSID          (0x02C)         /* Configuration: Subsystem ID */
-#define KS8695_CRCFIT          (0x03C)         /* Configuration: Interrupt */
-#define KS8695_PBCA            (0x100)         /* Bridge Configuration Address */
-#define KS8695_PBCD            (0x104)         /* Bridge Configuration Data */
-#define KS8695_PBM             (0x200)         /* Bridge Mode */
-#define KS8695_PBCS            (0x204)         /* Bridge Control and Status */
-#define KS8695_PMBA            (0x208)         /* Bridge Memory Base Address */
-#define KS8695_PMBAC           (0x20C)         /* Bridge Memory Base Address Control */
-#define KS8695_PMBAM           (0x210)         /* Bridge Memory Base Address Mask */
-#define KS8695_PMBAT           (0x214)         /* Bridge Memory Base Address Translation */
-#define KS8695_PIOBA           (0x218)         /* Bridge I/O Base Address */
-#define KS8695_PIOBAC          (0x21C)         /* Bridge I/O Base Address Control */
-#define KS8695_PIOBAM          (0x220)         /* Bridge I/O Base Address Mask */
-#define KS8695_PIOBAT          (0x224)         /* Bridge I/O Base Address Translation */
-
-
-/* Configuration: Identification */
-
-/* Configuration: Command and Status */
-
-/* Configuration: Revision */
-
-
-
-#define CFRV_GUEST             (1 << 23)
-
-#define PBCA_TYPE1             (1)
-#define PBCA_ENABLE            (1 << 31)
-
-
diff --git a/arch/arm/mach-ks8695/regs-sys.h b/arch/arm/mach-ks8695/regs-sys.h
deleted file mode 100644 (file)
index 57c20be..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-sys.h
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- *
- * KS8695 - System control registers and bit definitions
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef KS8695_SYS_H
-#define KS8695_SYS_H
-
-#define KS8695_SYS_OFFSET      (0xF0000 + 0x0000)
-#define KS8695_SYS_VA          (KS8695_IO_VA + KS8695_SYS_OFFSET)
-#define KS8695_SYS_PA          (KS8695_IO_PA + KS8695_SYS_OFFSET)
-
-
-#define KS8695_SYSCFG          (0x00)          /* System Configuration Register */
-#define KS8695_CLKCON          (0x04)          /* System Clock and Bus Control Register */
-
-
-/* System Configuration Register */
-#define SYSCFG_SPRBP           (0x3ff << 16)   /* Register Bank Base Pointer */
-
-/* System Clock and Bus Control Register */
-#define CLKCON_SFMODE          (1 << 8)        /* System Fast Mode for Simulation */
-#define CLKCON_SCDC            (7 << 0)        /* System Clock Divider Select */
-
-
-#endif
diff --git a/arch/arm/mach-ks8695/regs-wan.h b/arch/arm/mach-ks8695/regs-wan.h
deleted file mode 100644 (file)
index c475bed..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * arch/arm/mach-ks8695/include/mach/regs-wan.h
- *
- * Copyright (C) 2006 Andrew Victor
- *
- * KS8695 - WAN Registers and bit definitions.
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef KS8695_WAN_H
-#define KS8695_WAN_H
-
-#define KS8695_WAN_OFFSET      (0xF0000 + 0x6000)
-#define KS8695_WAN_VA          (KS8695_IO_VA + KS8695_WAN_OFFSET)
-#define KS8695_WAN_PA          (KS8695_IO_PA + KS8695_WAN_OFFSET)
-
-
-/*
- * WAN registers
- */
-#define KS8695_WMDTXC          (0x00)          /* DMA Transmit Control */
-#define KS8695_WMDRXC          (0x04)          /* DMA Receive Control */
-#define KS8695_WMDTSC          (0x08)          /* DMA Transmit Start Command */
-#define KS8695_WMDRSC          (0x0c)          /* DMA Receive Start Command */
-#define KS8695_WTDLB           (0x10)          /* Transmit Descriptor List Base Address */
-#define KS8695_WRDLB           (0x14)          /* Receive Descriptor List Base Address */
-#define KS8695_WMAL            (0x18)          /* MAC Station Address Low */
-#define KS8695_WMAH            (0x1c)          /* MAC Station Address High */
-#define KS8695_WMAAL(n)                (0x80 + ((n)*8))        /* MAC Additional Station Address (0..15) Low */
-#define KS8695_WMAAH(n)                (0x84 + ((n)*8))        /* MAC Additional Station Address (0..15) High */
-
-
-/* DMA Transmit Control Register */
-#define WMDTXC_WMTRST          (1    << 31)    /* Soft Reset */
-#define WMDTXC_WMTBS           (0x3f << 24)    /* Transmit Burst Size */
-#define WMDTXC_WMTUCG          (1    << 18)    /* Transmit UDP Checksum Generate */
-#define WMDTXC_WMTTCG          (1    << 17)    /* Transmit TCP Checksum Generate */
-#define WMDTXC_WMTICG          (1    << 16)    /* Transmit IP Checksum Generate */
-#define WMDTXC_WMTFCE          (1    <<  9)    /* Transmit Flow Control Enable */
-#define WMDTXC_WMTLB           (1    <<  8)    /* Loopback mode */
-#define WMDTXC_WMTEP           (1    <<  2)    /* Transmit Enable Padding */
-#define WMDTXC_WMTAC           (1    <<  1)    /* Transmit Add CRC */
-#define WMDTXC_WMTE            (1    <<  0)    /* TX Enable */
-
-/* DMA Receive Control Register */
-#define WMDRXC_WMRBS           (0x3f << 24)    /* Receive Burst Size */
-#define WMDRXC_WMRUCC          (1    << 18)    /* Receive UDP Checksum check */
-#define WMDRXC_WMRTCG          (1    << 17)    /* Receive TCP Checksum check */
-#define WMDRXC_WMRICG          (1    << 16)    /* Receive IP Checksum check */
-#define WMDRXC_WMRFCE          (1    <<  9)    /* Receive Flow Control Enable */
-#define WMDRXC_WMRB            (1    <<  6)    /* Receive Broadcast */
-#define WMDRXC_WMRM            (1    <<  5)    /* Receive Multicast */
-#define WMDRXC_WMRU            (1    <<  4)    /* Receive Unicast */
-#define WMDRXC_WMRERR          (1    <<  3)    /* Receive Error Frame */
-#define WMDRXC_WMRA            (1    <<  2)    /* Receive All */
-#define WMDRXC_WMRE            (1    <<  0)    /* RX Enable */
-
-/* Additional Station Address High */
-#define WMAAH_E                        (1    << 31)    /* Address Enabled */
-
-
-#endif
diff --git a/arch/arm/mach-ks8695/time.c b/arch/arm/mach-ks8695/time.c
deleted file mode 100644 (file)
index 50561ee..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * arch/arm/mach-ks8695/time.c
- *
- * Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
- * Copyright (C) 2006 Simtec Electronics
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/io.h>
-#include <linux/clockchips.h>
-
-#include <asm/mach/time.h>
-#include <asm/system_misc.h>
-
-#include <mach/regs-irq.h>
-
-#include "generic.h"
-
-#define KS8695_TMR_OFFSET      (0xF0000 + 0xE400)
-#define KS8695_TMR_VA          (KS8695_IO_VA + KS8695_TMR_OFFSET)
-#define KS8695_TMR_PA          (KS8695_IO_PA + KS8695_TMR_OFFSET)
-
-/*
- * Timer registers
- */
-#define KS8695_TMCON           (0x00)          /* Timer Control Register */
-#define KS8695_T1TC            (0x04)          /* Timer 1 Timeout Count Register */
-#define KS8695_T0TC            (0x08)          /* Timer 0 Timeout Count Register */
-#define KS8695_T1PD            (0x0C)          /* Timer 1 Pulse Count Register */
-#define KS8695_T0PD            (0x10)          /* Timer 0 Pulse Count Register */
-
-/* Timer Control Register */
-#define TMCON_T1EN             (1 << 1)        /* Timer 1 Enable */
-#define TMCON_T0EN             (1 << 0)        /* Timer 0 Enable */
-
-/* Timer0 Timeout Counter Register */
-#define T0TC_WATCHDOG          (0xff)          /* Enable watchdog mode */
-
-static int ks8695_set_periodic(struct clock_event_device *evt)
-{
-       u32 rate = DIV_ROUND_CLOSEST(KS8695_CLOCK_RATE, HZ);
-       u32 half = DIV_ROUND_CLOSEST(rate, 2);
-       u32 tmcon;
-
-       /* Disable timer 1 */
-       tmcon = readl_relaxed(KS8695_TMR_VA + KS8695_TMCON);
-       tmcon &= ~TMCON_T1EN;
-       writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
-
-       /* Both registers need to count down */
-       writel_relaxed(half, KS8695_TMR_VA + KS8695_T1TC);
-       writel_relaxed(half, KS8695_TMR_VA + KS8695_T1PD);
-
-       /* Re-enable timer1 */
-       tmcon |= TMCON_T1EN;
-       writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
-       return 0;
-}
-
-static int ks8695_set_next_event(unsigned long cycles,
-                                struct clock_event_device *evt)
-
-{
-       u32 half = DIV_ROUND_CLOSEST(cycles, 2);
-       u32 tmcon;
-
-       /* Disable timer 1 */
-       tmcon = readl_relaxed(KS8695_TMR_VA + KS8695_TMCON);
-       tmcon &= ~TMCON_T1EN;
-       writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
-
-       /* Both registers need to count down */
-       writel_relaxed(half, KS8695_TMR_VA + KS8695_T1TC);
-       writel_relaxed(half, KS8695_TMR_VA + KS8695_T1PD);
-
-       /* Re-enable timer1 */
-       tmcon |= TMCON_T1EN;
-       writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
-
-       return 0;
-}
-
-static struct clock_event_device clockevent_ks8695 = {
-       .name                   = "ks8695_t1tc",
-       /* Reasonably fast and accurate clock event */
-       .rating                 = 300,
-       .features               = CLOCK_EVT_FEAT_ONESHOT |
-                                 CLOCK_EVT_FEAT_PERIODIC,
-       .set_next_event         = ks8695_set_next_event,
-       .set_state_periodic     = ks8695_set_periodic,
-};
-
-/*
- * IRQ handler for the timer.
- */
-static irqreturn_t ks8695_timer_interrupt(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = &clockevent_ks8695;
-
-       evt->event_handler(evt);
-       return IRQ_HANDLED;
-}
-
-static struct irqaction ks8695_timer_irq = {
-       .name           = "ks8695_tick",
-       .flags          = IRQF_TIMER,
-       .handler        = ks8695_timer_interrupt,
-};
-
-static void ks8695_timer_setup(void)
-{
-       unsigned long tmcon;
-
-       /* Disable timer 0 and 1 */
-       tmcon = readl_relaxed(KS8695_TMR_VA + KS8695_TMCON);
-       tmcon &= ~TMCON_T0EN;
-       tmcon &= ~TMCON_T1EN;
-       writel_relaxed(tmcon, KS8695_TMR_VA + KS8695_TMCON);
-
-       /*
-        * Use timer 1 to fire IRQs on the timeline, minimum 2 cycles
-        * (one on each counter) maximum 2*2^32, but the API will only
-        * accept up to a 32bit full word (0xFFFFFFFFU).
-        */
-       clockevents_config_and_register(&clockevent_ks8695,
-                                       KS8695_CLOCK_RATE, 2,
-                                       0xFFFFFFFFU);
-}
-
-void __init ks8695_timer_init(void)
-{
-       ks8695_timer_setup();
-
-       /* Enable timer interrupts */
-       setup_irq(KS8695_IRQ_TIMER1, &ks8695_timer_irq);
-}
-
-void ks8695_restart(enum reboot_mode reboot_mode, const char *cmd)
-{
-       unsigned int reg;
-
-       if (reboot_mode == REBOOT_SOFT)
-               soft_restart(0);
-
-       /* disable timer0 */
-       reg = readl_relaxed(KS8695_TMR_VA + KS8695_TMCON);
-       writel_relaxed(reg & ~TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
-
-       /* enable watchdog mode */
-       writel_relaxed((10 << 8) | T0TC_WATCHDOG, KS8695_TMR_VA + KS8695_T0TC);
-
-       /* re-enable timer0 */
-       writel_relaxed(reg | TMCON_T0EN, KS8695_TMR_VA + KS8695_TMCON);
-}
diff --git a/arch/arm/mach-lpc32xx/Kconfig b/arch/arm/mach-lpc32xx/Kconfig
new file mode 100644 (file)
index 0000000..ec87c65
--- /dev/null
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+config ARCH_LPC32XX
+       bool "NXP LPC32XX"
+       depends on ARCH_MULTI_V5
+       select ARM_AMBA
+       select CLKSRC_LPC32XX
+       select CPU_ARM926T
+       select GPIOLIB
+       help
+         Support for the NXP LPC32XX family of processors
index 5b71b4f..304ea61 100644 (file)
@@ -8,12 +8,12 @@
  */
 
 #include <linux/init.h>
+#include <linux/soc/nxp/lpc32xx-misc.h>
 
 #include <asm/mach/map.h>
 #include <asm/system_info.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
+#include "lpc32xx.h"
 #include "common.h"
 
 /*
@@ -32,7 +32,7 @@ void lpc32xx_get_uid(u32 devid[4])
  */
 #define LPC32XX_IRAM_BANK_SIZE SZ_128K
 static u32 iram_size;
-u32 lpc32xx_return_iram_size(void)
+u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr)
 {
        if (iram_size == 0) {
                u32 savedval1, savedval2;
@@ -53,10 +53,26 @@ u32 lpc32xx_return_iram_size(void)
                } else
                        iram_size = LPC32XX_IRAM_BANK_SIZE * 2;
        }
+       if (dmaaddr)
+               *dmaaddr = LPC32XX_IRAM_BASE;
+       if (mapbase)
+               *mapbase = io_p2v(LPC32XX_IRAM_BASE);
 
        return iram_size;
 }
-EXPORT_SYMBOL_GPL(lpc32xx_return_iram_size);
+EXPORT_SYMBOL_GPL(lpc32xx_return_iram);
+
+void lpc32xx_set_phy_interface_mode(phy_interface_t mode)
+{
+       u32 tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL);
+       tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK;
+       if (mode == PHY_INTERFACE_MODE_MII)
+               tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS;
+       else
+               tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS;
+       __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL);
+}
+EXPORT_SYMBOL_GPL(lpc32xx_set_phy_interface_mode);
 
 static struct map_desc lpc32xx_io_desc[] __initdata = {
        {
index 8e597ce..32f0ad2 100644 (file)
@@ -23,7 +23,6 @@ extern void __init lpc32xx_serial_init(void);
  */
 extern void lpc32xx_get_uid(u32 devid[4]);
 
-extern u32 lpc32xx_return_iram_size(void);
 /*
  * Pointers used for sizing and copying suspend function data
  */
diff --git a/arch/arm/mach-lpc32xx/include/mach/board.h b/arch/arm/mach-lpc32xx/include/mach/board.h
deleted file mode 100644 (file)
index 476513d..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arm/arch/mach-lpc32xx/include/mach/board.h
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2010 NXP Semiconductors
- */
-
-#ifndef __ASM_ARCH_BOARD_H
-#define __ASM_ARCH_BOARD_H
-
-extern u32 lpc32xx_return_iram_size(void);
-
-#endif  /* __ASM_ARCH_BOARD_H */
diff --git a/arch/arm/mach-lpc32xx/include/mach/entry-macro.S b/arch/arm/mach-lpc32xx/include/mach/entry-macro.S
deleted file mode 100644 (file)
index eec0f5f..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-lpc32xx/include/mach/entry-macro.S
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2010 NXP Semiconductors
- */
-
-#include <mach/hardware.h>
-#include <mach/platform.h>
-
-#define LPC32XX_INTC_MASKED_STATUS_OFS 0x8
-
-       .macro  get_irqnr_preamble, base, tmp
-       ldr     \base, =IO_ADDRESS(LPC32XX_MIC_BASE)
-       .endm
-
-/*
- * Return IRQ number in irqnr. Also return processor Z flag status in CPSR
- * as set if an interrupt is pending.
- */
-       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-       ldr     \irqstat, [\base, #LPC32XX_INTC_MASKED_STATUS_OFS]
-       clz     \irqnr, \irqstat
-       rsb     \irqnr, \irqnr, #31
-       teq     \irqstat, #0
-       .endm
diff --git a/arch/arm/mach-lpc32xx/include/mach/hardware.h b/arch/arm/mach-lpc32xx/include/mach/hardware.h
deleted file mode 100644 (file)
index 4866f09..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-lpc32xx/include/mach/hardware.h
- *
- * Copyright (c) 2005 MontaVista Software, Inc. <source@mvista.com>
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-/*
- * Start of virtual addresses for IO devices
- */
-#define IO_BASE                0xF0000000
-
-/*
- * This macro relies on fact that for all HW i/o addresses bits 20-23 are 0
- */
-#define IO_ADDRESS(x)  IOMEM(((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) |\
-                        IO_BASE)
-
-#define io_p2v(x)      ((void __iomem *) (unsigned long) IO_ADDRESS(x))
-#define io_v2p(x)      ((((x) & 0x0ff00000) << 4) | ((x) & 0x000fffff))
-
-#endif
diff --git a/arch/arm/mach-lpc32xx/include/mach/uncompress.h b/arch/arm/mach-lpc32xx/include/mach/uncompress.h
deleted file mode 100644 (file)
index a568812..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-lpc32xx/include/mach/uncompress.h
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2010 NXP Semiconductors
- */
-
-#ifndef __ASM_ARM_ARCH_UNCOMPRESS_H
-#define __ASM_ARM_ARCH_UNCOMPRESS_H
-
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/platform.h>
-
-/*
- * Uncompress output is hardcoded to standard UART 5
- */
-
-#define UART_FIFO_CTL_TX_RESET (1 << 2)
-#define UART_STATUS_TX_MT      (1 << 6)
-
-#define _UARTREG(x)            (void __iomem *)(LPC32XX_UART5_BASE + (x))
-
-#define LPC32XX_UART_DLLFIFO_O 0x00
-#define LPC32XX_UART_IIRFCR_O  0x08
-#define LPC32XX_UART_LSR_O     0x14
-
-static inline void putc(int ch)
-{
-       /* Wait for transmit FIFO to empty */
-       while ((__raw_readl(_UARTREG(LPC32XX_UART_LSR_O)) &
-               UART_STATUS_TX_MT) == 0)
-               ;
-
-       __raw_writel((u32) ch, _UARTREG(LPC32XX_UART_DLLFIFO_O));
-}
-
-static inline void flush(void)
-{
-       __raw_writel(__raw_readl(_UARTREG(LPC32XX_UART_IIRFCR_O)) |
-               UART_FIFO_CTL_TX_RESET, _UARTREG(LPC32XX_UART_IIRFCR_O));
-}
-
-/* NULL functions; we don't presently need them */
-#define arch_decomp_setup()
-
-#endif
similarity index 98%
rename from arch/arm/mach-lpc32xx/include/mach/platform.h
rename to arch/arm/mach-lpc32xx/lpc32xx.h
index 1c53790..5eeb884 100644 (file)
@@ -7,8 +7,8 @@
  * Copyright (C) 2010 NXP Semiconductors
  */
 
-#ifndef __ASM_ARCH_PLATFORM_H
-#define __ASM_ARCH_PLATFORM_H
+#ifndef __ARM_LPC32XX_H
+#define __ARM_LPC32XX_H
 
 #define _SBF(f, v)                             ((v) << (f))
 #define _BIT(n)                                        _SBF(n, 1)
 #define LPC32XX_USB_OTG_DEV_CLOCK_ON   _BIT(1)
 #define LPC32XX_USB_OTG_HOST_CLOCK_ON  _BIT(0)
 
+/*
+ * Start of virtual addresses for IO devices
+ */
+#define IO_BASE                0xF0000000
+
+/*
+ * This macro relies on fact that for all HW i/o addresses bits 20-23 are 0
+ */
+#define IO_ADDRESS(x)  IOMEM(((((x) & 0xff000000) >> 4) | ((x) & 0xfffff)) |\
+                        IO_BASE)
+
+#define io_p2v(x)      ((void __iomem *) (unsigned long) IO_ADDRESS(x))
+#define io_v2p(x)      ((((x) & 0x0ff00000) << 4) | ((x) & 0x000fffff))
+
 #endif
index 32bca35..b27fa1b 100644 (file)
@@ -70,8 +70,7 @@
 
 #include <asm/cacheflush.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
+#include "lpc32xx.h"
 #include "common.h"
 
 #define TEMP_IRAM_AREA  IO_ADDRESS(LPC32XX_IRAM_BASE)
index 3f9b30d..3e765c4 100644 (file)
@@ -16,8 +16,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
+#include "lpc32xx.h"
 #include "common.h"
 
 #define LPC32XX_SUART_FIFO_SIZE        64
@@ -60,6 +59,36 @@ static struct uartinit uartinit_data[] __initdata = {
        },
 };
 
+/* LPC3250 Errata HSUART.1: Hang workaround via loopback mode on inactivity */
+void lpc32xx_loopback_set(resource_size_t mapbase, int state)
+{
+       int bit;
+       u32 tmp;
+
+       switch (mapbase) {
+       case LPC32XX_HS_UART1_BASE:
+               bit = 0;
+               break;
+       case LPC32XX_HS_UART2_BASE:
+               bit = 1;
+               break;
+       case LPC32XX_HS_UART7_BASE:
+               bit = 6;
+               break;
+       default:
+               WARN(1, "lpc32xx_hs: Warning: Unknown port at %08x\n", mapbase);
+               return;
+       }
+
+       tmp = readl(LPC32XX_UARTCTL_CLOOP);
+       if (state)
+               tmp |= (1 << bit);
+       else
+               tmp &= ~(1 << bit);
+       writel(tmp, LPC32XX_UARTCTL_CLOOP);
+}
+EXPORT_SYMBOL_GPL(lpc32xx_loopback_set);
+
 void __init lpc32xx_serial_init(void)
 {
        u32 tmp, clkmodes = 0;
index 374f9f0..3f0a828 100644 (file)
@@ -11,8 +11,7 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-#include <mach/platform.h>
-#include <mach/hardware.h>
+#include "lpc32xx.h"
 
 /* Using named register defines makes the code easier to follow */
 #define WORK1_REG                      r0
index 2db1265..c1a9a1d 100644 (file)
@@ -37,7 +37,7 @@
  * fee50000    f0d00000        64K     PCIe #5 I/O space
  * fee60000    f0e00000        64K     PCIe #6 I/O space
  * fee70000    f0f00000        64K     PCIe #7 I/O space
- * fd000000    f1000000        1M      on-chip peripheral registers
+ * fec00000    f1000000        1M      on-chip peripheral registers
  */
 #define MV78XX0_CORE0_REGS_PHYS_BASE   0xf1020000
 #define MV78XX0_CORE1_REGS_PHYS_BASE   0xf1024000
@@ -49,7 +49,7 @@
 #define MV78XX0_PCIE_IO_SIZE           SZ_1M
 
 #define MV78XX0_REGS_PHYS_BASE         0xf1000000
-#define MV78XX0_REGS_VIRT_BASE         IOMEM(0xfd000000)
+#define MV78XX0_REGS_VIRT_BASE         IOMEM(0xfec00000)
 #define MV78XX0_REGS_SIZE              SZ_1M
 
 #define MV78XX0_PCIE_MEM_PHYS_BASE     0xc0000000
index 1d568c6..4716b9b 100644 (file)
@@ -1,3 +1,2 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-y                          += nspire.o
-obj-y                          += clcd.o
diff --git a/arch/arm/mach-nspire/clcd.c b/arch/arm/mach-nspire/clcd.c
deleted file mode 100644 (file)
index 44738dc..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- *     linux/arch/arm/mach-nspire/clcd.c
- *
- *     Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
- */
-
-#include <linux/init.h>
-#include <linux/of.h>
-#include <linux/amba/bus.h>
-#include <linux/amba/clcd.h>
-#include <linux/dma-mapping.h>
-
-static struct clcd_panel nspire_cx_lcd_panel = {
-       .mode           = {
-               .name           = "Color LCD",
-               .refresh        = 60,
-               .xres           = 320,
-               .yres           = 240,
-               .sync           = 0,
-               .vmode          = FB_VMODE_NONINTERLACED,
-               .pixclock       = 1,
-               .hsync_len      = 6,
-               .vsync_len      = 1,
-               .right_margin   = 50,
-               .left_margin    = 38,
-               .lower_margin   = 3,
-               .upper_margin   = 17,
-       },
-       .width          = 65, /* ~6.50 cm */
-       .height         = 49, /* ~4.87 cm */
-       .tim2           = TIM2_IPC,
-       .cntl           = CNTL_LCDTFT | CNTL_LCDVCOMP(1),
-       .bpp            = 16,
-       .caps           = CLCD_CAP_565,
-};
-
-static struct clcd_panel nspire_classic_lcd_panel = {
-       .mode           = {
-               .name           = "Grayscale LCD",
-               .refresh        = 60,
-               .xres           = 320,
-               .yres           = 240,
-               .sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-               .vmode          = FB_VMODE_NONINTERLACED,
-               .pixclock       = 1,
-               .hsync_len      = 6,
-               .vsync_len      = 1,
-               .right_margin   = 6,
-               .left_margin    = 6,
-       },
-       .width          = 71, /* 7.11cm */
-       .height         = 53, /* 5.33cm */
-       .tim2           = 0x80007d0,
-       .cntl           = CNTL_LCDMONO8,
-       .bpp            = 8,
-       .grayscale      = 1,
-       .caps           = CLCD_CAP_5551,
-};
-
-int nspire_clcd_setup(struct clcd_fb *fb)
-{
-       struct clcd_panel *panel;
-       size_t panel_size;
-       const char *type;
-       dma_addr_t dma;
-       int err;
-
-       BUG_ON(!fb->dev->dev.of_node);
-
-       err = of_property_read_string(fb->dev->dev.of_node, "lcd-type", &type);
-       if (err) {
-               pr_err("CLCD: Could not find lcd-type property\n");
-               return err;
-       }
-
-       if (!strcmp(type, "cx")) {
-               panel = &nspire_cx_lcd_panel;
-       } else if (!strcmp(type, "classic")) {
-               panel = &nspire_classic_lcd_panel;
-       } else {
-               pr_err("CLCD: Unknown lcd-type %s\n", type);
-               return -EINVAL;
-       }
-
-       panel_size = ((panel->mode.xres * panel->mode.yres) * panel->bpp) / 8;
-       panel_size = ALIGN(panel_size, PAGE_SIZE);
-
-       fb->fb.screen_base = dma_alloc_wc(&fb->dev->dev, panel_size, &dma,
-                                         GFP_KERNEL);
-
-       if (!fb->fb.screen_base) {
-               pr_err("CLCD: unable to map framebuffer\n");
-               return -ENOMEM;
-       }
-
-       fb->fb.fix.smem_start = dma;
-       fb->fb.fix.smem_len = panel_size;
-       fb->panel = panel;
-
-       return 0;
-}
-
-int nspire_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
-{
-       return dma_mmap_wc(&fb->dev->dev, vma, fb->fb.screen_base,
-                          fb->fb.fix.smem_start, fb->fb.fix.smem_len);
-}
-
-void nspire_clcd_remove(struct clcd_fb *fb)
-{
-       dma_free_wc(&fb->dev->dev, fb->fb.fix.smem_len, fb->fb.screen_base,
-                   fb->fb.fix.smem_start);
-}
diff --git a/arch/arm/mach-nspire/clcd.h b/arch/arm/mach-nspire/clcd.h
deleted file mode 100644 (file)
index 7f36bd8..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- *     linux/arch/arm/mach-nspire/clcd.h
- *
- *     Copyright (C) 2013 Daniel Tang <tangrs@tangrs.id.au>
- */
-
-int nspire_clcd_setup(struct clcd_fb *fb);
-int nspire_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma);
-void nspire_clcd_remove(struct clcd_fb *fb);
index 957bd0c..2d4abb0 100644 (file)
 #include <linux/irqchip/arm-vic.h>
 #include <linux/clkdev.h>
 #include <linux/amba/bus.h>
-#include <linux/amba/clcd.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach-types.h>
 #include <asm/mach/map.h>
 
 #include "mmio.h"
-#include "clcd.h"
 
 static const char *const nspire_dt_match[] __initconst = {
        "ti,nspire",
@@ -29,28 +27,6 @@ static const char *const nspire_dt_match[] __initconst = {
        NULL,
 };
 
-static struct clcd_board nspire_clcd_data = {
-       .name           = "LCD",
-       .caps           = CLCD_CAP_5551 | CLCD_CAP_565,
-       .check          = clcdfb_check,
-       .decode         = clcdfb_decode,
-       .setup          = nspire_clcd_setup,
-       .mmap           = nspire_clcd_mmap,
-       .remove         = nspire_clcd_remove,
-};
-
-
-static struct of_dev_auxdata nspire_auxdata[] __initdata = {
-       OF_DEV_AUXDATA("arm,pl111", NSPIRE_LCD_PHYS_BASE,
-                       NULL, &nspire_clcd_data),
-       { }
-};
-
-static void __init nspire_init(void)
-{
-       of_platform_default_populate(NULL, nspire_auxdata, NULL);
-}
-
 static void nspire_restart(enum reboot_mode mode, const char *cmd)
 {
        void __iomem *base = ioremap(NSPIRE_MISC_PHYS_BASE, SZ_4K);
@@ -62,6 +38,5 @@ static void nspire_restart(enum reboot_mode mode, const char *cmd)
 
 DT_MACHINE_START(NSPIRE, "TI-NSPIRE")
        .dt_compat      = nspire_dt_match,
-       .init_machine   = nspire_init,
        .restart        = nspire_restart,
 MACHINE_END
index 81159af..14a6c3e 100644 (file)
@@ -126,6 +126,8 @@ restart:
        orr r11, r11, r13                       @ mask all requested interrupts
        str r11, [r12, #OMAP1510_GPIO_INT_MASK]
 
+       str r13, [r12, #OMAP1510_GPIO_INT_STATUS] @ ack all requested interrupts
+
        ands r10, r13, #KEYBRD_CLK_MASK         @ extract keyboard status - set?
        beq hksw                                @ no - try next source
 
@@ -133,7 +135,6 @@ restart:
        @@@@@@@@@@@@@@@@@@@@@@
        @ Keyboard clock FIQ mode interrupt handler
        @ r10 now contains KEYBRD_CLK_MASK, use it
-       str r10, [r12, #OMAP1510_GPIO_INT_STATUS]       @ ack the interrupt
        bic r11, r11, r10                               @ unmask it
        str r11, [r12, #OMAP1510_GPIO_INT_MASK]
 
index 43899fa..0254eb9 100644 (file)
@@ -70,9 +70,7 @@ static irqreturn_t deferred_fiq(int irq, void *dev_id)
                         * interrupts default to since commit 80ac93c27441
                         * requires interrupt already acked and unmasked.
                         */
-                       if (irq_chip->irq_ack)
-                               irq_chip->irq_ack(d);
-                       if (irq_chip->irq_unmask)
+                       if (!WARN_ON_ONCE(!irq_chip->irq_unmask))
                                irq_chip->irq_unmask(d);
                }
                for (; irq_counter[gpio] < fiq_count; irq_counter[gpio]++)
diff --git a/arch/arm/mach-omap2/.gitignore b/arch/arm/mach-omap2/.gitignore
new file mode 100644 (file)
index 0000000..79a8d6e
--- /dev/null
@@ -0,0 +1 @@
+pm-asm-offsets.h
index 6006505..8f20819 100644 (file)
@@ -223,9 +223,12 @@ obj-y                                      += omap_phy_internal.o
 
 obj-$(CONFIG_MACH_OMAP2_TUSB6010)      += usb-tusb6010.o
 
-include/generated/ti-pm-asm-offsets.h: arch/arm/mach-omap2/pm-asm-offsets.s FORCE
+$(obj)/pm-asm-offsets.h: $(obj)/pm-asm-offsets.s FORCE
        $(call filechk,offsets,__TI_PM_ASM_OFFSETS_H__)
 
-$(obj)/sleep33xx.o $(obj)/sleep43xx.o: include/generated/ti-pm-asm-offsets.h
+$(obj)/sleep33xx.o $(obj)/sleep43xx.o: $(obj)/pm-asm-offsets.h
 
 targets += pm-asm-offsets.s
+clean-files += pm-asm-offsets.h
+
+obj-$(CONFIG_OMAP_IOMMU)               += omap-iommu.o
index 14b9c13..63423ea 100644 (file)
@@ -32,10 +32,8 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
        char *hc_name;
 
        hc_name = kzalloc(HSMMC_NAME_LEN + 1, GFP_KERNEL);
-       if (!hc_name) {
-               kfree(hc_name);
+       if (!hc_name)
                return -ENOMEM;
-       }
 
        snprintf(hc_name, (HSMMC_NAME_LEN + 1), "mmc%islot%i", c->mmc, 1);
        mmc->name = hc_name;
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
new file mode 100644 (file)
index 0000000..f1a6ece
--- /dev/null
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * OMAP IOMMU quirks for various TI SoCs
+ *
+ * Copyright (C) 2015-2019 Texas Instruments Incorporated - http://www.ti.com/
+ *      Suman Anna <s-anna@ti.com>
+ */
+
+#include <linux/platform_device.h>
+#include <linux/err.h>
+
+#include "omap_hwmod.h"
+#include "omap_device.h"
+#include "powerdomain.h"
+
+int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
+                                   u8 *pwrst)
+{
+       struct powerdomain *pwrdm;
+       struct omap_device *od;
+       u8 next_pwrst;
+
+       od = to_omap_device(pdev);
+       if (!od)
+               return -ENODEV;
+
+       if (od->hwmods_cnt != 1)
+               return -EINVAL;
+
+       pwrdm = omap_hwmod_get_pwrdm(od->hwmods[0]);
+       if (!pwrdm)
+               return -EINVAL;
+
+       if (request)
+               *pwrst = pwrdm_read_next_pwrst(pwrdm);
+
+       if (*pwrst > PWRDM_POWER_RET)
+               return 0;
+
+       next_pwrst = request ? PWRDM_POWER_ON : *pwrst;
+
+       return pwrdm_set_next_pwrst(pwrdm, next_pwrst);
+}
index f9c02f9..5c38457 100644 (file)
@@ -127,6 +127,9 @@ static int __init omap4_sram_init(void)
        struct device_node *np;
        struct gen_pool *sram_pool;
 
+       if (!soc_is_omap44xx() && !soc_is_omap54xx())
+               return 0;
+
        np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");
        if (!np)
                pr_warn("%s:Unable to allocate sram needed to handle errata I688\n",
index 4a5b4ae..1ec21e9 100644 (file)
@@ -379,7 +379,8 @@ static struct omap_hwmod dra7xx_dcan2_hwmod = {
 static struct omap_hwmod_class_sysconfig dra7xx_epwmss_sysc = {
        .rev_offs       = 0x0,
        .sysc_offs      = 0x4,
-       .sysc_flags     = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET,
+       .sysc_flags     = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+                         SYSC_HAS_RESET_STATUS,
        .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
        .sysc_fields    = &omap_hwmod_sysc_type2,
 };
index 68fee33..dc22124 100644 (file)
@@ -6,7 +6,6 @@
  *     Dave Gerlach, Vaibhav Bedia
  */
 
-#include <generated/ti-pm-asm-offsets.h>
 #include <linux/linkage.h>
 #include <linux/platform_data/pm33xx.h>
 #include <linux/ti-emif-sram.h>
@@ -15,6 +14,7 @@
 
 #include "iomap.h"
 #include "cm33xx.h"
+#include "pm-asm-offsets.h"
 
 #define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED                 0x00030000
 #define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE                   0x0003
index c1f4e48..90d2907 100644 (file)
@@ -6,7 +6,6 @@
  *     Dave Gerlach, Vaibhav Bedia
  */
 
-#include <generated/ti-pm-asm-offsets.h>
 #include <linux/linkage.h>
 #include <linux/ti-emif-sram.h>
 #include <linux/platform_data/pm33xx.h>
@@ -19,6 +18,7 @@
 #include "iomap.h"
 #include "omap-secure.h"
 #include "omap44xx.h"
+#include "pm-asm-offsets.h"
 #include "prm33xx.h"
 #include "prcm43xx.h"
 
index 3364df3..2b66120 100644 (file)
  * fc000000    device bus mappings (cs0/cs1)
  *
  * virt                phys            size
- * fe000000    f1000000        1M      on-chip peripheral registers
+ * fec00000    f1000000        1M      on-chip peripheral registers
  * fee00000    f2000000        64K     PCIe I/O space
  * fee10000    f2100000        64K     PCI I/O space
  * fd000000    f0000000        16M     PCIe WA space (Orion-1/Orion-NAS only)
  ****************************************************************************/
 #define ORION5X_REGS_PHYS_BASE         0xf1000000
-#define ORION5X_REGS_VIRT_BASE         IOMEM(0xfe000000)
+#define ORION5X_REGS_VIRT_BASE         IOMEM(0xfec00000)
 #define ORION5X_REGS_SIZE              SZ_1M
 
 #define ORION5X_PCIE_IO_PHYS_BASE      0xf2000000
index 46a9e95..6aaaa1d 100644 (file)
 #include "regs-sys.h"
 #include "regs-usb-hsotg-phy.h"
 
+enum samsung_usb_phy_type {
+       USB_PHY_TYPE_DEVICE,
+       USB_PHY_TYPE_HOST,
+};
+
 static int s3c_usb_otgphy_init(struct platform_device *pdev)
 {
        struct clk *xusbxti;
index 9580525..3875027 100644 (file)
@@ -110,7 +110,6 @@ static void ux500_restart(enum reboot_mode mode, const char *cmd)
 static const struct of_device_id u8500_local_bus_nodes[] = {
        /* only create devices below soc node */
        { .compatible = "stericsson,db8500", },
-       { .compatible = "stericsson,db8500-prcmu", },
        { .compatible = "simple-bus"},
        { },
 };
index 0f5381d..354e0e7 100644 (file)
@@ -69,7 +69,7 @@
 #define A7_PERFVAL_BASE                0xC30
 
 /* Config interface control bits */
-#define SYSCFG_START           (1 << 31)
+#define SYSCFG_START           BIT(31)
 #define SYSCFG_SCC             (6 << 20)
 #define SYSCFG_STAT            (14 << 20)
 
@@ -162,7 +162,7 @@ void ve_spc_cpu_wakeup_irq(u32 cluster, u32 cpu, bool set)
        if (cluster >= MAX_CLUSTERS)
                return;
 
-       mask = 1 << cpu;
+       mask = BIT(cpu);
 
        if (!cluster_is_a15(cluster))
                mask <<= 4;
diff --git a/arch/arm/mach-w90x900/Kconfig b/arch/arm/mach-w90x900/Kconfig
deleted file mode 100644 (file)
index b16ffc0..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-if ARCH_W90X900
-
-config CPU_W90P910
-       bool
-       help
-         Support for W90P910 of Nuvoton W90X900 CPUs.
-
-config CPU_NUC950
-       bool
-       help
-         Support for NUCP950 of Nuvoton NUC900 CPUs.
-
-config CPU_NUC960
-       bool
-       help
-         Support for NUCP960 of Nuvoton NUC900 CPUs.
-
-menu "W90P910 Machines"
-
-config MACH_W90P910EVB
-       bool "Nuvoton W90P910 Evaluation Board"
-       default y
-       select CPU_W90P910
-       help
-          Say Y here if you are using the Nuvoton W90P910EVB
-
-endmenu
-
-menu "NUC950 Machines"
-
-config MACH_W90P950EVB
-       bool "Nuvoton NUC950 Evaluation Board"
-       select CPU_NUC950
-       help
-          Say Y here if you are using the Nuvoton NUC950EVB
-
-endmenu
-
-menu "NUC960 Machines"
-
-config MACH_W90N960EVB
-       bool "Nuvoton NUC960 Evaluation Board"
-       select CPU_NUC960
-       help
-          Say Y here if you are using the Nuvoton NUC960EVB
-
-endmenu
-
-endif
diff --git a/arch/arm/mach-w90x900/Makefile b/arch/arm/mach-w90x900/Makefile
deleted file mode 100644 (file)
index 33b5bf5..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the linux kernel.
-#
-
-# Object file lists.
-
-obj-y                          := irq.o time.o mfp.o gpio.o clock.o
-obj-y                          += clksel.o dev.o cpu.o
-# W90X900 CPU support files
-
-obj-$(CONFIG_CPU_W90P910)      += nuc910.o
-obj-$(CONFIG_CPU_NUC950)       += nuc950.o
-obj-$(CONFIG_CPU_NUC960)       += nuc960.o
-
-# machine support
-
-obj-$(CONFIG_MACH_W90P910EVB)  += mach-nuc910evb.o
-obj-$(CONFIG_MACH_W90P950EVB)  += mach-nuc950evb.o
-obj-$(CONFIG_MACH_W90N960EVB)  += mach-nuc960evb.o
diff --git a/arch/arm/mach-w90x900/Makefile.boot b/arch/arm/mach-w90x900/Makefile.boot
deleted file mode 100644 (file)
index 07d1b3b..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-zreladdr-y     += 0x00008000
-params_phys-y  := 0x00000100
-
diff --git a/arch/arm/mach-w90x900/clksel.c b/arch/arm/mach-w90x900/clksel.c
deleted file mode 100644 (file)
index b50577a..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/clksel.c
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/string.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-clock.h>
-
-#define PLL0           0x00
-#define PLL1           0x01
-#define OTHER          0x02
-#define EXT            0x03
-#define MSOFFSET       0x0C
-#define ATAOFFSET      0x0a
-#define LCDOFFSET      0x06
-#define AUDOFFSET      0x04
-#define CPUOFFSET      0x00
-
-static DEFINE_MUTEX(clksel_sem);
-
-static void clock_source_select(const char *dev_id, unsigned int clkval)
-{
-       unsigned int clksel, offset;
-
-       clksel = __raw_readl(REG_CLKSEL);
-
-       if (strcmp(dev_id, "nuc900-ms") == 0)
-               offset = MSOFFSET;
-       else if (strcmp(dev_id, "nuc900-atapi") == 0)
-               offset = ATAOFFSET;
-       else if (strcmp(dev_id, "nuc900-lcd") == 0)
-               offset = LCDOFFSET;
-       else if (strcmp(dev_id, "nuc900-ac97") == 0)
-               offset = AUDOFFSET;
-       else
-               offset = CPUOFFSET;
-
-       clksel &= ~(0x03 << offset);
-       clksel |= (clkval << offset);
-
-       __raw_writel(clksel, REG_CLKSEL);
-}
-
-void nuc900_clock_source(struct device *dev, unsigned char *src)
-{
-       unsigned int clkval;
-       const char *dev_id;
-
-       BUG_ON(!src);
-       clkval = 0;
-
-       mutex_lock(&clksel_sem);
-
-       if (dev)
-               dev_id = dev_name(dev);
-       else
-               dev_id = "cpufreq";
-
-       if (strcmp(src, "pll0") == 0)
-               clkval = PLL0;
-       else if (strcmp(src, "pll1") == 0)
-               clkval = PLL1;
-       else if (strcmp(src, "ext") == 0)
-               clkval = EXT;
-       else if (strcmp(src, "oth") == 0)
-               clkval = OTHER;
-
-       clock_source_select(dev_id, clkval);
-
-       mutex_unlock(&clksel_sem);
-}
-EXPORT_SYMBOL(nuc900_clock_source);
-
diff --git a/arch/arm/mach-w90x900/clock.c b/arch/arm/mach-w90x900/clock.c
deleted file mode 100644 (file)
index df55aa8..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/clock.c
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/string.h>
-#include <linux/clk.h>
-#include <linux/spinlock.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-
-#include "clock.h"
-
-#define SUBCLK 0x24
-
-static DEFINE_SPINLOCK(clocks_lock);
-
-int clk_enable(struct clk *clk)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&clocks_lock, flags);
-       if (clk->enabled++ == 0)
-               (clk->enable)(clk, 1);
-       spin_unlock_irqrestore(&clocks_lock, flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-void clk_disable(struct clk *clk)
-{
-       unsigned long flags;
-
-       if (!clk)
-               return;
-
-       WARN_ON(clk->enabled == 0);
-
-       spin_lock_irqsave(&clocks_lock, flags);
-       if (--clk->enabled == 0)
-               (clk->enable)(clk, 0);
-       spin_unlock_irqrestore(&clocks_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-       return 15000000;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-void nuc900_clk_enable(struct clk *clk, int enable)
-{
-       unsigned int clocks = clk->cken;
-       unsigned long clken;
-
-       clken = __raw_readl(W90X900_VA_CLKPWR);
-
-       if (enable)
-               clken |= clocks;
-       else
-               clken &= ~clocks;
-
-       __raw_writel(clken, W90X900_VA_CLKPWR);
-}
-
-void nuc900_subclk_enable(struct clk *clk, int enable)
-{
-       unsigned int clocks = clk->cken;
-       unsigned long clken;
-
-       clken = __raw_readl(W90X900_VA_CLKPWR + SUBCLK);
-
-       if (enable)
-               clken |= clocks;
-       else
-               clken &= ~clocks;
-
-       __raw_writel(clken, W90X900_VA_CLKPWR + SUBCLK);
-}
-
-/* dummy functions, should not be called */
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-       WARN_ON(clk);
-       return 0;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-       WARN_ON(clk);
-       return 0;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-       WARN_ON(clk);
-       return 0;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
-       WARN_ON(clk);
-       return NULL;
-}
-EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mach-w90x900/clock.h b/arch/arm/mach-w90x900/clock.h
deleted file mode 100644 (file)
index e81c369..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * linux/arch/arm/mach-w90x900/clock.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/clkdev.h>
-
-void nuc900_clk_enable(struct clk *clk, int enable);
-void nuc900_subclk_enable(struct clk *clk, int enable);
-
-struct clk {
-       unsigned long           cken;
-       unsigned int            enabled;
-       void                    (*enable)(struct clk *, int enable);
-};
-
-#define DEFINE_CLK(_name, _ctrlbit)                    \
-struct clk clk_##_name = {                             \
-               .enable = nuc900_clk_enable,            \
-               .cken   = (1 << _ctrlbit),              \
-       }
-
-#define DEFINE_SUBCLK(_name, _ctrlbit)                 \
-struct clk clk_##_name = {                             \
-               .enable = nuc900_subclk_enable, \
-               .cken   = (1 << _ctrlbit),              \
-       }
-
-
-#define DEF_CLKLOOK(_clk, _devname, _conname)          \
-       {                                               \
-               .clk            = _clk,                 \
-               .dev_id         = _devname,             \
-               .con_id         = _conname,             \
-       }
-
diff --git a/arch/arm/mach-w90x900/cpu.c b/arch/arm/mach-w90x900/cpu.c
deleted file mode 100644 (file)
index aeaafc2..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/cpu.c
- *
- * Copyright (c) 2009 Nuvoton corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * NUC900 series cpu common support
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/serial_8250.h>
-#include <linux/delay.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/irq.h>
-#include <asm/system_misc.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-serial.h>
-#include <mach/regs-clock.h>
-#include "regs-ebi.h"
-#include "regs-timer.h"
-
-#include "cpu.h"
-#include "clock.h"
-#include "nuc9xx.h"
-
-/* Initial IO mappings */
-
-static struct map_desc nuc900_iodesc[] __initdata = {
-       IODESC_ENT(IRQ),
-       IODESC_ENT(GCR),
-       IODESC_ENT(UART),
-       IODESC_ENT(TIMER),
-       IODESC_ENT(EBI),
-       IODESC_ENT(GPIO),
-};
-
-/* Initial clock declarations. */
-static DEFINE_CLK(lcd, 0);
-static DEFINE_CLK(audio, 1);
-static DEFINE_CLK(fmi, 4);
-static DEFINE_SUBCLK(ms, 0);
-static DEFINE_SUBCLK(sd, 1);
-static DEFINE_CLK(dmac, 5);
-static DEFINE_CLK(atapi, 6);
-static DEFINE_CLK(emc, 7);
-static DEFINE_SUBCLK(rmii, 2);
-static DEFINE_CLK(usbd, 8);
-static DEFINE_CLK(usbh, 9);
-static DEFINE_CLK(g2d, 10);
-static DEFINE_CLK(pwm, 18);
-static DEFINE_CLK(ps2, 24);
-static DEFINE_CLK(kpi, 25);
-static DEFINE_CLK(wdt, 26);
-static DEFINE_CLK(gdma, 27);
-static DEFINE_CLK(adc, 28);
-static DEFINE_CLK(usi, 29);
-static DEFINE_CLK(ext, 0);
-static DEFINE_CLK(timer0, 19);
-static DEFINE_CLK(timer1, 20);
-static DEFINE_CLK(timer2, 21);
-static DEFINE_CLK(timer3, 22);
-static DEFINE_CLK(timer4, 23);
-
-static struct clk_lookup nuc900_clkregs[] = {
-       DEF_CLKLOOK(&clk_lcd, "nuc900-lcd", NULL),
-       DEF_CLKLOOK(&clk_audio, "nuc900-ac97", NULL),
-       DEF_CLKLOOK(&clk_fmi, "nuc900-fmi", NULL),
-       DEF_CLKLOOK(&clk_ms, "nuc900-fmi", "MS"),
-       DEF_CLKLOOK(&clk_sd, "nuc900-fmi", "SD"),
-       DEF_CLKLOOK(&clk_dmac, "nuc900-dmac", NULL),
-       DEF_CLKLOOK(&clk_atapi, "nuc900-atapi", NULL),
-       DEF_CLKLOOK(&clk_emc, "nuc900-emc", NULL),
-       DEF_CLKLOOK(&clk_rmii, "nuc900-emc", "RMII"),
-       DEF_CLKLOOK(&clk_usbd, "nuc900-usbd", NULL),
-       DEF_CLKLOOK(&clk_usbh, "nuc900-usbh", NULL),
-       DEF_CLKLOOK(&clk_g2d, "nuc900-g2d", NULL),
-       DEF_CLKLOOK(&clk_pwm, "nuc900-pwm", NULL),
-       DEF_CLKLOOK(&clk_ps2, "nuc900-ps2", NULL),
-       DEF_CLKLOOK(&clk_kpi, "nuc900-kpi", NULL),
-       DEF_CLKLOOK(&clk_wdt, "nuc900-wdt", NULL),
-       DEF_CLKLOOK(&clk_gdma, "nuc900-gdma", NULL),
-       DEF_CLKLOOK(&clk_adc, "nuc900-ts", NULL),
-       DEF_CLKLOOK(&clk_usi, "nuc900-spi", NULL),
-       DEF_CLKLOOK(&clk_ext, NULL, "ext"),
-       DEF_CLKLOOK(&clk_timer0, NULL, "timer0"),
-       DEF_CLKLOOK(&clk_timer1, NULL, "timer1"),
-       DEF_CLKLOOK(&clk_timer2, NULL, "timer2"),
-       DEF_CLKLOOK(&clk_timer3, NULL, "timer3"),
-       DEF_CLKLOOK(&clk_timer4, NULL, "timer4"),
-};
-
-/* Initial serial platform data */
-
-struct plat_serial8250_port nuc900_uart_data[] = {
-       NUC900_8250PORT(UART0),
-       {},
-};
-
-struct platform_device nuc900_serial_device = {
-       .name                   = "serial8250",
-       .id                     = PLAT8250_DEV_PLATFORM,
-       .dev                    = {
-               .platform_data  = nuc900_uart_data,
-       },
-};
-
-/*Set NUC900 series cpu frequence*/
-static int __init nuc900_set_clkval(unsigned int cpufreq)
-{
-       unsigned int pllclk, ahbclk, apbclk, val;
-
-       pllclk = 0;
-       ahbclk = 0;
-       apbclk = 0;
-
-       switch (cpufreq) {
-       case 66:
-               pllclk = PLL_66MHZ;
-               ahbclk = AHB_CPUCLK_1_1;
-               apbclk = APB_AHB_1_2;
-               break;
-
-       case 100:
-               pllclk = PLL_100MHZ;
-               ahbclk = AHB_CPUCLK_1_1;
-               apbclk = APB_AHB_1_2;
-               break;
-
-       case 120:
-               pllclk = PLL_120MHZ;
-               ahbclk = AHB_CPUCLK_1_2;
-               apbclk = APB_AHB_1_2;
-               break;
-
-       case 166:
-               pllclk = PLL_166MHZ;
-               ahbclk = AHB_CPUCLK_1_2;
-               apbclk = APB_AHB_1_2;
-               break;
-
-       case 200:
-               pllclk = PLL_200MHZ;
-               ahbclk = AHB_CPUCLK_1_2;
-               apbclk = APB_AHB_1_2;
-               break;
-       }
-
-       __raw_writel(pllclk, REG_PLLCON0);
-
-       val = __raw_readl(REG_CLKDIV);
-       val &= ~(0x03 << 24 | 0x03 << 26);
-       val |= (ahbclk << 24 | apbclk << 26);
-       __raw_writel(val, REG_CLKDIV);
-
-       return  0;
-}
-static int __init nuc900_set_cpufreq(char *str)
-{
-       unsigned long cpufreq, val;
-
-       if (!*str)
-               return 0;
-
-       if (kstrtoul(str, 0, &cpufreq))
-               return 0;
-
-       nuc900_clock_source(NULL, "ext");
-
-       nuc900_set_clkval(cpufreq);
-
-       mdelay(1);
-
-       val = __raw_readl(REG_CKSKEW);
-       val &= ~0xff;
-       val |= DEFAULTSKEW;
-       __raw_writel(val, REG_CKSKEW);
-
-       nuc900_clock_source(NULL, "pll0");
-
-       return 1;
-}
-
-__setup("cpufreq=", nuc900_set_cpufreq);
-
-/*Init NUC900 evb io*/
-
-void __init nuc900_map_io(struct map_desc *mach_desc, int mach_size)
-{
-       unsigned long idcode = 0x0;
-
-       iotable_init(mach_desc, mach_size);
-       iotable_init(nuc900_iodesc, ARRAY_SIZE(nuc900_iodesc));
-
-       idcode = __raw_readl(NUC900PDID);
-       if (idcode == NUC910_CPUID)
-               printk(KERN_INFO "CPU type 0x%08lx is NUC910\n", idcode);
-       else if (idcode == NUC920_CPUID)
-               printk(KERN_INFO "CPU type 0x%08lx is NUC920\n", idcode);
-       else if (idcode == NUC950_CPUID)
-               printk(KERN_INFO "CPU type 0x%08lx is NUC950\n", idcode);
-       else if (idcode == NUC960_CPUID)
-               printk(KERN_INFO "CPU type 0x%08lx is NUC960\n", idcode);
-}
-
-/*Init NUC900 clock*/
-
-void __init nuc900_init_clocks(void)
-{
-       clkdev_add_table(nuc900_clkregs, ARRAY_SIZE(nuc900_clkregs));
-}
-
-#define        WTCR    (TMR_BA + 0x1C)
-#define        WTCLK   (1 << 10)
-#define        WTE     (1 << 7)
-#define        WTRE    (1 << 1)
-
-void nuc9xx_restart(enum reboot_mode mode, const char *cmd)
-{
-       if (mode == REBOOT_SOFT) {
-               /* Jump into ROM at address 0 */
-               soft_restart(0);
-       } else {
-               __raw_writel(WTE | WTRE | WTCLK, WTCR);
-       }
-}
diff --git a/arch/arm/mach-w90x900/cpu.h b/arch/arm/mach-w90x900/cpu.h
deleted file mode 100644 (file)
index a56f36d..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-w90x900/cpu.h
- *
- * Based on linux/include/asm-arm/plat-s3c24xx/cpu.h by Ben Dooks
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
- *
- * Header file for NUC900 CPU support
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#define IODESC_ENT(y)                                  \
-{                                                      \
-       .virtual = (unsigned long)W90X900_VA_##y,       \
-       .pfn     = __phys_to_pfn(W90X900_PA_##y),       \
-       .length  = W90X900_SZ_##y,                      \
-       .type    = MT_DEVICE,                           \
-}
-
-#define NUC900_8250PORT(name)                                  \
-{                                                              \
-       .membase        = name##_BA,                            \
-       .mapbase        = name##_PA,                            \
-       .irq            = IRQ_##name,                           \
-       .uartclk        = 11313600,                             \
-       .regshift       = 2,                                    \
-       .iotype         = UPIO_MEM,                             \
-       .flags          = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,    \
-}
-
-/*Cpu identifier register*/
-
-#define NUC900PDID     W90X900_VA_GCR
-#define NUC910_CPUID   0x02900910
-#define NUC920_CPUID   0x02900920
-#define NUC950_CPUID   0x02900950
-#define NUC960_CPUID   0x02900960
-
-/* extern file from cpu.c */
-
-extern void nuc900_clock_source(struct device *dev, unsigned char *src);
-extern void nuc900_init_clocks(void);
-extern void nuc900_map_io(struct map_desc *mach_desc, int mach_size);
-extern void nuc900_board_init(struct platform_device **device, int size);
-
-/* for either public between 910 and 920, or between 920 and 950 */
-
-extern struct platform_device nuc900_serial_device;
-extern struct platform_device nuc900_device_fmi;
-extern struct platform_device nuc900_device_kpi;
-extern struct platform_device nuc900_device_rtc;
-extern struct platform_device nuc900_device_ts;
-extern struct platform_device nuc900_device_lcd;
diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c
deleted file mode 100644 (file)
index ce5fe40..0000000
+++ /dev/null
@@ -1,537 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/dev.c
- *
- * Copyright (C) 2009 Nuvoton corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/cpu.h>
-
-#include <linux/mtd/physmap.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-#include <linux/spi/spi.h>
-#include <linux/spi/flash.h>
-
-#include <asm/system_misc.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-#include <asm/mach-types.h>
-
-#include <mach/regs-serial.h>
-#include <linux/platform_data/spi-nuc900.h>
-#include <mach/map.h>
-#include <linux/platform_data/video-nuc900fb.h>
-#include <mach/regs-ldm.h>
-#include <linux/platform_data/keypad-w90p910.h>
-
-#include "cpu.h"
-
-/*NUC900 evb norflash driver data */
-
-#define NUC900_FLASH_BASE      0xA0000000
-#define NUC900_FLASH_SIZE      0x400000
-#define SPIOFFSET              0x200
-#define SPIOREG_SIZE           0x100
-
-static struct mtd_partition nuc900_flash_partitions[] = {
-       {
-               .name   =       "NOR Partition 1 for kernel (960K)",
-               .size   =       0xF0000,
-               .offset =       0x10000,
-       },
-       {
-               .name   =       "NOR Partition 2 for image (1M)",
-               .size   =       0x100000,
-               .offset =       0x100000,
-       },
-       {
-               .name   =       "NOR Partition 3 for user (2M)",
-               .size   =       0x200000,
-               .offset =       0x00200000,
-       }
-};
-
-static struct physmap_flash_data nuc900_flash_data = {
-       .width          =       2,
-       .parts          =       nuc900_flash_partitions,
-       .nr_parts       =       ARRAY_SIZE(nuc900_flash_partitions),
-};
-
-static struct resource nuc900_flash_resources[] = {
-       {
-               .start  =       NUC900_FLASH_BASE,
-               .end    =       NUC900_FLASH_BASE + NUC900_FLASH_SIZE - 1,
-               .flags  =       IORESOURCE_MEM,
-       }
-};
-
-static struct platform_device nuc900_flash_device = {
-       .name           =       "physmap-flash",
-       .id             =       0,
-       .dev            = {
-                               .platform_data = &nuc900_flash_data,
-                       },
-       .resource       =       nuc900_flash_resources,
-       .num_resources  =       ARRAY_SIZE(nuc900_flash_resources),
-};
-
-/* USB EHCI Host Controller */
-
-static struct resource nuc900_usb_ehci_resource[] = {
-       [0] = {
-               .start = W90X900_PA_USBEHCIHOST,
-               .end   = W90X900_PA_USBEHCIHOST + W90X900_SZ_USBEHCIHOST - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_USBH,
-               .end   = IRQ_USBH,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static u64 nuc900_device_usb_ehci_dmamask = 0xffffffffUL;
-
-static struct platform_device nuc900_device_usb_ehci = {
-       .name             = "nuc900-ehci",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(nuc900_usb_ehci_resource),
-       .resource         = nuc900_usb_ehci_resource,
-       .dev              = {
-               .dma_mask = &nuc900_device_usb_ehci_dmamask,
-               .coherent_dma_mask = 0xffffffffUL
-       }
-};
-
-/* USB OHCI Host Controller */
-
-static struct resource nuc900_usb_ohci_resource[] = {
-       [0] = {
-               .start = W90X900_PA_USBOHCIHOST,
-               .end   = W90X900_PA_USBOHCIHOST + W90X900_SZ_USBOHCIHOST - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_USBH,
-               .end   = IRQ_USBH,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static u64 nuc900_device_usb_ohci_dmamask = 0xffffffffUL;
-static struct platform_device nuc900_device_usb_ohci = {
-       .name             = "nuc900-ohci",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(nuc900_usb_ohci_resource),
-       .resource         = nuc900_usb_ohci_resource,
-       .dev              = {
-               .dma_mask = &nuc900_device_usb_ohci_dmamask,
-               .coherent_dma_mask = 0xffffffffUL
-       }
-};
-
-/* USB Device (Gadget)*/
-
-static struct resource nuc900_usbgadget_resource[] = {
-       [0] = {
-               .start = W90X900_PA_USBDEV,
-               .end   = W90X900_PA_USBDEV + W90X900_SZ_USBDEV - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_USBD,
-               .end   = IRQ_USBD,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static struct platform_device nuc900_device_usbgadget = {
-       .name           = "nuc900-usbgadget",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(nuc900_usbgadget_resource),
-       .resource       = nuc900_usbgadget_resource,
-};
-
-/* MAC device */
-
-static struct resource nuc900_emc_resource[] = {
-       [0] = {
-               .start = W90X900_PA_EMC,
-               .end   = W90X900_PA_EMC + W90X900_SZ_EMC - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_EMCTX,
-               .end   = IRQ_EMCTX,
-               .flags = IORESOURCE_IRQ,
-       },
-       [2] = {
-               .start = IRQ_EMCRX,
-               .end   = IRQ_EMCRX,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static u64 nuc900_device_emc_dmamask = 0xffffffffUL;
-static struct platform_device nuc900_device_emc = {
-       .name           = "nuc900-emc",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(nuc900_emc_resource),
-       .resource       = nuc900_emc_resource,
-       .dev              = {
-               .dma_mask = &nuc900_device_emc_dmamask,
-               .coherent_dma_mask = 0xffffffffUL
-       }
-};
-
-/* SPI device */
-
-static struct nuc900_spi_info nuc900_spiflash_data = {
-       .num_cs         = 1,
-       .lsb            = 0,
-       .txneg          = 1,
-       .rxneg          = 0,
-       .divider        = 24,
-       .sleep          = 0,
-       .txnum          = 0,
-       .txbitlen       = 8,
-       .bus_num        = 0,
-};
-
-static struct resource nuc900_spi_resource[] = {
-       [0] = {
-               .start = W90X900_PA_I2C + SPIOFFSET,
-               .end   = W90X900_PA_I2C + SPIOFFSET + SPIOREG_SIZE - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_SSP,
-               .end   = IRQ_SSP,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static struct platform_device nuc900_device_spi = {
-       .name           = "nuc900-spi",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(nuc900_spi_resource),
-       .resource       = nuc900_spi_resource,
-       .dev            = {
-                               .platform_data = &nuc900_spiflash_data,
-                       }
-};
-
-/* spi device, spi flash info */
-
-static struct mtd_partition nuc900_spi_flash_partitions[] = {
-       {
-               .name = "bootloader(spi)",
-               .size = 0x0100000,
-               .offset = 0,
-       },
-};
-
-static struct flash_platform_data nuc900_spi_flash_data = {
-       .name = "m25p80",
-       .parts =  nuc900_spi_flash_partitions,
-       .nr_parts = ARRAY_SIZE(nuc900_spi_flash_partitions),
-       .type = "w25x16",
-};
-
-static struct spi_board_info nuc900_spi_board_info[] __initdata = {
-       {
-               .modalias = "m25p80",
-               .max_speed_hz = 20000000,
-               .bus_num = 0,
-               .chip_select = 0,
-               .platform_data = &nuc900_spi_flash_data,
-               .mode = SPI_MODE_0,
-       },
-};
-
-/* WDT Device */
-
-static struct resource nuc900_wdt_resource[] = {
-       [0] = {
-               .start = W90X900_PA_TIMER,
-               .end   = W90X900_PA_TIMER + W90X900_SZ_TIMER - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_WDT,
-               .end   = IRQ_WDT,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static struct platform_device nuc900_device_wdt = {
-       .name           = "nuc900-wdt",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(nuc900_wdt_resource),
-       .resource       = nuc900_wdt_resource,
-};
-
-/*
- * public device definition between 910 and 920, or 910
- * and 950 or 950 and 960...,their dev platform register
- * should be in specific file such as nuc950, nuc960 c
- * files rather than the public dev.c file here. so the
- * corresponding platform_device definition should not be
- * static.
-*/
-
-/* RTC controller*/
-
-static struct resource nuc900_rtc_resource[] = {
-       [0] = {
-               .start = W90X900_PA_RTC,
-               .end   = W90X900_PA_RTC + 0xff,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_RTC,
-               .end   = IRQ_RTC,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device nuc900_device_rtc = {
-       .name           = "nuc900-rtc",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(nuc900_rtc_resource),
-       .resource       = nuc900_rtc_resource,
-};
-
-/*TouchScreen controller*/
-
-static struct resource nuc900_ts_resource[] = {
-       [0] = {
-               .start = W90X900_PA_ADC,
-               .end   = W90X900_PA_ADC + W90X900_SZ_ADC-1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_ADC,
-               .end   = IRQ_ADC,
-               .flags = IORESOURCE_IRQ,
-       },
-};
-
-struct platform_device nuc900_device_ts = {
-       .name           = "nuc900-ts",
-       .id             = -1,
-       .resource       = nuc900_ts_resource,
-       .num_resources  = ARRAY_SIZE(nuc900_ts_resource),
-};
-
-/* FMI Device */
-
-static struct resource nuc900_fmi_resource[] = {
-       [0] = {
-               .start = W90X900_PA_FMI,
-               .end   = W90X900_PA_FMI + W90X900_SZ_FMI - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_FMI,
-               .end   = IRQ_FMI,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-struct platform_device nuc900_device_fmi = {
-       .name           = "nuc900-fmi",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(nuc900_fmi_resource),
-       .resource       = nuc900_fmi_resource,
-};
-
-/* KPI controller*/
-
-static int nuc900_keymap[] = {
-       KEY(0, 0, KEY_A),
-       KEY(0, 1, KEY_B),
-       KEY(0, 2, KEY_C),
-       KEY(0, 3, KEY_D),
-
-       KEY(1, 0, KEY_E),
-       KEY(1, 1, KEY_F),
-       KEY(1, 2, KEY_G),
-       KEY(1, 3, KEY_H),
-
-       KEY(2, 0, KEY_I),
-       KEY(2, 1, KEY_J),
-       KEY(2, 2, KEY_K),
-       KEY(2, 3, KEY_L),
-
-       KEY(3, 0, KEY_M),
-       KEY(3, 1, KEY_N),
-       KEY(3, 2, KEY_O),
-       KEY(3, 3, KEY_P),
-};
-
-static struct matrix_keymap_data nuc900_map_data = {
-       .keymap                 = nuc900_keymap,
-       .keymap_size            = ARRAY_SIZE(nuc900_keymap),
-};
-
-struct w90p910_keypad_platform_data nuc900_keypad_info = {
-       .keymap_data    = &nuc900_map_data,
-       .prescale       = 0xfa,
-       .debounce       = 0x50,
-};
-
-static struct resource nuc900_kpi_resource[] = {
-       [0] = {
-               .start = W90X900_PA_KPI,
-               .end   = W90X900_PA_KPI + W90X900_SZ_KPI - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_KPI,
-               .end   = IRQ_KPI,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device nuc900_device_kpi = {
-       .name           = "nuc900-kpi",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(nuc900_kpi_resource),
-       .resource       = nuc900_kpi_resource,
-       .dev            = {
-                               .platform_data = &nuc900_keypad_info,
-                       }
-};
-
-/* LCD controller*/
-
-static struct nuc900fb_display nuc900_lcd_info[] = {
-       /* Giantplus Technology GPM1040A0 320x240 Color TFT LCD */
-       [0] = {
-               .type           = LCM_DCCS_VA_SRC_RGB565,
-               .width          = 320,
-               .height         = 240,
-               .xres           = 320,
-               .yres           = 240,
-               .bpp            = 16,
-               .pixclock       = 200000,
-               .left_margin    = 34,
-               .right_margin   = 54,
-               .hsync_len      = 10,
-               .upper_margin   = 18,
-               .lower_margin   = 4,
-               .vsync_len      = 1,
-               .dccs           = 0x8e00041a,
-               .devctl         = 0x060800c0,
-               .fbctrl         = 0x00a000a0,
-               .scale          = 0x04000400,
-       },
-};
-
-static struct nuc900fb_mach_info nuc900_fb_info = {
-#if defined(CONFIG_GPM1040A0_320X240)
-       .displays               = &nuc900_lcd_info[0],
-#else
-       .displays               = nuc900_lcd_info,
-#endif
-       .num_displays           = ARRAY_SIZE(nuc900_lcd_info),
-       .default_display        = 0,
-       .gpio_dir               = 0x00000004,
-       .gpio_dir_mask          = 0xFFFFFFFD,
-       .gpio_data              = 0x00000004,
-       .gpio_data_mask         = 0xFFFFFFFD,
-};
-
-static struct resource nuc900_lcd_resource[] = {
-       [0] = {
-               .start = W90X900_PA_LCD,
-               .end   = W90X900_PA_LCD + W90X900_SZ_LCD - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_LCD,
-               .end   = IRQ_LCD,
-               .flags = IORESOURCE_IRQ,
-       }
-};
-
-static u64 nuc900_device_lcd_dmamask = -1;
-struct platform_device nuc900_device_lcd = {
-       .name             = "nuc900-lcd",
-       .id               = -1,
-       .num_resources    = ARRAY_SIZE(nuc900_lcd_resource),
-       .resource         = nuc900_lcd_resource,
-       .dev              = {
-               .dma_mask               = &nuc900_device_lcd_dmamask,
-               .coherent_dma_mask      = -1,
-               .platform_data = &nuc900_fb_info,
-       }
-};
-
-/* AUDIO controller*/
-static u64 nuc900_device_audio_dmamask = -1;
-static struct resource nuc900_ac97_resource[] = {
-       [0] = {
-               .start = W90X900_PA_ACTL,
-               .end   = W90X900_PA_ACTL + W90X900_SZ_ACTL - 1,
-               .flags = IORESOURCE_MEM,
-       },
-       [1] = {
-               .start = IRQ_ACTL,
-               .end   = IRQ_ACTL,
-               .flags = IORESOURCE_IRQ,
-       }
-
-};
-
-struct platform_device nuc900_device_ac97 = {
-       .name           = "nuc900-ac97",
-       .id             = -1,
-       .num_resources  = ARRAY_SIZE(nuc900_ac97_resource),
-       .resource       = nuc900_ac97_resource,
-       .dev              = {
-               .dma_mask               = &nuc900_device_audio_dmamask,
-               .coherent_dma_mask      = -1,
-       }
-};
-
-/*Here should be your evb resourse,such as LCD*/
-
-static struct platform_device *nuc900_public_dev[] __initdata = {
-       &nuc900_serial_device,
-       &nuc900_flash_device,
-       &nuc900_device_usb_ehci,
-       &nuc900_device_usb_ohci,
-       &nuc900_device_usbgadget,
-       &nuc900_device_emc,
-       &nuc900_device_spi,
-       &nuc900_device_wdt,
-       &nuc900_device_ac97,
-};
-
-/* Provide adding specific CPU platform devices API */
-
-void __init nuc900_board_init(struct platform_device **device, int size)
-{
-       cpu_idle_poll_ctrl(true);
-       platform_add_devices(device, size);
-       platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev));
-       spi_register_board_info(nuc900_spi_board_info,
-                                       ARRAY_SIZE(nuc900_spi_board_info));
-}
-
diff --git a/arch/arm/mach-w90x900/gpio.c b/arch/arm/mach-w90x900/gpio.c
deleted file mode 100644 (file)
index cb5df21..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/gpio.c
- *
- * Generic nuc900 GPIO handling
- *
- *  Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/clk.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/io.h>
-#include <linux/gpio/driver.h>
-
-#include <mach/hardware.h>
-
-#define GPIO_BASE              (W90X900_VA_GPIO)
-#define GPIO_DIR               (0x04)
-#define GPIO_OUT               (0x08)
-#define GPIO_IN                        (0x0C)
-#define GROUPINERV             (0x10)
-#define GPIO_GPIO(Nb)          (0x00000001 << (Nb))
-
-#define NUC900_GPIO_CHIP(name, base_gpio, nr_gpio)                     \
-       {                                                               \
-               .chip = {                                               \
-                       .label            = name,                       \
-                       .direction_input  = nuc900_dir_input,           \
-                       .direction_output = nuc900_dir_output,          \
-                       .get              = nuc900_gpio_get,            \
-                       .set              = nuc900_gpio_set,            \
-                       .base             = base_gpio,                  \
-                       .ngpio            = nr_gpio,                    \
-               }                                                       \
-       }
-
-struct nuc900_gpio_chip {
-       struct gpio_chip        chip;
-       void __iomem            *regbase;       /* Base of group register*/
-       spinlock_t              gpio_lock;
-};
-
-static int nuc900_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-       struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
-       void __iomem *pio = nuc900_gpio->regbase + GPIO_IN;
-       unsigned int regval;
-
-       regval = __raw_readl(pio);
-       regval &= GPIO_GPIO(offset);
-
-       return (regval != 0);
-}
-
-static void nuc900_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
-{
-       struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
-       void __iomem *pio = nuc900_gpio->regbase + GPIO_OUT;
-       unsigned int regval;
-       unsigned long flags;
-
-       spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
-
-       regval = __raw_readl(pio);
-
-       if (val)
-               regval |= GPIO_GPIO(offset);
-       else
-               regval &= ~GPIO_GPIO(offset);
-
-       __raw_writel(regval, pio);
-
-       spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
-}
-
-static int nuc900_dir_input(struct gpio_chip *chip, unsigned offset)
-{
-       struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
-       void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
-       unsigned int regval;
-       unsigned long flags;
-
-       spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
-
-       regval = __raw_readl(pio);
-       regval &= ~GPIO_GPIO(offset);
-       __raw_writel(regval, pio);
-
-       spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
-
-       return 0;
-}
-
-static int nuc900_dir_output(struct gpio_chip *chip, unsigned offset, int val)
-{
-       struct nuc900_gpio_chip *nuc900_gpio = gpiochip_get_data(chip);
-       void __iomem *outreg = nuc900_gpio->regbase + GPIO_OUT;
-       void __iomem *pio = nuc900_gpio->regbase + GPIO_DIR;
-       unsigned int regval;
-       unsigned long flags;
-
-       spin_lock_irqsave(&nuc900_gpio->gpio_lock, flags);
-
-       regval = __raw_readl(pio);
-       regval |= GPIO_GPIO(offset);
-       __raw_writel(regval, pio);
-
-       regval = __raw_readl(outreg);
-
-       if (val)
-               regval |= GPIO_GPIO(offset);
-       else
-               regval &= ~GPIO_GPIO(offset);
-
-       __raw_writel(regval, outreg);
-
-       spin_unlock_irqrestore(&nuc900_gpio->gpio_lock, flags);
-
-       return 0;
-}
-
-static struct nuc900_gpio_chip nuc900_gpio[] = {
-       NUC900_GPIO_CHIP("GROUPC", 0, 16),
-       NUC900_GPIO_CHIP("GROUPD", 16, 10),
-       NUC900_GPIO_CHIP("GROUPE", 26, 14),
-       NUC900_GPIO_CHIP("GROUPF", 40, 10),
-       NUC900_GPIO_CHIP("GROUPG", 50, 17),
-       NUC900_GPIO_CHIP("GROUPH", 67, 8),
-       NUC900_GPIO_CHIP("GROUPI", 75, 17),
-};
-
-void __init nuc900_init_gpio(int nr_group)
-{
-       unsigned        i;
-       struct nuc900_gpio_chip *gpio_chip;
-
-       for (i = 0; i < nr_group; i++) {
-               gpio_chip = &nuc900_gpio[i];
-               spin_lock_init(&gpio_chip->gpio_lock);
-               gpio_chip->regbase = GPIO_BASE + i * GROUPINERV;
-               gpiochip_add_data(&gpio_chip->chip, gpio_chip);
-       }
-}
diff --git a/arch/arm/mach-w90x900/include/mach/entry-macro.S b/arch/arm/mach-w90x900/include/mach/entry-macro.S
deleted file mode 100644 (file)
index 0ff612a..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * arch/arm/mach-w90x900/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for W90P910-based platforms
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- *
- */
-
-#include <mach/hardware.h>
-#include <mach/regs-irq.h>
-
-       .macro  get_irqnr_preamble, base, tmp
-       .endm
-
-       .macro  get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-               mov     \base, #AIC_BA
-
-               ldr     \irqnr, [\base, #AIC_IPER]
-               ldr     \irqnr, [\base, #AIC_ISNR]
-               cmp     \irqnr, #0
-
-       .endm
diff --git a/arch/arm/mach-w90x900/include/mach/hardware.h b/arch/arm/mach-w90x900/include/mach/hardware.h
deleted file mode 100644 (file)
index 1374039..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-w90x900/include/mach/hardware.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * Based on arch/arm/mach-s3c2410/include/mach/hardware.h
- */
-
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-#include <linux/sizes.h>
-#include <mach/map.h>
-
-#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-w90x900/include/mach/irqs.h b/arch/arm/mach-w90x900/include/mach/irqs.h
deleted file mode 100644 (file)
index 23ea01d..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-w90x900/include/mach/irqs.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * Based on arch/arm/mach-s3c2410/include/mach/irqs.h
- */
-
-#ifndef __ASM_ARCH_IRQS_H
-#define __ASM_ARCH_IRQS_H
-
-/*
- * we keep the first set of CPU IRQs out of the range of
- * the ISA space, so that the PC104 has them to itself
- * and we don't end up having to do horrible things to the
- * standard ISA drivers....
- *
- */
-
-#define W90X900_IRQ(x) (x)
-
-/* Main cpu interrupts */
-
-#define IRQ_WDT                W90X900_IRQ(1)
-#define IRQ_GROUP0     W90X900_IRQ(2)
-#define IRQ_GROUP1     W90X900_IRQ(3)
-#define IRQ_ACTL       W90X900_IRQ(4)
-#define IRQ_LCD                W90X900_IRQ(5)
-#define IRQ_RTC                W90X900_IRQ(6)
-#define IRQ_UART0      W90X900_IRQ(7)
-#define IRQ_UART1      W90X900_IRQ(8)
-#define IRQ_UART2      W90X900_IRQ(9)
-#define IRQ_UART3      W90X900_IRQ(10)
-#define IRQ_UART4      W90X900_IRQ(11)
-#define IRQ_TIMER0     W90X900_IRQ(12)
-#define IRQ_TIMER1     W90X900_IRQ(13)
-#define IRQ_T_INT_GROUP        W90X900_IRQ(14)
-#define IRQ_USBH       W90X900_IRQ(15)
-#define IRQ_EMCTX      W90X900_IRQ(16)
-#define IRQ_EMCRX      W90X900_IRQ(17)
-#define IRQ_GDMAGROUP  W90X900_IRQ(18)
-#define IRQ_DMAC       W90X900_IRQ(19)
-#define IRQ_FMI                W90X900_IRQ(20)
-#define IRQ_USBD       W90X900_IRQ(21)
-#define IRQ_ATAPI      W90X900_IRQ(22)
-#define IRQ_G2D                W90X900_IRQ(23)
-#define IRQ_PCI                W90X900_IRQ(24)
-#define IRQ_SCGROUP    W90X900_IRQ(25)
-#define IRQ_I2CGROUP   W90X900_IRQ(26)
-#define IRQ_SSP                W90X900_IRQ(27)
-#define IRQ_PWM                W90X900_IRQ(28)
-#define IRQ_KPI                W90X900_IRQ(29)
-#define IRQ_P2SGROUP   W90X900_IRQ(30)
-#define IRQ_ADC                W90X900_IRQ(31)
-#define NR_IRQS                (IRQ_ADC+1)
-
-/*for irq group*/
-
-#define        IRQ_PS2_PORT0   0x10000000
-#define        IRQ_PS2_PORT1   0x20000000
-#define        IRQ_I2C_LINE0   0x04000000
-#define        IRQ_I2C_LINE1   0x08000000
-#define        IRQ_SC_CARD0    0x01000000
-#define        IRQ_SC_CARD1    0x02000000
-#define        IRQ_GDMA_CH0    0x00100000
-#define        IRQ_GDMA_CH1    0x00200000
-#define        IRQ_TIMER2      0x00010000
-#define        IRQ_TIMER3      0x00020000
-#define        IRQ_TIMER4      0x00040000
-#define        IRQ_GROUP0_IRQ0 0x00000001
-#define        IRQ_GROUP0_IRQ1 0x00000002
-#define        IRQ_GROUP0_IRQ2 0x00000004
-#define        IRQ_GROUP0_IRQ3 0x00000008
-#define        IRQ_GROUP1_IRQ4 0x00000010
-#define        IRQ_GROUP1_IRQ5 0x00000020
-#define        IRQ_GROUP1_IRQ6 0x00000040
-#define        IRQ_GROUP1_IRQ7 0x00000080
-
-#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-w90x900/include/mach/map.h b/arch/arm/mach-w90x900/include/mach/map.h
deleted file mode 100644 (file)
index 570a74e..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-w90x900/include/mach/map.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * Based on arch/arm/mach-s3c2410/include/mach/map.h
- */
-
-#ifndef __ASM_ARCH_MAP_H
-#define __ASM_ARCH_MAP_H
-
-#ifndef __ASSEMBLY__
-#define W90X900_ADDR(x)                ((void __iomem *)(0xF0000000 + (x)))
-#else
-#define W90X900_ADDR(x)                (0xF0000000 + (x))
-#endif
-
-#define AHB_IO_BASE            0xB0000000
-#define APB_IO_BASE            0xB8000000
-#define CLOCKPW_BASE           (APB_IO_BASE+0x200)
-#define AIC_IO_BASE            (APB_IO_BASE+0x2000)
-#define TIMER_IO_BASE          (APB_IO_BASE+0x1000)
-
-/*
- * interrupt controller is the first thing we put in, to make
- * the assembly code for the irq detection easier
- */
-#define W90X900_VA_IRQ         W90X900_ADDR(0x00000000)
-#define W90X900_PA_IRQ         (0xB8002000)
-#define W90X900_SZ_IRQ         SZ_4K
-
-#define W90X900_VA_GCR         W90X900_ADDR(0x08002000)
-#define W90X900_PA_GCR         (0xB0000000)
-#define W90X900_SZ_GCR         SZ_4K
-
-/* Clock and Power management */
-#define W90X900_VA_CLKPWR      (W90X900_VA_GCR+0x200)
-#define W90X900_PA_CLKPWR      (0xB0000200)
-#define W90X900_SZ_CLKPWR      SZ_4K
-
-/* EBI management */
-#define W90X900_VA_EBI         W90X900_ADDR(0x00001000)
-#define W90X900_PA_EBI         (0xB0001000)
-#define W90X900_SZ_EBI         SZ_4K
-
-/* UARTs */
-#define W90X900_VA_UART                W90X900_ADDR(0x08000000)
-#define W90X900_PA_UART                (0xB8000000)
-#define W90X900_SZ_UART                SZ_4K
-
-/* Timers */
-#define W90X900_VA_TIMER       W90X900_ADDR(0x08001000)
-#define W90X900_PA_TIMER       (0xB8001000)
-#define W90X900_SZ_TIMER       SZ_4K
-
-/* GPIO ports */
-#define W90X900_VA_GPIO                W90X900_ADDR(0x08003000)
-#define W90X900_PA_GPIO                (0xB8003000)
-#define W90X900_SZ_GPIO                SZ_4K
-
-/* GDMA control */
-#define W90X900_VA_GDMA                W90X900_ADDR(0x00004000)
-#define W90X900_PA_GDMA                (0xB0004000)
-#define W90X900_SZ_GDMA                SZ_4K
-
-/* USB host controller*/
-#define W90X900_VA_USBEHCIHOST W90X900_ADDR(0x00005000)
-#define W90X900_PA_USBEHCIHOST (0xB0005000)
-#define W90X900_SZ_USBEHCIHOST SZ_4K
-
-#define W90X900_VA_USBOHCIHOST W90X900_ADDR(0x00007000)
-#define W90X900_PA_USBOHCIHOST (0xB0007000)
-#define W90X900_SZ_USBOHCIHOST SZ_4K
-
-/* I2C hardware controller */
-#define W90X900_VA_I2C         W90X900_ADDR(0x08006000)
-#define W90X900_PA_I2C         (0xB8006000)
-#define W90X900_SZ_I2C         SZ_4K
-
-/* Keypad Interface*/
-#define W90X900_VA_KPI         W90X900_ADDR(0x08008000)
-#define W90X900_PA_KPI         (0xB8008000)
-#define W90X900_SZ_KPI         SZ_4K
-
-/* Smart card host*/
-#define W90X900_VA_SC          W90X900_ADDR(0x08005000)
-#define W90X900_PA_SC          (0xB8005000)
-#define W90X900_SZ_SC          SZ_4K
-
-/* LCD controller*/
-#define W90X900_VA_LCD         W90X900_ADDR(0x00008000)
-#define W90X900_PA_LCD         (0xB0008000)
-#define W90X900_SZ_LCD         SZ_4K
-
-/* 2D controller*/
-#define W90X900_VA_GE          W90X900_ADDR(0x0000B000)
-#define W90X900_PA_GE          (0xB000B000)
-#define W90X900_SZ_GE          SZ_4K
-
-/* ATAPI */
-#define W90X900_VA_ATAPI       W90X900_ADDR(0x0000A000)
-#define W90X900_PA_ATAPI       (0xB000A000)
-#define W90X900_SZ_ATAPI       SZ_4K
-
-/* ADC */
-#define W90X900_VA_ADC         W90X900_ADDR(0x0800A000)
-#define W90X900_PA_ADC         (0xB800A000)
-#define W90X900_SZ_ADC         SZ_4K
-
-/* PS2 Interface*/
-#define W90X900_VA_PS2         W90X900_ADDR(0x08009000)
-#define W90X900_PA_PS2         (0xB8009000)
-#define W90X900_SZ_PS2         SZ_4K
-
-/* RTC */
-#define W90X900_VA_RTC         W90X900_ADDR(0x08004000)
-#define W90X900_PA_RTC         (0xB8004000)
-#define W90X900_SZ_RTC         SZ_4K
-
-/* Pulse Width Modulation(PWM) Registers */
-#define W90X900_VA_PWM         W90X900_ADDR(0x08007000)
-#define W90X900_PA_PWM         (0xB8007000)
-#define W90X900_SZ_PWM         SZ_4K
-
-/* Audio Controller controller */
-#define W90X900_VA_ACTL                W90X900_ADDR(0x00009000)
-#define W90X900_PA_ACTL                (0xB0009000)
-#define W90X900_SZ_ACTL                SZ_4K
-
-/* DMA controller */
-#define W90X900_VA_DMA         W90X900_ADDR(0x0000c000)
-#define W90X900_PA_DMA         (0xB000c000)
-#define W90X900_SZ_DMA         SZ_4K
-
-/* FMI controller */
-#define W90X900_VA_FMI         W90X900_ADDR(0x0000d000)
-#define W90X900_PA_FMI         (0xB000d000)
-#define W90X900_SZ_FMI         SZ_4K
-
-/* USB Device port */
-#define W90X900_VA_USBDEV      W90X900_ADDR(0x00006000)
-#define W90X900_PA_USBDEV      (0xB0006000)
-#define W90X900_SZ_USBDEV      SZ_4K
-
-/* External MAC control*/
-#define W90X900_VA_EMC         W90X900_ADDR(0x00003000)
-#define W90X900_PA_EMC         (0xB0003000)
-#define W90X900_SZ_EMC         SZ_4K
-
-#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-w90x900/include/mach/mfp.h b/arch/arm/mach-w90x900/include/mach/mfp.h
deleted file mode 100644 (file)
index be5485e..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-w90x900/include/mach/mfp.h
- *
- * Copyright (c) 2010 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * Based on arch/arm/mach-s3c2410/include/mach/map.h
- */
-
-#ifndef __ASM_ARCH_MFP_H
-#define __ASM_ARCH_MFP_H
-
-extern void mfp_set_groupf(struct device *dev);
-extern void mfp_set_groupc(struct device *dev);
-extern void mfp_set_groupi(struct device *dev);
-extern void mfp_set_groupg(struct device *dev, const char *subname);
-extern void mfp_set_groupd(struct device *dev, const char *subname);
-
-#endif /* __ASM_ARCH_MFP_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-clock.h b/arch/arm/mach-w90x900/include/mach/regs-clock.h
deleted file mode 100644 (file)
index f06245d..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-w90x900/include/mach/regs-clock.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#ifndef __ASM_ARCH_REGS_CLOCK_H
-#define __ASM_ARCH_REGS_CLOCK_H
-
-/* Clock Control Registers  */
-#define CLK_BA         W90X900_VA_CLKPWR
-#define REG_CLKEN      (CLK_BA + 0x00)
-#define REG_CLKSEL     (CLK_BA + 0x04)
-#define REG_CLKDIV     (CLK_BA + 0x08)
-#define REG_PLLCON0    (CLK_BA + 0x0C)
-#define REG_PLLCON1    (CLK_BA + 0x10)
-#define REG_PMCON      (CLK_BA + 0x14)
-#define REG_IRQWAKECON (CLK_BA + 0x18)
-#define REG_IRQWAKEFLAG        (CLK_BA + 0x1C)
-#define REG_IPSRST     (CLK_BA + 0x20)
-#define REG_CLKEN1     (CLK_BA + 0x24)
-#define REG_CLKDIV1    (CLK_BA + 0x28)
-
-/* Define PLL freq setting */
-#define PLL_DISABLE            0x12B63
-#define        PLL_66MHZ               0x2B63
-#define        PLL_100MHZ              0x4F64
-#define PLL_120MHZ             0x4F63
-#define        PLL_166MHZ              0x4124
-#define        PLL_200MHZ              0x4F24
-
-/* Define AHB:CPUFREQ ratio */
-#define        AHB_CPUCLK_1_1          0x00
-#define        AHB_CPUCLK_1_2          0x01
-#define        AHB_CPUCLK_1_4          0x02
-#define        AHB_CPUCLK_1_8          0x03
-
-/* Define APB:AHB ratio */
-#define APB_AHB_1_2            0x01
-#define APB_AHB_1_4            0x02
-#define APB_AHB_1_8            0x03
-
-/* Define clock skew */
-#define DEFAULTSKEW            0x48
-
-#endif /*  __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-irq.h b/arch/arm/mach-w90x900/include/mach/regs-irq.h
deleted file mode 100644 (file)
index 89fcbc6..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-w90x900/include/mach/regs-irq.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * Based on arch/arm/mach-s3c2410/include/mach/regs-irq.h
- */
-
-#ifndef ___ASM_ARCH_REGS_IRQ_H
-#define ___ASM_ARCH_REGS_IRQ_H
-
-/* Advance Interrupt Controller (AIC) Registers */
-
-#define AIC_BA                 W90X900_VA_IRQ
-
-#define REG_AIC_IRQSC          (AIC_BA+0x80)
-#define REG_AIC_GEN            (AIC_BA+0x84)
-#define REG_AIC_GASR           (AIC_BA+0x88)
-#define REG_AIC_GSCR           (AIC_BA+0x8C)
-#define REG_AIC_IRSR           (AIC_BA+0x100)
-#define REG_AIC_IASR           (AIC_BA+0x104)
-#define REG_AIC_ISR            (AIC_BA+0x108)
-#define REG_AIC_IPER           (AIC_BA+0x10C)
-#define REG_AIC_ISNR           (AIC_BA+0x110)
-#define REG_AIC_IMR            (AIC_BA+0x114)
-#define REG_AIC_OISR           (AIC_BA+0x118)
-#define REG_AIC_MECR           (AIC_BA+0x120)
-#define REG_AIC_MDCR           (AIC_BA+0x124)
-#define REG_AIC_SSCR           (AIC_BA+0x128)
-#define REG_AIC_SCCR           (AIC_BA+0x12C)
-#define REG_AIC_EOSCR          (AIC_BA+0x130)
-#define AIC_IPER               (0x10C)
-#define AIC_ISNR               (0x110)
-
-/*16-18 bits of REG_AIC_GEN define irq(2-4) group*/
-
-#define TIMER2_IRQ             (1 << 16)
-#define TIMER3_IRQ             (1 << 17)
-#define TIMER4_IRQ             (1 << 18)
-#define TIME_GROUP_IRQ         (TIMER2_IRQ|TIMER3_IRQ|TIMER4_IRQ)
-
-#endif /* ___ASM_ARCH_REGS_IRQ_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-ldm.h b/arch/arm/mach-w90x900/include/mach/regs-ldm.h
deleted file mode 100644 (file)
index ffe7e67..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-w90x900/include/mach/regs-serial.h
- *
- * Copyright (c) 2009 Nuvoton technology corporation
- * All rights reserved.
- *
- *  Description:
- *     Nuvoton Display, LCM Register list
- *  Author:  Wang Qiang (rurality.linux@gmail.com) 2009/12/11
- */
-
-
-#ifndef __ASM_ARM_W90X900_REGS_LDM_H
-#define __ASM_ARM_W90X900_REGS_LDM_H
-
-#include <mach/map.h>
-
-/* Display Controller Control/Status Register */
-#define REG_LCM_DCCS                   (0x00)
-
-#define LCM_DCCS_ENG_RST               (1 << 0)
-#define LCM_DCCS_VA_EN                 (1 << 1)
-#define LCM_DCCS_OSD_EN                        (1 << 2)
-#define LCM_DCCS_DISP_OUT_EN           (1 << 3)
-#define LCM_DCCS_DISP_INT_EN           (1 << 4)
-#define LCM_DCCS_CMD_ON                        (1 << 5)
-#define LCM_DCCS_FIELD_INTR            (1 << 6)
-#define LCM_DCCS_SINGLE                        (1 << 7)
-
-enum LCM_DCCS_VA_SRC {
-       LCM_DCCS_VA_SRC_YUV422          = (0 << 8),
-       LCM_DCCS_VA_SRC_YCBCR422        = (1 << 8),
-       LCM_DCCS_VA_SRC_RGB888          = (2 << 8),
-       LCM_DCCS_VA_SRC_RGB666          = (3 << 8),
-       LCM_DCCS_VA_SRC_RGB565          = (4 << 8),
-       LCM_DCCS_VA_SRC_RGB444LOW       = (5 << 8),
-       LCM_DCCS_VA_SRC_RGB444HIGH      = (7 << 8)
-};
-
-
-/* Display Device Control Register */
-#define REG_LCM_DEV_CTRL               (0x04)
-
-enum LCM_DEV_CTRL_SWAP_YCbCr {
-       LCM_DEV_CTRL_SWAP_UYVY          = (0 << 1),
-       LCM_DEV_CTRL_SWAP_YUYV          = (1 << 1),
-       LCM_DEV_CTRL_SWAP_VYUY          = (2 << 1),
-       LCM_DEV_CTRL_SWAP_YVYU          = (3 << 1)
-};
-
-enum LCM_DEV_CTRL_RGB_SHIFT {
-       LCM_DEV_CTRL_RGB_SHIFT_NOT      = (0 << 3),
-       LCM_DEV_CTRL_RGB_SHIFT_ONECYCLE = (1 << 3),
-       LCM_DEV_CTRL_RGB_SHIFT_TWOCYCLE = (2 << 3),
-       LCM_DEV_CTRL_RGB_SHIFT_NOT_DEF  = (3 << 3)
-};
-
-enum LCM_DEV_CTRL_DEVICE {
-       LCM_DEV_CTRL_DEVICE_YUV422      = (0 << 5),
-       LCM_DEV_CTRL_DEVICE_YUV444      = (1 << 5),
-       LCM_DEV_CTRL_DEVICE_UNIPAC      = (4 << 5),
-       LCM_DEV_CTRL_DEVICE_SEIKO_EPSON = (5 << 5),
-       LCM_DEV_CTRL_DEVICE_HIGH_COLOR  = (6 << 5),
-       LCM_DEV_CTRL_DEVICE_MPU         = (7 << 5)
-};
-
-#define LCM_DEV_CTRL_LCD_DDA           (8)
-#define LCM_DEV_CTRL_YUV2CCIR          (16)
-
-enum LCM_DEV_CTRL_LCD_SEL {
-       LCM_DEV_CTRL_LCD_SEL_RGB_GBR    = (0 << 17),
-       LCM_DEV_CTRL_LCD_SEL_BGR_RBG    = (1 << 17),
-       LCM_DEV_CTRL_LCD_SEL_GBR_RGB    = (2 << 17),
-       LCM_DEV_CTRL_LCD_SEL_RBG_BGR    = (3 << 17)
-};
-
-enum LCM_DEV_CTRL_FAL_D {
-       LCM_DEV_CTRL_FAL_D_FALLING      = (0 << 19),
-       LCM_DEV_CTRL_FAL_D_RISING       = (1 << 19),
-};
-
-enum LCM_DEV_CTRL_H_POL {
-       LCM_DEV_CTRL_H_POL_LOW          = (0 << 20),
-       LCM_DEV_CTRL_H_POL_HIGH         = (1 << 20),
-};
-
-enum LCM_DEV_CTRL_V_POL {
-       LCM_DEV_CTRL_V_POL_LOW          = (0 << 21),
-       LCM_DEV_CTRL_V_POL_HIGH         = (1 << 21),
-};
-
-enum LCM_DEV_CTRL_VR_LACE {
-       LCM_DEV_CTRL_VR_LACE_NINTERLACE = (0 << 22),
-       LCM_DEV_CTRL_VR_LACE_INTERLACE  = (1 << 22),
-};
-
-enum LCM_DEV_CTRL_LACE {
-       LCM_DEV_CTRL_LACE_NINTERLACE    = (0 << 23),
-       LCM_DEV_CTRL_LACE_INTERLACE     = (1 << 23),
-};
-
-enum LCM_DEV_CTRL_RGB_SCALE {
-       LCM_DEV_CTRL_RGB_SCALE_4096     = (0 << 24),
-       LCM_DEV_CTRL_RGB_SCALE_65536    = (1 << 24),
-       LCM_DEV_CTRL_RGB_SCALE_262144   = (2 << 24),
-       LCM_DEV_CTRL_RGB_SCALE_16777216 = (3 << 24),
-};
-
-enum LCM_DEV_CTRL_DBWORD {
-       LCM_DEV_CTRL_DBWORD_HALFWORD    = (0 << 26),
-       LCM_DEV_CTRL_DBWORD_FULLWORD    = (1 << 26),
-};
-
-enum LCM_DEV_CTRL_MPU68 {
-       LCM_DEV_CTRL_MPU68_80_SERIES    = (0 << 27),
-       LCM_DEV_CTRL_MPU68_68_SERIES    = (1 << 27),
-};
-
-enum LCM_DEV_CTRL_DE_POL {
-       LCM_DEV_CTRL_DE_POL_HIGH        = (0 << 28),
-       LCM_DEV_CTRL_DE_POL_LOW         = (1 << 28),
-};
-
-#define LCM_DEV_CTRL_CMD16             (29)
-#define LCM_DEV_CTRL_CM16t18           (30)
-#define LCM_DEV_CTRL_CMD_LOW           (31)
-
-/* MPU-Interface LCD Write Command */
-#define REG_LCM_MPU_CMD                        (0x08)
-
-/* Interrupt Control/Status Register */
-#define REG_LCM_INT_CS                 (0x0c)
-#define LCM_INT_CS_DISP_F_EN           (1 << 0)
-#define LCM_INT_CS_UNDERRUN_EN         (1 << 1)
-#define LCM_INT_CS_BUS_ERROR_INT       (1 << 28)
-#define LCM_INT_CS_UNDERRUN_INT        (1 << 29)
-#define LCM_INT_CS_DISP_F_STATUS       (1 << 30)
-#define LCM_INT_CS_DISP_F_INT          (1 << 31)
-
-/* CRTC Display Size Control Register */
-#define REG_LCM_CRTC_SIZE              (0x10)
-#define LCM_CRTC_SIZE_VTTVAL(x)                ((x) << 16)
-#define LCM_CRTC_SIZE_HTTVAL(x)                ((x) << 0)
-
-/* CRTC Display Enable End */
-#define REG_LCM_CRTC_DEND              (0x14)
-#define LCM_CRTC_DEND_VDENDVAL(x)      ((x) << 16)
-#define LCM_CRTC_DEND_HDENDVAL(x)      ((x) << 0)
-
-/* CRTC Internal Horizontal Retrace Control Register */
-#define REG_LCM_CRTC_HR                        (0x18)
-#define LCM_CRTC_HR_EVAL(x)            ((x) << 16)
-#define LCM_CRTC_HR_SVAL(x)            ((x) << 0)
-
-/* CRTC Horizontal Sync Control Register */
-#define REG_LCM_CRTC_HSYNC             (0x1C)
-#define LCM_CRTC_HSYNC_SHIFTVAL(x)     ((x) << 30)
-#define LCM_CRTC_HSYNC_EVAL(x)         ((x) << 16)
-#define LCM_CRTC_HSYNC_SVAL(x)         ((x) << 0)
-
-/* CRTC Internal Vertical Retrace Control Register */
-#define REG_LCM_CRTC_VR                        (0x20)
-#define LCM_CRTC_VR_EVAL(x)            ((x) << 16)
-#define LCM_CRTC_VR_SVAL(x)            ((x) << 0)
-
-/* Video Stream Frame Buffer-0 Starting Address */
-#define REG_LCM_VA_BADDR0              (0x24)
-
-/* Video Stream Frame Buffer-1 Starting Address */
-#define REG_LCM_VA_BADDR1              (0x28)
-
-/* Video Stream Frame Buffer Control Register */
-#define REG_LCM_VA_FBCTRL              (0x2C)
-#define LCM_VA_FBCTRL_IO_REGION_HALF   (1 << 28)
-#define LCM_VA_FBCTRL_FIELD_DUAL       (1 << 29)
-#define LCM_VA_FBCTRL_START_BUF        (1 << 30)
-#define LCM_VA_FBCTRL_DB_EN            (1 << 31)
-
-/* Video Stream Scaling Control Register */
-#define REG_LCM_VA_SCALE               (0x30)
-#define LCM_VA_SCALE_XCOPY_INTERPOLATION (0 << 15)
-#define LCM_VA_SCALE_XCOPY_DUPLICATION  (1 << 15)
-
-/* Image Stream Active Window Coordinates */
-#define REG_LCM_VA_WIN                 (0x38)
-
-/* Image Stream Stuff Pixel */
-#define REG_LCM_VA_STUFF               (0x3C)
-
-/* OSD Window Starting Coordinates */
-#define REG_LCM_OSD_WINS               (0x40)
-
-/* OSD Window Ending Coordinates */
-#define REG_LCM_OSD_WINE               (0x44)
-
-/* OSD Stream Frame Buffer Starting Address */
-#define REG_LCM_OSD_BADDR              (0x48)
-
-/* OSD Stream Frame Buffer Control Register */
-#define REG_LCM_OSD_FBCTRL             (0x4c)
-
-/* OSD Overlay Control Register */
-#define REG_LCM_OSD_OVERLAY            (0x50)
-
-/* OSD Overlay Color-Key Pattern Register */
-#define REG_LCM_OSD_CKEY               (0x54)
-
-/* OSD Overlay Color-Key Mask Register */
-#define REG_LCM_OSD_CMASK              (0x58)
-
-/* OSD Window Skip1 Register */
-#define REG_LCM_OSD_SKIP1              (0x5C)
-
-/* OSD Window Skip2 Register */
-#define REG_LCM_OSD_SKIP2              (0x60)
-
-/* OSD horizontal up scaling control register */
-#define REG_LCM_OSD_SCALE              (0x64)
-
-/* MPU Vsync control register */
-#define REG_LCM_MPU_VSYNC              (0x68)
-
-/* Hardware cursor control Register */
-#define REG_LCM_HC_CTRL                        (0x6C)
-
-/* Hardware cursot tip point potison on va picture */
-#define REG_LCM_HC_POS                 (0x70)
-
-/* Hardware Cursor Window Buffer Control Register */
-#define REG_LCM_HC_WBCTRL              (0x74)
-
-/* Hardware cursor memory base address register */
-#define REG_LCM_HC_BADDR               (0x78)
-
-/* Hardware cursor color ram register mapped to bpp = 0 */
-#define REG_LCM_HC_COLOR0              (0x7C)
-
-/* Hardware cursor color ram register mapped to bpp = 1 */
-#define REG_LCM_HC_COLOR1              (0x80)
-
-/* Hardware cursor color ram register mapped to bpp = 2 */
-#define REG_LCM_HC_COLOR2              (0x84)
-
-/* Hardware cursor color ram register mapped to bpp = 3 */
-#define REG_LCM_HC_COLOR3              (0x88)
-
-#endif /* __ASM_ARM_W90X900_REGS_LDM_H */
diff --git a/arch/arm/mach-w90x900/include/mach/regs-serial.h b/arch/arm/mach-w90x900/include/mach/regs-serial.h
deleted file mode 100644 (file)
index 797c972..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-w90x900/include/mach/regs-serial.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * Based on arch/arm/mach-s3c2410/include/mach/regs-serial.h
- */
-
-#ifndef __ASM_ARM_REGS_SERIAL_H
-#define __ASM_ARM_REGS_SERIAL_H
-
-#define UART0_BA       W90X900_VA_UART
-#define UART1_BA       (W90X900_VA_UART+0x100)
-#define UART2_BA       (W90X900_VA_UART+0x200)
-#define UART3_BA       (W90X900_VA_UART+0x300)
-#define UART4_BA       (W90X900_VA_UART+0x400)
-
-#define UART0_PA       W90X900_PA_UART
-#define UART1_PA       (W90X900_PA_UART+0x100)
-#define UART2_PA       (W90X900_PA_UART+0x200)
-#define UART3_PA       (W90X900_PA_UART+0x300)
-#define UART4_PA       (W90X900_PA_UART+0x400)
-
-#ifndef __ASSEMBLY__
-
-struct w90x900_uart_clksrc {
-       const char      *name;
-       unsigned int    divisor;
-       unsigned int    min_baud;
-       unsigned int    max_baud;
-};
-
-struct w90x900_uartcfg {
-       unsigned char   hwport;
-       unsigned char   unused;
-       unsigned short  flags;
-       unsigned long   uart_flags;
-
-       unsigned long   ucon;
-       unsigned long   ulcon;
-       unsigned long   ufcon;
-
-       struct w90x900_uart_clksrc *clocks;
-       unsigned int    clocks_size;
-};
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __ASM_ARM_REGS_SERIAL_H */
-
diff --git a/arch/arm/mach-w90x900/include/mach/uncompress.h b/arch/arm/mach-w90x900/include/mach/uncompress.h
deleted file mode 100644 (file)
index 32e92a7..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-w90x900/include/mach/uncompress.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * Based on arch/arm/mach-s3c2410/include/mach/uncompress.h
- */
-
-#ifndef __ASM_ARCH_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H
-
-/* Defines for UART registers */
-
-#include <mach/regs-serial.h>
-#include <mach/map.h>
-#include <linux/serial_reg.h>
-
-#define TX_DONE        (UART_LSR_TEMT | UART_LSR_THRE)
-static volatile u32 * const uart_base = (u32 *)UART0_PA;
-
-static inline void putc(int ch)
-{
-       /* Check THRE and TEMT bits before we transmit the character.
-        */
-       while ((uart_base[UART_LSR] & TX_DONE) != TX_DONE)
-               barrier();
-
-       *uart_base = ch;
-}
-
-static inline void flush(void)
-{
-}
-
-static void arch_decomp_setup(void)
-{
-}
-
-#endif/* __ASM_W90X900_UNCOMPRESS_H */
diff --git a/arch/arm/mach-w90x900/irq.c b/arch/arm/mach-w90x900/irq.c
deleted file mode 100644 (file)
index 081b0f6..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/irq.c
- *
- * based on linux/arch/arm/plat-s3c24xx/irq.c by Ben Dooks
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/ptrace.h>
-#include <linux/device.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-#include <asm/mach/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/regs-irq.h>
-
-#include "nuc9xx.h"
-
-struct group_irq {
-       unsigned long           gpen;
-       unsigned int            enabled;
-       void                    (*enable)(struct group_irq *, int enable);
-};
-
-static DEFINE_SPINLOCK(groupirq_lock);
-
-#define DEFINE_GROUP(_name, _ctrlbit, _num)                            \
-struct group_irq group_##_name = {                                     \
-               .enable         = nuc900_group_enable,                  \
-               .gpen           = ((1 << _num) - 1) << _ctrlbit,        \
-       }
-
-static void nuc900_group_enable(struct group_irq *gpirq, int enable);
-
-static DEFINE_GROUP(nirq0, 0, 4);
-static DEFINE_GROUP(nirq1, 4, 4);
-static DEFINE_GROUP(usbh, 8, 2);
-static DEFINE_GROUP(ottimer, 16, 3);
-static DEFINE_GROUP(gdma, 20, 2);
-static DEFINE_GROUP(sc, 24, 2);
-static DEFINE_GROUP(i2c, 26, 2);
-static DEFINE_GROUP(ps2, 28, 2);
-
-static int group_irq_enable(struct group_irq *group_irq)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&groupirq_lock, flags);
-       if (group_irq->enabled++ == 0)
-               (group_irq->enable)(group_irq, 1);
-       spin_unlock_irqrestore(&groupirq_lock, flags);
-
-       return 0;
-}
-
-static void group_irq_disable(struct group_irq *group_irq)
-{
-       unsigned long flags;
-
-       WARN_ON(group_irq->enabled == 0);
-
-       spin_lock_irqsave(&groupirq_lock, flags);
-       if (--group_irq->enabled == 0)
-               (group_irq->enable)(group_irq, 0);
-       spin_unlock_irqrestore(&groupirq_lock, flags);
-}
-
-static void nuc900_group_enable(struct group_irq *gpirq, int enable)
-{
-       unsigned int groupen = gpirq->gpen;
-       unsigned long regval;
-
-       regval = __raw_readl(REG_AIC_GEN);
-
-       if (enable)
-               regval |= groupen;
-       else
-               regval &= ~groupen;
-
-       __raw_writel(regval, REG_AIC_GEN);
-}
-
-static void nuc900_irq_mask(struct irq_data *d)
-{
-       struct group_irq *group_irq;
-
-       group_irq = NULL;
-
-       __raw_writel(1 << d->irq, REG_AIC_MDCR);
-
-       switch (d->irq) {
-       case IRQ_GROUP0:
-               group_irq = &group_nirq0;
-               break;
-
-       case IRQ_GROUP1:
-               group_irq = &group_nirq1;
-               break;
-
-       case IRQ_USBH:
-               group_irq = &group_usbh;
-               break;
-
-       case IRQ_T_INT_GROUP:
-               group_irq = &group_ottimer;
-               break;
-
-       case IRQ_GDMAGROUP:
-               group_irq = &group_gdma;
-               break;
-
-       case IRQ_SCGROUP:
-               group_irq = &group_sc;
-               break;
-
-       case IRQ_I2CGROUP:
-               group_irq = &group_i2c;
-               break;
-
-       case IRQ_P2SGROUP:
-               group_irq = &group_ps2;
-               break;
-       }
-
-       if (group_irq)
-               group_irq_disable(group_irq);
-}
-
-/*
- * By the w90p910 spec,any irq,only write 1
- * to REG_AIC_EOSCR for ACK
- */
-
-static void nuc900_irq_ack(struct irq_data *d)
-{
-       __raw_writel(0x01, REG_AIC_EOSCR);
-}
-
-static void nuc900_irq_unmask(struct irq_data *d)
-{
-       struct group_irq *group_irq;
-
-       group_irq = NULL;
-
-       __raw_writel(1 << d->irq, REG_AIC_MECR);
-
-       switch (d->irq) {
-       case IRQ_GROUP0:
-               group_irq = &group_nirq0;
-               break;
-
-       case IRQ_GROUP1:
-               group_irq = &group_nirq1;
-               break;
-
-       case IRQ_USBH:
-               group_irq = &group_usbh;
-               break;
-
-       case IRQ_T_INT_GROUP:
-               group_irq = &group_ottimer;
-               break;
-
-       case IRQ_GDMAGROUP:
-               group_irq = &group_gdma;
-               break;
-
-       case IRQ_SCGROUP:
-               group_irq = &group_sc;
-               break;
-
-       case IRQ_I2CGROUP:
-               group_irq = &group_i2c;
-               break;
-
-       case IRQ_P2SGROUP:
-               group_irq = &group_ps2;
-               break;
-       }
-
-       if (group_irq)
-               group_irq_enable(group_irq);
-}
-
-static struct irq_chip nuc900_irq_chip = {
-       .irq_ack        = nuc900_irq_ack,
-       .irq_mask       = nuc900_irq_mask,
-       .irq_unmask     = nuc900_irq_unmask,
-};
-
-void __init nuc900_init_irq(void)
-{
-       int irqno;
-
-       __raw_writel(0xFFFFFFFE, REG_AIC_MDCR);
-
-       for (irqno = IRQ_WDT; irqno <= IRQ_ADC; irqno++) {
-               irq_set_chip_and_handler(irqno, &nuc900_irq_chip,
-                                        handle_level_irq);
-               irq_clear_status_flags(irqno, IRQ_NOREQUEST);
-       }
-}
diff --git a/arch/arm/mach-w90x900/mach-nuc910evb.c b/arch/arm/mach-w90x900/mach-nuc910evb.c
deleted file mode 100644 (file)
index e6d30af..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/mach-nuc910evb.c
- *
- * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
- *
- * Copyright (C) 2008 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/platform_device.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach-types.h>
-#include <mach/map.h>
-
-#include "nuc910.h"
-
-static void __init nuc910evb_map_io(void)
-{
-       nuc910_map_io();
-       nuc910_init_clocks();
-}
-
-static void __init nuc910evb_init(void)
-{
-       nuc910_board_init();
-}
-
-MACHINE_START(W90P910EVB, "W90P910EVB")
-       /* Maintainer: Wan ZongShun */
-       .map_io         = nuc910evb_map_io,
-       .init_irq       = nuc900_init_irq,
-       .init_machine   = nuc910evb_init,
-       .init_time      = nuc900_timer_init,
-       .restart        = nuc9xx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-w90x900/mach-nuc950evb.c b/arch/arm/mach-w90x900/mach-nuc950evb.c
deleted file mode 100644 (file)
index 6254730..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/mach-nuc950evb.c
- *
- * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
- *
- * Copyright (C) 2008 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- *   history:
- *     Wang Qiang (rurality.linux@gmail.com) add LCD support
- */
-
-#include <linux/platform_device.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach-types.h>
-#include <mach/map.h>
-#include <linux/platform_data/video-nuc900fb.h>
-
-#include "nuc950.h"
-
-static void __init nuc950evb_map_io(void)
-{
-       nuc950_map_io();
-       nuc950_init_clocks();
-}
-
-static void __init nuc950evb_init(void)
-{
-       nuc950_board_init();
-}
-
-MACHINE_START(W90P950EVB, "W90P950EVB")
-       /* Maintainer: Wan ZongShun */
-       .map_io         = nuc950evb_map_io,
-       .init_irq       = nuc900_init_irq,
-       .init_machine   = nuc950evb_init,
-       .init_time      = nuc900_timer_init,
-       .restart        = nuc9xx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-w90x900/mach-nuc960evb.c b/arch/arm/mach-w90x900/mach-nuc960evb.c
deleted file mode 100644 (file)
index 35a5345..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/mach-nuc960evb.c
- *
- * Based on mach-s3c2410/mach-smdk2410.c by Jonas Dietsche
- *
- * Copyright (C) 2008 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/platform_device.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach-types.h>
-#include <mach/map.h>
-
-#include "nuc960.h"
-
-static void __init nuc960evb_map_io(void)
-{
-       nuc960_map_io();
-       nuc960_init_clocks();
-}
-
-static void __init nuc960evb_init(void)
-{
-       nuc960_board_init();
-}
-
-MACHINE_START(W90N960EVB, "W90N960EVB")
-       /* Maintainer: Wan ZongShun */
-       .map_io         = nuc960evb_map_io,
-       .init_irq       = nuc900_init_irq,
-       .init_machine   = nuc960evb_init,
-       .init_time      = nuc900_timer_init,
-       .restart        = nuc9xx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-w90x900/mfp.c b/arch/arm/mach-w90x900/mfp.c
deleted file mode 100644 (file)
index 05f3779..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/mfp.c
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/string.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-
-#define REG_MFSEL      (W90X900_VA_GCR + 0xC)
-
-#define GPSELF         (0x01 << 1)
-#define GPSELC         (0x03 << 2)
-#define GPSELD         (0x0f << 4)
-
-#define GPSELEI0       (0x01 << 26)
-#define GPSELEI1       (0x01 << 27)
-
-#define GPIOG0TO1      (0x03 << 14)
-#define GPIOG2TO3      (0x03 << 16)
-#define GPIOG22TO23    (0x03 << 22)
-#define GPIOG18TO20    (0x07 << 18)
-
-#define ENSPI          (0x0a << 14)
-#define ENI2C0         (0x01 << 14)
-#define ENI2C1         (0x01 << 16)
-#define ENAC97         (0x02 << 22)
-#define ENSD1          (0x02 << 18)
-#define ENSD0          (0x0a << 4)
-#define ENKPI          (0x02 << 2)
-#define ENNAND         (0x01 << 2)
-
-static DEFINE_MUTEX(mfp_mutex);
-
-void mfp_set_groupf(struct device *dev)
-{
-       unsigned long mfpen;
-       const char *dev_id;
-
-       BUG_ON(!dev);
-
-       mutex_lock(&mfp_mutex);
-
-       dev_id = dev_name(dev);
-
-       mfpen = __raw_readl(REG_MFSEL);
-
-       if (strcmp(dev_id, "nuc900-emc") == 0)
-               mfpen |= GPSELF;/*enable mac*/
-       else
-               mfpen &= ~GPSELF;/*GPIOF[9:0]*/
-
-       __raw_writel(mfpen, REG_MFSEL);
-
-       mutex_unlock(&mfp_mutex);
-}
-EXPORT_SYMBOL(mfp_set_groupf);
-
-void mfp_set_groupc(struct device *dev)
-{
-       unsigned long mfpen;
-       const char *dev_id;
-
-       BUG_ON(!dev);
-
-       mutex_lock(&mfp_mutex);
-
-       dev_id = dev_name(dev);
-
-       mfpen = __raw_readl(REG_MFSEL);
-
-       if (strcmp(dev_id, "nuc900-lcd") == 0)
-               mfpen |= GPSELC;/*enable lcd*/
-       else if (strcmp(dev_id, "nuc900-kpi") == 0) {
-               mfpen &= (~GPSELC);/*enable kpi*/
-               mfpen |= ENKPI;
-       } else if (strcmp(dev_id, "nuc900-nand") == 0) {
-               mfpen &= (~GPSELC);/*enable nand*/
-               mfpen |= ENNAND;
-       } else
-               mfpen &= (~GPSELC);/*GPIOC[14:0]*/
-
-       __raw_writel(mfpen, REG_MFSEL);
-
-       mutex_unlock(&mfp_mutex);
-}
-EXPORT_SYMBOL(mfp_set_groupc);
-
-void mfp_set_groupi(struct device *dev)
-{
-       unsigned long mfpen;
-       const char *dev_id;
-
-       BUG_ON(!dev);
-
-       mutex_lock(&mfp_mutex);
-
-       dev_id = dev_name(dev);
-
-       mfpen = __raw_readl(REG_MFSEL);
-
-       mfpen &= ~GPSELEI1;/*default gpio16*/
-
-       if (strcmp(dev_id, "nuc900-wdog") == 0)
-               mfpen |= GPSELEI1;/*enable wdog*/
-       else if (strcmp(dev_id, "nuc900-atapi") == 0)
-               mfpen |= GPSELEI0;/*enable atapi*/
-       else if (strcmp(dev_id, "nuc900-keypad") == 0)
-               mfpen &= ~GPSELEI0;/*enable keypad*/
-
-       __raw_writel(mfpen, REG_MFSEL);
-
-       mutex_unlock(&mfp_mutex);
-}
-EXPORT_SYMBOL(mfp_set_groupi);
-
-void mfp_set_groupg(struct device *dev, const char *subname)
-{
-       unsigned long mfpen;
-       const char *dev_id;
-
-       BUG_ON((!dev) && (!subname));
-
-       mutex_lock(&mfp_mutex);
-
-       if (subname != NULL)
-               dev_id = subname;
-       else
-               dev_id = dev_name(dev);
-
-       mfpen = __raw_readl(REG_MFSEL);
-
-       if (strcmp(dev_id, "nuc900-spi") == 0) {
-               mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);
-               mfpen |= ENSPI;/*enable spi*/
-       } else if (strcmp(dev_id, "nuc900-i2c0") == 0) {
-               mfpen &= ~(GPIOG0TO1);
-               mfpen |= ENI2C0;/*enable i2c0*/
-       } else if (strcmp(dev_id, "nuc900-i2c1") == 0) {
-               mfpen &= ~(GPIOG2TO3);
-               mfpen |= ENI2C1;/*enable i2c1*/
-       } else if (strcmp(dev_id, "nuc900-ac97") == 0) {
-               mfpen &= ~(GPIOG22TO23);
-               mfpen |= ENAC97;/*enable AC97*/
-       } else if (strcmp(dev_id, "nuc900-mmc-port1") == 0) {
-               mfpen &= ~(GPIOG18TO20);
-               mfpen |= (ENSD1 | 0x01);/*enable sd1*/
-       } else {
-               mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);/*GPIOG[3:0]*/
-       }
-
-       __raw_writel(mfpen, REG_MFSEL);
-
-       mutex_unlock(&mfp_mutex);
-}
-EXPORT_SYMBOL(mfp_set_groupg);
-
-void mfp_set_groupd(struct device *dev, const char *subname)
-{
-       unsigned long mfpen;
-       const char *dev_id;
-
-       BUG_ON((!dev) && (!subname));
-
-       mutex_lock(&mfp_mutex);
-
-       if (subname != NULL)
-               dev_id = subname;
-       else
-               dev_id = dev_name(dev);
-
-       mfpen = __raw_readl(REG_MFSEL);
-
-       if (strcmp(dev_id, "nuc900-mmc-port0") == 0) {
-               mfpen &= ~GPSELD;/*enable sd0*/
-               mfpen |= ENSD0;
-       } else
-               mfpen &= (~GPSELD);
-
-       __raw_writel(mfpen, REG_MFSEL);
-
-       mutex_unlock(&mfp_mutex);
-}
-EXPORT_SYMBOL(mfp_set_groupd);
diff --git a/arch/arm/mach-w90x900/nuc910.c b/arch/arm/mach-w90x900/nuc910.c
deleted file mode 100644 (file)
index 45ae828..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/nuc910.c
- *
- * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
- *
- * Copyright (c) 2009 Nuvoton corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * NUC910 cpu support
- */
-
-#include <linux/platform_device.h>
-#include <asm/mach/map.h>
-#include <mach/hardware.h>
-#include "cpu.h"
-#include "clock.h"
-
-/* define specific CPU platform device */
-
-static struct platform_device *nuc910_dev[] __initdata = {
-       &nuc900_device_ts,
-       &nuc900_device_rtc,
-       &nuc900_device_lcd,
-       &nuc900_device_kpi,
-};
-
-/* define specific CPU platform io map */
-
-static struct map_desc nuc910evb_iodesc[] __initdata = {
-       IODESC_ENT(USBEHCIHOST),
-       IODESC_ENT(USBOHCIHOST),
-       IODESC_ENT(KPI),
-       IODESC_ENT(USBDEV),
-       IODESC_ENT(ADC),
-};
-
-/*Init NUC910 evb io*/
-
-void __init nuc910_map_io(void)
-{
-       nuc900_map_io(nuc910evb_iodesc, ARRAY_SIZE(nuc910evb_iodesc));
-}
-
-/*Init NUC910 clock*/
-
-void __init nuc910_init_clocks(void)
-{
-       nuc900_init_clocks();
-}
-
-/*Init NUC910 board info*/
-
-void __init nuc910_board_init(void)
-{
-       nuc900_board_init(nuc910_dev, ARRAY_SIZE(nuc910_dev));
-}
diff --git a/arch/arm/mach-w90x900/nuc910.h b/arch/arm/mach-w90x900/nuc910.h
deleted file mode 100644 (file)
index 53be332..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-w90x900/nuc910.h
- *
- * Copyright (c) 2008 Nuvoton corporation
- *
- * Header file for NUC900 CPU support
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-#include "nuc9xx.h"
-
-/* extern file from nuc910.c */
-
-extern void nuc910_board_init(void);
-extern void nuc910_init_clocks(void);
-extern void nuc910_map_io(void);
diff --git a/arch/arm/mach-w90x900/nuc950.c b/arch/arm/mach-w90x900/nuc950.c
deleted file mode 100644 (file)
index 3be1142..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/nuc950.c
- *
- * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
- *
- * Copyright (c) 2008 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * NUC950 cpu support
- */
-
-#include <linux/platform_device.h>
-#include <asm/mach/map.h>
-#include <mach/hardware.h>
-
-#include "cpu.h"
-
-/* define specific CPU platform device */
-
-static struct platform_device *nuc950_dev[] __initdata = {
-       &nuc900_device_kpi,
-       &nuc900_device_fmi,
-       &nuc900_device_lcd,
-};
-
-/* define specific CPU platform io map */
-
-static struct map_desc nuc950evb_iodesc[] __initdata = {
-};
-
-/*Init NUC950 evb io*/
-
-void __init nuc950_map_io(void)
-{
-       nuc900_map_io(nuc950evb_iodesc, ARRAY_SIZE(nuc950evb_iodesc));
-}
-
-/*Init NUC950 clock*/
-
-void __init nuc950_init_clocks(void)
-{
-       nuc900_init_clocks();
-}
-
-/*Init NUC950 board info*/
-
-void __init nuc950_board_init(void)
-{
-       nuc900_board_init(nuc950_dev, ARRAY_SIZE(nuc950_dev));
-}
diff --git a/arch/arm/mach-w90x900/nuc950.h b/arch/arm/mach-w90x900/nuc950.h
deleted file mode 100644 (file)
index 23cff81..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-w90x900/nuc950.h
- *
- * Copyright (c) 2008 Nuvoton corporation
- *
- * Header file for NUC900 CPU support
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-#include "nuc9xx.h"
-
-/* extern file from nuc950.c */
-
-extern void nuc950_board_init(void);
-extern void nuc950_init_clocks(void);
-extern void nuc950_map_io(void);
diff --git a/arch/arm/mach-w90x900/nuc960.c b/arch/arm/mach-w90x900/nuc960.c
deleted file mode 100644 (file)
index 8a27d74..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * linux/arch/arm/mach-w90x900/nuc960.c
- *
- * Based on linux/arch/arm/plat-s3c24xx/s3c244x.c by Ben Dooks
- *
- * Copyright (c) 2008 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * NUC960 cpu support
- */
-
-#include <linux/platform_device.h>
-#include <asm/mach/map.h>
-#include <mach/hardware.h>
-#include "cpu.h"
-
-/* define specific CPU platform device */
-
-static struct platform_device *nuc960_dev[] __initdata = {
-       &nuc900_device_kpi,
-       &nuc900_device_fmi,
-};
-
-/* define specific CPU platform io map */
-
-static struct map_desc nuc960evb_iodesc[] __initdata = {
-};
-
-/*Init NUC960 evb io*/
-
-void __init nuc960_map_io(void)
-{
-       nuc900_map_io(nuc960evb_iodesc, ARRAY_SIZE(nuc960evb_iodesc));
-}
-
-/*Init NUC960 clock*/
-
-void __init nuc960_init_clocks(void)
-{
-       nuc900_init_clocks();
-}
-
-/*Init NUC960 board info*/
-
-void __init nuc960_board_init(void)
-{
-       nuc900_board_init(nuc960_dev, ARRAY_SIZE(nuc960_dev));
-}
diff --git a/arch/arm/mach-w90x900/nuc960.h b/arch/arm/mach-w90x900/nuc960.h
deleted file mode 100644 (file)
index 88bb13c..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-w90x900/nuc960.h
- *
- * Copyright (c) 2008 Nuvoton corporation
- *
- * Header file for NUC900 CPU support
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-#include "nuc9xx.h"
-
-/* extern file from nuc960.c */
-
-extern void nuc960_board_init(void);
-extern void nuc960_init_clocks(void);
-extern void nuc960_map_io(void);
diff --git a/arch/arm/mach-w90x900/nuc9xx.h b/arch/arm/mach-w90x900/nuc9xx.h
deleted file mode 100644 (file)
index 21f6f9c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-w90x900/nuc9xx.h
- *
- * Copied from nuc910.h, which had:
- *
- * Copyright (c) 2008 Nuvoton corporation
- *
- * Header file for NUC900 CPU support
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/reboot.h>
-
-struct map_desc;
-
-/* core initialisation functions */
-
-extern void nuc900_init_irq(void);
-extern void nuc900_timer_init(void);
-extern void nuc9xx_restart(enum reboot_mode, const char *);
diff --git a/arch/arm/mach-w90x900/regs-ebi.h b/arch/arm/mach-w90x900/regs-ebi.h
deleted file mode 100644 (file)
index 3fb2270..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-w90x900/include/mach/regs-ebi.h
- *
- * Copyright (c) 2009 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#ifndef __ASM_ARCH_REGS_EBI_H
-#define __ASM_ARCH_REGS_EBI_H
-
-/* EBI Control Registers */
-
-#define EBI_BA         W90X900_VA_EBI
-#define REG_EBICON     (EBI_BA + 0x00)
-#define REG_ROMCON     (EBI_BA + 0x04)
-#define REG_SDCONF0    (EBI_BA + 0x08)
-#define REG_SDCONF1    (EBI_BA + 0x0C)
-#define REG_SDTIME0    (EBI_BA + 0x10)
-#define REG_SDTIME1    (EBI_BA + 0x14)
-#define REG_EXT0CON    (EBI_BA + 0x18)
-#define REG_EXT1CON    (EBI_BA + 0x1C)
-#define REG_EXT2CON    (EBI_BA + 0x20)
-#define REG_EXT3CON    (EBI_BA + 0x24)
-#define REG_EXT4CON    (EBI_BA + 0x28)
-#define REG_CKSKEW     (EBI_BA + 0x2C)
-
-#endif /*  __ASM_ARCH_REGS_EBI_H */
diff --git a/arch/arm/mach-w90x900/regs-gcr.h b/arch/arm/mach-w90x900/regs-gcr.h
deleted file mode 100644 (file)
index caf1090..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-w90x900/include/mach/regs-gcr.h
- *
- * Copyright (c) 2010 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#ifndef __ASM_ARCH_REGS_GCR_H
-#define __ASM_ARCH_REGS_GCR_H
-
-/* Global control registers */
-
-#define GCR_BA         W90X900_VA_GCR
-#define REG_PDID       (GCR_BA+0x000)
-#define REG_PWRON      (GCR_BA+0x004)
-#define REG_ARBCON     (GCR_BA+0x008)
-#define REG_MFSEL      (GCR_BA+0x00C)
-#define REG_EBIDPE     (GCR_BA+0x010)
-#define REG_LCDDPE     (GCR_BA+0x014)
-#define REG_GPIOCPE    (GCR_BA+0x018)
-#define REG_GPIODPE    (GCR_BA+0x01C)
-#define REG_GPIOEPE    (GCR_BA+0x020)
-#define REG_GPIOFPE    (GCR_BA+0x024)
-#define REG_GPIOGPE    (GCR_BA+0x028)
-#define REG_GPIOHPE    (GCR_BA+0x02C)
-#define REG_GPIOIPE    (GCR_BA+0x030)
-#define REG_GTMP1      (GCR_BA+0x034)
-#define REG_GTMP2      (GCR_BA+0x038)
-#define REG_GTMP3      (GCR_BA+0x03C)
-
-#endif /*  __ASM_ARCH_REGS_GCR_H */
diff --git a/arch/arm/mach-w90x900/regs-timer.h b/arch/arm/mach-w90x900/regs-timer.h
deleted file mode 100644 (file)
index d12807f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-w90x900/include/mach/regs-timer.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * Based on arch/arm/mach-s3c2410/include/mach/regs-timer.h
- */
-
-#ifndef __ASM_ARCH_REGS_TIMER_H
-#define __ASM_ARCH_REGS_TIMER_H
-
-/* Timer Registers */
-
-#define TMR_BA                 W90X900_VA_TIMER
-#define REG_TCSR0              (TMR_BA+0x00)
-#define REG_TCSR1              (TMR_BA+0x04)
-#define REG_TICR0              (TMR_BA+0x08)
-#define REG_TICR1              (TMR_BA+0x0C)
-#define REG_TDR0               (TMR_BA+0x10)
-#define REG_TDR1               (TMR_BA+0x14)
-#define REG_TISR               (TMR_BA+0x18)
-#define REG_WTCR               (TMR_BA+0x1C)
-#define REG_TCSR2              (TMR_BA+0x20)
-#define REG_TCSR3              (TMR_BA+0x24)
-#define REG_TICR2              (TMR_BA+0x28)
-#define REG_TICR3              (TMR_BA+0x2C)
-#define REG_TDR2               (TMR_BA+0x30)
-#define REG_TDR3               (TMR_BA+0x34)
-#define REG_TCSR4              (TMR_BA+0x40)
-#define REG_TICR4              (TMR_BA+0x48)
-#define REG_TDR4               (TMR_BA+0x50)
-
-#endif /*  __ASM_ARCH_REGS_TIMER_H */
diff --git a/arch/arm/mach-w90x900/regs-usb.h b/arch/arm/mach-w90x900/regs-usb.h
deleted file mode 100644 (file)
index 98046c8..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * arch/arm/mach-w90x900/include/mach/regs-usb.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#ifndef __ASM_ARCH_REGS_USB_H
-#define __ASM_ARCH_REGS_USB_H
-
-/* usb Control Registers  */
-#define USBH_BA                W90X900_VA_USBEHCIHOST
-#define USBD_BA                W90X900_VA_USBDEV
-#define USBO_BA                W90X900_VA_USBOHCIHOST
-
-/* USB Host Control Registers */
-#define REG_UPSCR0     (USBH_BA+0x064)
-#define REG_UPSCR1     (USBH_BA+0x068)
-#define REG_USBPCR0    (USBH_BA+0x0C4)
-#define REG_USBPCR1    (USBH_BA+0x0C8)
-
-/* USBH OHCI Control Registers */
-#define REG_OpModEn    (USBO_BA+0x204)
-/*This bit controls the polarity of over
-*current flag from external power IC.
-*/
-#define OCALow         0x08
-
-#endif /*  __ASM_ARCH_REGS_USB_H */
diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c
deleted file mode 100644 (file)
index dd20fab..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * linux/arch/arm/mach-w90x900/time.c
- *
- * Based on linux/arch/arm/plat-s3c24xx/time.c by Ben Dooks
- *
- * Copyright (c) 2009 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/leds.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/time.h>
-
-#include <mach/map.h>
-#include "regs-timer.h"
-
-#include "nuc9xx.h"
-
-#define RESETINT       0x1f
-#define PERIOD         (0x01 << 27)
-#define ONESHOT                (0x00 << 27)
-#define COUNTEN                (0x01 << 30)
-#define INTEN          (0x01 << 29)
-
-#define TICKS_PER_SEC  100
-#define PRESCALE       0x63 /* Divider = prescale + 1 */
-
-#define        TDR_SHIFT       24
-
-static unsigned int timer0_load;
-
-static int nuc900_clockevent_shutdown(struct clock_event_device *evt)
-{
-       unsigned int val = __raw_readl(REG_TCSR0) & ~(0x03 << 27);
-
-       __raw_writel(val, REG_TCSR0);
-       return 0;
-}
-
-static int nuc900_clockevent_set_oneshot(struct clock_event_device *evt)
-{
-       unsigned int val = __raw_readl(REG_TCSR0) & ~(0x03 << 27);
-
-       val |= (ONESHOT | COUNTEN | INTEN | PRESCALE);
-
-       __raw_writel(val, REG_TCSR0);
-       return 0;
-}
-
-static int nuc900_clockevent_set_periodic(struct clock_event_device *evt)
-{
-       unsigned int val = __raw_readl(REG_TCSR0) & ~(0x03 << 27);
-
-       __raw_writel(timer0_load, REG_TICR0);
-       val |= (PERIOD | COUNTEN | INTEN | PRESCALE);
-       __raw_writel(val, REG_TCSR0);
-       return 0;
-}
-
-static int nuc900_clockevent_setnextevent(unsigned long evt,
-               struct clock_event_device *clk)
-{
-       unsigned int val;
-
-       __raw_writel(evt, REG_TICR0);
-
-       val = __raw_readl(REG_TCSR0);
-       val |= (COUNTEN | INTEN | PRESCALE);
-       __raw_writel(val, REG_TCSR0);
-
-       return 0;
-}
-
-static struct clock_event_device nuc900_clockevent_device = {
-       .name                   = "nuc900-timer0",
-       .features               = CLOCK_EVT_FEAT_PERIODIC |
-                                 CLOCK_EVT_FEAT_ONESHOT,
-       .set_state_shutdown     = nuc900_clockevent_shutdown,
-       .set_state_periodic     = nuc900_clockevent_set_periodic,
-       .set_state_oneshot      = nuc900_clockevent_set_oneshot,
-       .tick_resume            = nuc900_clockevent_shutdown,
-       .set_next_event         = nuc900_clockevent_setnextevent,
-       .rating                 = 300,
-};
-
-/*IRQ handler for the timer*/
-
-static irqreturn_t nuc900_timer0_interrupt(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = &nuc900_clockevent_device;
-
-       __raw_writel(0x01, REG_TISR); /* clear TIF0 */
-
-       evt->event_handler(evt);
-       return IRQ_HANDLED;
-}
-
-static struct irqaction nuc900_timer0_irq = {
-       .name           = "nuc900-timer0",
-       .flags          = IRQF_TIMER | IRQF_IRQPOLL,
-       .handler        = nuc900_timer0_interrupt,
-};
-
-static void __init nuc900_clockevents_init(void)
-{
-       unsigned int rate;
-       struct clk *clk = clk_get(NULL, "timer0");
-
-       BUG_ON(IS_ERR(clk));
-
-       __raw_writel(0x00, REG_TCSR0);
-
-       clk_enable(clk);
-       rate = clk_get_rate(clk) / (PRESCALE + 1);
-
-       timer0_load = (rate / TICKS_PER_SEC);
-
-       __raw_writel(RESETINT, REG_TISR);
-       setup_irq(IRQ_TIMER0, &nuc900_timer0_irq);
-
-       nuc900_clockevent_device.cpumask = cpumask_of(0);
-
-       clockevents_config_and_register(&nuc900_clockevent_device, rate,
-                                       0xf, 0xffffffff);
-}
-
-static void __init nuc900_clocksource_init(void)
-{
-       unsigned int val;
-       unsigned int rate;
-       struct clk *clk = clk_get(NULL, "timer1");
-
-       BUG_ON(IS_ERR(clk));
-
-       __raw_writel(0x00, REG_TCSR1);
-
-       clk_enable(clk);
-       rate = clk_get_rate(clk) / (PRESCALE + 1);
-
-       __raw_writel(0xffffffff, REG_TICR1);
-
-       val = __raw_readl(REG_TCSR1);
-       val |= (COUNTEN | PERIOD | PRESCALE);
-       __raw_writel(val, REG_TCSR1);
-
-       clocksource_mmio_init(REG_TDR1, "nuc900-timer1", rate, 200,
-               TDR_SHIFT, clocksource_mmio_readl_down);
-}
-
-void __init nuc900_timer_init(void)
-{
-       nuc900_clocksource_init();
-       nuc900_clockevents_init();
-}
index ab85003..3449e0d 100644 (file)
@@ -7,6 +7,8 @@
 #include <linux/init.h>
 #include <asm/assembler.h>
 
+       .arm
+
 ENTRY(zynq_secondary_trampoline)
 ARM_BE8(setend be)                             @ ensure we are in BE8 mode
        ldr     r0, zynq_secondary_trampoline_jump
index a7cfe07..a10085b 100644 (file)
@@ -57,7 +57,7 @@ int zynq_cpun_start(u32 address, int cpu)
                        * 0x4: Jump by mov instruction
                        * 0x8: Jumping address
                        */
-                       memcpy((__force void *)zero, &zynq_secondary_trampoline,
+                       memcpy_toio(zero, &zynq_secondary_trampoline,
                                                        trampoline_size);
                        writel(address, zero + trampoline_size);
 
@@ -81,7 +81,7 @@ EXPORT_SYMBOL(zynq_cpun_start);
 
 static int zynq_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
-       return zynq_cpun_start(__pa_symbol(secondary_startup), cpu);
+       return zynq_cpun_start(__pa_symbol(secondary_startup_arm), cpu);
 }
 
 /*
index c1222c0..0ab3a86 100644 (file)
@@ -106,7 +106,7 @@ config CPU_ARM922T
        help
          The ARM922T is a version of the ARM920T, but with smaller
          instruction and data caches. It is used in Altera's
-         Excalibur XA device family and Micrel's KS8695 Centaur.
+         Excalibur XA device family and the ARM Integrator.
 
          Say Y if you want support for the ARM922T processor.
          Otherwise, say N.
index 61d8341..382e1c2 100644 (file)
@@ -42,6 +42,7 @@ static void mc_copy_user_page(void *from, void *to)
         * when prefetching destination as well.  (NP)
         */
        asm volatile ("\
+.arch xscale                                   \n\
        pld     [%0, #0]                        \n\
        pld     [%0, #32]                       \n\
        pld     [%1, #0]                        \n\
@@ -106,8 +107,9 @@ void
 xscale_mc_clear_user_highpage(struct page *page, unsigned long vaddr)
 {
        void *ptr, *kaddr = kmap_atomic(page);
-       asm volatile(
-       "mov    r1, %2                          \n\
+       asm volatile("\
+.arch xscale                                   \n\
+       mov     r1, %2                          \n\
        mov     r2, #0                          \n\
        mov     r3, #0                          \n\
 1:     mov     ip, %0                          \n\
index 16d373d..b4be3ba 100644 (file)
@@ -175,6 +175,11 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max_low,
 #ifdef CONFIG_HAVE_ARCH_PFN_VALID
 int pfn_valid(unsigned long pfn)
 {
+       phys_addr_t addr = __pfn_to_phys(pfn);
+
+       if (__phys_to_pfn(addr) != pfn)
+               return 0;
+
        return memblock_is_map_memory(__pfn_to_phys(pfn));
 }
 EXPORT_SYMBOL(pfn_valid);
@@ -628,7 +633,8 @@ static void update_sections_early(struct section_perm perms[], int n)
                if (t->flags & PF_KTHREAD)
                        continue;
                for_each_thread(t, s)
-                       set_section_perms(perms, n, true, s->mm);
+                       if (s->mm)
+                               set_section_perms(perms, n, true, s->mm);
        }
        set_section_perms(perms, n, true, current->active_mm);
        set_section_perms(perms, n, true, &init_mm);
diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile
deleted file mode 100644 (file)
index 4d839a3..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the linux kernel.
-#
-
-# IOP32X
-obj-$(CONFIG_ARCH_IOP32X) += i2c.o
-obj-$(CONFIG_ARCH_IOP32X) += pci.o
-obj-$(CONFIG_ARCH_IOP32X) += setup.o
-obj-$(CONFIG_ARCH_IOP32X) += time.o
-obj-$(CONFIG_ARCH_IOP32X) += cp6.o
-obj-$(CONFIG_ARCH_IOP32X) += adma.o
-obj-$(CONFIG_ARCH_IOP32X) += pmu.o
-obj-$(CONFIG_ARCH_IOP32X) += restart.o
-
-# IOP33X
-obj-$(CONFIG_ARCH_IOP33X) += i2c.o
-obj-$(CONFIG_ARCH_IOP33X) += pci.o
-obj-$(CONFIG_ARCH_IOP33X) += setup.o
-obj-$(CONFIG_ARCH_IOP33X) += time.o
-obj-$(CONFIG_ARCH_IOP33X) += cp6.o
-obj-$(CONFIG_ARCH_IOP33X) += adma.o
-obj-$(CONFIG_ARCH_IOP33X) += pmu.o
-obj-$(CONFIG_ARCH_IOP33X) += restart.o
-
-# IOP13XX
-obj-$(CONFIG_ARCH_IOP13XX) += cp6.o
-obj-$(CONFIG_ARCH_IOP13XX) += time.o
index 51e721f..c0bfceb 100644 (file)
@@ -12,6 +12,7 @@
 
 /* Bring in machine-local definitions, especially S3C_GPIO_END */
 #include <mach/gpio-samsung.h>
+#include <linux/gpio/driver.h>
 
 #define GPIOCON_OFF    (0x00)
 #define GPIODAT_OFF    (0x04)
index 6d0c788..94da89e 100644 (file)
@@ -7,8 +7,6 @@
 #ifndef __PLAT_SAMSUNG_USB_PHY_H
 #define __PLAT_SAMSUNG_USB_PHY_H __FILE__
 
-#include <linux/usb/samsung_usb_phy.h>
-
 extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
 extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
 
diff --git a/arch/arm64/Kbuild b/arch/arm64/Kbuild
new file mode 100644 (file)
index 0000000..d646582
--- /dev/null
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-only
+obj-y                  += kernel/ mm/
+obj-$(CONFIG_NET)      += net/
+obj-$(CONFIG_KVM)      += kvm/
+obj-$(CONFIG_XEN)      += xen/
+obj-$(CONFIG_CRYPTO)   += crypto/
index 3adcec0..6ae6ad8 100644 (file)
@@ -148,6 +148,7 @@ config ARM64
        select HAVE_FAST_GUP
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_FUNCTION_TRACER
+       select HAVE_FUNCTION_ERROR_INJECTION
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_GCC_PLUGINS
        select HAVE_HW_BREAKPOINT if PERF_EVENTS
@@ -286,7 +287,7 @@ config PGTABLE_LEVELS
        int
        default 2 if ARM64_16K_PAGES && ARM64_VA_BITS_36
        default 2 if ARM64_64K_PAGES && ARM64_VA_BITS_42
-       default 3 if ARM64_64K_PAGES && (ARM64_VA_BITS_48 || ARM64_USER_VA_BITS_52)
+       default 3 if ARM64_64K_PAGES && (ARM64_VA_BITS_48 || ARM64_VA_BITS_52)
        default 3 if ARM64_4K_PAGES && ARM64_VA_BITS_39
        default 3 if ARM64_16K_PAGES && ARM64_VA_BITS_47
        default 4 if !ARM64_64K_PAGES && ARM64_VA_BITS_48
@@ -297,6 +298,21 @@ config ARCH_SUPPORTS_UPROBES
 config ARCH_PROC_KCORE_TEXT
        def_bool y
 
+config KASAN_SHADOW_OFFSET
+       hex
+       depends on KASAN
+       default 0xdfffa00000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && !KASAN_SW_TAGS
+       default 0xdfffd00000000000 if ARM64_VA_BITS_47 && !KASAN_SW_TAGS
+       default 0xdffffe8000000000 if ARM64_VA_BITS_42 && !KASAN_SW_TAGS
+       default 0xdfffffd000000000 if ARM64_VA_BITS_39 && !KASAN_SW_TAGS
+       default 0xdffffffa00000000 if ARM64_VA_BITS_36 && !KASAN_SW_TAGS
+       default 0xefff900000000000 if (ARM64_VA_BITS_48 || ARM64_VA_BITS_52) && KASAN_SW_TAGS
+       default 0xefffc80000000000 if ARM64_VA_BITS_47 && KASAN_SW_TAGS
+       default 0xeffffe4000000000 if ARM64_VA_BITS_42 && KASAN_SW_TAGS
+       default 0xefffffc800000000 if ARM64_VA_BITS_39 && KASAN_SW_TAGS
+       default 0xeffffff900000000 if ARM64_VA_BITS_36 && KASAN_SW_TAGS
+       default 0xffffffffffffffff
+
 source "arch/arm64/Kconfig.platforms"
 
 menu "Kernel Features"
@@ -744,13 +760,14 @@ config ARM64_VA_BITS_47
 config ARM64_VA_BITS_48
        bool "48-bit"
 
-config ARM64_USER_VA_BITS_52
-       bool "52-bit (user)"
+config ARM64_VA_BITS_52
+       bool "52-bit"
        depends on ARM64_64K_PAGES && (ARM64_PAN || !ARM64_SW_TTBR0_PAN)
        help
          Enable 52-bit virtual addressing for userspace when explicitly
-         requested via a hint to mmap(). The kernel will continue to
-         use 48-bit virtual addresses for its own mappings.
+         requested via a hint to mmap(). The kernel will also use 52-bit
+         virtual addresses for its own mappings (provided HW support for
+         this feature is available, otherwise it reverts to 48-bit).
 
          NOTE: Enabling 52-bit virtual addressing in conjunction with
          ARMv8.3 Pointer Authentication will result in the PAC being
@@ -763,7 +780,7 @@ endchoice
 
 config ARM64_FORCE_52BIT
        bool "Force 52-bit virtual addresses for userspace"
-       depends on ARM64_USER_VA_BITS_52 && EXPERT
+       depends on ARM64_VA_BITS_52 && EXPERT
        help
          For systems with 52-bit userspace VAs enabled, the kernel will attempt
          to maintain compatibility with older software by providing 48-bit VAs
@@ -780,7 +797,8 @@ config ARM64_VA_BITS
        default 39 if ARM64_VA_BITS_39
        default 42 if ARM64_VA_BITS_42
        default 47 if ARM64_VA_BITS_47
-       default 48 if ARM64_VA_BITS_48 || ARM64_USER_VA_BITS_52
+       default 48 if ARM64_VA_BITS_48
+       default 52 if ARM64_VA_BITS_52
 
 choice
        prompt "Physical address space size"
@@ -1110,6 +1128,15 @@ config ARM64_SW_TTBR0_PAN
          zeroed area and reserved ASID. The user access routines
          restore the valid TTBR0_EL1 temporarily.
 
+config ARM64_TAGGED_ADDR_ABI
+       bool "Enable the tagged user addresses syscall ABI"
+       default y
+       help
+         When this option is enabled, user applications can opt in to a
+         relaxed ABI via prctl() allowing tagged addresses to be passed
+         to system calls as pointer arguments. For details, see
+         Documentation/arm64/tagged-address-abi.txt.
+
 menuconfig COMPAT
        bool "Kernel support for 32-bit EL0"
        depends on ARM64_4K_PAGES || EXPERT
@@ -1263,6 +1290,7 @@ config ARM64_PAN
 
 config ARM64_LSE_ATOMICS
        bool "Atomic instructions"
+       depends on JUMP_LABEL
        default y
        help
          As part of the Large System Extensions, ARMv8.1 introduces new
@@ -1467,6 +1495,7 @@ endif
 
 config RELOCATABLE
        bool
+       select ARCH_HAS_RELR
        help
          This builds the kernel as a Position Independent Executable (PIE),
          which retains all relocation metadata required to relocate the
index 4778c77..16d7614 100644 (file)
@@ -77,6 +77,7 @@ config ARCH_BRCMSTB
 config ARCH_EXYNOS
        bool "ARMv8 based Samsung Exynos SoC family"
        select COMMON_CLK_SAMSUNG
+       select EXYNOS_CHIPID
        select EXYNOS_PM_DOMAINS if PM_GENERIC_DOMAINS
        select EXYNOS_PMU
        select HAVE_S3C2410_WATCHDOG if WATCHDOG
@@ -173,6 +174,7 @@ config ARCH_MXC
        select PM
        select PM_GENERIC_DOMAINS
        select SOC_BUS
+       select TIMER_IMX_SYS_CTR
        help
          This enables support for the ARMv8 based SoCs in the
          NXP i.MX family.
index 61de992..f843d29 100644 (file)
@@ -39,6 +39,12 @@ $(warning LSE atomics not supported by binutils)
   endif
 endif
 
+cc_has_k_constraint := $(call try-run,echo                             \
+       'int main(void) {                                               \
+               asm volatile("and w0, w0, %w0" :: "K" (4294967295));    \
+               return 0;                                               \
+       }' | $(CC) -S -x c -o "$$TMP" -,,-DCONFIG_CC_HAS_K_CONSTRAINT=1)
+
 ifeq ($(CONFIG_ARM64), y)
 brokengasinst := $(call as-instr,1:\n.inst 0\n.rept . - 1b\n\nnop\n.endr\n,,-DCONFIG_BROKEN_GAS_INST=1)
 
@@ -63,7 +69,8 @@ ifeq ($(CONFIG_GENERIC_COMPAT_VDSO), y)
   endif
 endif
 
-KBUILD_CFLAGS  += -mgeneral-regs-only $(lseinstr) $(brokengasinst) $(compat_vdso)
+KBUILD_CFLAGS  += -mgeneral-regs-only $(lseinstr) $(brokengasinst)     \
+                  $(compat_vdso) $(cc_has_k_constraint)
 KBUILD_CFLAGS  += -fno-asynchronous-unwind-tables
 KBUILD_CFLAGS  += $(call cc-disable-warning, psabi)
 KBUILD_AFLAGS  += $(lseinstr) $(brokengasinst) $(compat_vdso)
@@ -126,21 +133,9 @@ KBUILD_CFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
 KBUILD_CPPFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
 KBUILD_AFLAGS += -DKASAN_SHADOW_SCALE_SHIFT=$(KASAN_SHADOW_SCALE_SHIFT)
 
-# KASAN_SHADOW_OFFSET = VA_START + (1 << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT))
-#                               - (1 << (64 - KASAN_SHADOW_SCALE_SHIFT))
-# in 32-bit arithmetic
-KASAN_SHADOW_OFFSET := $(shell printf "0x%08x00000000\n" $$(( \
-       (0xffffffff & (-1 << ($(CONFIG_ARM64_VA_BITS) - 32))) \
-       + (1 << ($(CONFIG_ARM64_VA_BITS) - 32 - $(KASAN_SHADOW_SCALE_SHIFT))) \
-       - (1 << (64 - 32 - $(KASAN_SHADOW_SCALE_SHIFT))) )) )
-
 export TEXT_OFFSET GZFLAGS
 
-core-y         += arch/arm64/kernel/ arch/arm64/mm/
-core-$(CONFIG_NET) += arch/arm64/net/
-core-$(CONFIG_KVM) += arch/arm64/kvm/
-core-$(CONFIG_XEN) += arch/arm64/xen/
-core-$(CONFIG_CRYPTO) += arch/arm64/crypto/
+core-y         += arch/arm64/
 libs-y         := arch/arm64/lib/ $(libs-y)
 core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
 
index f6db061..d241802 100644 (file)
@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-bananapi-m64.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-nanopi-a64.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-oceanic-5205-5inmfd.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-olinuxino.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-olinuxino-emmc.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-orangepi-win.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-lts.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb
@@ -25,3 +26,4 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-3.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-lite2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-one-plus.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino-emmc.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino-emmc.dts
new file mode 100644 (file)
index 0000000..96ab022
--- /dev/null
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (C) 2018 Martin Ayotte <martinayotte@gmail.com>
+ * Copyright (C) 2019 Sunil Mohan Adapa <sunil@medhas.org>
+ */
+
+#include "sun50i-a64-olinuxino.dts"
+
+/ {
+       model = "Olimex A64-Olinuxino-eMMC";
+       compatible = "olimex,a64-olinuxino-emmc", "allwinner,sun50i-a64";
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       vmmc-supply = <&reg_dcdc1>;
+       vqmmc-supply = <&reg_dcdc1>;
+       bus-width = <8>;
+       non-removable;
+       cap-mmc-hw-reset;
+       status = "okay";
+};
index 5ef3c62..04446e4 100644 (file)
        status = "okay";
 };
 
+&r_ir {
+       status = "okay";
+};
+
 &r_rsb {
        status = "okay";
 
index 9cc9bdd..69128a6 100644 (file)
                        display_clocks: clock@0 {
                                compatible = "allwinner,sun50i-a64-de2-clk";
                                reg = <0x0 0x100000>;
-                               clocks = <&ccu CLK_DE>,
-                                        <&ccu CLK_BUS_DE>;
-                               clock-names = "mod",
-                                             "bus";
+                               clocks = <&ccu CLK_BUS_DE>,
+                                        <&ccu CLK_DE>;
+                               clock-names = "bus",
+                                             "mod";
                                resets = <&ccu RST_BUS_DE>;
                                #clock-cells = <1>;
                                #reset-cells = <1>;
                        resets = <&ccu RST_BUS_HDMI1>;
                        reset-names = "ctrl";
                        phys = <&hdmi_phy>;
-                       phy-names = "hdmi-phy";
+                       phy-names = "phy";
                        status = "disabled";
 
                        ports {
                        #size-cells = <0>;
                };
 
+               r_ir: ir@1f02000 {
+                       compatible = "allwinner,sun50i-a64-ir",
+                                    "allwinner,sun6i-a31-ir";
+                       reg = <0x01f02000 0x400>;
+                       clocks = <&r_ccu CLK_APB0_IR>, <&r_ccu CLK_IR>;
+                       clock-names = "apb", "ir";
+                       resets = <&r_ccu RST_APB0_IR>;
+                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&r_ir_rx_pin>;
+                       status = "disabled";
+               };
+
                r_pwm: pwm@1f03800 {
                        compatible = "allwinner,sun50i-a64-pwm",
                                     "allwinner,sun5i-a13-pwm";
                                function = "s_i2c";
                        };
 
+                       r_ir_rx_pin: r-ir-rx-pin {
+                               pins = "PL11";
+                               function = "s_cir_rx";
+                       };
+
                        r_pwm_pin: r-pwm-pin {
                                pins = "PL10";
                                function = "s_pwm";
                                     "allwinner,sun6i-a31-wdt";
                        reg = <0x01c20ca0 0x20>;
                        interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&osc24M>;
                };
        };
 };
index 0dc33c9..1d05d57 100644 (file)
@@ -25,6 +25,7 @@
        connector {
                compatible = "hdmi-connector";
                type = "a";
+               ddc-en-gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */
 
                port {
                        hdmi_con_in: endpoint {
                regulator-max-microvolt = <5000000>;
                regulator-always-on;
        };
+
+       sound-spdif {
+               compatible = "simple-audio-card";
+               simple-audio-card,name = "sun50i-h6-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";
+       };
 };
 
 &de {
        };
 };
 
+&r_ir {
+       status = "okay";
+};
+
 &r_pio {
        /*
         * PL0 and PL1 are used for PMIC I2C
        vcc-pm-supply = <&reg_aldo1>;
 };
 
+&spdif {
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_ph_pins>;
index 17d4969..eb379cd 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
+       connector {
+               compatible = "hdmi-connector";
+               ddc-en-gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */
+               type = "a";
+
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&hdmi_out_con>;
+                       };
+               };
+       };
+
        leds {
                compatible = "gpio-leds";
 
                regulator-max-microvolt = <5000000>;
                regulator-always-on;
        };
+
+       reg_vcc33_wifi: vcc33-wifi {
+               /* Always on 3.3V regulator for WiFi and BT */
+               compatible = "regulator-fixed";
+               regulator-name = "vcc33-wifi";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               vin-supply = <&reg_vcc5v>;
+       };
+
+       reg_vcc_wifi_io: vcc-wifi-io {
+               /* Always on 1.8V/300mA regulator for WiFi and BT IO */
+               compatible = "regulator-fixed";
+               regulator-name = "vcc-wifi-io";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+               vin-supply = <&reg_vcc33_wifi>;
+       };
+
+       wifi_pwrseq: wifi-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&rtc 1>;
+               clock-names = "ext_clock";
+               reset-gpios = <&r_pio 1 3 GPIO_ACTIVE_LOW>; /* PM3 */
+               post-power-on-delay-ms = <200>;
+       };
 };
 
 &cpu0 {
        cpu-supply = <&reg_dcdca>;
 };
 
+&de {
+       status = "okay";
+};
+
 &ehci0 {
        status = "okay";
 };
        status = "okay";
 };
 
+&hdmi {
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
 &mmc0 {
        vmmc-supply = <&reg_cldo1>;
        cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
        status = "okay";
 };
 
+&mmc1 {
+       vmmc-supply = <&reg_vcc33_wifi>;
+       vqmmc-supply = <&reg_vcc_wifi_io>;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+
+       brcm: sdio-wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+               interrupt-parent = <&r_pio>;
+               interrupts = <1 0 IRQ_TYPE_LEVEL_LOW>; /* PM0 */
+               interrupt-names = "host-wake";
+       };
+};
+
 &ohci0 {
        status = "okay";
 };
 &pio {
        vcc-pc-supply = <&reg_bldo2>;
        vcc-pd-supply = <&reg_cldo1>;
+       vcc-pg-supply = <&reg_vcc_wifi_io>;
 };
 
 &r_i2c {
index 62e2794..ec9b6a5 100644 (file)
        };
 };
 
+&r_ir {
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_ph_pins>;
index 1898345..30102da 100644 (file)
        };
 };
 
+&r_ir {
+       status = "okay";
+};
+
 &r_pio {
        vcc-pm-supply = <&reg_aldo1>;
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-tanix-tx6.dts
new file mode 100644 (file)
index 0000000..7e7cb10
--- /dev/null
@@ -0,0 +1,100 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (c) 2019 Jernej Skrabec <jernej.skrabec@siol.net>
+ */
+
+/dts-v1/;
+
+#include "sun50i-h6.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "Tanix TX6";
+       compatible = "oranth,tanix-tx6", "allwinner,sun50i-h6";
+
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       connector {
+               compatible = "hdmi-connector";
+               ddc-en-gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */
+               type = "a";
+
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&hdmi_out_con>;
+                       };
+               };
+       };
+
+       reg_vcc3v3: vcc3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&de {
+       status = "okay";
+};
+
+&ehci0 {
+       status = "okay";
+};
+
+&ehci3 {
+       status = "okay";
+};
+
+&hdmi {
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
+&mmc0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc0_pins>;
+       vmmc-supply = <&reg_vcc3v3>;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&ohci3 {
+       status = "okay";
+};
+
+&r_ir {
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_ph_pins>;
+       status = "okay";
+};
+
+&usb2otg {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&usb2phy {
+       status = "okay";
+};
index 7628a7c..4020a1a 100644 (file)
                status = "disabled";
        };
 
-       iosc: internal-osc-clk {
-               #clock-cells = <0>;
-               compatible = "fixed-clock";
-               clock-frequency = <16000000>;
-               clock-accuracy = <300000000>;
-               clock-output-names = "iosc";
-       };
-
        osc24M: osc24M_clk {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-output-names = "osc24M";
        };
 
-       osc32k: osc32k_clk {
+       ext_osc32k: ext_osc32k_clk {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <32768>;
-               clock-output-names = "osc32k";
+               clock-output-names = "ext_osc32k";
        };
 
        psci {
                ccu: clock@3001000 {
                        compatible = "allwinner,sun50i-h6-ccu";
                        reg = <0x03001000 0x1000>;
-                       clocks = <&osc24M>, <&osc32k>, <&iosc>;
+                       clocks = <&osc24M>, <&rtc 0>, <&rtc 2>;
                        clock-names = "hosc", "losc", "iosc";
                        #clock-cells = <1>;
                        #reset-cells = <1>;
                        #dma-cells = <1>;
                };
 
-               sid: sid@3006000 {
+               sid: efuse@3006000 {
                        compatible = "allwinner,sun50i-h6-sid";
                        reg = <0x03006000 0x400>;
                };
                                     "allwinner,sun6i-a31-wdt";
                        reg = <0x030090a0 0x20>;
                        interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&osc24M>;
                        /* Broken on some H6 boards */
                        status = "disabled";
                };
                                     <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&ccu CLK_APB1>, <&osc24M>, <&osc32k>;
+                       clocks = <&ccu CLK_APB1>, <&osc24M>, <&rtc 0>;
                        clock-names = "apb", "hosc", "losc";
                        gpio-controller;
                        #gpio-cells = <3>;
                                function = "hdmi";
                        };
 
+                       i2c0_pins: i2c0-pins {
+                               pins = "PD25", "PD26";
+                               function = "i2c0";
+                       };
+
+                       i2c1_pins: i2c1-pins {
+                               pins = "PH5", "PH6";
+                               function = "i2c1";
+                       };
+
+                       i2c2_pins: i2c2-pins {
+                               pins = "PD23", "PD24";
+                               function = "i2c2";
+                       };
+
                        mmc0_pins: mmc0-pins {
                                pins = "PF0", "PF1", "PF2", "PF3",
                                       "PF4", "PF5";
                                bias-pull-up;
                        };
 
+                       spdif_tx_pin: spdif-tx-pin {
+                               pins = "PH7";
+                               function = "spdif";
+                       };
+
                        uart0_ph_pins: uart0-ph-pins {
                                pins = "PH0", "PH1";
                                function = "uart0";
                        status = "disabled";
                };
 
+               i2c0: i2c@5002000 {
+                       compatible = "allwinner,sun50i-h6-i2c",
+                                    "allwinner,sun6i-a31-i2c";
+                       reg = <0x05002000 0x400>;
+                       interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_I2C0>;
+                       resets = <&ccu RST_BUS_I2C0>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c0_pins>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               i2c1: i2c@5002400 {
+                       compatible = "allwinner,sun50i-h6-i2c",
+                                    "allwinner,sun6i-a31-i2c";
+                       reg = <0x05002400 0x400>;
+                       interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_I2C1>;
+                       resets = <&ccu RST_BUS_I2C1>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c1_pins>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               i2c2: i2c@5002800 {
+                       compatible = "allwinner,sun50i-h6-i2c",
+                                    "allwinner,sun6i-a31-i2c";
+                       reg = <0x05002800 0x400>;
+                       interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_I2C2>;
+                       resets = <&ccu RST_BUS_I2C2>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&i2c2_pins>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
                emac: ethernet@5020000 {
                        compatible = "allwinner,sun50i-h6-emac",
                                     "allwinner,sun50i-a64-emac";
                        };
                };
 
+               spdif: spdif@5093000 {
+                       #sound-dai-cells = <0>;
+                       compatible = "allwinner,sun50i-h6-spdif";
+                       reg = <0x05093000 0x400>;
+                       interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_SPDIF>, <&ccu CLK_SPDIF>;
+                       clock-names = "apb", "spdif";
+                       resets = <&ccu RST_BUS_SPDIF>;
+                       dmas = <&dma 2>;
+                       dma-names = "tx";
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&spdif_tx_pin>;
+                       status = "disabled";
+               };
+
                usb2otg: usb@5100000 {
                        compatible = "allwinner,sun50i-h6-musb",
                                     "allwinner,sun8i-a33-musb";
                        resets = <&ccu RST_BUS_HDMI_SUB>, <&ccu RST_BUS_HDCP>;
                        reset-names = "ctrl", "hdcp";
                        phys = <&hdmi_phy>;
-                       phy-names = "hdmi-phy";
+                       phy-names = "phy";
                        pinctrl-names = "default";
                        pinctrl-0 = <&hdmi_pins>;
                        status = "disabled";
                        };
                };
 
+               rtc: rtc@7000000 {
+                       compatible = "allwinner,sun50i-h6-rtc";
+                       reg = <0x07000000 0x400>;
+                       interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-output-names = "osc32k", "osc32k-out", "iosc";
+                       clocks = <&ext_osc32k>;
+                       #clock-cells = <1>;
+               };
+
                r_ccu: clock@7010000 {
                        compatible = "allwinner,sun50i-h6-r-ccu";
                        reg = <0x07010000 0x400>;
-                       clocks = <&osc24M>, <&osc32k>, <&iosc>,
+                       clocks = <&osc24M>, <&rtc 0>, <&rtc 2>,
                                 <&ccu CLK_PLL_PERIPH0>;
                        clock-names = "hosc", "losc", "iosc", "pll-periph";
                        #clock-cells = <1>;
                                     "allwinner,sun6i-a31-wdt";
                        reg = <0x07020400 0x20>;
                        interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&osc24M>;
                };
 
                r_intc: interrupt-controller@7021000 {
                        reg = <0x07022000 0x400>;
                        interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&r_ccu CLK_R_APB1>, <&osc24M>, <&osc32k>;
+                       clocks = <&r_ccu CLK_R_APB1>, <&osc24M>, <&rtc 0>;
                        clock-names = "apb", "hosc", "losc";
                        gpio-controller;
                        #gpio-cells = <3>;
                                pins = "PL0", "PL1";
                                function = "s_i2c";
                        };
+
+                       r_ir_rx_pin: r-ir-rx-pin {
+                               pins = "PL9";
+                               function = "s_cir_rx";
+                       };
+               };
+
+               r_ir: ir@7040000 {
+                               compatible = "allwinner,sun50i-h6-ir",
+                                            "allwinner,sun6i-a31-ir";
+                               reg = <0x07040000 0x400>;
+                               interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&r_ccu CLK_R_APB1_IR>,
+                                        <&r_ccu CLK_IR>;
+                               clock-names = "apb", "ir";
+                               resets = <&r_ccu RST_R_APB1_IR>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&r_ir_rx_pin>;
+                               status = "disabled";
                };
 
                r_i2c: i2c@7081400 {
-                       compatible = "allwinner,sun6i-a31-i2c";
+                       compatible = "allwinner,sun50i-h6-i2c",
+                                    "allwinner,sun6i-a31-i2c";
                        reg = <0x07081400 0x400>;
                        interrupts = <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&r_ccu CLK_R_APB2_I2C>;
index b05d781..144a2c1 100644 (file)
                        status = "disabled";
                };
 
+               nand: nand@ffb90000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "altr,socfpga-denali-nand";
+                       reg = <0xffb90000 0x10000>,
+                             <0xffb80000 0x1000>;
+                       reg-names = "nand_data", "denali_reg";
+                       interrupts = <0 97 4>;
+                       clocks = <&clkmgr STRATIX10_NAND_CLK>,
+                                <&clkmgr STRATIX10_NAND_X_CLK>,
+                                <&clkmgr STRATIX10_NAND_ECC_CLK>;
+                       clock-names = "nand", "nand_x", "ecc";
+                       resets = <&rst NAND_RESET>, <&rst NAND_OCP_RESET>;
+                       status = "disabled";
+               };
+
                ocram: sram@ffe00000 {
                        compatible = "mmio-sram";
                        reg = <0xffe00000 0x100000>;
                        #dma-requests = <32>;
                        clocks = <&clkmgr STRATIX10_L4_MAIN_CLK>;
                        clock-names = "apb_pclk";
+                       resets = <&rst DMA_RESET>, <&rst DMA_OCP_RESET>;
+                       reset-names = "dma", "dma-ocp";
                };
 
                rst: rstmgr@ffd11000 {
index 07b861f..84afecb 100644 (file)
@@ -3,6 +3,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-axg-s400.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12a-sei510.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12a-u200.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12a-x96-max.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-khadas-vim3.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-s922x-khadas-vim3.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nanopi-k2.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb
@@ -32,3 +34,5 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q200.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q201.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-vega-s96.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-sei610.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-sm1-khadas-vim3l.dtb
index 6219337..82919b1 100644 (file)
                        compatible = "amlogic,meson-axg-dwmac",
                                     "snps,dwmac-3.70a",
                                     "snps,dwmac";
-                       reg = <0x0 0xff3f0000 0x0 0x10000
-                              0x0 0xff634540 0x0 0x8>;
+                       reg = <0x0 0xff3f0000 0x0 0x10000>,
+                             <0x0 0xff634540 0x0 0x8>;
                        interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "macirq";
                        clocks = <&clkc CLKID_ETH>,
                                 <&clkc CLKID_FCLK_DIV2>,
                                 <&clkc CLKID_MPLL2>;
                        clock-names = "stmmaceth", "clkin0", "clkin1";
+                       rx-fifo-depth = <4096>;
+                       tx-fifo-depth = <2048>;
                        status = "disabled";
                };
 
                };
 
                mailbox: mailbox@ff63c404 {
-                       compatible = "amlogic,meson-gx-mhu", "amlogic,meson-gxbb-mhu";
+                       compatible = "amlogic,meson-gxbb-mhu";
                        reg = <0 0xff63c404 0 0x4c>;
                        interrupts = <GIC_SPI 208 IRQ_TYPE_EDGE_RISING>,
                                     <GIC_SPI 209 IRQ_TYPE_EDGE_RISING>,
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
new file mode 100644 (file)
index 0000000..3f39e02
--- /dev/null
@@ -0,0 +1,2435 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2018 Amlogic, Inc. All rights reserved.
+ */
+
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/axg-audio-clkc.h>
+#include <dt-bindings/clock/g12a-clkc.h>
+#include <dt-bindings/clock/g12a-aoclkc.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h>
+#include <dt-bindings/reset/amlogic,meson-g12a-audio-reset.h>
+#include <dt-bindings/reset/amlogic,meson-g12a-reset.h>
+
+/ {
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       tdmif_a: audio-controller-0 {
+               compatible = "amlogic,axg-tdm-iface";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "TDM_A";
+               clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
+                        <&clkc_audio AUD_CLKID_MST_A_SCLK>,
+                        <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
+               clock-names = "mclk", "sclk", "lrclk";
+               status = "disabled";
+       };
+
+       tdmif_b: audio-controller-1 {
+               compatible = "amlogic,axg-tdm-iface";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "TDM_B";
+               clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>,
+                        <&clkc_audio AUD_CLKID_MST_B_SCLK>,
+                        <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
+               clock-names = "mclk", "sclk", "lrclk";
+               status = "disabled";
+       };
+
+       tdmif_c: audio-controller-2 {
+               compatible = "amlogic,axg-tdm-iface";
+               #sound-dai-cells = <0>;
+               sound-name-prefix = "TDM_C";
+               clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>,
+                        <&clkc_audio AUD_CLKID_MST_C_SCLK>,
+                        <&clkc_audio AUD_CLKID_MST_C_LRCLK>;
+               clock-names = "mclk", "sclk", "lrclk";
+               status = "disabled";
+       };
+
+       efuse: efuse {
+               compatible = "amlogic,meson-gxbb-efuse";
+               clocks = <&clkc CLKID_EFUSE>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               read-only;
+       };
+
+       psci {
+               compatible = "arm,psci-1.0";
+               method = "smc";
+       };
+
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               /* 3 MiB reserved for ARM Trusted Firmware (BL31) */
+               secmon_reserved: secmon@5000000 {
+                       reg = <0x0 0x05000000 0x0 0x300000>;
+                       no-map;
+               };
+
+               linux,cma {
+                       compatible = "shared-dma-pool";
+                       reusable;
+                       size = <0x0 0x10000000>;
+                       alignment = <0x0 0x400000>;
+                       linux,cma-default;
+               };
+       };
+
+       sm: secure-monitor {
+               compatible = "amlogic,meson-gxbb-sm";
+       };
+
+       soc {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               ethmac: ethernet@ff3f0000 {
+                       compatible = "amlogic,meson-axg-dwmac",
+                                    "snps,dwmac-3.70a",
+                                    "snps,dwmac";
+                       reg = <0x0 0xff3f0000 0x0 0x10000>,
+                             <0x0 0xff634540 0x0 0x8>;
+                       interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "macirq";
+                       clocks = <&clkc CLKID_ETH>,
+                                <&clkc CLKID_FCLK_DIV2>,
+                                <&clkc CLKID_MPLL2>;
+                       clock-names = "stmmaceth", "clkin0", "clkin1";
+                       rx-fifo-depth = <4096>;
+                       tx-fifo-depth = <2048>;
+                       status = "disabled";
+
+                       mdio0: mdio {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "snps,dwmac-mdio";
+                       };
+               };
+
+               apb: bus@ff600000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xff600000 0x0 0x200000>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xff600000 0x0 0x200000>;
+
+                       hdmi_tx: hdmi-tx@0 {
+                               compatible = "amlogic,meson-g12a-dw-hdmi";
+                               reg = <0x0 0x0 0x0 0x10000>;
+                               interrupts = <GIC_SPI 57 IRQ_TYPE_EDGE_RISING>;
+                               resets = <&reset RESET_HDMITX_CAPB3>,
+                                        <&reset RESET_HDMITX_PHY>,
+                                        <&reset RESET_HDMITX>;
+                               reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy";
+                               clocks = <&clkc CLKID_HDMI>,
+                                        <&clkc CLKID_HTX_PCLK>,
+                                        <&clkc CLKID_VPU_INTR>;
+                               clock-names = "isfr", "iahb", "venci";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               #sound-dai-cells = <0>;
+                               status = "disabled";
+
+                               /* VPU VENC Input */
+                               hdmi_tx_venc_port: port@0 {
+                                       reg = <0>;
+
+                                       hdmi_tx_in: endpoint {
+                                               remote-endpoint = <&hdmi_tx_out>;
+                                       };
+                               };
+
+                               /* TMDS Output */
+                               hdmi_tx_tmds_port: port@1 {
+                                       reg = <1>;
+                               };
+                       };
+
+                       apb_efuse: bus@30000 {
+                               compatible = "simple-bus";
+                               reg = <0x0 0x30000 0x0 0x2000>;
+                               #address-cells = <2>;
+                               #size-cells = <2>;
+                               ranges = <0x0 0x0 0x0 0x30000 0x0 0x2000>;
+
+                               hwrng: rng@218 {
+                                       compatible = "amlogic,meson-rng";
+                                       reg = <0x0 0x218 0x0 0x4>;
+                               };
+                       };
+
+                       periphs: bus@34400 {
+                               compatible = "simple-bus";
+                               reg = <0x0 0x34400 0x0 0x400>;
+                               #address-cells = <2>;
+                               #size-cells = <2>;
+                               ranges = <0x0 0x0 0x0 0x34400 0x0 0x400>;
+
+                               periphs_pinctrl: pinctrl@40 {
+                                       compatible = "amlogic,meson-g12a-periphs-pinctrl";
+                                       #address-cells = <2>;
+                                       #size-cells = <2>;
+                                       ranges;
+
+                                       gpio: bank@40 {
+                                               reg = <0x0 0x40  0x0 0x4c>,
+                                                     <0x0 0xe8  0x0 0x18>,
+                                                     <0x0 0x120 0x0 0x18>,
+                                                     <0x0 0x2c0 0x0 0x40>,
+                                                     <0x0 0x340 0x0 0x1c>;
+                                               reg-names = "gpio",
+                                                           "pull",
+                                                           "pull-enable",
+                                                           "mux",
+                                                           "ds";
+                                               gpio-controller;
+                                               #gpio-cells = <2>;
+                                               gpio-ranges = <&periphs_pinctrl 0 0 86>;
+                                       };
+
+                                       cec_ao_a_h_pins: cec_ao_a_h {
+                                               mux {
+                                                       groups = "cec_ao_a_h";
+                                                       function = "cec_ao_a_h";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       cec_ao_b_h_pins: cec_ao_b_h {
+                                               mux {
+                                                       groups = "cec_ao_b_h";
+                                                       function = "cec_ao_b_h";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       emmc_pins: emmc {
+                                               mux-0 {
+                                                       groups = "emmc_nand_d0",
+                                                                "emmc_nand_d1",
+                                                                "emmc_nand_d2",
+                                                                "emmc_nand_d3",
+                                                                "emmc_nand_d4",
+                                                                "emmc_nand_d5",
+                                                                "emmc_nand_d6",
+                                                                "emmc_nand_d7",
+                                                                "emmc_cmd";
+                                                       function = "emmc";
+                                                       bias-pull-up;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+
+                                               mux-1 {
+                                                       groups = "emmc_clk";
+                                                       function = "emmc";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+                                       };
+
+                                       emmc_ds_pins: emmc-ds {
+                                               mux {
+                                                       groups = "emmc_nand_ds";
+                                                       function = "emmc";
+                                                       bias-pull-down;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+                                       };
+
+                                       emmc_clk_gate_pins: emmc_clk_gate {
+                                               mux {
+                                                       groups = "BOOT_8";
+                                                       function = "gpio_periphs";
+                                                       bias-pull-down;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+                                       };
+
+                                       hdmitx_ddc_pins: hdmitx_ddc {
+                                               mux {
+                                                       groups = "hdmitx_sda",
+                                                                "hdmitx_sck";
+                                                       function = "hdmitx";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+                                       };
+
+                                       hdmitx_hpd_pins: hdmitx_hpd {
+                                               mux {
+                                                       groups = "hdmitx_hpd_in";
+                                                       function = "hdmitx";
+                                                       bias-disable;
+                                               };
+                                       };
+
+
+                                       i2c0_sda_c_pins: i2c0-sda-c {
+                                               mux {
+                                                       groups = "i2c0_sda_c";
+                                                       function = "i2c0";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+
+                                               };
+                                       };
+
+                                       i2c0_sck_c_pins: i2c0-sck-c {
+                                               mux {
+                                                       groups = "i2c0_sck_c";
+                                                       function = "i2c0";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c0_sda_z0_pins: i2c0-sda-z0 {
+                                               mux {
+                                                       groups = "i2c0_sda_z0";
+                                                       function = "i2c0";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c0_sck_z1_pins: i2c0-sck-z1 {
+                                               mux {
+                                                       groups = "i2c0_sck_z1";
+                                                       function = "i2c0";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c0_sda_z7_pins: i2c0-sda-z7 {
+                                               mux {
+                                                       groups = "i2c0_sda_z7";
+                                                       function = "i2c0";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c0_sda_z8_pins: i2c0-sda-z8 {
+                                               mux {
+                                                       groups = "i2c0_sda_z8";
+                                                       function = "i2c0";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c1_sda_x_pins: i2c1-sda-x {
+                                               mux {
+                                                       groups = "i2c1_sda_x";
+                                                       function = "i2c1";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c1_sck_x_pins: i2c1-sck-x {
+                                               mux {
+                                                       groups = "i2c1_sck_x";
+                                                       function = "i2c1";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c1_sda_h2_pins: i2c1-sda-h2 {
+                                               mux {
+                                                       groups = "i2c1_sda_h2";
+                                                       function = "i2c1";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c1_sck_h3_pins: i2c1-sck-h3 {
+                                               mux {
+                                                       groups = "i2c1_sck_h3";
+                                                       function = "i2c1";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c1_sda_h6_pins: i2c1-sda-h6 {
+                                               mux {
+                                                       groups = "i2c1_sda_h6";
+                                                       function = "i2c1";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c1_sck_h7_pins: i2c1-sck-h7 {
+                                               mux {
+                                                       groups = "i2c1_sck_h7";
+                                                       function = "i2c1";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c2_sda_x_pins: i2c2-sda-x {
+                                               mux {
+                                                       groups = "i2c2_sda_x";
+                                                       function = "i2c2";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c2_sck_x_pins: i2c2-sck-x {
+                                               mux {
+                                                       groups = "i2c2_sck_x";
+                                                       function = "i2c2";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c2_sda_z_pins: i2c2-sda-z {
+                                               mux {
+                                                       groups = "i2c2_sda_z";
+                                                       function = "i2c2";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c2_sck_z_pins: i2c2-sck-z {
+                                               mux {
+                                                       groups = "i2c2_sck_z";
+                                                       function = "i2c2";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c3_sda_h_pins: i2c3-sda-h {
+                                               mux {
+                                                       groups = "i2c3_sda_h";
+                                                       function = "i2c3";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c3_sck_h_pins: i2c3-sck-h {
+                                               mux {
+                                                       groups = "i2c3_sck_h";
+                                                       function = "i2c3";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c3_sda_a_pins: i2c3-sda-a {
+                                               mux {
+                                                       groups = "i2c3_sda_a";
+                                                       function = "i2c3";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c3_sck_a_pins: i2c3-sck-a {
+                                               mux {
+                                                       groups = "i2c3_sck_a";
+                                                       function = "i2c3";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       mclk0_a_pins: mclk0-a {
+                                               mux {
+                                                       groups = "mclk0_a";
+                                                       function = "mclk0";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       mclk1_a_pins: mclk1-a {
+                                               mux {
+                                                       groups = "mclk1_a";
+                                                       function = "mclk1";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       mclk1_x_pins: mclk1-x {
+                                               mux {
+                                                       groups = "mclk1_x";
+                                                       function = "mclk1";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       mclk1_z_pins: mclk1-z {
+                                               mux {
+                                                       groups = "mclk1_z";
+                                                       function = "mclk1";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       pdm_din0_a_pins: pdm-din0-a {
+                                               mux {
+                                                       groups = "pdm_din0_a";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din0_c_pins: pdm-din0-c {
+                                               mux {
+                                                       groups = "pdm_din0_c";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din0_x_pins: pdm-din0-x {
+                                               mux {
+                                                       groups = "pdm_din0_x";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din0_z_pins: pdm-din0-z {
+                                               mux {
+                                                       groups = "pdm_din0_z";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din1_a_pins: pdm-din1-a {
+                                               mux {
+                                                       groups = "pdm_din1_a";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din1_c_pins: pdm-din1-c {
+                                               mux {
+                                                       groups = "pdm_din1_c";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din1_x_pins: pdm-din1-x {
+                                               mux {
+                                                       groups = "pdm_din1_x";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din1_z_pins: pdm-din1-z {
+                                               mux {
+                                                       groups = "pdm_din1_z";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din2_a_pins: pdm-din2-a {
+                                               mux {
+                                                       groups = "pdm_din2_a";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din2_c_pins: pdm-din2-c {
+                                               mux {
+                                                       groups = "pdm_din2_c";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din2_x_pins: pdm-din2-x {
+                                               mux {
+                                                       groups = "pdm_din2_x";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din2_z_pins: pdm-din2-z {
+                                               mux {
+                                                       groups = "pdm_din2_z";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din3_a_pins: pdm-din3-a {
+                                               mux {
+                                                       groups = "pdm_din3_a";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din3_c_pins: pdm-din3-c {
+                                               mux {
+                                                       groups = "pdm_din3_c";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din3_x_pins: pdm-din3-x {
+                                               mux {
+                                                       groups = "pdm_din3_x";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_din3_z_pins: pdm-din3-z {
+                                               mux {
+                                                       groups = "pdm_din3_z";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pdm_dclk_a_pins: pdm-dclk-a {
+                                               mux {
+                                                       groups = "pdm_dclk_a";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <500>;
+                                               };
+                                       };
+
+                                       pdm_dclk_c_pins: pdm-dclk-c {
+                                               mux {
+                                                       groups = "pdm_dclk_c";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <500>;
+                                               };
+                                       };
+
+                                       pdm_dclk_x_pins: pdm-dclk-x {
+                                               mux {
+                                                       groups = "pdm_dclk_x";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <500>;
+                                               };
+                                       };
+
+                                       pdm_dclk_z_pins: pdm-dclk-z {
+                                               mux {
+                                                       groups = "pdm_dclk_z";
+                                                       function = "pdm";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <500>;
+                                               };
+                                       };
+
+                                       pwm_a_pins: pwm-a {
+                                               mux {
+                                                       groups = "pwm_a";
+                                                       function = "pwm_a";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_b_x7_pins: pwm-b-x7 {
+                                               mux {
+                                                       groups = "pwm_b_x7";
+                                                       function = "pwm_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_b_x19_pins: pwm-b-x19 {
+                                               mux {
+                                                       groups = "pwm_b_x19";
+                                                       function = "pwm_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_c_c_pins: pwm-c-c {
+                                               mux {
+                                                       groups = "pwm_c_c";
+                                                       function = "pwm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_c_x5_pins: pwm-c-x5 {
+                                               mux {
+                                                       groups = "pwm_c_x5";
+                                                       function = "pwm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_c_x8_pins: pwm-c-x8 {
+                                               mux {
+                                                       groups = "pwm_c_x8";
+                                                       function = "pwm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_d_x3_pins: pwm-d-x3 {
+                                               mux {
+                                                       groups = "pwm_d_x3";
+                                                       function = "pwm_d";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_d_x6_pins: pwm-d-x6 {
+                                               mux {
+                                                       groups = "pwm_d_x6";
+                                                       function = "pwm_d";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_e_pins: pwm-e {
+                                               mux {
+                                                       groups = "pwm_e";
+                                                       function = "pwm_e";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_f_x_pins: pwm-f-x {
+                                               mux {
+                                                       groups = "pwm_f_x";
+                                                       function = "pwm_f";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_f_h_pins: pwm-f-h {
+                                               mux {
+                                                       groups = "pwm_f_h";
+                                                       function = "pwm_f";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       sdcard_c_pins: sdcard_c {
+                                               mux-0 {
+                                                       groups = "sdcard_d0_c",
+                                                                "sdcard_d1_c",
+                                                                "sdcard_d2_c",
+                                                                "sdcard_d3_c",
+                                                                "sdcard_cmd_c";
+                                                       function = "sdcard";
+                                                       bias-pull-up;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+
+                                               mux-1 {
+                                                       groups = "sdcard_clk_c";
+                                                       function = "sdcard";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+                                       };
+
+                                       sdcard_clk_gate_c_pins: sdcard_clk_gate_c {
+                                               mux {
+                                                       groups = "GPIOC_4";
+                                                       function = "gpio_periphs";
+                                                       bias-pull-down;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+                                       };
+
+                                       sdcard_z_pins: sdcard_z {
+                                               mux-0 {
+                                                       groups = "sdcard_d0_z",
+                                                                "sdcard_d1_z",
+                                                                "sdcard_d2_z",
+                                                                "sdcard_d3_z",
+                                                                "sdcard_cmd_z";
+                                                       function = "sdcard";
+                                                       bias-pull-up;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+
+                                               mux-1 {
+                                                       groups = "sdcard_clk_z";
+                                                       function = "sdcard";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+                                       };
+
+                                       sdcard_clk_gate_z_pins: sdcard_clk_gate_z {
+                                               mux {
+                                                       groups = "GPIOZ_6";
+                                                       function = "gpio_periphs";
+                                                       bias-pull-down;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+                                       };
+
+                                       sdio_pins: sdio {
+                                               mux {
+                                                       groups = "sdio_d0",
+                                                                "sdio_d1",
+                                                                "sdio_d2",
+                                                                "sdio_d3",
+                                                                "sdio_clk",
+                                                                "sdio_cmd";
+                                                       function = "sdio";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+                                       };
+
+                                       sdio_clk_gate_pins: sdio_clk_gate {
+                                               mux {
+                                                       groups = "GPIOX_4";
+                                                       function = "gpio_periphs";
+                                                       bias-pull-down;
+                                                       drive-strength-microamp = <4000>;
+                                               };
+                                       };
+
+                                       spdif_in_a10_pins: spdif-in-a10 {
+                                               mux {
+                                                       groups = "spdif_in_a10";
+                                                       function = "spdif_in";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       spdif_in_a12_pins: spdif-in-a12 {
+                                               mux {
+                                                       groups = "spdif_in_a12";
+                                                       function = "spdif_in";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       spdif_in_h_pins: spdif-in-h {
+                                               mux {
+                                                       groups = "spdif_in_h";
+                                                       function = "spdif_in";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       spdif_out_h_pins: spdif-out-h {
+                                               mux {
+                                                       groups = "spdif_out_h";
+                                                       function = "spdif_out";
+                                                       drive-strength-microamp = <500>;
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       spdif_out_a11_pins: spdif-out-a11 {
+                                               mux {
+                                                       groups = "spdif_out_a11";
+                                                       function = "spdif_out";
+                                                       drive-strength-microamp = <500>;
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       spdif_out_a13_pins: spdif-out-a13 {
+                                               mux {
+                                                       groups = "spdif_out_a13";
+                                                       function = "spdif_out";
+                                                       drive-strength-microamp = <500>;
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_a_din0_pins: tdm-a-din0 {
+                                               mux {
+                                                       groups = "tdm_a_din0";
+                                                       function = "tdm_a";
+                                                       bias-disable;
+                                               };
+                                       };
+
+
+                                       tdm_a_din1_pins: tdm-a-din1 {
+                                               mux {
+                                                       groups = "tdm_a_din1";
+                                                       function = "tdm_a";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_a_dout0_pins: tdm-a-dout0 {
+                                               mux {
+                                                       groups = "tdm_a_dout0";
+                                                       function = "tdm_a";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_a_dout1_pins: tdm-a-dout1 {
+                                               mux {
+                                                       groups = "tdm_a_dout1";
+                                                       function = "tdm_a";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_a_fs_pins: tdm-a-fs {
+                                               mux {
+                                                       groups = "tdm_a_fs";
+                                                       function = "tdm_a";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_a_sclk_pins: tdm-a-sclk {
+                                               mux {
+                                                       groups = "tdm_a_sclk";
+                                                       function = "tdm_a";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_a_slv_fs_pins: tdm-a-slv-fs {
+                                               mux {
+                                                       groups = "tdm_a_slv_fs";
+                                                       function = "tdm_a";
+                                                       bias-disable;
+                                               };
+                                       };
+
+
+                                       tdm_a_slv_sclk_pins: tdm-a-slv-sclk {
+                                               mux {
+                                                       groups = "tdm_a_slv_sclk";
+                                                       function = "tdm_a";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_b_din0_pins: tdm-b-din0 {
+                                               mux {
+                                                       groups = "tdm_b_din0";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_b_din1_pins: tdm-b-din1 {
+                                               mux {
+                                                       groups = "tdm_b_din1";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_b_din2_pins: tdm-b-din2 {
+                                               mux {
+                                                       groups = "tdm_b_din2";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_b_din3_a_pins: tdm-b-din3-a {
+                                               mux {
+                                                       groups = "tdm_b_din3_a";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_b_din3_h_pins: tdm-b-din3-h {
+                                               mux {
+                                                       groups = "tdm_b_din3_h";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_b_dout0_pins: tdm-b-dout0 {
+                                               mux {
+                                                       groups = "tdm_b_dout0";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_b_dout1_pins: tdm-b-dout1 {
+                                               mux {
+                                                       groups = "tdm_b_dout1";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_b_dout2_pins: tdm-b-dout2 {
+                                               mux {
+                                                       groups = "tdm_b_dout2";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_b_dout3_a_pins: tdm-b-dout3-a {
+                                               mux {
+                                                       groups = "tdm_b_dout3_a";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_b_dout3_h_pins: tdm-b-dout3-h {
+                                               mux {
+                                                       groups = "tdm_b_dout3_h";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_b_fs_pins: tdm-b-fs {
+                                               mux {
+                                                       groups = "tdm_b_fs";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_b_sclk_pins: tdm-b-sclk {
+                                               mux {
+                                                       groups = "tdm_b_sclk";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_b_slv_fs_pins: tdm-b-slv-fs {
+                                               mux {
+                                                       groups = "tdm_b_slv_fs";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_b_slv_sclk_pins: tdm-b-slv-sclk {
+                                               mux {
+                                                       groups = "tdm_b_slv_sclk";
+                                                       function = "tdm_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_c_din0_a_pins: tdm-c-din0-a {
+                                               mux {
+                                                       groups = "tdm_c_din0_a";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_c_din0_z_pins: tdm-c-din0-z {
+                                               mux {
+                                                       groups = "tdm_c_din0_z";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_c_din1_a_pins: tdm-c-din1-a {
+                                               mux {
+                                                       groups = "tdm_c_din1_a";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_c_din1_z_pins: tdm-c-din1-z {
+                                               mux {
+                                                       groups = "tdm_c_din1_z";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_c_din2_a_pins: tdm-c-din2-a {
+                                               mux {
+                                                       groups = "tdm_c_din2_a";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       eth_leds_pins: eth-leds {
+                                               mux {
+                                                       groups = "eth_link_led",
+                                                                "eth_act_led";
+                                                       function = "eth";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       eth_pins: eth {
+                                               mux {
+                                                       groups = "eth_mdio",
+                                                                "eth_mdc",
+                                                                "eth_rgmii_rx_clk",
+                                                                "eth_rx_dv",
+                                                                "eth_rxd0",
+                                                                "eth_rxd1",
+                                                                "eth_txen",
+                                                                "eth_txd0",
+                                                                "eth_txd1";
+                                                       function = "eth";
+                                                       drive-strength-microamp = <4000>;
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       eth_rgmii_pins: eth-rgmii {
+                                               mux {
+                                                       groups = "eth_rxd2_rgmii",
+                                                                "eth_rxd3_rgmii",
+                                                                "eth_rgmii_tx_clk",
+                                                                "eth_txd2_rgmii",
+                                                                "eth_txd3_rgmii";
+                                                       function = "eth";
+                                                       drive-strength-microamp = <4000>;
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_c_din2_z_pins: tdm-c-din2-z {
+                                               mux {
+                                                       groups = "tdm_c_din2_z";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_c_din3_a_pins: tdm-c-din3-a {
+                                               mux {
+                                                       groups = "tdm_c_din3_a";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_c_din3_z_pins: tdm-c-din3-z {
+                                               mux {
+                                                       groups = "tdm_c_din3_z";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_c_dout0_a_pins: tdm-c-dout0-a {
+                                               mux {
+                                                       groups = "tdm_c_dout0_a";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_c_dout0_z_pins: tdm-c-dout0-z {
+                                               mux {
+                                                       groups = "tdm_c_dout0_z";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_c_dout1_a_pins: tdm-c-dout1-a {
+                                               mux {
+                                                       groups = "tdm_c_dout1_a";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_c_dout1_z_pins: tdm-c-dout1-z {
+                                               mux {
+                                                       groups = "tdm_c_dout1_z";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_c_dout2_a_pins: tdm-c-dout2-a {
+                                               mux {
+                                                       groups = "tdm_c_dout2_a";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_c_dout2_z_pins: tdm-c-dout2-z {
+                                               mux {
+                                                       groups = "tdm_c_dout2_z";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_c_dout3_a_pins: tdm-c-dout3-a {
+                                               mux {
+                                                       groups = "tdm_c_dout3_a";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_c_dout3_z_pins: tdm-c-dout3-z {
+                                               mux {
+                                                       groups = "tdm_c_dout3_z";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_c_fs_a_pins: tdm-c-fs-a {
+                                               mux {
+                                                       groups = "tdm_c_fs_a";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_c_fs_z_pins: tdm-c-fs-z {
+                                               mux {
+                                                       groups = "tdm_c_fs_z";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_c_sclk_a_pins: tdm-c-sclk-a {
+                                               mux {
+                                                       groups = "tdm_c_sclk_a";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_c_sclk_z_pins: tdm-c-sclk-z {
+                                               mux {
+                                                       groups = "tdm_c_sclk_z";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_c_slv_fs_a_pins: tdm-c-slv-fs-a {
+                                               mux {
+                                                       groups = "tdm_c_slv_fs_a";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_c_slv_fs_z_pins: tdm-c-slv-fs-z {
+                                               mux {
+                                                       groups = "tdm_c_slv_fs_z";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_c_slv_sclk_a_pins: tdm-c-slv-sclk-a {
+                                               mux {
+                                                       groups = "tdm_c_slv_sclk_a";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_c_slv_sclk_z_pins: tdm-c-slv-sclk-z {
+                                               mux {
+                                                       groups = "tdm_c_slv_sclk_z";
+                                                       function = "tdm_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       uart_a_pins: uart-a {
+                                               mux {
+                                                       groups = "uart_a_tx",
+                                                                "uart_a_rx";
+                                                       function = "uart_a";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       uart_a_cts_rts_pins: uart-a-cts-rts {
+                                               mux {
+                                                       groups = "uart_a_cts",
+                                                                "uart_a_rts";
+                                                       function = "uart_a";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       uart_b_pins: uart-b {
+                                               mux {
+                                                       groups = "uart_b_tx",
+                                                                "uart_b_rx";
+                                                       function = "uart_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       uart_c_pins: uart-c {
+                                               mux {
+                                                       groups = "uart_c_tx",
+                                                                "uart_c_rx";
+                                                       function = "uart_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       uart_c_cts_rts_pins: uart-c-cts-rts {
+                                               mux {
+                                                       groups = "uart_c_cts",
+                                                                "uart_c_rts";
+                                                       function = "uart_c";
+                                                       bias-disable;
+                                               };
+                                       };
+                               };
+                       };
+
+                       usb2_phy0: phy@36000 {
+                               compatible = "amlogic,g12a-usb2-phy";
+                               reg = <0x0 0x36000 0x0 0x2000>;
+                               clocks = <&xtal>;
+                               clock-names = "xtal";
+                               resets = <&reset RESET_USB_PHY20>;
+                               reset-names = "phy";
+                               #phy-cells = <0>;
+                       };
+
+                       dmc: bus@38000 {
+                               compatible = "simple-bus";
+                               reg = <0x0 0x38000 0x0 0x400>;
+                               #address-cells = <2>;
+                               #size-cells = <2>;
+                               ranges = <0x0 0x0 0x0 0x38000 0x0 0x400>;
+
+                               canvas: video-lut@48 {
+                                       compatible = "amlogic,canvas";
+                                       reg = <0x0 0x48 0x0 0x14>;
+                               };
+                       };
+
+                       usb2_phy1: phy@3a000 {
+                               compatible = "amlogic,g12a-usb2-phy";
+                               reg = <0x0 0x3a000 0x0 0x2000>;
+                               clocks = <&xtal>;
+                               clock-names = "xtal";
+                               resets = <&reset RESET_USB_PHY21>;
+                               reset-names = "phy";
+                               #phy-cells = <0>;
+                       };
+
+                       hiu: bus@3c000 {
+                               compatible = "simple-bus";
+                               reg = <0x0 0x3c000 0x0 0x1400>;
+                               #address-cells = <2>;
+                               #size-cells = <2>;
+                               ranges = <0x0 0x0 0x0 0x3c000 0x0 0x1400>;
+
+                               hhi: system-controller@0 {
+                                       compatible = "amlogic,meson-gx-hhi-sysctrl",
+                                                    "simple-mfd", "syscon";
+                                       reg = <0 0 0 0x400>;
+
+                                       clkc: clock-controller {
+                                               compatible = "amlogic,g12a-clkc";
+                                               #clock-cells = <1>;
+                                               clocks = <&xtal>;
+                                               clock-names = "xtal";
+                                       };
+
+                                       pwrc: power-controller {
+                                               compatible = "amlogic,meson-g12a-pwrc";
+                                               #power-domain-cells = <1>;
+                                               amlogic,ao-sysctrl = <&rti>;
+                                               resets = <&reset RESET_VIU>,
+                                                        <&reset RESET_VENC>,
+                                                        <&reset RESET_VCBUS>,
+                                                        <&reset RESET_BT656>,
+                                                        <&reset RESET_RDMA>,
+                                                        <&reset RESET_VENCI>,
+                                                        <&reset RESET_VENCP>,
+                                                        <&reset RESET_VDAC>,
+                                                        <&reset RESET_VDI6>,
+                                                        <&reset RESET_VENCL>,
+                                                        <&reset RESET_VID_LOCK>;
+                                               reset-names = "viu", "venc", "vcbus", "bt656",
+                                                             "rdma", "venci", "vencp", "vdac",
+                                                             "vdi6", "vencl", "vid_lock";
+                                               clocks = <&clkc CLKID_VPU>,
+                                                        <&clkc CLKID_VAPB>;
+                                               clock-names = "vpu", "vapb";
+                                               /*
+                                                * VPU clocking is provided by two identical clock paths
+                                                * VPU_0 and VPU_1 muxed to a single clock by a glitch
+                                                * free mux to safely change frequency while running.
+                                                * Same for VAPB but with a final gate after the glitch free mux.
+                                                */
+                                               assigned-clocks = <&clkc CLKID_VPU_0_SEL>,
+                                                                 <&clkc CLKID_VPU_0>,
+                                                                 <&clkc CLKID_VPU>, /* Glitch free mux */
+                                                                 <&clkc CLKID_VAPB_0_SEL>,
+                                                                 <&clkc CLKID_VAPB_0>,
+                                                                 <&clkc CLKID_VAPB_SEL>; /* Glitch free mux */
+                                               assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>,
+                                                                        <0>, /* Do Nothing */
+                                                                        <&clkc CLKID_VPU_0>,
+                                                                        <&clkc CLKID_FCLK_DIV4>,
+                                                                        <0>, /* Do Nothing */
+                                                                        <&clkc CLKID_VAPB_0>;
+                                               assigned-clock-rates = <0>, /* Do Nothing */
+                                                                      <666666666>,
+                                                                      <0>, /* Do Nothing */
+                                                                      <0>, /* Do Nothing */
+                                                                      <250000000>,
+                                                                      <0>; /* Do Nothing */
+                                       };
+                               };
+                       };
+
+                       pdm: audio-controller@40000 {
+                               compatible = "amlogic,g12a-pdm",
+                                            "amlogic,axg-pdm";
+                               reg = <0x0 0x40000 0x0 0x34>;
+                               #sound-dai-cells = <0>;
+                               sound-name-prefix = "PDM";
+                               clocks = <&clkc_audio AUD_CLKID_PDM>,
+                                        <&clkc_audio AUD_CLKID_PDM_DCLK>,
+                                        <&clkc_audio AUD_CLKID_PDM_SYSCLK>;
+                               clock-names = "pclk", "dclk", "sysclk";
+                               status = "disabled";
+                       };
+
+                       audio: bus@42000 {
+                               compatible = "simple-bus";
+                               reg = <0x0 0x42000 0x0 0x2000>;
+                               #address-cells = <2>;
+                               #size-cells = <2>;
+                               ranges = <0x0 0x0 0x0 0x42000 0x0 0x2000>;
+
+                               clkc_audio: clock-controller@0 {
+                                       status = "disabled";
+                                       compatible = "amlogic,g12a-audio-clkc";
+                                       reg = <0x0 0x0 0x0 0xb4>;
+                                       #clock-cells = <1>;
+                                       #reset-cells = <1>;
+
+                                       clocks = <&clkc CLKID_AUDIO>,
+                                                <&clkc CLKID_MPLL0>,
+                                                <&clkc CLKID_MPLL1>,
+                                                <&clkc CLKID_MPLL2>,
+                                                <&clkc CLKID_MPLL3>,
+                                                <&clkc CLKID_HIFI_PLL>,
+                                                <&clkc CLKID_FCLK_DIV3>,
+                                                <&clkc CLKID_FCLK_DIV4>,
+                                                <&clkc CLKID_GP0_PLL>;
+                                       clock-names = "pclk",
+                                                     "mst_in0",
+                                                     "mst_in1",
+                                                     "mst_in2",
+                                                     "mst_in3",
+                                                     "mst_in4",
+                                                     "mst_in5",
+                                                     "mst_in6",
+                                                     "mst_in7";
+
+                                       resets = <&reset RESET_AUDIO>;
+                               };
+
+                               toddr_a: audio-controller@100 {
+                                       compatible = "amlogic,g12a-toddr",
+                                                    "amlogic,axg-toddr";
+                                       reg = <0x0 0x100 0x0 0x1c>;
+                                       #sound-dai-cells = <0>;
+                                       sound-name-prefix = "TODDR_A";
+                                       interrupts = <GIC_SPI 148 IRQ_TYPE_EDGE_RISING>;
+                                       clocks = <&clkc_audio AUD_CLKID_TODDR_A>;
+                                       resets = <&arb AXG_ARB_TODDR_A>;
+                                       status = "disabled";
+                               };
+
+                               toddr_b: audio-controller@140 {
+                                       compatible = "amlogic,g12a-toddr",
+                                                    "amlogic,axg-toddr";
+                                       reg = <0x0 0x140 0x0 0x1c>;
+                                       #sound-dai-cells = <0>;
+                                       sound-name-prefix = "TODDR_B";
+                                       interrupts = <GIC_SPI 149 IRQ_TYPE_EDGE_RISING>;
+                                       clocks = <&clkc_audio AUD_CLKID_TODDR_B>;
+                                       resets = <&arb AXG_ARB_TODDR_B>;
+                                       status = "disabled";
+                               };
+
+                               toddr_c: audio-controller@180 {
+                                       compatible = "amlogic,g12a-toddr",
+                                                    "amlogic,axg-toddr";
+                                       reg = <0x0 0x180 0x0 0x1c>;
+                                       #sound-dai-cells = <0>;
+                                       sound-name-prefix = "TODDR_C";
+                                       interrupts = <GIC_SPI 150 IRQ_TYPE_EDGE_RISING>;
+                                       clocks = <&clkc_audio AUD_CLKID_TODDR_C>;
+                                       resets = <&arb AXG_ARB_TODDR_C>;
+                                       status = "disabled";
+                               };
+
+                               frddr_a: audio-controller@1c0 {
+                                       compatible = "amlogic,g12a-frddr",
+                                                    "amlogic,axg-frddr";
+                                       reg = <0x0 0x1c0 0x0 0x1c>;
+                                       #sound-dai-cells = <0>;
+                                       sound-name-prefix = "FRDDR_A";
+                                       interrupts = <GIC_SPI 152 IRQ_TYPE_EDGE_RISING>;
+                                       clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
+                                       resets = <&arb AXG_ARB_FRDDR_A>;
+                                       status = "disabled";
+                               };
+
+                               frddr_b: audio-controller@200 {
+                                       compatible = "amlogic,g12a-frddr",
+                                                    "amlogic,axg-frddr";
+                                       reg = <0x0 0x200 0x0 0x1c>;
+                                       #sound-dai-cells = <0>;
+                                       sound-name-prefix = "FRDDR_B";
+                                       interrupts = <GIC_SPI 153 IRQ_TYPE_EDGE_RISING>;
+                                       clocks = <&clkc_audio AUD_CLKID_FRDDR_B>;
+                                       resets = <&arb AXG_ARB_FRDDR_B>;
+                                       status = "disabled";
+                               };
+
+                               frddr_c: audio-controller@240 {
+                                       compatible = "amlogic,g12a-frddr",
+                                                    "amlogic,axg-frddr";
+                                       reg = <0x0 0x240 0x0 0x1c>;
+                                       #sound-dai-cells = <0>;
+                                       sound-name-prefix = "FRDDR_C";
+                                       interrupts = <GIC_SPI 154 IRQ_TYPE_EDGE_RISING>;
+                                       clocks = <&clkc_audio AUD_CLKID_FRDDR_C>;
+                                       resets = <&arb AXG_ARB_FRDDR_C>;
+                                       status = "disabled";
+                               };
+
+                               arb: reset-controller@280 {
+                                       status = "disabled";
+                                       compatible = "amlogic,meson-axg-audio-arb";
+                                       reg = <0x0 0x280 0x0 0x4>;
+                                       #reset-cells = <1>;
+                                       clocks = <&clkc_audio AUD_CLKID_DDR_ARB>;
+                               };
+
+                               tdmin_a: audio-controller@300 {
+                                       compatible = "amlogic,g12a-tdmin",
+                                                    "amlogic,axg-tdmin";
+                                       reg = <0x0 0x300 0x0 0x40>;
+                                       sound-name-prefix = "TDMIN_A";
+                                       resets = <&clkc_audio AUD_RESET_TDMIN_A>;
+                                       clocks = <&clkc_audio AUD_CLKID_TDMIN_A>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_A_SCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_A_SCLK_SEL>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>;
+                                       clock-names = "pclk", "sclk", "sclk_sel",
+                                                     "lrclk", "lrclk_sel";
+                                       status = "disabled";
+                               };
+
+                               tdmin_b: audio-controller@340 {
+                                       compatible = "amlogic,g12a-tdmin",
+                                                    "amlogic,axg-tdmin";
+                                       reg = <0x0 0x340 0x0 0x40>;
+                                       sound-name-prefix = "TDMIN_B";
+                                       resets = <&clkc_audio AUD_RESET_TDMIN_B>;
+                                       clocks = <&clkc_audio AUD_CLKID_TDMIN_B>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_B_SCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_B_SCLK_SEL>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>;
+                                       clock-names = "pclk", "sclk", "sclk_sel",
+                                                     "lrclk", "lrclk_sel";
+                                       status = "disabled";
+                               };
+
+                               tdmin_c: audio-controller@380 {
+                                       compatible = "amlogic,g12a-tdmin",
+                                                    "amlogic,axg-tdmin";
+                                       reg = <0x0 0x380 0x0 0x40>;
+                                       sound-name-prefix = "TDMIN_C";
+                                       resets = <&clkc_audio AUD_RESET_TDMIN_C>;
+                                       clocks = <&clkc_audio AUD_CLKID_TDMIN_C>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_C_SCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_C_SCLK_SEL>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>;
+                                       clock-names = "pclk", "sclk", "sclk_sel",
+                                                     "lrclk", "lrclk_sel";
+                                       status = "disabled";
+                               };
+
+                               tdmin_lb: audio-controller@3c0 {
+                                       compatible = "amlogic,g12a-tdmin",
+                                                    "amlogic,axg-tdmin";
+                                       reg = <0x0 0x3c0 0x0 0x40>;
+                                       sound-name-prefix = "TDMIN_LB";
+                                       resets = <&clkc_audio AUD_RESET_TDMIN_LB>;
+                                       clocks = <&clkc_audio AUD_CLKID_TDMIN_LB>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK_SEL>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>;
+                                       clock-names = "pclk", "sclk", "sclk_sel",
+                                                     "lrclk", "lrclk_sel";
+                                       status = "disabled";
+                               };
+
+                               spdifin: audio-controller@400 {
+                                       compatible = "amlogic,g12a-spdifin",
+                                                    "amlogic,axg-spdifin";
+                                       reg = <0x0 0x400 0x0 0x30>;
+                                       #sound-dai-cells = <0>;
+                                       sound-name-prefix = "SPDIFIN";
+                                       interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
+                                       clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
+                                                <&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
+                                       clock-names = "pclk", "refclk";
+                                       status = "disabled";
+                               };
+
+                               spdifout: audio-controller@480 {
+                                       compatible = "amlogic,g12a-spdifout",
+                                                    "amlogic,axg-spdifout";
+                                       reg = <0x0 0x480 0x0 0x50>;
+                                       #sound-dai-cells = <0>;
+                                       sound-name-prefix = "SPDIFOUT";
+                                       clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
+                                                <&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
+                                       clock-names = "pclk", "mclk";
+                                       status = "disabled";
+                               };
+
+                               tdmout_a: audio-controller@500 {
+                                       compatible = "amlogic,g12a-tdmout";
+                                       reg = <0x0 0x500 0x0 0x40>;
+                                       sound-name-prefix = "TDMOUT_A";
+                                       resets = <&clkc_audio AUD_RESET_TDMOUT_A>;
+                                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
+                                                <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
+                                                <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>;
+                                       clock-names = "pclk", "sclk", "sclk_sel",
+                                                     "lrclk", "lrclk_sel";
+                                       status = "disabled";
+                               };
+
+                               tdmout_b: audio-controller@540 {
+                                       compatible = "amlogic,g12a-tdmout";
+                                       reg = <0x0 0x540 0x0 0x40>;
+                                       sound-name-prefix = "TDMOUT_B";
+                                       resets = <&clkc_audio AUD_RESET_TDMOUT_B>;
+                                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_B>,
+                                                <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK_SEL>,
+                                                <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>;
+                                       clock-names = "pclk", "sclk", "sclk_sel",
+                                                     "lrclk", "lrclk_sel";
+                                       status = "disabled";
+                               };
+
+                               tdmout_c: audio-controller@580 {
+                                       compatible = "amlogic,g12a-tdmout";
+                                       reg = <0x0 0x580 0x0 0x40>;
+                                       sound-name-prefix = "TDMOUT_C";
+                                       resets = <&clkc_audio AUD_RESET_TDMOUT_C>;
+                                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_C>,
+                                                <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK_SEL>,
+                                                <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>,
+                                                <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>;
+                                       clock-names = "pclk", "sclk", "sclk_sel",
+                                                     "lrclk", "lrclk_sel";
+                                       status = "disabled";
+                               };
+
+                               spdifout_b: audio-controller@680 {
+                                       compatible = "amlogic,g12a-spdifout",
+                                                    "amlogic,axg-spdifout";
+                                       reg = <0x0 0x680 0x0 0x50>;
+                                       #sound-dai-cells = <0>;
+                                       sound-name-prefix = "SPDIFOUT_B";
+                                       clocks = <&clkc_audio AUD_CLKID_SPDIFOUT_B>,
+                                                <&clkc_audio AUD_CLKID_SPDIFOUT_B_CLK>;
+                                       clock-names = "pclk", "mclk";
+                                       status = "disabled";
+                               };
+
+                               tohdmitx: audio-controller@744 {
+                                       compatible = "amlogic,g12a-tohdmitx";
+                                       reg = <0x0 0x744 0x0 0x4>;
+                                       #sound-dai-cells = <1>;
+                                       sound-name-prefix = "TOHDMITX";
+                                       status = "disabled";
+                               };
+                       };
+
+                       usb3_pcie_phy: phy@46000 {
+                               compatible = "amlogic,g12a-usb3-pcie-phy";
+                               reg = <0x0 0x46000 0x0 0x2000>;
+                               clocks = <&clkc CLKID_PCIE_PLL>;
+                               clock-names = "ref_clk";
+                               resets = <&reset RESET_PCIE_PHY>;
+                               reset-names = "phy";
+                               assigned-clocks = <&clkc CLKID_PCIE_PLL>;
+                               assigned-clock-rates = <100000000>;
+                               #phy-cells = <1>;
+                       };
+
+                       eth_phy: mdio-multiplexer@4c000 {
+                               compatible = "amlogic,g12a-mdio-mux";
+                               reg = <0x0 0x4c000 0x0 0xa4>;
+                               clocks = <&clkc CLKID_ETH_PHY>,
+                                        <&xtal>,
+                                        <&clkc CLKID_MPLL_50M>;
+                               clock-names = "pclk", "clkin0", "clkin1";
+                               mdio-parent-bus = <&mdio0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               ext_mdio: mdio@0 {
+                                       reg = <0>;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                               };
+
+                               int_mdio: mdio@1 {
+                                       reg = <1>;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       internal_ephy: ethernet_phy@8 {
+                                               compatible = "ethernet-phy-id0180.3301",
+                                                            "ethernet-phy-ieee802.3-c22";
+                                               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+                                               reg = <8>;
+                                               max-speed = <100>;
+                                       };
+                               };
+                       };
+               };
+
+               aobus: bus@ff800000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xff800000 0x0 0x100000>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xff800000 0x0 0x100000>;
+
+                       rti: sys-ctrl@0 {
+                               compatible = "amlogic,meson-gx-ao-sysctrl",
+                                            "simple-mfd", "syscon";
+                               reg = <0x0 0x0 0x0 0x100>;
+                               #address-cells = <2>;
+                               #size-cells = <2>;
+                               ranges = <0x0 0x0 0x0 0x0 0x0 0x100>;
+
+                               clkc_AO: clock-controller {
+                                       compatible = "amlogic,meson-g12a-aoclkc";
+                                       #clock-cells = <1>;
+                                       #reset-cells = <1>;
+                                       clocks = <&xtal>, <&clkc CLKID_CLK81>;
+                                       clock-names = "xtal", "mpeg-clk";
+                               };
+
+                               ao_pinctrl: pinctrl@14 {
+                                       compatible = "amlogic,meson-g12a-aobus-pinctrl";
+                                       #address-cells = <2>;
+                                       #size-cells = <2>;
+                                       ranges;
+
+                                       gpio_ao: bank@14 {
+                                               reg = <0x0 0x14 0x0 0x8>,
+                                                     <0x0 0x1c 0x0 0x8>,
+                                                     <0x0 0x24 0x0 0x14>;
+                                               reg-names = "mux",
+                                                           "ds",
+                                                           "gpio";
+                                               gpio-controller;
+                                               #gpio-cells = <2>;
+                                               gpio-ranges = <&ao_pinctrl 0 0 15>;
+                                       };
+
+                                       i2c_ao_sck_pins: i2c_ao_sck_pins {
+                                               mux {
+                                                       groups = "i2c_ao_sck";
+                                                       function = "i2c_ao";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c_ao_sda_pins: i2c_ao_sda {
+                                               mux {
+                                                       groups = "i2c_ao_sda";
+                                                       function = "i2c_ao";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c_ao_sck_e_pins: i2c_ao_sck_e {
+                                               mux {
+                                                       groups = "i2c_ao_sck_e";
+                                                       function = "i2c_ao";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       i2c_ao_sda_e_pins: i2c_ao_sda_e {
+                                               mux {
+                                                       groups = "i2c_ao_sda_e";
+                                                       function = "i2c_ao";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       mclk0_ao_pins: mclk0-ao {
+                                               mux {
+                                                       groups = "mclk0_ao";
+                                                       function = "mclk0_ao";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_ao_b_din0_pins: tdm-ao-b-din0 {
+                                               mux {
+                                                       groups = "tdm_ao_b_din0";
+                                                       function = "tdm_ao_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       spdif_ao_out_pins: spdif-ao-out {
+                                               mux {
+                                                       groups = "spdif_ao_out";
+                                                       function = "spdif_ao_out";
+                                                       drive-strength-microamp = <500>;
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_ao_b_din1_pins: tdm-ao-b-din1 {
+                                               mux {
+                                                       groups = "tdm_ao_b_din1";
+                                                       function = "tdm_ao_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_ao_b_din2_pins: tdm-ao-b-din2 {
+                                               mux {
+                                                       groups = "tdm_ao_b_din2";
+                                                       function = "tdm_ao_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_ao_b_dout0_pins: tdm-ao-b-dout0 {
+                                               mux {
+                                                       groups = "tdm_ao_b_dout0";
+                                                       function = "tdm_ao_b";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_ao_b_dout1_pins: tdm-ao-b-dout1 {
+                                               mux {
+                                                       groups = "tdm_ao_b_dout1";
+                                                       function = "tdm_ao_b";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_ao_b_dout2_pins: tdm-ao-b-dout2 {
+                                               mux {
+                                                       groups = "tdm_ao_b_dout2";
+                                                       function = "tdm_ao_b";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_ao_b_fs_pins: tdm-ao-b-fs {
+                                               mux {
+                                                       groups = "tdm_ao_b_fs";
+                                                       function = "tdm_ao_b";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_ao_b_sclk_pins: tdm-ao-b-sclk {
+                                               mux {
+                                                       groups = "tdm_ao_b_sclk";
+                                                       function = "tdm_ao_b";
+                                                       bias-disable;
+                                                       drive-strength-microamp = <3000>;
+                                               };
+                                       };
+
+                                       tdm_ao_b_slv_fs_pins: tdm-ao-b-slv-fs {
+                                               mux {
+                                                       groups = "tdm_ao_b_slv_fs";
+                                                       function = "tdm_ao_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       tdm_ao_b_slv_sclk_pins: tdm-ao-b-slv-sclk {
+                                               mux {
+                                                       groups = "tdm_ao_b_slv_sclk";
+                                                       function = "tdm_ao_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       uart_ao_a_pins: uart-a-ao {
+                                               mux {
+                                                       groups = "uart_ao_a_tx",
+                                                                "uart_ao_a_rx";
+                                                       function = "uart_ao_a";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       uart_ao_a_cts_rts_pins: uart-ao-a-cts-rts {
+                                               mux {
+                                                       groups = "uart_ao_a_cts",
+                                                                "uart_ao_a_rts";
+                                                       function = "uart_ao_a";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_a_e_pins: pwm-a-e {
+                                               mux {
+                                                       groups = "pwm_a_e";
+                                                       function = "pwm_a_e";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_ao_a_pins: pwm-ao-a {
+                                               mux {
+                                                       groups = "pwm_ao_a";
+                                                       function = "pwm_ao_a";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_ao_b_pins: pwm-ao-b {
+                                               mux {
+                                                       groups = "pwm_ao_b";
+                                                       function = "pwm_ao_b";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_ao_c_4_pins: pwm-ao-c-4 {
+                                               mux {
+                                                       groups = "pwm_ao_c_4";
+                                                       function = "pwm_ao_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_ao_c_6_pins: pwm-ao-c-6 {
+                                               mux {
+                                                       groups = "pwm_ao_c_6";
+                                                       function = "pwm_ao_c";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_ao_d_5_pins: pwm-ao-d-5 {
+                                               mux {
+                                                       groups = "pwm_ao_d_5";
+                                                       function = "pwm_ao_d";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_ao_d_10_pins: pwm-ao-d-10 {
+                                               mux {
+                                                       groups = "pwm_ao_d_10";
+                                                       function = "pwm_ao_d";
+                                                       bias-disable;
+                                               };
+                                       };
+
+                                       pwm_ao_d_e_pins: pwm-ao-d-e {
+                                               mux {
+                                                       groups = "pwm_ao_d_e";
+                                                       function = "pwm_ao_d";
+                                               };
+                                       };
+
+                                       remote_input_ao_pins: remote-input-ao {
+                                               mux {
+                                                       groups = "remote_ao_input";
+                                                       function = "remote_ao_input";
+                                                       bias-disable;
+                                               };
+                                       };
+                               };
+                       };
+
+                       vrtc: rtc@0a8 {
+                               compatible = "amlogic,meson-vrtc";
+                               reg = <0x0 0x000a8 0x0 0x4>;
+                       };
+
+                       cec_AO: cec@100 {
+                               compatible = "amlogic,meson-gx-ao-cec";
+                               reg = <0x0 0x00100 0x0 0x14>;
+                               interrupts = <GIC_SPI 199 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&clkc_AO CLKID_AO_CEC>;
+                               clock-names = "core";
+                               status = "disabled";
+                       };
+
+                       sec_AO: ao-secure@140 {
+                               compatible = "amlogic,meson-gx-ao-secure", "syscon";
+                               reg = <0x0 0x140 0x0 0x140>;
+                               amlogic,has-chip-id;
+                       };
+
+                       cecb_AO: cec@280 {
+                               compatible = "amlogic,meson-g12a-ao-cec";
+                               reg = <0x0 0x00280 0x0 0x1c>;
+                               interrupts = <GIC_SPI 203 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&clkc_AO CLKID_AO_CTS_OSCIN>;
+                               clock-names = "oscin";
+                               status = "disabled";
+                       };
+
+                       pwm_AO_cd: pwm@2000 {
+                               compatible = "amlogic,meson-g12a-ao-pwm-cd";
+                               reg = <0x0 0x2000 0x0 0x20>;
+                               #pwm-cells = <3>;
+                               status = "disabled";
+                       };
+
+                       uart_AO: serial@3000 {
+                               compatible = "amlogic,meson-gx-uart",
+                                            "amlogic,meson-ao-uart";
+                               reg = <0x0 0x3000 0x0 0x18>;
+                               interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&xtal>, <&clkc_AO CLKID_AO_UART>, <&xtal>;
+                               clock-names = "xtal", "pclk", "baud";
+                               status = "disabled";
+                       };
+
+                       uart_AO_B: serial@4000 {
+                               compatible = "amlogic,meson-gx-uart",
+                                            "amlogic,meson-ao-uart";
+                               reg = <0x0 0x4000 0x0 0x18>;
+                               interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&xtal>, <&clkc_AO CLKID_AO_UART2>, <&xtal>;
+                               clock-names = "xtal", "pclk", "baud";
+                               status = "disabled";
+                       };
+
+                       i2c_AO: i2c@5000 {
+                               compatible = "amlogic,meson-axg-i2c";
+                               status = "disabled";
+                               reg = <0x0 0x05000 0x0 0x20>;
+                               interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&clkc CLKID_I2C>;
+                       };
+
+                       pwm_AO_ab: pwm@7000 {
+                               compatible = "amlogic,meson-g12a-ao-pwm-ab";
+                               reg = <0x0 0x7000 0x0 0x20>;
+                               #pwm-cells = <3>;
+                               status = "disabled";
+                       };
+
+                       ir: ir@8000 {
+                               compatible = "amlogic,meson-gxbb-ir";
+                               reg = <0x0 0x8000 0x0 0x20>;
+                               interrupts = <GIC_SPI 196 IRQ_TYPE_EDGE_RISING>;
+                               status = "disabled";
+                       };
+
+                       saradc: adc@9000 {
+                               compatible = "amlogic,meson-g12a-saradc",
+                                            "amlogic,meson-saradc";
+                               reg = <0x0 0x9000 0x0 0x48>;
+                               #io-channel-cells = <1>;
+                               interrupts = <GIC_SPI 200 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&xtal>,
+                                        <&clkc_AO CLKID_AO_SAR_ADC>,
+                                        <&clkc_AO CLKID_AO_SAR_ADC_CLK>,
+                                        <&clkc_AO CLKID_AO_SAR_ADC_SEL>;
+                               clock-names = "clkin", "core", "adc_clk", "adc_sel";
+                               status = "disabled";
+                       };
+               };
+
+               vpu: vpu@ff900000 {
+                       compatible = "amlogic,meson-g12a-vpu";
+                       reg = <0x0 0xff900000 0x0 0x100000>,
+                             <0x0 0xff63c000 0x0 0x1000>;
+                       reg-names = "vpu", "hhi";
+                       interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       amlogic,canvas = <&canvas>;
+
+                       /* CVBS VDAC output port */
+                       cvbs_vdac_port: port@0 {
+                               reg = <0>;
+                       };
+
+                       /* HDMI-TX output port */
+                       hdmi_tx_port: port@1 {
+                               reg = <1>;
+
+                               hdmi_tx_out: endpoint {
+                                       remote-endpoint = <&hdmi_tx_in>;
+                               };
+                       };
+               };
+
+               gic: interrupt-controller@ffc01000 {
+                       compatible = "arm,gic-400";
+                       reg = <0x0 0xffc01000 0 0x1000>,
+                             <0x0 0xffc02000 0 0x2000>,
+                             <0x0 0xffc04000 0 0x2000>,
+                             <0x0 0xffc06000 0 0x2000>;
+                       interrupt-controller;
+                       interrupts = <GIC_PPI 9
+                               (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
+                       #interrupt-cells = <3>;
+                       #address-cells = <0>;
+               };
+
+               cbus: bus@ffd00000 {
+                       compatible = "simple-bus";
+                       reg = <0x0 0xffd00000 0x0 0x100000>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges = <0x0 0x0 0x0 0xffd00000 0x0 0x100000>;
+
+                       reset: reset-controller@1004 {
+                               compatible = "amlogic,meson-axg-reset";
+                               reg = <0x0 0x1004 0x0 0x9c>;
+                               #reset-cells = <1>;
+                       };
+
+                       gpio_intc: interrupt-controller@f080 {
+                               compatible = "amlogic,meson-g12a-gpio-intc",
+                                            "amlogic,meson-gpio-intc";
+                               reg = <0x0 0xf080 0x0 0x10>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>;
+                       };
+
+                       pwm_ef: pwm@19000 {
+                               compatible = "amlogic,meson-g12a-ee-pwm";
+                               reg = <0x0 0x19000 0x0 0x20>;
+                               #pwm-cells = <3>;
+                               status = "disabled";
+                       };
+
+                       pwm_cd: pwm@1a000 {
+                               compatible = "amlogic,meson-g12a-ee-pwm";
+                               reg = <0x0 0x1a000 0x0 0x20>;
+                               #pwm-cells = <3>;
+                               status = "disabled";
+                       };
+
+                       pwm_ab: pwm@1b000 {
+                               compatible = "amlogic,meson-g12a-ee-pwm";
+                               reg = <0x0 0x1b000 0x0 0x20>;
+                               #pwm-cells = <3>;
+                               status = "disabled";
+                       };
+
+                       i2c3: i2c@1c000 {
+                               compatible = "amlogic,meson-axg-i2c";
+                               status = "disabled";
+                               reg = <0x0 0x1c000 0x0 0x20>;
+                               interrupts = <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&clkc CLKID_I2C>;
+                       };
+
+                       i2c2: i2c@1d000 {
+                               compatible = "amlogic,meson-axg-i2c";
+                               status = "disabled";
+                               reg = <0x0 0x1d000 0x0 0x20>;
+                               interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&clkc CLKID_I2C>;
+                       };
+
+                       i2c1: i2c@1e000 {
+                               compatible = "amlogic,meson-axg-i2c";
+                               status = "disabled";
+                               reg = <0x0 0x1e000 0x0 0x20>;
+                               interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&clkc CLKID_I2C>;
+                       };
+
+                       i2c0: i2c@1f000 {
+                               compatible = "amlogic,meson-axg-i2c";
+                               status = "disabled";
+                               reg = <0x0 0x1f000 0x0 0x20>;
+                               interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               clocks = <&clkc CLKID_I2C>;
+                       };
+
+                       clk_msr: clock-measure@18000 {
+                               compatible = "amlogic,meson-g12a-clk-measure";
+                               reg = <0x0 0x18000 0x0 0x10>;
+                       };
+
+                       uart_C: serial@22000 {
+                               compatible = "amlogic,meson-gx-uart";
+                               reg = <0x0 0x22000 0x0 0x18>;
+                               interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>;
+                               clock-names = "xtal", "pclk", "baud";
+                               status = "disabled";
+                       };
+
+                       uart_B: serial@23000 {
+                               compatible = "amlogic,meson-gx-uart";
+                               reg = <0x0 0x23000 0x0 0x18>;
+                               interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>;
+                               clock-names = "xtal", "pclk", "baud";
+                               status = "disabled";
+                       };
+
+                       uart_A: serial@24000 {
+                               compatible = "amlogic,meson-gx-uart";
+                               reg = <0x0 0x24000 0x0 0x18>;
+                               interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
+                               clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>;
+                               clock-names = "xtal", "pclk", "baud";
+                               status = "disabled";
+                       };
+               };
+
+               sd_emmc_a: sd@ffe03000 {
+                       compatible = "amlogic,meson-axg-mmc";
+                       reg = <0x0 0xffe03000 0x0 0x800>;
+                       interrupts = <GIC_SPI 189 IRQ_TYPE_EDGE_RISING>;
+                       status = "disabled";
+                       clocks = <&clkc CLKID_SD_EMMC_A>,
+                                <&clkc CLKID_SD_EMMC_A_CLK0>,
+                                <&clkc CLKID_FCLK_DIV2>;
+                       clock-names = "core", "clkin0", "clkin1";
+                       resets = <&reset RESET_SD_EMMC_A>;
+               };
+
+               sd_emmc_b: sd@ffe05000 {
+                       compatible = "amlogic,meson-axg-mmc";
+                       reg = <0x0 0xffe05000 0x0 0x800>;
+                       interrupts = <GIC_SPI 190 IRQ_TYPE_EDGE_RISING>;
+                       status = "disabled";
+                       clocks = <&clkc CLKID_SD_EMMC_B>,
+                                <&clkc CLKID_SD_EMMC_B_CLK0>,
+                                <&clkc CLKID_FCLK_DIV2>;
+                       clock-names = "core", "clkin0", "clkin1";
+                       resets = <&reset RESET_SD_EMMC_B>;
+               };
+
+               sd_emmc_c: mmc@ffe07000 {
+                       compatible = "amlogic,meson-axg-mmc";
+                       reg = <0x0 0xffe07000 0x0 0x800>;
+                       interrupts = <GIC_SPI 191 IRQ_TYPE_EDGE_RISING>;
+                       status = "disabled";
+                       clocks = <&clkc CLKID_SD_EMMC_C>,
+                                <&clkc CLKID_SD_EMMC_C_CLK0>,
+                                <&clkc CLKID_FCLK_DIV2>;
+                       clock-names = "core", "clkin0", "clkin1";
+                       resets = <&reset RESET_SD_EMMC_C>;
+               };
+
+               usb: usb@ffe09000 {
+                       status = "disabled";
+                       compatible = "amlogic,meson-g12a-usb-ctrl";
+                       reg = <0x0 0xffe09000 0x0 0xa0>;
+                       interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+
+                       clocks = <&clkc CLKID_USB>;
+                       resets = <&reset RESET_USB>;
+
+                       dr_mode = "otg";
+
+                       phys = <&usb2_phy0>, <&usb2_phy1>,
+                              <&usb3_pcie_phy PHY_TYPE_USB3>;
+                       phy-names = "usb2-phy0", "usb2-phy1", "usb3-phy0";
+
+                       dwc2: usb@ff400000 {
+                               compatible = "amlogic,meson-g12a-usb", "snps,dwc2";
+                               reg = <0x0 0xff400000 0x0 0x40000>;
+                               interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clkc CLKID_USB1_DDR_BRIDGE>;
+                               clock-names = "ddr";
+                               phys = <&usb2_phy1>;
+                               phy-names = "usb2-phy";
+                               dr_mode = "peripheral";
+                               g-rx-fifo-size = <192>;
+                               g-np-tx-fifo-size = <128>;
+                               g-tx-fifo-size = <128 128 16 16 16>;
+                       };
+
+                       dwc3: usb@ff500000 {
+                               compatible = "snps,dwc3";
+                               reg = <0x0 0xff500000 0x0 0x100000>;
+                               interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                               dr_mode = "host";
+                               snps,dis_u2_susphy_quirk;
+                               snps,quirk-frame-length-adjustment;
+                       };
+               };
+
+               mali: gpu@ffe40000 {
+                       compatible = "amlogic,meson-g12a-mali", "arm,mali-bifrost";
+                       reg = <0x0 0xffe40000 0x0 0x40000>;
+                       interrupt-parent = <&gic>;
+                       interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "gpu", "mmu", "job";
+                       clocks = <&clkc CLKID_MALI>;
+                       resets = <&reset RESET_DVALIN_CAPB3>, <&reset RESET_DVALIN>;
+
+                       /*
+                        * Mali clocking is provided by two identical clock paths
+                        * MALI_0 and MALI_1 muxed to a single clock by a glitch
+                        * free mux to safely change frequency while running.
+                        */
+                       assigned-clocks = <&clkc CLKID_MALI_0_SEL>,
+                                         <&clkc CLKID_MALI_0>,
+                                         <&clkc CLKID_MALI>; /* Glitch free mux */
+                       assigned-clock-parents = <&clkc CLKID_FCLK_DIV2P5>,
+                                                <0>, /* Do Nothing */
+                                                <&clkc CLKID_MALI_0>;
+                       assigned-clock-rates = <0>, /* Do Nothing */
+                                              <800000000>,
+                                              <0>; /* Do Nothing */
+               };
+       };
+
+       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)>;
+               arm,no-tick-in-suspend;
+       };
+
+       xtal: xtal-clk {
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+               clock-output-names = "xtal";
+               #clock-cells = <0>;
+       };
+
+};
index c7a8736..c9fa23a 100644 (file)
                enable-active-high;
        };
 
+       vddcpu: regulator-vddcpu {
+               /*
+                * SY8120B1ABC DC/DC Regulator.
+                */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDCPU";
+               regulator-min-microvolt = <721000>;
+               regulator-max-microvolt = <1022000>;
+
+               vin-supply = <&dc_in>;
+
+               pwms = <&pwm_AO_cd 1 1250 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
        vddio_ao1v8: regulator-vddio_ao1v8 {
                compatible = "regulator-fixed";
                regulator-name = "VDDIO_AO1V8";
        status = "okay";
 };
 
+&cpu0 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu1 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu2 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu3 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
 &cvbs_vdac_port {
        cvbs_vdac_out: endpoint {
                remote-endpoint = <&cvbs_connector_in>;
        pinctrl-names = "default";
 };
 
+&ir {
+       status = "okay";
+       pinctrl-0 = <&remote_input_ao_pins>;
+       pinctrl-names = "default";
+};
+
+&pwm_AO_cd {
+       pinctrl-0 = <&pwm_ao_d_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin1";
+       status = "okay";
+};
+
 &pwm_ef {
        status = "okay";
        pinctrl-0 = <&pwm_e_pins>;
index 8551fbd..2a324f0 100644 (file)
                regulator-always-on;
        };
 
+       vddcpu: regulator-vddcpu {
+               /*
+                * MP8756GD Regulator.
+                */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDCPU";
+               regulator-min-microvolt = <721000>;
+               regulator-max-microvolt = <1022000>;
+
+               vin-supply = <&main_12v>;
+
+               pwms = <&pwm_AO_cd 1 1250 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
 };
 
 &cec_AO {
        hdmi-phandle = <&hdmi_tx>;
 };
 
+&cpu0 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu1 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu2 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu3 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
 &cvbs_vdac_port {
        cvbs_vdac_out: endpoint {
                remote-endpoint = <&cvbs_connector_in>;
        pinctrl-names = "default";
 };
 
+&pwm_AO_cd {
+       pinctrl-0 = <&pwm_ao_d_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin1";
+       status = "okay";
+};
+
 /* SD card */
 &sd_emmc_b {
        status = "okay";
index fe4013c..17155fb 100644 (file)
@@ -11,7 +11,7 @@
 #include <dt-bindings/sound/meson-g12a-tohdmitx.h>
 
 / {
-       compatible = "amediatech,x96-max", "amlogic,u200", "amlogic,g12a";
+       compatible = "amediatech,x96-max", "amlogic,g12a";
        model = "Shenzhen Amediatech Technology Co., Ltd X96 Max";
 
        aliases {
                regulator-always-on;
        };
 
+       vddcpu: regulator-vddcpu {
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDCPU";
+               regulator-min-microvolt = <721000>;
+               regulator-max-microvolt = <1022000>;
+
+               vin-supply = <&dc_in>;
+
+               pwms = <&pwm_AO_cd 1 1250 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
        sound {
                compatible = "amlogic,axg-sound-card";
                model = "G12A-X96-MAX";
        status = "okay";
 };
 
+&cpu0 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu1 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu2 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu3 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
 &cvbs_vdac_port {
        cvbs_vdac_out: endpoint {
                remote-endpoint = <&cvbs_connector_in>;
        status = "okay";
        pinctrl-0 = <&remote_input_ao_pins>;
        pinctrl-names = "default";
+       linux,rc-map-name = "rc-x96max";
+};
+
+&pwm_AO_cd {
+       pinctrl-0 = <&pwm_ao_d_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin1";
+       status = "okay";
 };
 
 &ext_mdio {
index f8d43e3..eb5d177 100644 (file)
@@ -3,56 +3,12 @@
  * Copyright (c) 2018 Amlogic, Inc. All rights reserved.
  */
 
-#include <dt-bindings/phy/phy.h>
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/clock/axg-audio-clkc.h>
-#include <dt-bindings/clock/g12a-clkc.h>
-#include <dt-bindings/clock/g12a-aoclkc.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-#include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h>
-#include <dt-bindings/reset/amlogic,meson-g12a-reset.h>
+#include "meson-g12-common.dtsi"
+#include <dt-bindings/power/meson-g12a-power.h>
 
 / {
        compatible = "amlogic,g12a";
 
-       interrupt-parent = <&gic>;
-       #address-cells = <2>;
-       #size-cells = <2>;
-
-       tdmif_a: audio-controller-0 {
-               compatible = "amlogic,axg-tdm-iface";
-               #sound-dai-cells = <0>;
-               sound-name-prefix = "TDM_A";
-               clocks = <&clkc_audio AUD_CLKID_MST_A_MCLK>,
-                        <&clkc_audio AUD_CLKID_MST_A_SCLK>,
-                        <&clkc_audio AUD_CLKID_MST_A_LRCLK>;
-               clock-names = "mclk", "sclk", "lrclk";
-               status = "disabled";
-       };
-
-       tdmif_b: audio-controller-1 {
-               compatible = "amlogic,axg-tdm-iface";
-               #sound-dai-cells = <0>;
-               sound-name-prefix = "TDM_B";
-               clocks = <&clkc_audio AUD_CLKID_MST_B_MCLK>,
-                        <&clkc_audio AUD_CLKID_MST_B_SCLK>,
-                        <&clkc_audio AUD_CLKID_MST_B_LRCLK>;
-               clock-names = "mclk", "sclk", "lrclk";
-               status = "disabled";
-       };
-
-       tdmif_c: audio-controller-2 {
-               compatible = "amlogic,axg-tdm-iface";
-               #sound-dai-cells = <0>;
-               sound-name-prefix = "TDM_C";
-               clocks = <&clkc_audio AUD_CLKID_MST_C_MCLK>,
-                        <&clkc_audio AUD_CLKID_MST_C_SCLK>,
-                        <&clkc_audio AUD_CLKID_MST_C_LRCLK>;
-               clock-names = "mclk", "sclk", "lrclk";
-               status = "disabled";
-       };
-
        cpus {
                #address-cells = <0x2>;
                #size-cells = <0x0>;
                };
        };
 
-       efuse: efuse {
-               compatible = "amlogic,meson-gxbb-efuse";
-               clocks = <&clkc CLKID_EFUSE>;
-               #address-cells = <1>;
-               #size-cells = <1>;
-               read-only;
-       };
+       cpu_opp_table: opp-table {
+               compatible = "operating-points-v2";
+               opp-shared;
 
-       psci {
-               compatible = "arm,psci-1.0";
-               method = "smc";
-       };
-
-       reserved-memory {
-               #address-cells = <2>;
-               #size-cells = <2>;
-               ranges;
-
-               /* 3 MiB reserved for ARM Trusted Firmware (BL31) */
-               secmon_reserved: secmon@5000000 {
-                       reg = <0x0 0x05000000 0x0 0x300000>;
-                       no-map;
+               opp-100000000 {
+                       opp-hz = /bits/ 64 <100000000>;
+                       opp-microvolt = <731000>;
                };
 
-               linux,cma {
-                       compatible = "shared-dma-pool";
-                       reusable;
-                       size = <0x0 0x10000000>;
-                       alignment = <0x0 0x400000>;
-                       linux,cma-default;
+               opp-250000000 {
+                       opp-hz = /bits/ 64 <250000000>;
+                       opp-microvolt = <731000>;
                };
-       };
-
-       sm: secure-monitor {
-               compatible = "amlogic,meson-gxbb-sm";
-       };
-
-       soc {
-               compatible = "simple-bus";
-               #address-cells = <2>;
-               #size-cells = <2>;
-               ranges;
 
-               ethmac: ethernet@ff3f0000 {
-                       compatible = "amlogic,meson-axg-dwmac",
-                                    "snps,dwmac-3.70a",
-                                    "snps,dwmac";
-                       reg = <0x0 0xff3f0000 0x0 0x10000
-                              0x0 0xff634540 0x0 0x8>;
-                       interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "macirq";
-                       clocks = <&clkc CLKID_ETH>,
-                                <&clkc CLKID_FCLK_DIV2>,
-                                <&clkc CLKID_MPLL2>;
-                       clock-names = "stmmaceth", "clkin0", "clkin1";
-                       status = "disabled";
-
-                       mdio0: mdio {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               compatible = "snps,dwmac-mdio";
-                       };
+               opp-500000000 {
+                       opp-hz = /bits/ 64 <500000000>;
+                       opp-microvolt = <731000>;
                };
 
-               apb: bus@ff600000 {
-                       compatible = "simple-bus";
-                       reg = <0x0 0xff600000 0x0 0x200000>;
-                       #address-cells = <2>;
-                       #size-cells = <2>;
-                       ranges = <0x0 0x0 0x0 0xff600000 0x0 0x200000>;
-
-                       hdmi_tx: hdmi-tx@0 {
-                               compatible = "amlogic,meson-g12a-dw-hdmi";
-                               reg = <0x0 0x0 0x0 0x10000>;
-                               interrupts = <GIC_SPI 57 IRQ_TYPE_EDGE_RISING>;
-                               resets = <&reset RESET_HDMITX_CAPB3>,
-                                        <&reset RESET_HDMITX_PHY>,
-                                        <&reset RESET_HDMITX>;
-                               reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy";
-                               clocks = <&clkc CLKID_HDMI>,
-                                        <&clkc CLKID_HTX_PCLK>,
-                                        <&clkc CLKID_VPU_INTR>;
-                               clock-names = "isfr", "iahb", "venci";
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               #sound-dai-cells = <0>;
-                               status = "disabled";
-
-                               /* VPU VENC Input */
-                               hdmi_tx_venc_port: port@0 {
-                                       reg = <0>;
-
-                                       hdmi_tx_in: endpoint {
-                                               remote-endpoint = <&hdmi_tx_out>;
-                                       };
-                               };
-
-                               /* TMDS Output */
-                               hdmi_tx_tmds_port: port@1 {
-                                       reg = <1>;
-                               };
-                       };
-
-                       apb_efuse: bus@30000 {
-                               compatible = "simple-bus";
-                               reg = <0x0 0x30000 0x0 0x2000>;
-                               #address-cells = <2>;
-                               #size-cells = <2>;
-                               ranges = <0x0 0x0 0x0 0x30000 0x0 0x2000>;
-
-                               hwrng: rng@218 {
-                                       compatible = "amlogic,meson-rng";
-                                       reg = <0x0 0x218 0x0 0x4>;
-                               };
-                       };
-
-                       periphs: bus@34400 {
-                               compatible = "simple-bus";
-                               reg = <0x0 0x34400 0x0 0x400>;
-                               #address-cells = <2>;
-                               #size-cells = <2>;
-                               ranges = <0x0 0x0 0x0 0x34400 0x0 0x400>;
-
-                               periphs_pinctrl: pinctrl@40 {
-                                       compatible = "amlogic,meson-g12a-periphs-pinctrl";
-                                       #address-cells = <2>;
-                                       #size-cells = <2>;
-                                       ranges;
-
-                                       gpio: bank@40 {
-                                               reg = <0x0 0x40  0x0 0x4c>,
-                                                     <0x0 0xe8  0x0 0x18>,
-                                                     <0x0 0x120 0x0 0x18>,
-                                                     <0x0 0x2c0 0x0 0x40>,
-                                                     <0x0 0x340 0x0 0x1c>;
-                                               reg-names = "gpio",
-                                                           "pull",
-                                                           "pull-enable",
-                                                           "mux",
-                                                           "ds";
-                                               gpio-controller;
-                                               #gpio-cells = <2>;
-                                               gpio-ranges = <&periphs_pinctrl 0 0 86>;
-                                       };
-
-                                       cec_ao_a_h_pins: cec_ao_a_h {
-                                               mux {
-                                                       groups = "cec_ao_a_h";
-                                                       function = "cec_ao_a_h";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       cec_ao_b_h_pins: cec_ao_b_h {
-                                               mux {
-                                                       groups = "cec_ao_b_h";
-                                                       function = "cec_ao_b_h";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       emmc_pins: emmc {
-                                               mux-0 {
-                                                       groups = "emmc_nand_d0",
-                                                                "emmc_nand_d1",
-                                                                "emmc_nand_d2",
-                                                                "emmc_nand_d3",
-                                                                "emmc_nand_d4",
-                                                                "emmc_nand_d5",
-                                                                "emmc_nand_d6",
-                                                                "emmc_nand_d7",
-                                                                "emmc_cmd";
-                                                       function = "emmc";
-                                                       bias-pull-up;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-
-                                               mux-1 {
-                                                       groups = "emmc_clk";
-                                                       function = "emmc";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-                                       };
-
-                                       emmc_ds_pins: emmc-ds {
-                                               mux {
-                                                       groups = "emmc_nand_ds";
-                                                       function = "emmc";
-                                                       bias-pull-down;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-                                       };
-
-                                       emmc_clk_gate_pins: emmc_clk_gate {
-                                               mux {
-                                                       groups = "BOOT_8";
-                                                       function = "gpio_periphs";
-                                                       bias-pull-down;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-                                       };
-
-                                       hdmitx_ddc_pins: hdmitx_ddc {
-                                               mux {
-                                                       groups = "hdmitx_sda",
-                                                                "hdmitx_sck";
-                                                       function = "hdmitx";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-                                       };
-
-                                       hdmitx_hpd_pins: hdmitx_hpd {
-                                               mux {
-                                                       groups = "hdmitx_hpd_in";
-                                                       function = "hdmitx";
-                                                       bias-disable;
-                                               };
-                                       };
-
-
-                                       i2c0_sda_c_pins: i2c0-sda-c {
-                                               mux {
-                                                       groups = "i2c0_sda_c";
-                                                       function = "i2c0";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-
-                                               };
-                                       };
-
-                                       i2c0_sck_c_pins: i2c0-sck-c {
-                                               mux {
-                                                       groups = "i2c0_sck_c";
-                                                       function = "i2c0";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c0_sda_z0_pins: i2c0-sda-z0 {
-                                               mux {
-                                                       groups = "i2c0_sda_z0";
-                                                       function = "i2c0";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c0_sck_z1_pins: i2c0-sck-z1 {
-                                               mux {
-                                                       groups = "i2c0_sck_z1";
-                                                       function = "i2c0";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c0_sda_z7_pins: i2c0-sda-z7 {
-                                               mux {
-                                                       groups = "i2c0_sda_z7";
-                                                       function = "i2c0";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c0_sda_z8_pins: i2c0-sda-z8 {
-                                               mux {
-                                                       groups = "i2c0_sda_z8";
-                                                       function = "i2c0";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c1_sda_x_pins: i2c1-sda-x {
-                                               mux {
-                                                       groups = "i2c1_sda_x";
-                                                       function = "i2c1";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c1_sck_x_pins: i2c1-sck-x {
-                                               mux {
-                                                       groups = "i2c1_sck_x";
-                                                       function = "i2c1";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c1_sda_h2_pins: i2c1-sda-h2 {
-                                               mux {
-                                                       groups = "i2c1_sda_h2";
-                                                       function = "i2c1";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c1_sck_h3_pins: i2c1-sck-h3 {
-                                               mux {
-                                                       groups = "i2c1_sck_h3";
-                                                       function = "i2c1";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c1_sda_h6_pins: i2c1-sda-h6 {
-                                               mux {
-                                                       groups = "i2c1_sda_h6";
-                                                       function = "i2c1";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c1_sck_h7_pins: i2c1-sck-h7 {
-                                               mux {
-                                                       groups = "i2c1_sck_h7";
-                                                       function = "i2c1";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c2_sda_x_pins: i2c2-sda-x {
-                                               mux {
-                                                       groups = "i2c2_sda_x";
-                                                       function = "i2c2";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c2_sck_x_pins: i2c2-sck-x {
-                                               mux {
-                                                       groups = "i2c2_sck_x";
-                                                       function = "i2c2";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c2_sda_z_pins: i2c2-sda-z {
-                                               mux {
-                                                       groups = "i2c2_sda_z";
-                                                       function = "i2c2";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c2_sck_z_pins: i2c2-sck-z {
-                                               mux {
-                                                       groups = "i2c2_sck_z";
-                                                       function = "i2c2";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c3_sda_h_pins: i2c3-sda-h {
-                                               mux {
-                                                       groups = "i2c3_sda_h";
-                                                       function = "i2c3";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c3_sck_h_pins: i2c3-sck-h {
-                                               mux {
-                                                       groups = "i2c3_sck_h";
-                                                       function = "i2c3";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c3_sda_a_pins: i2c3-sda-a {
-                                               mux {
-                                                       groups = "i2c3_sda_a";
-                                                       function = "i2c3";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c3_sck_a_pins: i2c3-sck-a {
-                                               mux {
-                                                       groups = "i2c3_sck_a";
-                                                       function = "i2c3";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       mclk0_a_pins: mclk0-a {
-                                               mux {
-                                                       groups = "mclk0_a";
-                                                       function = "mclk0";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       mclk1_a_pins: mclk1-a {
-                                               mux {
-                                                       groups = "mclk1_a";
-                                                       function = "mclk1";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       mclk1_x_pins: mclk1-x {
-                                               mux {
-                                                       groups = "mclk1_x";
-                                                       function = "mclk1";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       mclk1_z_pins: mclk1-z {
-                                               mux {
-                                                       groups = "mclk1_z";
-                                                       function = "mclk1";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       pdm_din0_a_pins: pdm-din0-a {
-                                               mux {
-                                                       groups = "pdm_din0_a";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din0_c_pins: pdm-din0-c {
-                                               mux {
-                                                       groups = "pdm_din0_c";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din0_x_pins: pdm-din0-x {
-                                               mux {
-                                                       groups = "pdm_din0_x";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din0_z_pins: pdm-din0-z {
-                                               mux {
-                                                       groups = "pdm_din0_z";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din1_a_pins: pdm-din1-a {
-                                               mux {
-                                                       groups = "pdm_din1_a";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din1_c_pins: pdm-din1-c {
-                                               mux {
-                                                       groups = "pdm_din1_c";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din1_x_pins: pdm-din1-x {
-                                               mux {
-                                                       groups = "pdm_din1_x";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din1_z_pins: pdm-din1-z {
-                                               mux {
-                                                       groups = "pdm_din1_z";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din2_a_pins: pdm-din2-a {
-                                               mux {
-                                                       groups = "pdm_din2_a";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din2_c_pins: pdm-din2-c {
-                                               mux {
-                                                       groups = "pdm_din2_c";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din2_x_pins: pdm-din2-x {
-                                               mux {
-                                                       groups = "pdm_din2_x";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din2_z_pins: pdm-din2-z {
-                                               mux {
-                                                       groups = "pdm_din2_z";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din3_a_pins: pdm-din3-a {
-                                               mux {
-                                                       groups = "pdm_din3_a";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din3_c_pins: pdm-din3-c {
-                                               mux {
-                                                       groups = "pdm_din3_c";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din3_x_pins: pdm-din3-x {
-                                               mux {
-                                                       groups = "pdm_din3_x";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_din3_z_pins: pdm-din3-z {
-                                               mux {
-                                                       groups = "pdm_din3_z";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pdm_dclk_a_pins: pdm-dclk-a {
-                                               mux {
-                                                       groups = "pdm_dclk_a";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <500>;
-                                               };
-                                       };
-
-                                       pdm_dclk_c_pins: pdm-dclk-c {
-                                               mux {
-                                                       groups = "pdm_dclk_c";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <500>;
-                                               };
-                                       };
-
-                                       pdm_dclk_x_pins: pdm-dclk-x {
-                                               mux {
-                                                       groups = "pdm_dclk_x";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <500>;
-                                               };
-                                       };
-
-                                       pdm_dclk_z_pins: pdm-dclk-z {
-                                               mux {
-                                                       groups = "pdm_dclk_z";
-                                                       function = "pdm";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <500>;
-                                               };
-                                       };
-
-                                       pwm_a_pins: pwm-a {
-                                               mux {
-                                                       groups = "pwm_a";
-                                                       function = "pwm_a";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_b_x7_pins: pwm-b-x7 {
-                                               mux {
-                                                       groups = "pwm_b_x7";
-                                                       function = "pwm_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_b_x19_pins: pwm-b-x19 {
-                                               mux {
-                                                       groups = "pwm_b_x19";
-                                                       function = "pwm_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_c_c_pins: pwm-c-c {
-                                               mux {
-                                                       groups = "pwm_c_c";
-                                                       function = "pwm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_c_x5_pins: pwm-c-x5 {
-                                               mux {
-                                                       groups = "pwm_c_x5";
-                                                       function = "pwm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_c_x8_pins: pwm-c-x8 {
-                                               mux {
-                                                       groups = "pwm_c_x8";
-                                                       function = "pwm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_d_x3_pins: pwm-d-x3 {
-                                               mux {
-                                                       groups = "pwm_d_x3";
-                                                       function = "pwm_d";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_d_x6_pins: pwm-d-x6 {
-                                               mux {
-                                                       groups = "pwm_d_x6";
-                                                       function = "pwm_d";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_e_pins: pwm-e {
-                                               mux {
-                                                       groups = "pwm_e";
-                                                       function = "pwm_e";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_f_x_pins: pwm-f-x {
-                                               mux {
-                                                       groups = "pwm_f_x";
-                                                       function = "pwm_f";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_f_h_pins: pwm-f-h {
-                                               mux {
-                                                       groups = "pwm_f_h";
-                                                       function = "pwm_f";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       sdcard_c_pins: sdcard_c {
-                                               mux-0 {
-                                                       groups = "sdcard_d0_c",
-                                                                "sdcard_d1_c",
-                                                                "sdcard_d2_c",
-                                                                "sdcard_d3_c",
-                                                                "sdcard_cmd_c";
-                                                       function = "sdcard";
-                                                       bias-pull-up;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-
-                                               mux-1 {
-                                                       groups = "sdcard_clk_c";
-                                                       function = "sdcard";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-                                       };
-
-                                       sdcard_clk_gate_c_pins: sdcard_clk_gate_c {
-                                               mux {
-                                                       groups = "GPIOC_4";
-                                                       function = "gpio_periphs";
-                                                       bias-pull-down;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-                                       };
-
-                                       sdcard_z_pins: sdcard_z {
-                                               mux-0 {
-                                                       groups = "sdcard_d0_z",
-                                                                "sdcard_d1_z",
-                                                                "sdcard_d2_z",
-                                                                "sdcard_d3_z",
-                                                                "sdcard_cmd_z";
-                                                       function = "sdcard";
-                                                       bias-pull-up;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-
-                                               mux-1 {
-                                                       groups = "sdcard_clk_z";
-                                                       function = "sdcard";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-                                       };
-
-                                       sdcard_clk_gate_z_pins: sdcard_clk_gate_z {
-                                               mux {
-                                                       groups = "GPIOZ_6";
-                                                       function = "gpio_periphs";
-                                                       bias-pull-down;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-                                       };
-
-                                       sdio_pins: sdio {
-                                               mux {
-                                                       groups = "sdio_d0",
-                                                                "sdio_d1",
-                                                                "sdio_d2",
-                                                                "sdio_d3",
-                                                                "sdio_clk",
-                                                                "sdio_cmd";
-                                                       function = "sdio";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-                                       };
-
-                                       sdio_clk_gate_pins: sdio_clk_gate {
-                                               mux {
-                                                       groups = "GPIOX_4";
-                                                       function = "gpio_periphs";
-                                                       bias-pull-down;
-                                                       drive-strength-microamp = <4000>;
-                                               };
-                                       };
-
-                                       spdif_in_a10_pins: spdif-in-a10 {
-                                               mux {
-                                                       groups = "spdif_in_a10";
-                                                       function = "spdif_in";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       spdif_in_a12_pins: spdif-in-a12 {
-                                               mux {
-                                                       groups = "spdif_in_a12";
-                                                       function = "spdif_in";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       spdif_in_h_pins: spdif-in-h {
-                                               mux {
-                                                       groups = "spdif_in_h";
-                                                       function = "spdif_in";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       spdif_out_h_pins: spdif-out-h {
-                                               mux {
-                                                       groups = "spdif_out_h";
-                                                       function = "spdif_out";
-                                                       drive-strength-microamp = <500>;
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       spdif_out_a11_pins: spdif-out-a11 {
-                                               mux {
-                                                       groups = "spdif_out_a11";
-                                                       function = "spdif_out";
-                                                       drive-strength-microamp = <500>;
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       spdif_out_a13_pins: spdif-out-a13 {
-                                               mux {
-                                                       groups = "spdif_out_a13";
-                                                       function = "spdif_out";
-                                                       drive-strength-microamp = <500>;
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_a_din0_pins: tdm-a-din0 {
-                                               mux {
-                                                       groups = "tdm_a_din0";
-                                                       function = "tdm_a";
-                                                       bias-disable;
-                                               };
-                                       };
-
-
-                                       tdm_a_din1_pins: tdm-a-din1 {
-                                               mux {
-                                                       groups = "tdm_a_din1";
-                                                       function = "tdm_a";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_a_dout0_pins: tdm-a-dout0 {
-                                               mux {
-                                                       groups = "tdm_a_dout0";
-                                                       function = "tdm_a";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_a_dout1_pins: tdm-a-dout1 {
-                                               mux {
-                                                       groups = "tdm_a_dout1";
-                                                       function = "tdm_a";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_a_fs_pins: tdm-a-fs {
-                                               mux {
-                                                       groups = "tdm_a_fs";
-                                                       function = "tdm_a";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_a_sclk_pins: tdm-a-sclk {
-                                               mux {
-                                                       groups = "tdm_a_sclk";
-                                                       function = "tdm_a";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_a_slv_fs_pins: tdm-a-slv-fs {
-                                               mux {
-                                                       groups = "tdm_a_slv_fs";
-                                                       function = "tdm_a";
-                                                       bias-disable;
-                                               };
-                                       };
-
-
-                                       tdm_a_slv_sclk_pins: tdm-a-slv-sclk {
-                                               mux {
-                                                       groups = "tdm_a_slv_sclk";
-                                                       function = "tdm_a";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_b_din0_pins: tdm-b-din0 {
-                                               mux {
-                                                       groups = "tdm_b_din0";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_b_din1_pins: tdm-b-din1 {
-                                               mux {
-                                                       groups = "tdm_b_din1";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_b_din2_pins: tdm-b-din2 {
-                                               mux {
-                                                       groups = "tdm_b_din2";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_b_din3_a_pins: tdm-b-din3-a {
-                                               mux {
-                                                       groups = "tdm_b_din3_a";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_b_din3_h_pins: tdm-b-din3-h {
-                                               mux {
-                                                       groups = "tdm_b_din3_h";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_b_dout0_pins: tdm-b-dout0 {
-                                               mux {
-                                                       groups = "tdm_b_dout0";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_b_dout1_pins: tdm-b-dout1 {
-                                               mux {
-                                                       groups = "tdm_b_dout1";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_b_dout2_pins: tdm-b-dout2 {
-                                               mux {
-                                                       groups = "tdm_b_dout2";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_b_dout3_a_pins: tdm-b-dout3-a {
-                                               mux {
-                                                       groups = "tdm_b_dout3_a";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_b_dout3_h_pins: tdm-b-dout3-h {
-                                               mux {
-                                                       groups = "tdm_b_dout3_h";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_b_fs_pins: tdm-b-fs {
-                                               mux {
-                                                       groups = "tdm_b_fs";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_b_sclk_pins: tdm-b-sclk {
-                                               mux {
-                                                       groups = "tdm_b_sclk";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_b_slv_fs_pins: tdm-b-slv-fs {
-                                               mux {
-                                                       groups = "tdm_b_slv_fs";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_b_slv_sclk_pins: tdm-b-slv-sclk {
-                                               mux {
-                                                       groups = "tdm_b_slv_sclk";
-                                                       function = "tdm_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_c_din0_a_pins: tdm-c-din0-a {
-                                               mux {
-                                                       groups = "tdm_c_din0_a";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_c_din0_z_pins: tdm-c-din0-z {
-                                               mux {
-                                                       groups = "tdm_c_din0_z";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_c_din1_a_pins: tdm-c-din1-a {
-                                               mux {
-                                                       groups = "tdm_c_din1_a";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_c_din1_z_pins: tdm-c-din1-z {
-                                               mux {
-                                                       groups = "tdm_c_din1_z";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_c_din2_a_pins: tdm-c-din2-a {
-                                               mux {
-                                                       groups = "tdm_c_din2_a";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       eth_leds_pins: eth-leds {
-                                               mux {
-                                                       groups = "eth_link_led",
-                                                                "eth_act_led";
-                                                       function = "eth";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       eth_pins: eth {
-                                               mux {
-                                                       groups = "eth_mdio",
-                                                                "eth_mdc",
-                                                                "eth_rgmii_rx_clk",
-                                                                "eth_rx_dv",
-                                                                "eth_rxd0",
-                                                                "eth_rxd1",
-                                                                "eth_txen",
-                                                                "eth_txd0",
-                                                                "eth_txd1";
-                                                       function = "eth";
-                                                       drive-strength-microamp = <4000>;
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       eth_rgmii_pins: eth-rgmii {
-                                               mux {
-                                                       groups = "eth_rxd2_rgmii",
-                                                                "eth_rxd3_rgmii",
-                                                                "eth_rgmii_tx_clk",
-                                                                "eth_txd2_rgmii",
-                                                                "eth_txd3_rgmii";
-                                                       function = "eth";
-                                                       drive-strength-microamp = <4000>;
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_c_din2_z_pins: tdm-c-din2-z {
-                                               mux {
-                                                       groups = "tdm_c_din2_z";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_c_din3_a_pins: tdm-c-din3-a {
-                                               mux {
-                                                       groups = "tdm_c_din3_a";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_c_din3_z_pins: tdm-c-din3-z {
-                                               mux {
-                                                       groups = "tdm_c_din3_z";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_c_dout0_a_pins: tdm-c-dout0-a {
-                                               mux {
-                                                       groups = "tdm_c_dout0_a";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_c_dout0_z_pins: tdm-c-dout0-z {
-                                               mux {
-                                                       groups = "tdm_c_dout0_z";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_c_dout1_a_pins: tdm-c-dout1-a {
-                                               mux {
-                                                       groups = "tdm_c_dout1_a";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_c_dout1_z_pins: tdm-c-dout1-z {
-                                               mux {
-                                                       groups = "tdm_c_dout1_z";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_c_dout2_a_pins: tdm-c-dout2-a {
-                                               mux {
-                                                       groups = "tdm_c_dout2_a";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_c_dout2_z_pins: tdm-c-dout2-z {
-                                               mux {
-                                                       groups = "tdm_c_dout2_z";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_c_dout3_a_pins: tdm-c-dout3-a {
-                                               mux {
-                                                       groups = "tdm_c_dout3_a";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_c_dout3_z_pins: tdm-c-dout3-z {
-                                               mux {
-                                                       groups = "tdm_c_dout3_z";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_c_fs_a_pins: tdm-c-fs-a {
-                                               mux {
-                                                       groups = "tdm_c_fs_a";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_c_fs_z_pins: tdm-c-fs-z {
-                                               mux {
-                                                       groups = "tdm_c_fs_z";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_c_sclk_a_pins: tdm-c-sclk-a {
-                                               mux {
-                                                       groups = "tdm_c_sclk_a";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_c_sclk_z_pins: tdm-c-sclk-z {
-                                               mux {
-                                                       groups = "tdm_c_sclk_z";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_c_slv_fs_a_pins: tdm-c-slv-fs-a {
-                                               mux {
-                                                       groups = "tdm_c_slv_fs_a";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_c_slv_fs_z_pins: tdm-c-slv-fs-z {
-                                               mux {
-                                                       groups = "tdm_c_slv_fs_z";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_c_slv_sclk_a_pins: tdm-c-slv-sclk-a {
-                                               mux {
-                                                       groups = "tdm_c_slv_sclk_a";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_c_slv_sclk_z_pins: tdm-c-slv-sclk-z {
-                                               mux {
-                                                       groups = "tdm_c_slv_sclk_z";
-                                                       function = "tdm_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       uart_a_pins: uart-a {
-                                               mux {
-                                                       groups = "uart_a_tx",
-                                                                "uart_a_rx";
-                                                       function = "uart_a";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       uart_a_cts_rts_pins: uart-a-cts-rts {
-                                               mux {
-                                                       groups = "uart_a_cts",
-                                                                "uart_a_rts";
-                                                       function = "uart_a";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       uart_b_pins: uart-b {
-                                               mux {
-                                                       groups = "uart_b_tx",
-                                                                "uart_b_rx";
-                                                       function = "uart_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       uart_c_pins: uart-c {
-                                               mux {
-                                                       groups = "uart_c_tx",
-                                                                "uart_c_rx";
-                                                       function = "uart_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       uart_c_cts_rts_pins: uart-c-cts-rts {
-                                               mux {
-                                                       groups = "uart_c_cts",
-                                                                "uart_c_rts";
-                                                       function = "uart_c";
-                                                       bias-disable;
-                                               };
-                                       };
-                               };
-                       };
-
-                       usb2_phy0: phy@36000 {
-                               compatible = "amlogic,g12a-usb2-phy";
-                               reg = <0x0 0x36000 0x0 0x2000>;
-                               clocks = <&xtal>;
-                               clock-names = "xtal";
-                               resets = <&reset RESET_USB_PHY20>;
-                               reset-names = "phy";
-                               #phy-cells = <0>;
-                       };
-
-                       dmc: bus@38000 {
-                               compatible = "simple-bus";
-                               reg = <0x0 0x38000 0x0 0x400>;
-                               #address-cells = <2>;
-                               #size-cells = <2>;
-                               ranges = <0x0 0x0 0x0 0x38000 0x0 0x400>;
-
-                               canvas: video-lut@48 {
-                                       compatible = "amlogic,canvas";
-                                       reg = <0x0 0x48 0x0 0x14>;
-                               };
-                       };
-
-                       usb2_phy1: phy@3a000 {
-                               compatible = "amlogic,g12a-usb2-phy";
-                               reg = <0x0 0x3a000 0x0 0x2000>;
-                               clocks = <&xtal>;
-                               clock-names = "xtal";
-                               resets = <&reset RESET_USB_PHY21>;
-                               reset-names = "phy";
-                               #phy-cells = <0>;
-                       };
-
-                       hiu: bus@3c000 {
-                               compatible = "simple-bus";
-                               reg = <0x0 0x3c000 0x0 0x1400>;
-                               #address-cells = <2>;
-                               #size-cells = <2>;
-                               ranges = <0x0 0x0 0x0 0x3c000 0x0 0x1400>;
-
-                               hhi: system-controller@0 {
-                                       compatible = "amlogic,meson-gx-hhi-sysctrl",
-                                                    "simple-mfd", "syscon";
-                                       reg = <0 0 0 0x400>;
-
-                                       clkc: clock-controller {
-                                               compatible = "amlogic,g12a-clkc";
-                                               #clock-cells = <1>;
-                                               clocks = <&xtal>;
-                                               clock-names = "xtal";
-                                       };
-                               };
-                       };
-
-                       pdm: audio-controller@40000 {
-                               compatible = "amlogic,g12a-pdm",
-                                            "amlogic,axg-pdm";
-                               reg = <0x0 0x40000 0x0 0x34>;
-                               #sound-dai-cells = <0>;
-                               sound-name-prefix = "PDM";
-                               clocks = <&clkc_audio AUD_CLKID_PDM>,
-                                        <&clkc_audio AUD_CLKID_PDM_DCLK>,
-                                        <&clkc_audio AUD_CLKID_PDM_SYSCLK>;
-                               clock-names = "pclk", "dclk", "sysclk";
-                               status = "disabled";
-                       };
-
-                       audio: bus@42000 {
-                               compatible = "simple-bus";
-                               reg = <0x0 0x42000 0x0 0x2000>;
-                               #address-cells = <2>;
-                               #size-cells = <2>;
-                               ranges = <0x0 0x0 0x0 0x42000 0x0 0x2000>;
-
-                               clkc_audio: clock-controller@0 {
-                                       status = "disabled";
-                                       compatible = "amlogic,g12a-audio-clkc";
-                                       reg = <0x0 0x0 0x0 0xb4>;
-                                       #clock-cells = <1>;
-
-                                       clocks = <&clkc CLKID_AUDIO>,
-                                                <&clkc CLKID_MPLL0>,
-                                                <&clkc CLKID_MPLL1>,
-                                                <&clkc CLKID_MPLL2>,
-                                                <&clkc CLKID_MPLL3>,
-                                                <&clkc CLKID_HIFI_PLL>,
-                                                <&clkc CLKID_FCLK_DIV3>,
-                                                <&clkc CLKID_FCLK_DIV4>,
-                                                <&clkc CLKID_GP0_PLL>;
-                                       clock-names = "pclk",
-                                                     "mst_in0",
-                                                     "mst_in1",
-                                                     "mst_in2",
-                                                     "mst_in3",
-                                                     "mst_in4",
-                                                     "mst_in5",
-                                                     "mst_in6",
-                                                     "mst_in7";
-
-                                       resets = <&reset RESET_AUDIO>;
-                               };
-
-                               toddr_a: audio-controller@100 {
-                                       compatible = "amlogic,g12a-toddr",
-                                                    "amlogic,axg-toddr";
-                                       reg = <0x0 0x100 0x0 0x1c>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "TODDR_A";
-                                       interrupts = <GIC_SPI 148 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_TODDR_A>;
-                                       resets = <&arb AXG_ARB_TODDR_A>;
-                                       status = "disabled";
-                               };
-
-                               toddr_b: audio-controller@140 {
-                                       compatible = "amlogic,g12a-toddr",
-                                                    "amlogic,axg-toddr";
-                                       reg = <0x0 0x140 0x0 0x1c>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "TODDR_B";
-                                       interrupts = <GIC_SPI 149 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_TODDR_B>;
-                                       resets = <&arb AXG_ARB_TODDR_B>;
-                                       status = "disabled";
-                               };
-
-                               toddr_c: audio-controller@180 {
-                                       compatible = "amlogic,g12a-toddr",
-                                                    "amlogic,axg-toddr";
-                                       reg = <0x0 0x180 0x0 0x1c>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "TODDR_C";
-                                       interrupts = <GIC_SPI 150 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_TODDR_C>;
-                                       resets = <&arb AXG_ARB_TODDR_C>;
-                                       status = "disabled";
-                               };
-
-                               frddr_a: audio-controller@1c0 {
-                                       compatible = "amlogic,g12a-frddr",
-                                                    "amlogic,axg-frddr";
-                                       reg = <0x0 0x1c0 0x0 0x1c>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "FRDDR_A";
-                                       interrupts = <GIC_SPI 152 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
-                                       resets = <&arb AXG_ARB_FRDDR_A>;
-                                       status = "disabled";
-                               };
-
-                               frddr_b: audio-controller@200 {
-                                       compatible = "amlogic,g12a-frddr",
-                                                    "amlogic,axg-frddr";
-                                       reg = <0x0 0x200 0x0 0x1c>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "FRDDR_B";
-                                       interrupts = <GIC_SPI 153 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_FRDDR_B>;
-                                       resets = <&arb AXG_ARB_FRDDR_B>;
-                                       status = "disabled";
-                               };
-
-                               frddr_c: audio-controller@240 {
-                                       compatible = "amlogic,g12a-frddr",
-                                                    "amlogic,axg-frddr";
-                                       reg = <0x0 0x240 0x0 0x1c>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "FRDDR_C";
-                                       interrupts = <GIC_SPI 154 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_FRDDR_C>;
-                                       resets = <&arb AXG_ARB_FRDDR_C>;
-                                       status = "disabled";
-                               };
-
-                               arb: reset-controller@280 {
-                                       status = "disabled";
-                                       compatible = "amlogic,meson-axg-audio-arb";
-                                       reg = <0x0 0x280 0x0 0x4>;
-                                       #reset-cells = <1>;
-                                       clocks = <&clkc_audio AUD_CLKID_DDR_ARB>;
-                               };
-
-                               tdmin_a: audio-controller@300 {
-                                       compatible = "amlogic,g12a-tdmin",
-                                                    "amlogic,axg-tdmin";
-                                       reg = <0x0 0x300 0x0 0x40>;
-                                       sound-name-prefix = "TDMIN_A";
-                                       clocks = <&clkc_audio AUD_CLKID_TDMIN_A>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_A_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_A_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_A_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               tdmin_b: audio-controller@340 {
-                                       compatible = "amlogic,g12a-tdmin",
-                                                    "amlogic,axg-tdmin";
-                                       reg = <0x0 0x340 0x0 0x40>;
-                                       sound-name-prefix = "TDMIN_B";
-                                       clocks = <&clkc_audio AUD_CLKID_TDMIN_B>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_B_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_B_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_B_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               tdmin_c: audio-controller@380 {
-                                       compatible = "amlogic,g12a-tdmin",
-                                                    "amlogic,axg-tdmin";
-                                       reg = <0x0 0x380 0x0 0x40>;
-                                       sound-name-prefix = "TDMIN_C";
-                                       clocks = <&clkc_audio AUD_CLKID_TDMIN_C>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_C_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_C_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_C_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               tdmin_lb: audio-controller@3c0 {
-                                       compatible = "amlogic,g12a-tdmin",
-                                                    "amlogic,axg-tdmin";
-                                       reg = <0x0 0x3c0 0x0 0x40>;
-                                       sound-name-prefix = "TDMIN_LB";
-                                       clocks = <&clkc_audio AUD_CLKID_TDMIN_LB>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_LB_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMIN_LB_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               spdifin: audio-controller@400 {
-                                       compatible = "amlogic,g12a-spdifin",
-                                                    "amlogic,axg-spdifin";
-                                       reg = <0x0 0x400 0x0 0x30>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "SPDIFIN";
-                                       interrupts = <GIC_SPI 151 IRQ_TYPE_EDGE_RISING>;
-                                       clocks = <&clkc_audio AUD_CLKID_SPDIFIN>,
-                                                <&clkc_audio AUD_CLKID_SPDIFIN_CLK>;
-                                       clock-names = "pclk", "refclk";
-                                       status = "disabled";
-                               };
-
-                               spdifout: audio-controller@480 {
-                                       compatible = "amlogic,g12a-spdifout",
-                                                    "amlogic,axg-spdifout";
-                                       reg = <0x0 0x480 0x0 0x50>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "SPDIFOUT";
-                                       clocks = <&clkc_audio AUD_CLKID_SPDIFOUT>,
-                                                <&clkc_audio AUD_CLKID_SPDIFOUT_CLK>;
-                                       clock-names = "pclk", "mclk";
-                                       status = "disabled";
-                               };
-
-                               tdmout_a: audio-controller@500 {
-                                       compatible = "amlogic,g12a-tdmout";
-                                       reg = <0x0 0x500 0x0 0x40>;
-                                       sound-name-prefix = "TDMOUT_A";
-                                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_A_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               tdmout_b: audio-controller@540 {
-                                       compatible = "amlogic,g12a-tdmout";
-                                       reg = <0x0 0x540 0x0 0x40>;
-                                       sound-name-prefix = "TDMOUT_B";
-                                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_B>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_B_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_B_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               tdmout_c: audio-controller@580 {
-                                       compatible = "amlogic,g12a-tdmout";
-                                       reg = <0x0 0x580 0x0 0x40>;
-                                       sound-name-prefix = "TDMOUT_C";
-                                       clocks = <&clkc_audio AUD_CLKID_TDMOUT_C>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_C_SCLK_SEL>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>,
-                                                <&clkc_audio AUD_CLKID_TDMOUT_C_LRCLK>;
-                                       clock-names = "pclk", "sclk", "sclk_sel",
-                                                     "lrclk", "lrclk_sel";
-                                       status = "disabled";
-                               };
-
-                               spdifout_b: audio-controller@680 {
-                                       compatible = "amlogic,g12a-spdifout",
-                                                    "amlogic,axg-spdifout";
-                                       reg = <0x0 0x680 0x0 0x50>;
-                                       #sound-dai-cells = <0>;
-                                       sound-name-prefix = "SPDIFOUT_B";
-                                       clocks = <&clkc_audio AUD_CLKID_SPDIFOUT_B>,
-                                                <&clkc_audio AUD_CLKID_SPDIFOUT_B_CLK>;
-                                       clock-names = "pclk", "mclk";
-                                       status = "disabled";
-                               };
-
-                               tohdmitx: audio-controller@744 {
-                                       compatible = "amlogic,g12a-tohdmitx";
-                                       reg = <0x0 0x744 0x0 0x4>;
-                                       #sound-dai-cells = <1>;
-                                       sound-name-prefix = "TOHDMITX";
-                                       status = "disabled";
-                               };
-                       };
-
-                       usb3_pcie_phy: phy@46000 {
-                               compatible = "amlogic,g12a-usb3-pcie-phy";
-                               reg = <0x0 0x46000 0x0 0x2000>;
-                               clocks = <&clkc CLKID_PCIE_PLL>;
-                               clock-names = "ref_clk";
-                               resets = <&reset RESET_PCIE_PHY>;
-                               reset-names = "phy";
-                               assigned-clocks = <&clkc CLKID_PCIE_PLL>;
-                               assigned-clock-rates = <100000000>;
-                               #phy-cells = <1>;
-                       };
-
-                       eth_phy: mdio-multiplexer@4c000 {
-                               compatible = "amlogic,g12a-mdio-mux";
-                               reg = <0x0 0x4c000 0x0 0xa4>;
-                               clocks = <&clkc CLKID_ETH_PHY>,
-                                        <&xtal>,
-                                        <&clkc CLKID_MPLL_50M>;
-                               clock-names = "pclk", "clkin0", "clkin1";
-                               mdio-parent-bus = <&mdio0>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               ext_mdio: mdio@0 {
-                                       reg = <0>;
-                                       #address-cells = <1>;
-                                       #size-cells = <0>;
-                               };
-
-                               int_mdio: mdio@1 {
-                                       reg = <1>;
-                                       #address-cells = <1>;
-                                       #size-cells = <0>;
-
-                                       internal_ephy: ethernet_phy@8 {
-                                               compatible = "ethernet-phy-id0180.3301",
-                                                            "ethernet-phy-ieee802.3-c22";
-                                               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
-                                               reg = <8>;
-                                               max-speed = <100>;
-                                       };
-                               };
-                       };
+               opp-667000000 {
+                       opp-hz = /bits/ 64 <666666666>;
+                       opp-microvolt = <731000>;
                };
 
-               aobus: bus@ff800000 {
-                       compatible = "simple-bus";
-                       reg = <0x0 0xff800000 0x0 0x100000>;
-                       #address-cells = <2>;
-                       #size-cells = <2>;
-                       ranges = <0x0 0x0 0x0 0xff800000 0x0 0x100000>;
-
-                       rti: sys-ctrl@0 {
-                               compatible = "amlogic,meson-gx-ao-sysctrl",
-                                            "simple-mfd", "syscon";
-                               reg = <0x0 0x0 0x0 0x100>;
-                               #address-cells = <2>;
-                               #size-cells = <2>;
-                               ranges = <0x0 0x0 0x0 0x0 0x0 0x100>;
-
-                               clkc_AO: clock-controller {
-                                       compatible = "amlogic,meson-g12a-aoclkc";
-                                       #clock-cells = <1>;
-                                       #reset-cells = <1>;
-                                       clocks = <&xtal>, <&clkc CLKID_CLK81>;
-                                       clock-names = "xtal", "mpeg-clk";
-                               };
-
-                               pwrc_vpu: power-controller-vpu {
-                                       compatible = "amlogic,meson-g12a-pwrc-vpu";
-                                       #power-domain-cells = <0>;
-                                       amlogic,hhi-sysctrl = <&hhi>;
-                                       resets = <&reset RESET_VIU>,
-                                                <&reset RESET_VENC>,
-                                                <&reset RESET_VCBUS>,
-                                                <&reset RESET_BT656>,
-                                                <&reset RESET_RDMA>,
-                                                <&reset RESET_VENCI>,
-                                                <&reset RESET_VENCP>,
-                                                <&reset RESET_VDAC>,
-                                                <&reset RESET_VDI6>,
-                                                <&reset RESET_VENCL>,
-                                                <&reset RESET_VID_LOCK>;
-                                       clocks = <&clkc CLKID_VPU>,
-                                                <&clkc CLKID_VAPB>;
-                                       clock-names = "vpu", "vapb";
-                                       /*
-                                        * VPU clocking is provided by two identical clock paths
-                                        * VPU_0 and VPU_1 muxed to a single clock by a glitch
-                                        * free mux to safely change frequency while running.
-                                        * Same for VAPB but with a final gate after the glitch free mux.
-                                        */
-                                       assigned-clocks = <&clkc CLKID_VPU_0_SEL>,
-                                                         <&clkc CLKID_VPU_0>,
-                                                         <&clkc CLKID_VPU>, /* Glitch free mux */
-                                                         <&clkc CLKID_VAPB_0_SEL>,
-                                                         <&clkc CLKID_VAPB_0>,
-                                                         <&clkc CLKID_VAPB_SEL>; /* Glitch free mux */
-                                       assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>,
-                                                                <0>, /* Do Nothing */
-                                                                <&clkc CLKID_VPU_0>,
-                                                                <&clkc CLKID_FCLK_DIV4>,
-                                                                <0>, /* Do Nothing */
-                                                                <&clkc CLKID_VAPB_0>;
-                                       assigned-clock-rates = <0>, /* Do Nothing */
-                                                              <666666666>,
-                                                              <0>, /* Do Nothing */
-                                                              <0>, /* Do Nothing */
-                                                              <250000000>,
-                                                              <0>; /* Do Nothing */
-                               };
-
-                               ao_pinctrl: pinctrl@14 {
-                                       compatible = "amlogic,meson-g12a-aobus-pinctrl";
-                                       #address-cells = <2>;
-                                       #size-cells = <2>;
-                                       ranges;
-
-                                       gpio_ao: bank@14 {
-                                               reg = <0x0 0x14 0x0 0x8>,
-                                                     <0x0 0x1c 0x0 0x8>,
-                                                     <0x0 0x24 0x0 0x14>;
-                                               reg-names = "mux",
-                                                           "ds",
-                                                           "gpio";
-                                               gpio-controller;
-                                               #gpio-cells = <2>;
-                                               gpio-ranges = <&ao_pinctrl 0 0 15>;
-                                       };
-
-                                       i2c_ao_sck_pins: i2c_ao_sck_pins {
-                                               mux {
-                                                       groups = "i2c_ao_sck";
-                                                       function = "i2c_ao";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c_ao_sda_pins: i2c_ao_sda {
-                                               mux {
-                                                       groups = "i2c_ao_sda";
-                                                       function = "i2c_ao";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c_ao_sck_e_pins: i2c_ao_sck_e {
-                                               mux {
-                                                       groups = "i2c_ao_sck_e";
-                                                       function = "i2c_ao";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       i2c_ao_sda_e_pins: i2c_ao_sda_e {
-                                               mux {
-                                                       groups = "i2c_ao_sda_e";
-                                                       function = "i2c_ao";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       mclk0_ao_pins: mclk0-ao {
-                                               mux {
-                                                       groups = "mclk0_ao";
-                                                       function = "mclk0_ao";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_ao_b_din0_pins: tdm-ao-b-din0 {
-                                               mux {
-                                                       groups = "tdm_ao_b_din0";
-                                                       function = "tdm_ao_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       spdif_ao_out_pins: spdif-ao-out {
-                                               mux {
-                                                       groups = "spdif_ao_out";
-                                                       function = "spdif_ao_out";
-                                                       drive-strength-microamp = <500>;
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_ao_b_din1_pins: tdm-ao-b-din1 {
-                                               mux {
-                                                       groups = "tdm_ao_b_din1";
-                                                       function = "tdm_ao_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_ao_b_din2_pins: tdm-ao-b-din2 {
-                                               mux {
-                                                       groups = "tdm_ao_b_din2";
-                                                       function = "tdm_ao_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_ao_b_dout0_pins: tdm-ao-b-dout0 {
-                                               mux {
-                                                       groups = "tdm_ao_b_dout0";
-                                                       function = "tdm_ao_b";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_ao_b_dout1_pins: tdm-ao-b-dout1 {
-                                               mux {
-                                                       groups = "tdm_ao_b_dout1";
-                                                       function = "tdm_ao_b";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_ao_b_dout2_pins: tdm-ao-b-dout2 {
-                                               mux {
-                                                       groups = "tdm_ao_b_dout2";
-                                                       function = "tdm_ao_b";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_ao_b_fs_pins: tdm-ao-b-fs {
-                                               mux {
-                                                       groups = "tdm_ao_b_fs";
-                                                       function = "tdm_ao_b";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_ao_b_sclk_pins: tdm-ao-b-sclk {
-                                               mux {
-                                                       groups = "tdm_ao_b_sclk";
-                                                       function = "tdm_ao_b";
-                                                       bias-disable;
-                                                       drive-strength-microamp = <3000>;
-                                               };
-                                       };
-
-                                       tdm_ao_b_slv_fs_pins: tdm-ao-b-slv-fs {
-                                               mux {
-                                                       groups = "tdm_ao_b_slv_fs";
-                                                       function = "tdm_ao_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       tdm_ao_b_slv_sclk_pins: tdm-ao-b-slv-sclk {
-                                               mux {
-                                                       groups = "tdm_ao_b_slv_sclk";
-                                                       function = "tdm_ao_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       uart_ao_a_pins: uart-a-ao {
-                                               mux {
-                                                       groups = "uart_ao_a_tx",
-                                                                "uart_ao_a_rx";
-                                                       function = "uart_ao_a";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       uart_ao_a_cts_rts_pins: uart-ao-a-cts-rts {
-                                               mux {
-                                                       groups = "uart_ao_a_cts",
-                                                                "uart_ao_a_rts";
-                                                       function = "uart_ao_a";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_ao_a_pins: pwm-ao-a {
-                                               mux {
-                                                       groups = "pwm_ao_a";
-                                                       function = "pwm_ao_a";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_ao_b_pins: pwm-ao-b {
-                                               mux {
-                                                       groups = "pwm_ao_b";
-                                                       function = "pwm_ao_b";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_ao_c_4_pins: pwm-ao-c-4 {
-                                               mux {
-                                                       groups = "pwm_ao_c_4";
-                                                       function = "pwm_ao_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_ao_c_6_pins: pwm-ao-c-6 {
-                                               mux {
-                                                       groups = "pwm_ao_c_6";
-                                                       function = "pwm_ao_c";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_ao_d_5_pins: pwm-ao-d-5 {
-                                               mux {
-                                                       groups = "pwm_ao_d_5";
-                                                       function = "pwm_ao_d";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_ao_d_10_pins: pwm-ao-d-10 {
-                                               mux {
-                                                       groups = "pwm_ao_d_10";
-                                                       function = "pwm_ao_d";
-                                                       bias-disable;
-                                               };
-                                       };
-
-                                       pwm_ao_d_e_pins: pwm-ao-d-e {
-                                               mux {
-                                                       groups = "pwm_ao_d_e";
-                                                       function = "pwm_ao_d";
-                                               };
-                                       };
-
-                                       remote_input_ao_pins: remote-input-ao {
-                                               mux {
-                                                       groups = "remote_ao_input";
-                                                       function = "remote_ao_input";
-                                                       bias-disable;
-                                               };
-                                       };
-                               };
-                       };
-
-                       cec_AO: cec@100 {
-                               compatible = "amlogic,meson-gx-ao-cec";
-                               reg = <0x0 0x00100 0x0 0x14>;
-                               interrupts = <GIC_SPI 199 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&clkc_AO CLKID_AO_CEC>;
-                               clock-names = "core";
-                               status = "disabled";
-                       };
-
-                       sec_AO: ao-secure@140 {
-                               compatible = "amlogic,meson-gx-ao-secure", "syscon";
-                               reg = <0x0 0x140 0x0 0x140>;
-                               amlogic,has-chip-id;
-                       };
-
-                       cecb_AO: cec@280 {
-                               compatible = "amlogic,meson-g12a-ao-cec";
-                               reg = <0x0 0x00280 0x0 0x1c>;
-                               interrupts = <GIC_SPI 203 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&clkc_AO CLKID_AO_CTS_OSCIN>;
-                               clock-names = "oscin";
-                               status = "disabled";
-                       };
-
-                       pwm_AO_cd: pwm@2000 {
-                               compatible = "amlogic,meson-g12a-ao-pwm-cd";
-                               reg = <0x0 0x2000 0x0 0x20>;
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       uart_AO: serial@3000 {
-                               compatible = "amlogic,meson-gx-uart",
-                                            "amlogic,meson-ao-uart";
-                               reg = <0x0 0x3000 0x0 0x18>;
-                               interrupts = <GIC_SPI 193 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&xtal>, <&clkc_AO CLKID_AO_UART>, <&xtal>;
-                               clock-names = "xtal", "pclk", "baud";
-                               status = "disabled";
-                       };
-
-                       uart_AO_B: serial@4000 {
-                               compatible = "amlogic,meson-gx-uart",
-                                            "amlogic,meson-ao-uart";
-                               reg = <0x0 0x4000 0x0 0x18>;
-                               interrupts = <GIC_SPI 197 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&xtal>, <&clkc_AO CLKID_AO_UART2>, <&xtal>;
-                               clock-names = "xtal", "pclk", "baud";
-                               status = "disabled";
-                       };
-
-                       i2c_AO: i2c@5000 {
-                               compatible = "amlogic,meson-axg-i2c";
-                               status = "disabled";
-                               reg = <0x0 0x05000 0x0 0x20>;
-                               interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               clocks = <&clkc CLKID_I2C>;
-                       };
-
-                       pwm_AO_ab: pwm@7000 {
-                               compatible = "amlogic,meson-g12a-ao-pwm-ab";
-                               reg = <0x0 0x7000 0x0 0x20>;
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       ir: ir@8000 {
-                               compatible = "amlogic,meson-gxbb-ir";
-                               reg = <0x0 0x8000 0x0 0x20>;
-                               interrupts = <GIC_SPI 196 IRQ_TYPE_EDGE_RISING>;
-                               status = "disabled";
-                       };
-
-                       saradc: adc@9000 {
-                               compatible = "amlogic,meson-g12a-saradc",
-                                            "amlogic,meson-saradc";
-                               reg = <0x0 0x9000 0x0 0x48>;
-                               #io-channel-cells = <1>;
-                               interrupts = <GIC_SPI 200 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&xtal>,
-                                        <&clkc_AO CLKID_AO_SAR_ADC>,
-                                        <&clkc_AO CLKID_AO_SAR_ADC_CLK>,
-                                        <&clkc_AO CLKID_AO_SAR_ADC_SEL>;
-                               clock-names = "clkin", "core", "adc_clk", "adc_sel";
-                               status = "disabled";
-                       };
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
+                       opp-microvolt = <731000>;
                };
 
-               vpu: vpu@ff900000 {
-                       compatible = "amlogic,meson-g12a-vpu";
-                       reg = <0x0 0xff900000 0x0 0x100000>,
-                             <0x0 0xff63c000 0x0 0x1000>;
-                       reg-names = "vpu", "hhi";
-                       interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       amlogic,canvas = <&canvas>;
-                       power-domains = <&pwrc_vpu>;
-
-                       /* CVBS VDAC output port */
-                       cvbs_vdac_port: port@0 {
-                               reg = <0>;
-                       };
-
-                       /* HDMI-TX output port */
-                       hdmi_tx_port: port@1 {
-                               reg = <1>;
-
-                               hdmi_tx_out: endpoint {
-                                       remote-endpoint = <&hdmi_tx_in>;
-                               };
-                       };
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
+                       opp-microvolt = <731000>;
                };
 
-               gic: interrupt-controller@ffc01000 {
-                       compatible = "arm,gic-400";
-                       reg = <0x0 0xffc01000 0 0x1000>,
-                             <0x0 0xffc02000 0 0x2000>,
-                             <0x0 0xffc04000 0 0x2000>,
-                             <0x0 0xffc06000 0 0x2000>;
-                       interrupt-controller;
-                       interrupts = <GIC_PPI 9
-                               (GIC_CPU_MASK_SIMPLE(8) | IRQ_TYPE_LEVEL_HIGH)>;
-                       #interrupt-cells = <3>;
-                       #address-cells = <0>;
+               opp-1398000000 {
+                       opp-hz = /bits/ 64 <1398000000>;
+                       opp-microvolt = <761000>;
                };
 
-               cbus: bus@ffd00000 {
-                       compatible = "simple-bus";
-                       reg = <0x0 0xffd00000 0x0 0x100000>;
-                       #address-cells = <2>;
-                       #size-cells = <2>;
-                       ranges = <0x0 0x0 0x0 0xffd00000 0x0 0x100000>;
-
-                       reset: reset-controller@1004 {
-                               compatible = "amlogic,meson-g12a-reset",
-                                            "amlogic,meson-axg-reset";
-                               reg = <0x0 0x1004 0x0 0x9c>;
-                               #reset-cells = <1>;
-                       };
-
-                       gpio_intc: interrupt-controller@f080 {
-                               compatible = "amlogic,meson-g12a-gpio-intc",
-                                            "amlogic,meson-gpio-intc";
-                               reg = <0x0 0xf080 0x0 0x10>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               amlogic,channel-interrupts = <64 65 66 67 68 69 70 71>;
-                       };
-
-                       pwm_ef: pwm@19000 {
-                               compatible = "amlogic,meson-g12a-ee-pwm";
-                               reg = <0x0 0x19000 0x0 0x20>;
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       pwm_cd: pwm@1a000 {
-                               compatible = "amlogic,meson-g12a-ee-pwm";
-                               reg = <0x0 0x1a000 0x0 0x20>;
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       pwm_ab: pwm@1b000 {
-                               compatible = "amlogic,meson-g12a-ee-pwm";
-                               reg = <0x0 0x1b000 0x0 0x20>;
-                               #pwm-cells = <3>;
-                               status = "disabled";
-                       };
-
-                       i2c3: i2c@1c000 {
-                               compatible = "amlogic,meson-axg-i2c";
-                               status = "disabled";
-                               reg = <0x0 0x1c000 0x0 0x20>;
-                               interrupts = <GIC_SPI 39 IRQ_TYPE_EDGE_RISING>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               clocks = <&clkc CLKID_I2C>;
-                       };
-
-                       i2c2: i2c@1d000 {
-                               compatible = "amlogic,meson-axg-i2c";
-                               status = "disabled";
-                               reg = <0x0 0x1d000 0x0 0x20>;
-                               interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               clocks = <&clkc CLKID_I2C>;
-                       };
-
-                       i2c1: i2c@1e000 {
-                               compatible = "amlogic,meson-axg-i2c";
-                               status = "disabled";
-                               reg = <0x0 0x1e000 0x0 0x20>;
-                               interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               clocks = <&clkc CLKID_I2C>;
-                       };
-
-                       i2c0: i2c@1f000 {
-                               compatible = "amlogic,meson-axg-i2c";
-                               status = "disabled";
-                               reg = <0x0 0x1f000 0x0 0x20>;
-                               interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               clocks = <&clkc CLKID_I2C>;
-                       };
-
-                       clk_msr: clock-measure@18000 {
-                               compatible = "amlogic,meson-g12a-clk-measure";
-                               reg = <0x0 0x18000 0x0 0x10>;
-                       };
-
-                       uart_C: serial@22000 {
-                               compatible = "amlogic,meson-gx-uart";
-                               reg = <0x0 0x22000 0x0 0x18>;
-                               interrupts = <GIC_SPI 93 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&xtal>, <&clkc CLKID_UART2>, <&xtal>;
-                               clock-names = "xtal", "pclk", "baud";
-                               status = "disabled";
-                       };
-
-                       uart_B: serial@23000 {
-                               compatible = "amlogic,meson-gx-uart";
-                               reg = <0x0 0x23000 0x0 0x18>;
-                               interrupts = <GIC_SPI 75 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&xtal>, <&clkc CLKID_UART1>, <&xtal>;
-                               clock-names = "xtal", "pclk", "baud";
-                               status = "disabled";
-                       };
-
-                       uart_A: serial@24000 {
-                               compatible = "amlogic,meson-gx-uart";
-                               reg = <0x0 0x24000 0x0 0x18>;
-                               interrupts = <GIC_SPI 26 IRQ_TYPE_EDGE_RISING>;
-                               clocks = <&xtal>, <&clkc CLKID_UART0>, <&xtal>;
-                               clock-names = "xtal", "pclk", "baud";
-                               status = "disabled";
-                       };
-               };
-
-               sd_emmc_a: sd@ffe03000 {
-                       compatible = "amlogic,meson-axg-mmc";
-                       reg = <0x0 0xffe03000 0x0 0x800>;
-                       interrupts = <GIC_SPI 189 IRQ_TYPE_EDGE_RISING>;
-                       status = "disabled";
-                       clocks = <&clkc CLKID_SD_EMMC_A>,
-                                <&clkc CLKID_SD_EMMC_A_CLK0>,
-                                <&clkc CLKID_FCLK_DIV2>;
-                       clock-names = "core", "clkin0", "clkin1";
-                       resets = <&reset RESET_SD_EMMC_A>;
-                       amlogic,dram-access-quirk;
-               };
-
-               sd_emmc_b: sd@ffe05000 {
-                       compatible = "amlogic,meson-axg-mmc";
-                       reg = <0x0 0xffe05000 0x0 0x800>;
-                       interrupts = <GIC_SPI 190 IRQ_TYPE_EDGE_RISING>;
-                       status = "disabled";
-                       clocks = <&clkc CLKID_SD_EMMC_B>,
-                                <&clkc CLKID_SD_EMMC_B_CLK0>,
-                                <&clkc CLKID_FCLK_DIV2>;
-                       clock-names = "core", "clkin0", "clkin1";
-                       resets = <&reset RESET_SD_EMMC_B>;
+               opp-1512000000 {
+                       opp-hz = /bits/ 64 <1512000000>;
+                       opp-microvolt = <791000>;
                };
 
-               sd_emmc_c: mmc@ffe07000 {
-                       compatible = "amlogic,meson-axg-mmc";
-                       reg = <0x0 0xffe07000 0x0 0x800>;
-                       interrupts = <GIC_SPI 191 IRQ_TYPE_EDGE_RISING>;
-                       status = "disabled";
-                       clocks = <&clkc CLKID_SD_EMMC_C>,
-                                <&clkc CLKID_SD_EMMC_C_CLK0>,
-                                <&clkc CLKID_FCLK_DIV2>;
-                       clock-names = "core", "clkin0", "clkin1";
-                       resets = <&reset RESET_SD_EMMC_C>;
+               opp-1608000000 {
+                       opp-hz = /bits/ 64 <1608000000>;
+                       opp-microvolt = <831000>;
                };
 
-               usb: usb@ffe09000 {
-                       status = "disabled";
-                       compatible = "amlogic,meson-g12a-usb-ctrl";
-                       reg = <0x0 0xffe09000 0x0 0xa0>;
-                       interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
-                       #address-cells = <2>;
-                       #size-cells = <2>;
-                       ranges;
-
-                       clocks = <&clkc CLKID_USB>;
-                       resets = <&reset RESET_USB>;
-
-                       dr_mode = "otg";
-
-                       phys = <&usb2_phy0>, <&usb2_phy1>,
-                              <&usb3_pcie_phy PHY_TYPE_USB3>;
-                       phy-names = "usb2-phy0", "usb2-phy1", "usb3-phy0";
-
-                       dwc2: usb@ff400000 {
-                               compatible = "amlogic,meson-g12a-usb", "snps,dwc2";
-                               reg = <0x0 0xff400000 0x0 0x40000>;
-                               interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
-                               clocks = <&clkc CLKID_USB1_DDR_BRIDGE>;
-                               clock-names = "ddr";
-                               phys = <&usb2_phy1>;
-                               dr_mode = "peripheral";
-                               g-rx-fifo-size = <192>;
-                               g-np-tx-fifo-size = <128>;
-                               g-tx-fifo-size = <128 128 16 16 16>;
-                       };
-
-                       dwc3: usb@ff500000 {
-                               compatible = "snps,dwc3";
-                               reg = <0x0 0xff500000 0x0 0x100000>;
-                               interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
-                               dr_mode = "host";
-                               snps,dis_u2_susphy_quirk;
-                               snps,quirk-frame-length-adjustment;
-                       };
+               opp-1704000000 {
+                       opp-hz = /bits/ 64 <1704000000>;
+                       opp-microvolt = <861000>;
                };
 
-               mali: gpu@ffe40000 {
-                       compatible = "amlogic,meson-g12a-mali", "arm,mali-bifrost";
-                       reg = <0x0 0xffe40000 0x0 0x40000>;
-                       interrupt-parent = <&gic>;
-                       interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "gpu", "mmu", "job";
-                       clocks = <&clkc CLKID_MALI>;
-                       resets = <&reset RESET_DVALIN_CAPB3>, <&reset RESET_DVALIN>;
-
-                       /*
-                        * Mali clocking is provided by two identical clock paths
-                        * MALI_0 and MALI_1 muxed to a single clock by a glitch
-                        * free mux to safely change frequency while running.
-                        */
-                       assigned-clocks = <&clkc CLKID_MALI_0_SEL>,
-                                         <&clkc CLKID_MALI_0>,
-                                         <&clkc CLKID_MALI>; /* Glitch free mux */
-                       assigned-clock-parents = <&clkc CLKID_FCLK_DIV2P5>,
-                                                <0>, /* Do Nothing */
-                                                <&clkc CLKID_MALI_0>;
-                       assigned-clock-rates = <0>, /* Do Nothing */
-                                              <800000000>,
-                                              <0>; /* Do Nothing */
+               opp-1800000000 {
+                       opp-hz = /bits/ 64 <1800000000>;
+                       opp-microvolt = <981000>;
                };
        };
+};
 
-       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)>;
-       };
+&ethmac {
+       power-domains = <&pwrc PWRC_G12A_ETH_ID>;
+};
 
-       xtal: xtal-clk {
-               compatible = "fixed-clock";
-               clock-frequency = <24000000>;
-               clock-output-names = "xtal";
-               #clock-cells = <0>;
-       };
+&vpu {
+       power-domains = <&pwrc PWRC_G12A_VPU_ID>;
+};
 
+&sd_emmc_a {
+       amlogic,dram-access-quirk;
 };
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts
new file mode 100644 (file)
index 0000000..3a6a1e0
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-g12b-a311d.dtsi"
+#include "meson-khadas-vim3.dtsi"
+#include "meson-g12b-khadas-vim3.dtsi"
+
+/ {
+       compatible = "khadas,vim3", "amlogic,a311d", "amlogic,g12b";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi
new file mode 100644 (file)
index 0000000..d61f430
--- /dev/null
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include "meson-g12b.dtsi"
+
+/ {
+       cpu_opp_table_0: opp-table-0 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-100000000 {
+                       opp-hz = /bits/ 64 <100000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-250000000 {
+                       opp-hz = /bits/ 64 <250000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-500000000 {
+                       opp-hz = /bits/ 64 <500000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-667000000 {
+                       opp-hz = /bits/ 64 <667000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
+                       opp-microvolt = <761000>;
+               };
+
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
+                       opp-microvolt = <781000>;
+               };
+
+               opp-1398000000 {
+                       opp-hz = /bits/ 64 <1398000000>;
+                       opp-microvolt = <811000>;
+               };
+
+               opp-1512000000 {
+                       opp-hz = /bits/ 64 <1512000000>;
+                       opp-microvolt = <861000>;
+               };
+
+               opp-1608000000 {
+                       opp-hz = /bits/ 64 <1608000000>;
+                       opp-microvolt = <901000>;
+               };
+
+               opp-1704000000 {
+                       opp-hz = /bits/ 64 <1704000000>;
+                       opp-microvolt = <951000>;
+               };
+
+               opp-1800000000 {
+                       opp-hz = /bits/ 64 <1800000000>;
+                       opp-microvolt = <1001000>;
+               };
+       };
+
+       cpub_opp_table_1: opp-table-1 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-100000000 {
+                       opp-hz = /bits/ 64 <100000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-250000000 {
+                       opp-hz = /bits/ 64 <250000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-500000000 {
+                       opp-hz = /bits/ 64 <500000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-667000000 {
+                       opp-hz = /bits/ 64 <667000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
+                       opp-microvolt = <751000>;
+               };
+
+               opp-1398000000 {
+                       opp-hz = /bits/ 64 <1398000000>;
+                       opp-microvolt = <771000>;
+               };
+
+               opp-1512000000 {
+                       opp-hz = /bits/ 64 <1512000000>;
+                       opp-microvolt = <771000>;
+               };
+
+               opp-1608000000 {
+                       opp-hz = /bits/ 64 <1608000000>;
+                       opp-microvolt = <781000>;
+               };
+
+               opp-1704000000 {
+                       opp-hz = /bits/ 64 <1704000000>;
+                       opp-microvolt = <791000>;
+               };
+
+               opp-1800000000 {
+                       opp-hz = /bits/ 64 <1800000000>;
+                       opp-microvolt = <831000>;
+               };
+
+                opp-1908000000 {
+                        opp-hz = /bits/ 64 <1908000000>;
+                        opp-microvolt = <861000>;
+                };
+
+                opp-2016000000 {
+                        opp-hz = /bits/ 64 <2016000000>;
+                        opp-microvolt = <911000>;
+                };
+
+                opp-2108000000 {
+                        opp-hz = /bits/ 64 <2108000000>;
+                        opp-microvolt = <951000>;
+                };
+
+                opp-2208000000 {
+                        opp-hz = /bits/ 64 <2208000000>;
+                        opp-microvolt = <1011000>;
+                };
+       };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi
new file mode 100644 (file)
index 0000000..5548634
--- /dev/null
@@ -0,0 +1,189 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+
+/ {
+       vddcpu_a: regulator-vddcpu-a {
+               /*
+                * MP8756GD Regulator.
+                */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDCPU_A";
+               regulator-min-microvolt = <690000>;
+               regulator-max-microvolt = <1050000>;
+
+               vin-supply = <&dc_in>;
+
+               pwms = <&pwm_ab 0 1250 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       vddcpu_b: regulator-vddcpu-b {
+               /*
+                * Silergy SY8030DEC Regulator.
+                */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDCPU_B";
+               regulator-min-microvolt = <690000>;
+               regulator-max-microvolt = <1050000>;
+
+               vin-supply = <&vsys_3v3>;
+
+               pwms = <&pwm_AO_cd 1 1250 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       sound {
+               compatible = "amlogic,axg-sound-card";
+               model = "G12A-KHADAS-VIM3";
+               audio-aux-devs = <&tdmout_b>;
+               audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+                               "TDMOUT_B IN 1", "FRDDR_B OUT 1",
+                               "TDMOUT_B IN 2", "FRDDR_C OUT 1",
+                               "TDM_B Playback", "TDMOUT_B OUT";
+
+               assigned-clocks = <&clkc CLKID_MPLL2>,
+                                 <&clkc CLKID_MPLL0>,
+                                 <&clkc CLKID_MPLL1>;
+               assigned-clock-parents = <0>, <0>, <0>;
+               assigned-clock-rates = <294912000>,
+                                      <270950400>,
+                                      <393216000>;
+               status = "okay";
+
+               dai-link-0 {
+                       sound-dai = <&frddr_a>;
+               };
+
+               dai-link-1 {
+                       sound-dai = <&frddr_b>;
+               };
+
+               dai-link-2 {
+                       sound-dai = <&frddr_c>;
+               };
+
+               /* 8ch hdmi interface */
+               dai-link-3 {
+                       sound-dai = <&tdmif_b>;
+                       dai-format = "i2s";
+                       dai-tdm-slot-tx-mask-0 = <1 1>;
+                       dai-tdm-slot-tx-mask-1 = <1 1>;
+                       dai-tdm-slot-tx-mask-2 = <1 1>;
+                       dai-tdm-slot-tx-mask-3 = <1 1>;
+                       mclk-fs = <256>;
+
+                       codec {
+                               sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+                       };
+               };
+
+               /* hdmi glue */
+               dai-link-4 {
+                       sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+                       codec {
+                               sound-dai = <&hdmi_tx>;
+                       };
+               };
+       };
+};
+
+&arb {
+       status = "okay";
+};
+
+&clkc_audio {
+       status = "okay";
+};
+
+&cpu0 {
+       cpu-supply = <&vddcpu_b>;
+       operating-points-v2 = <&cpu_opp_table_0>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu1 {
+       cpu-supply = <&vddcpu_b>;
+       operating-points-v2 = <&cpu_opp_table_0>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu100 {
+       cpu-supply = <&vddcpu_a>;
+       operating-points-v2 = <&cpub_opp_table_1>;
+       clocks = <&clkc CLKID_CPUB_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu101 {
+       cpu-supply = <&vddcpu_a>;
+       operating-points-v2 = <&cpub_opp_table_1>;
+       clocks = <&clkc CLKID_CPUB_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu102 {
+       cpu-supply = <&vddcpu_a>;
+       operating-points-v2 = <&cpub_opp_table_1>;
+       clocks = <&clkc CLKID_CPUB_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu103 {
+       cpu-supply = <&vddcpu_a>;
+       operating-points-v2 = <&cpub_opp_table_1>;
+       clocks = <&clkc CLKID_CPUB_CLK>;
+       clock-latency = <50000>;
+};
+
+&frddr_b {
+       status = "okay";
+};
+
+&frddr_c {
+       status = "okay";
+};
+
+&pwm_ab {
+       pinctrl-0 = <&pwm_a_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin0";
+       status = "okay";
+};
+
+&pwm_AO_cd {
+       pinctrl-0 = <&pwm_ao_d_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin1";
+       status = "okay";
+};
+
+&tdmif_b {
+       status = "okay";
+};
+
+&tdmout_b {
+       status = "okay";
+};
+
+&tohdmitx {
+       status = "okay";
+};
index 81780ff..42f1540 100644 (file)
@@ -6,7 +6,7 @@
 
 /dts-v1/;
 
-#include "meson-g12b.dtsi"
+#include "meson-g12b-s922x.dtsi"
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/gpio/meson-g12a-gpio.h>
 #include <dt-bindings/sound/meson-g12a-tohdmitx.h>
@@ -53,6 +53,7 @@
 
                gpio = <&gpio_ao GPIOAO_8 GPIO_ACTIVE_HIGH>;
                enable-active-high;
+               regulator-always-on;
        };
 
        tf_io: gpio-regulator-tf_io {
@@ -65,8 +66,8 @@
                gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>;
                gpios-states = <0>;
 
-               states = <3300000 0
-                         1800000 1>;
+               states = <3300000 0>,
+                        <1800000 1>;
        };
 
        flash_1v8: regulator-flash_1v8 {
                /* FIXME: actually controlled by VDDCPU_B_EN */
        };
 
+       vddcpu_a: regulator-vddcpu-a {
+               /*
+                * MP8756GD Regulator.
+                */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDCPU_A";
+               regulator-min-microvolt = <721000>;
+               regulator-max-microvolt = <1022000>;
+
+               vin-supply = <&main_12v>;
+
+               pwms = <&pwm_ab 0 1250 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       vddcpu_b: regulator-vddcpu-b {
+               /*
+                * Silergy SY8120B1ABC Regulator.
+                */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDCPU_B";
+               regulator-min-microvolt = <721000>;
+               regulator-max-microvolt = <1022000>;
+
+               vin-supply = <&main_12v>;
+
+               pwms = <&pwm_AO_cd 1 1250 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
        hub_5v: regulator-hub_5v {
                compatible = "regulator-fixed";
                regulator-name = "HUB_5V";
        status = "okay";
 };
 
+&cpu0 {
+       cpu-supply = <&vddcpu_b>;
+       operating-points-v2 = <&cpu_opp_table_0>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu1 {
+       cpu-supply = <&vddcpu_b>;
+       operating-points-v2 = <&cpu_opp_table_0>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu100 {
+       cpu-supply = <&vddcpu_a>;
+       operating-points-v2 = <&cpub_opp_table_1>;
+       clocks = <&clkc CLKID_CPUB_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu101 {
+       cpu-supply = <&vddcpu_a>;
+       operating-points-v2 = <&cpub_opp_table_1>;
+       clocks = <&clkc CLKID_CPUB_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu102 {
+       cpu-supply = <&vddcpu_a>;
+       operating-points-v2 = <&cpub_opp_table_1>;
+       clocks = <&clkc CLKID_CPUB_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu103 {
+       cpu-supply = <&vddcpu_a>;
+       operating-points-v2 = <&cpub_opp_table_1>;
+       clocks = <&clkc CLKID_CPUB_CLK>;
+       clock-latency = <50000>;
+};
+
 &ext_mdio {
        external_phy: ethernet-phy@0 {
                /* Realtek RTL8211F (0x001cc916) */     
        status = "okay";
        pinctrl-0 = <&remote_input_ao_pins>;
        pinctrl-names = "default";
+       linux,rc-map-name = "rc-odroid";
+};
+
+&pwm_ab {
+       pinctrl-0 = <&pwm_a_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin0";
+       status = "okay";
+};
+
+&pwm_AO_cd {
+       pinctrl-0 = <&pwm_ao_d_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin1";
+       status = "okay";
 };
 
 /* SD card */
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts
new file mode 100644 (file)
index 0000000..b73deb2
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-g12b-s922x.dtsi"
+#include "meson-khadas-vim3.dtsi"
+#include "meson-g12b-khadas-vim3.dtsi"
+
+/ {
+       compatible = "khadas,vim3", "amlogic,s922x", "amlogic,g12b";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi
new file mode 100644 (file)
index 0000000..046cc33
--- /dev/null
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include "meson-g12b.dtsi"
+
+/ {
+       cpu_opp_table_0: opp-table-0 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-100000000 {
+                       opp-hz = /bits/ 64 <100000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-250000000 {
+                       opp-hz = /bits/ 64 <250000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-500000000 {
+                       opp-hz = /bits/ 64 <500000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-667000000 {
+                       opp-hz = /bits/ 64 <667000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
+                       opp-microvolt = <731000>;
+               };
+
+               opp-1398000000 {
+                       opp-hz = /bits/ 64 <1398000000>;
+                       opp-microvolt = <761000>;
+               };
+
+               opp-1512000000 {
+                       opp-hz = /bits/ 64 <1512000000>;
+                       opp-microvolt = <791000>;
+               };
+
+               opp-1608000000 {
+                       opp-hz = /bits/ 64 <1608000000>;
+                       opp-microvolt = <831000>;
+               };
+
+               opp-1704000000 {
+                       opp-hz = /bits/ 64 <1704000000>;
+                       opp-microvolt = <861000>;
+               };
+
+               opp-1896000000 {
+                       opp-hz = /bits/ 64 <1896000000>;
+                       opp-microvolt = <981000>;
+               };
+       };
+
+       cpub_opp_table_1: opp-table-1 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-100000000 {
+                       opp-hz = /bits/ 64 <100000000>;
+                       opp-microvolt = <751000>;
+               };
+
+               opp-250000000 {
+                       opp-hz = /bits/ 64 <250000000>;
+                       opp-microvolt = <751000>;
+               };
+
+               opp-500000000 {
+                       opp-hz = /bits/ 64 <500000000>;
+                       opp-microvolt = <751000>;
+               };
+
+               opp-667000000 {
+                       opp-hz = /bits/ 64 <667000000>;
+                       opp-microvolt = <751000>;
+               };
+
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
+                       opp-microvolt = <771000>;
+               };
+
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
+                       opp-microvolt = <771000>;
+               };
+
+               opp-1398000000 {
+                       opp-hz = /bits/ 64 <1398000000>;
+                       opp-microvolt = <791000>;
+               };
+
+               opp-1512000000 {
+                       opp-hz = /bits/ 64 <1512000000>;
+                       opp-microvolt = <821000>;
+               };
+
+               opp-1608000000 {
+                       opp-hz = /bits/ 64 <1608000000>;
+                       opp-microvolt = <861000>;
+               };
+
+               opp-1704000000 {
+                       opp-hz = /bits/ 64 <1704000000>;
+                       opp-microvolt = <891000>;
+               };
+       };
+};
index 9e88e51..5628ccd 100644 (file)
@@ -4,12 +4,16 @@
  * Author: Neil Armstrong <narmstrong@baylibre.com>
  */
 
-#include "meson-g12a.dtsi"
+#include "meson-g12-common.dtsi"
+#include <dt-bindings/power/meson-g12a-power.h>
 
 / {
        compatible = "amlogic,g12b";
 
        cpus {
+               #address-cells = <0x2>;
+               #size-cells = <0x0>;
+
                cpu-map {
                        cluster0 {
                                core0 {
                        };
                };
 
-               /delete-node/ cpu@2;
-               /delete-node/ cpu@3;
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x0>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0 0x1>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+               };
 
                cpu100: cpu@100 {
                        device_type = "cpu";
                        enable-method = "psci";
                        next-level-cache = <&l2>;
                };
+
+               l2: l2-cache0 {
+                       compatible = "cache";
+               };
        };
 };
 
 &clkc {
        compatible = "amlogic,g12b-clkc";
 };
+
+&ethmac {
+       power-domains = <&pwrc PWRC_G12A_ETH_ID>;
+};
+
+&vpu {
+       power-domains = <&pwrc PWRC_G12A_VPU_ID>;
+};
+
+&sd_emmc_a {
+       amlogic,dram-access-quirk;
+};
index 74d03fc..6733050 100644 (file)
                        };
 
                        reset: reset-controller@4404 {
-                               compatible = "amlogic,meson-gx-reset", "amlogic,meson-gxbb-reset";
+                               compatible = "amlogic,meson-gxbb-reset";
                                reg = <0x0 0x04404 0x0 0x9c>;
                                #reset-cells = <1>;
                        };
                        };
 
                        spifc: spi@8c80 {
-                               compatible = "amlogic,meson-gx-spifc", "amlogic,meson-gxbb-spifc";
+                               compatible = "amlogic,meson-gxbb-spifc";
                                reg = <0x0 0x08c80 0x0 0x80>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                        };
 
                        watchdog@98d0 {
-                               compatible = "amlogic,meson-gx-wdt", "amlogic,meson-gxbb-wdt";
+                               compatible = "amlogic,meson-gxbb-wdt";
                                reg = <0x0 0x098d0 0x0 0x10>;
                                clocks = <&xtal>;
                        };
                        };
                };
 
-               periphs: periphs@c8834000 {
+               vdec: video-codec@c8820000 {
+                       compatible = "amlogic,gx-vdec";
+                       reg = <0x0 0xc8820000 0x0 0x10000>,
+                             <0x0 0xc110a580 0x0 0xe4>;
+                       reg-names = "dos", "esparser";
+
+                       interrupts = <GIC_SPI 44 IRQ_TYPE_EDGE_RISING>,
+                                    <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "vdec", "esparser";
+
+                       amlogic,ao-sysctrl = <&sysctrl_AO>;
+                       amlogic,canvas = <&canvas>;
+               };
+
+               periphs: bus@c8834000 {
                        compatible = "simple-bus";
                        reg = <0x0 0xc8834000 0x0 0x2000>;
                        #address-cells = <2>;
                        };
 
                        mailbox: mailbox@404 {
-                               compatible = "amlogic,meson-gx-mhu", "amlogic,meson-gxbb-mhu";
+                               compatible = "amlogic,meson-gxbb-mhu";
                                reg = <0 0x404 0 0x4c>;
                                interrupts = <GIC_SPI 208 IRQ_TYPE_EDGE_RISING>,
                                             <GIC_SPI 209 IRQ_TYPE_EDGE_RISING>,
                        compatible = "amlogic,meson-gxbb-dwmac",
                                     "snps,dwmac-3.70a",
                                     "snps,dwmac";
-                       reg = <0x0 0xc9410000 0x0 0x10000
-                              0x0 0xc8834540 0x0 0x4>;
+                       reg = <0x0 0xc9410000 0x0 0x10000>,
+                             <0x0 0xc8834540 0x0 0x4>;
                        interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "macirq";
+                       rx-fifo-depth = <4096>;
+                       tx-fifo-depth = <2048>;
                        status = "disabled";
                };
 
                vpu: vpu@d0100000 {
                        compatible = "amlogic,meson-gx-vpu";
                        reg = <0x0 0xd0100000 0x0 0x100000>,
-                             <0x0 0xc883c000 0x0 0x1000>,
-                             <0x0 0xc8838000 0x0 0x1000>;
-                       reg-names = "vpu", "hhi", "dmc";
+                             <0x0 0xc883c000 0x0 0x1000>;
+                       reg-names = "vpu", "hhi";
                        interrupts = <GIC_SPI 3 IRQ_TYPE_EDGE_RISING>;
                        #address-cells = <1>;
                        #size-cells = <0>;
index c34c1c9..233eb1c 100644 (file)
@@ -10,6 +10,7 @@
 
 / {
        compatible = "friendlyarm,nanopi-k2", "amlogic,meson-gxbb";
+       model = "FriendlyARM NanoPi K2";
 
        aliases {
                serial0 = &uart_AO;
index b636912..afcf8a9 100644 (file)
@@ -75,8 +75,8 @@
                gpios-states = <1>;
 
                /* Based on P200 schematics, signal CARD_1.8V/3.3V_CTR */
-               states = <1800000 0
-                         3300000 1>;
+               states = <1800000 0>,
+                        <3300000 1>;
        };
 
        vddio_boot: regulator-vddio_boot {
index 9972b15..6039add 100644 (file)
@@ -77,8 +77,8 @@
                gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
                gpios-states = <0>;
 
-               states = <3300000 0
-                         1800000 1>;
+               states = <3300000 0>,
+                        <1800000 1>;
        };
 
        vcc1v8: regulator-vcc1v8 {
index 56e0dd1..150a82f 100644 (file)
@@ -21,6 +21,6 @@
        phy-mode = "rmii";
 
        snps,reset-gpio = <&gpio GPIOZ_14 0>;
-       snps,reset-delays-us = <0 10000 1000000>;
+       snps,reset-delays-us = <0>, <10000>, <1000000>;
        snps,reset-active-low;
 };
index e8f9258..89f7b41 100644 (file)
@@ -46,8 +46,8 @@
                gpios-states = <1>;
 
                /* Based on P200 schematics, signal CARD_1.8V/3.3V_CTR */
-               states = <1800000 0
-                         3300000 1>;
+               states = <1800000 0>,
+                        <3300000 1>;
 
                regulator-settling-time-up-us = <10000>;
                regulator-settling-time-down-us = <150000>;
index 2bfe699..83b985b 100644 (file)
@@ -12,3 +12,7 @@
        compatible = "wetek,hub", "amlogic,meson-gxbb";
        model = "WeTek Hub";
 };
+
+&ir {
+       linux,rc-map-name = "rc-wetek-hub";
+};
index 0038522..1d32d1f 100644 (file)
@@ -54,3 +54,7 @@
 &usb1 {
        status = "okay";
 };
+
+&ir {
+       linux,rc-map-name = "rc-wetek-play2";
+};
index f734faa..0cb4032 100644 (file)
        compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu";
        power-domains = <&pwrc_vpu>;
 };
+
+&vdec {
+       compatible = "amlogic,gxbb-vdec", "amlogic,gx-vdec";
+       clocks = <&clkc CLKID_DOS_PARSER>,
+                <&clkc CLKID_DOS>,
+                <&clkc CLKID_VDEC_1>,
+                <&clkc CLKID_VDEC_HEVC>;
+       clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc";
+       resets = <&reset RESET_PARSER>;
+       reset-names = "esparser";
+};
index 789c819..dd729ac 100644 (file)
@@ -20,3 +20,7 @@
                reg = <0x0 0x0 0x0 0x40000000>; /* 1 GiB or 2 GiB */
        };
 };
+
+&ir {
+       linux,rc-map-name = "rc-tanix-tx3mini";
+};
index 796baea..c8d74e6 100644 (file)
@@ -38,8 +38,8 @@
                gpios-states = <1>;
 
                /* Based on P200 schematics, signal CARD_1.8V/3.3V_CTR */
-               states = <1800000 0
-                         3300000 1>;
+               states = <1800000 0>,
+                        <3300000 1>;
        };
 
        vddio_boot: regulator-vddio_boot {
index 5499e8d..2a5cd30 100644 (file)
 };
 
 &ir {
-       linux,rc-map-name = "rc-geekbox";
+       linux,rc-map-name = "rc-khadas";
 };
 
 &gpio_ao {
index 26907ac..c433a03 100644 (file)
@@ -38,8 +38,8 @@
                gpios-states = <1>;
 
                /* Based on P200 schematics, signal CARD_1.8V/3.3V_CTR */
-               states = <1800000 0
-                         3300000 1>;
+               states = <1800000 0>,
+                        <3300000 1>;
        };
 
        vddio_boot: regulator-vddio_boot {
index c959456..49ff0a7 100644 (file)
@@ -80,9 +80,6 @@
 };
 
 &ethmac {
-       reg = <0x0 0xc9410000 0x0 0x10000
-              0x0 0xc8834540 0x0 0x4>;
-
        clocks = <&clkc CLKID_ETH>,
                 <&clkc CLKID_FCLK_DIV2>,
                 <&clkc CLKID_MPLL2>;
                        #size-cells = <0>;
 
                        internal_phy: ethernet-phy@8 {
-                               compatible = "ethernet-phy-id0181.4400", "ethernet-phy-ieee802.3-c22";
+                               compatible = "ethernet-phy-id0181.4400";
                                interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <8>;
                                max-speed = <100>;
        compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu";
        power-domains = <&pwrc_vpu>;
 };
+
+&vdec {
+       compatible = "amlogic,gxl-vdec", "amlogic,gx-vdec";
+       clocks = <&clkc CLKID_DOS_PARSER>,
+                <&clkc CLKID_DOS>,
+                <&clkc CLKID_VDEC_1>,
+                <&clkc CLKID_VDEC_HEVC>;
+       clock-names = "dos_parser", "dos", "vdec_1", "vdec_hevc";
+       resets = <&reset RESET_PARSER>;
+       reset-names = "esparser";
+};
index 989d33a..f25ddd1 100644 (file)
        status = "okay";
        pinctrl-0 = <&remote_input_ao_pins>;
        pinctrl-names = "default";
-       linux,rc-map-name = "rc-geekbox";
+       linux,rc-map-name = "rc-khadas";
 };
 
 &pwm_AO_ab {
index 7a85a82..a0e677d 100644 (file)
 &dwc3 {
        phys = <&usb3_phy>, <&usb2_phy0>, <&usb2_phy1>, <&usb2_phy2>;
 };
+
+&vdec {
+       compatible = "amlogic,gxm-vdec", "amlogic,gx-vdec";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-khadas-vim3.dtsi
new file mode 100644 (file)
index 0000000..8647da7
--- /dev/null
@@ -0,0 +1,360 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+
+/ {
+       model = "Khadas VIM3";
+
+       aliases {
+               serial0 = &uart_AO;
+               ethernet0 = &ethmac;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x80000000>;
+       };
+
+       adc-keys {
+               compatible = "adc-keys";
+               io-channels = <&saradc 2>;
+               io-channel-names = "buttons";
+               keyup-threshold-microvolt = <1710000>;
+
+               button-function {
+                       label = "Function";
+                       linux,code = <KEY_FN>;
+                       press-threshold-microvolt = <10000>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               white {
+                       label = "vim3:white:sys";
+                       gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               red {
+                       label = "vim3:red";
+                       gpios = <&gpio_expander 5 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       emmc_pwrseq: emmc-pwrseq {
+               compatible = "mmc-pwrseq-emmc";
+               reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+       };
+
+       gpio-keys-polled {
+               compatible = "gpio-keys-polled";
+               poll-interval = <100>;
+
+               power-button {
+                       label = "power";
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio_ao GPIOAO_7 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+               clocks = <&wifi32k>;
+               clock-names = "ext_clock";
+       };
+
+       dc_in: regulator-dc_in {
+               compatible = "regulator-fixed";
+               regulator-name = "DC_IN";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+
+       vcc_5v: regulator-vcc_5v {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&dc_in>;
+
+               gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
+               enable-active-high;
+       };
+
+       vcc_1v8: regulator-vcc_1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vcc_3v3>;
+               regulator-always-on;
+       };
+
+       vcc_3v3: regulator-vcc_3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vsys_3v3>;
+               regulator-always-on;
+               /* FIXME: actually controlled by VDDCPU_B_EN */
+       };
+
+       vddao_1v8: regulator-vddao_1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDIO_AO1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vsys_3v3>;
+               regulator-always-on;
+       };
+
+       emmc_1v8: regulator-emmc_1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "EMMC_AO1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vcc_3v3>;
+               regulator-always-on;
+       };
+
+       vsys_3v3: regulator-vsys_3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "VSYS_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&dc_in>;
+               regulator-always-on;
+       };
+
+       usb_pwr: regulator-usb_pwr {
+               compatible = "regulator-fixed";
+               regulator-name = "USB_PWR";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc_5v>;
+
+               gpio = <&gpio GPIOA_6 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&hdmi_tx_tmds_out>;
+                       };
+               };
+       };
+
+       wifi32k: wifi32k {
+               compatible = "pwm-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+       };
+};
+
+&cec_AO {
+       pinctrl-0 = <&cec_ao_a_h_pins>;
+       pinctrl-names = "default";
+       status = "disabled";
+       hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+       pinctrl-0 = <&cec_ao_b_h_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+       hdmi-phandle = <&hdmi_tx>;
+};
+
+&ext_mdio {
+       external_phy: ethernet-phy@0 {
+               /* Realtek RTL8211F (0x001cc916) */
+               reg = <0>;
+               max-speed = <1000>;
+
+               interrupt-parent = <&gpio_intc>;
+               /* MAC_INTR on GPIOZ_14 */
+               interrupts = <26 IRQ_TYPE_LEVEL_LOW>;
+       };
+};
+
+&ethmac {
+        pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+        pinctrl-names = "default";
+        status = "okay";
+        phy-mode = "rgmii";
+        phy-handle = <&external_phy>;
+        amlogic,tx-delay-ns = <2>;
+};
+
+&hdmi_tx {
+       status = "okay";
+       pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+       pinctrl-names = "default";
+       hdmi-supply = <&vcc_5v>;
+};
+
+&hdmi_tx_tmds_port {
+       hdmi_tx_tmds_out: endpoint {
+               remote-endpoint = <&hdmi_connector_in>;
+       };
+};
+
+&i2c_AO {
+       status = "okay";
+       pinctrl-0 = <&i2c_ao_sck_pins>, <&i2c_ao_sda_pins>;
+       pinctrl-names = "default";
+
+       gpio_expander: gpio-controller@20 {
+               compatible = "ti,tca6408";
+               reg = <0x20>;
+               vcc-supply = <&vcc_3v3>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       rtc@51 {
+               compatible = "haoyu,hym8563";
+               reg = <0x51>;
+               #clock-cells = <0>;
+       };
+};
+
+&ir {
+       status = "okay";
+       pinctrl-0 = <&remote_input_ao_pins>;
+       pinctrl-names = "default";
+       linux,rc-map-name = "rc-khadas";
+};
+
+&pwm_ef {
+        status = "okay";
+        pinctrl-0 = <&pwm_e_pins>;
+        pinctrl-names = "default";
+};
+
+&saradc {
+       status = "okay";
+       vref-supply = <&vddao_1v8>;
+};
+
+/* SDIO */
+&sd_emmc_a {
+       status = "okay";
+       pinctrl-0 = <&sdio_pins>;
+       pinctrl-1 = <&sdio_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       bus-width = <4>;
+       cap-sd-highspeed;
+       sd-uhs-sdr50;
+       max-frequency = <100000000>;
+
+       non-removable;
+       disable-wp;
+
+       mmc-pwrseq = <&sdio_pwrseq>;
+
+       vmmc-supply = <&vsys_3v3>;
+       vqmmc-supply = <&vddao_1v8>;
+
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+       };
+};
+
+/* SD card */
+&sd_emmc_b {
+       status = "okay";
+       pinctrl-0 = <&sdcard_c_pins>;
+       pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+       pinctrl-names = "default", "clk-gate";
+
+       bus-width = <4>;
+       cap-sd-highspeed;
+       max-frequency = <50000000>;
+       disable-wp;
+
+       cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&vsys_3v3>;
+       vqmmc-supply = <&vsys_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+       status = "okay";
+       pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+       pinctrl-1 = <&emmc_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
+
+       bus-width = <8>;
+       cap-mmc-highspeed;
+       mmc-ddr-1_8v;
+       mmc-hs200-1_8v;
+       max-frequency = <200000000>;
+       disable-wp;
+
+       mmc-pwrseq = <&emmc_pwrseq>;
+       vmmc-supply = <&vcc_3v3>;
+       vqmmc-supply = <&emmc_1v8>;
+};
+
+&uart_A {
+       status = "okay";
+       pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+       pinctrl-names = "default";
+       uart-has-rtscts;
+
+       bluetooth {
+               compatible = "brcm,bcm43438-bt";
+               shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+               max-speed = <2000000>;
+               clocks = <&wifi32k>;
+               clock-names = "lpo";
+       };
+};
+
+&uart_AO {
+       status = "okay";
+       pinctrl-0 = <&uart_ao_a_pins>;
+       pinctrl-names = "default";
+};
+
+&usb2_phy0 {
+       phy-supply = <&dc_in>;
+};
+
+&usb2_phy1 {
+       phy-supply = <&usb_pwr>;
+};
+
+&usb3_pcie_phy {
+       phy-supply = <&usb_pwr>;
+};
+
+&usb {
+       status = "okay";
+       dr_mode = "peripheral";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-khadas-vim3l.dts
new file mode 100644 (file)
index 0000000..5233bd7
--- /dev/null
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+/dts-v1/;
+
+#include "meson-sm1.dtsi"
+#include "meson-khadas-vim3.dtsi"
+
+/ {
+       compatible = "khadas,vim3l", "amlogic,sm1";
+       model = "Khadas VIM3L";
+
+       vddcpu: regulator-vddcpu {
+               /*
+                * Silergy SY8030DEC Regulator.
+                */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDCPU";
+               regulator-min-microvolt = <690000>;
+               regulator-max-microvolt = <1050000>;
+
+               vin-supply = <&vsys_3v3>;
+
+               pwms = <&pwm_AO_cd 1 1250 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu1 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU1_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu2 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU2_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu3 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU3_CLK>;
+       clock-latency = <50000>;
+};
+
+&pwm_AO_cd {
+       pinctrl-0 = <&pwm_ao_d_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin1";
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-sei610.dts
new file mode 100644 (file)
index 0000000..3435aaa
--- /dev/null
@@ -0,0 +1,383 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include "meson-sm1.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+
+/ {
+       compatible = "seirobotics,sei610", "amlogic,sm1";
+       model = "SEI Robotics SEI610";
+
+       aliases {
+               serial0 = &uart_AO;
+               ethernet0 = &ethmac;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       emmc_pwrseq: emmc-pwrseq {
+               compatible = "mmc-pwrseq-emmc";
+               reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys-polled";
+               poll-interval = <100>;
+
+               key1 {
+                       label = "A";
+                       linux,code = <BTN_0>;
+                       gpios = <&gpio GPIOH_6 GPIO_ACTIVE_LOW>;
+               };
+
+               key2 {
+                       label = "B";
+                       linux,code = <BTN_1>;
+                       gpios = <&gpio GPIOH_7 GPIO_ACTIVE_LOW>;
+               };
+
+               key3 {
+                       label = "C";
+                       linux,code = <BTN_2>;
+                       gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&hdmi_tx_tmds_out>;
+                       };
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               bluetooth {
+                       label = "sei610:blue:bt";
+                       gpios = <&gpio GPIOC_7 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>;
+                       default-state = "off";
+               };
+       };
+
+       pwmleds {
+               compatible = "pwm-leds";
+
+               power {
+                       label = "sei610:red:power";
+                       pwms = <&pwm_AO_ab 0 30518 0>;
+                       max-brightness = <255>;
+                       linux,default-trigger = "default-on";
+                       active-low;
+               };
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x40000000>;
+       };
+
+       ao_5v: regulator-ao_5v {
+               compatible = "regulator-fixed";
+               regulator-name = "AO_5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&dc_in>;
+               regulator-always-on;
+       };
+
+       dc_in: regulator-dc_in {
+               compatible = "regulator-fixed";
+               regulator-name = "DC_IN";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+
+       emmc_1v8: regulator-emmc_1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "EMMC_1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vddao_3v3>;
+               regulator-always-on;
+       };
+
+       vddao_3v3: regulator-vddao_3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDAO_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&dc_in>;
+               regulator-always-on;
+       };
+
+       /* Used by Tuner, RGB Led & IR Emitter LED array */
+       vddao_3v3_t: regulator-vddao_3v3_t {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDAO_3V3_T";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vddao_3v3>;
+               gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
+               enable-active-low;
+               regulator-always-on;
+       };
+
+       vddcpu: regulator-vddcpu {
+               /*
+                * SY8120B1ABC DC/DC Regulator.
+                */
+               compatible = "pwm-regulator";
+
+               regulator-name = "VDDCPU";
+               regulator-min-microvolt = <690000>;
+               regulator-max-microvolt = <1050000>;
+
+               vin-supply = <&dc_in>;
+
+               pwms = <&pwm_AO_cd 1 1500 0>;
+               pwm-dutycycle-range = <100 0>;
+
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       vddio_ao1v8: regulator-vddio_ao1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDIO_AO1V8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vddao_3v3>;
+               regulator-always-on;
+       };
+
+       reserved-memory {
+               /* TEE Reserved Memory */
+               bl32_reserved: bl32@5000000 {
+                       reg = <0x0 0x05300000 0x0 0x2000000>;
+                       no-map;
+               };
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+               clocks = <&wifi32k>;
+               clock-names = "ext_clock";
+       };
+
+       wifi32k: wifi32k {
+               compatible = "pwm-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+       };
+};
+
+&cec_AO {
+       pinctrl-0 = <&cec_ao_a_h_pins>;
+       pinctrl-names = "default";
+       status = "disabled";
+       hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+       pinctrl-0 = <&cec_ao_b_h_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+       hdmi-phandle = <&hdmi_tx>;
+};
+
+&cpu0 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu1 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU1_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu2 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU2_CLK>;
+       clock-latency = <50000>;
+};
+
+&cpu3 {
+       cpu-supply = <&vddcpu>;
+       operating-points-v2 = <&cpu_opp_table>;
+       clocks = <&clkc CLKID_CPU3_CLK>;
+       clock-latency = <50000>;
+};
+
+&ethmac {
+       status = "okay";
+       phy-handle = <&internal_ephy>;
+       phy-mode = "rmii";
+};
+
+&hdmi_tx {
+       status = "okay";
+       pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+       pinctrl-names = "default";
+};
+
+&hdmi_tx_tmds_port {
+       hdmi_tx_tmds_out: endpoint {
+               remote-endpoint = <&hdmi_connector_in>;
+       };
+};
+
+&i2c3 {
+       status = "okay";
+       pinctrl-0 = <&i2c3_sda_a_pins>, <&i2c3_sck_a_pins>;
+       pinctrl-names = "default";
+};
+
+&ir {
+       status = "okay";
+       pinctrl-0 = <&remote_input_ao_pins>;
+       pinctrl-names = "default";
+};
+
+&pwm_AO_ab {
+       status = "okay";
+       pinctrl-0 = <&pwm_ao_a_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin0";
+};
+
+&pwm_AO_cd {
+       pinctrl-0 = <&pwm_ao_d_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin1";
+       status = "okay";
+};
+
+&pwm_ef {
+       status = "okay";
+       pinctrl-0 = <&pwm_e_pins>;
+       pinctrl-names = "default";
+       clocks = <&xtal>;
+       clock-names = "clkin0";
+};
+
+&saradc {
+       status = "okay";
+       vref-supply = <&vddio_ao1v8>;
+};
+
+/* SDIO */
+&sd_emmc_a {
+       status = "okay";
+       pinctrl-0 = <&sdio_pins>;
+       pinctrl-1 = <&sdio_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
+       #address-cells = <1>;
+       #size-cells = <0>;
+
+       bus-width = <4>;
+       cap-sd-highspeed;
+       sd-uhs-sdr50;
+       max-frequency = <100000000>;
+
+       non-removable;
+       disable-wp;
+
+       mmc-pwrseq = <&sdio_pwrseq>;
+
+       vmmc-supply = <&vddao_3v3>;
+       vqmmc-supply = <&vddio_ao1v8>;
+
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+       };
+};
+
+/* SD card */
+&sd_emmc_b {
+       status = "okay";
+       pinctrl-0 = <&sdcard_c_pins>;
+       pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+       pinctrl-names = "default", "clk-gate";
+
+       bus-width = <4>;
+       cap-sd-highspeed;
+       max-frequency = <50000000>;
+       disable-wp;
+
+       cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&vddao_3v3>;
+       vqmmc-supply = <&vddao_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+       status = "okay";
+       pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+       pinctrl-1 = <&emmc_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
+
+       bus-width = <8>;
+       cap-mmc-highspeed;
+       mmc-ddr-1_8v;
+       mmc-hs200-1_8v;
+       max-frequency = <200000000>;
+       non-removable;
+       disable-wp;
+
+       mmc-pwrseq = <&emmc_pwrseq>;
+       vmmc-supply = <&vddao_3v3>;
+       vqmmc-supply = <&emmc_1v8>;
+};
+
+&uart_A {
+       status = "okay";
+       pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+       pinctrl-names = "default";
+       uart-has-rtscts;
+
+       bluetooth {
+               compatible = "brcm,bcm43438-bt";
+               shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+               max-speed = <2000000>;
+               clocks = <&wifi32k>;
+               clock-names = "lpo";
+               vbat-supply = <&vddao_3v3>;
+               vddio-supply = <&vddio_ao1v8>;
+       };
+};
+
+/* Exposed via the on-board USB to Serial FT232RL IC */
+&uart_AO {
+       status = "okay";
+       pinctrl-0 = <&uart_ao_a_pins>;
+       pinctrl-names = "default";
+};
+
+&usb {
+       status = "okay";
+       dr_mode = "otg";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi b/arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
new file mode 100644 (file)
index 0000000..521573f
--- /dev/null
@@ -0,0 +1,147 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include "meson-g12-common.dtsi"
+#include <dt-bindings/power/meson-sm1-power.h>
+
+/ {
+       compatible = "amlogic,sm1";
+
+       cpus {
+               #address-cells = <0x2>;
+               #size-cells = <0x0>;
+
+               cpu0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a55";
+                       reg = <0x0 0x0>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+               };
+
+               cpu1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a55";
+                       reg = <0x0 0x1>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+               };
+
+               cpu2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a55";
+                       reg = <0x0 0x2>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+               };
+
+               cpu3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a55";
+                       reg = <0x0 0x3>;
+                       enable-method = "psci";
+                       next-level-cache = <&l2>;
+               };
+
+               l2: l2-cache0 {
+                       compatible = "cache";
+               };
+       };
+
+       cpu_opp_table: opp-table {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-100000000 {
+                       opp-hz = /bits/ 64 <100000000>;
+                       opp-microvolt = <730000>;
+               };
+
+               opp-250000000 {
+                       opp-hz = /bits/ 64 <250000000>;
+                       opp-microvolt = <730000>;
+               };
+
+               opp-500000000 {
+                       opp-hz = /bits/ 64 <500000000>;
+                       opp-microvolt = <730000>;
+               };
+
+               opp-667000000 {
+                       opp-hz = /bits/ 64 <666666666>;
+                       opp-microvolt = <750000>;
+               };
+
+               opp-1000000000 {
+                       opp-hz = /bits/ 64 <1000000000>;
+                       opp-microvolt = <770000>;
+               };
+
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
+                       opp-microvolt = <780000>;
+               };
+
+               opp-1404000000 {
+                       opp-hz = /bits/ 64 <1404000000>;
+                       opp-microvolt = <790000>;
+               };
+
+               opp-1512000000 {
+                       opp-hz = /bits/ 64 <1500000000>;
+                       opp-microvolt = <800000>;
+               };
+
+               opp-1608000000 {
+                       opp-hz = /bits/ 64 <1608000000>;
+                       opp-microvolt = <810000>;
+               };
+
+               opp-1704000000 {
+                       opp-hz = /bits/ 64 <1704000000>;
+                       opp-microvolt = <850000>;
+               };
+
+               opp-1800000000 {
+                       opp-hz = /bits/ 64 <1800000000>;
+                       opp-microvolt = <900000>;
+               };
+
+               opp-1908000000 {
+                       opp-hz = /bits/ 64 <1908000000>;
+                       opp-microvolt = <950000>;
+               };
+       };
+};
+
+&cecb_AO {
+       compatible = "amlogic,meson-sm1-ao-cec";
+};
+
+&clk_msr {
+       compatible = "amlogic,meson-sm1-clk-measure";
+};
+
+
+&clkc {
+       compatible = "amlogic,sm1-clkc";
+};
+
+&ethmac {
+       power-domains = <&pwrc PWRC_SM1_ETH_ID>;
+};
+
+&pwrc {
+       compatible = "amlogic,meson-sm1-pwrc";
+};
+
+&vpu {
+       power-domains = <&pwrc PWRC_SM1_VPU_ID>;
+};
+
+&usb {
+       power-domains = <&pwrc PWRC_SM1_USB_ID>;
+};
index 6877070..62ab0d5 100644 (file)
                                <0 0 42 &gic 0 0 GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
                                <0 0 43 &gic 0 0 GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
                                <0 0 44 &gic 0 0 GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
-
-               motherboard {
-                       iofpga@3,00000000 {
-                               clcd@1f0000 {
-                                       max-memory-bandwidth = <130000000>; /* 16bpp @ 63.5MHz */
-                               };
-                       };
-               };
        };
 };
index 454cf6c..03a7bf0 100644 (file)
                                        interrupts = <14>;
                                        clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>;
                                        clock-names = "clcdclk", "apb_pclk";
-                                       /* 800x600 16bpp @36MHz works fine */
-                                       max-memory-bandwidth = <54000000>;
                                        memory-region = <&vram>;
 
                                        port {
index 7726fd4..d65453f 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/reset/bitmain,bm1880-reset.h>
 
 / {
        compatible = "bitmain,bm1880";
                        #size-cells = <1>;
                        ranges = <0x0 0x0 0x50010000 0x1000>;
 
-                       pinctrl: pinctrl@50 {
+                       pinctrl: pinctrl@400 {
                                compatible = "bitmain,bm1880-pinctrl";
-                               reg = <0x50 0x4B0>;
+                               reg = <0x400 0x120>;
+                       };
+
+                       rst: reset-controller@c00 {
+                               compatible = "bitmain,bm1880-reset";
+                               reg = <0xc00 0x8>;
+                               #reset-cells = <1>;
                        };
                };
 
                        interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
+                       resets = <&rst BM1880_RST_UART0_1_CLK>;
                        status = "disabled";
                };
 
                        interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
+                       resets = <&rst BM1880_RST_UART0_1_ACLK>;
                        status = "disabled";
                };
 
                        interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
+                       resets = <&rst BM1880_RST_UART2_3_CLK>;
                        status = "disabled";
                };
 
                        interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
+                       resets = <&rst BM1880_RST_UART2_3_ACLK>;
                        status = "disabled";
                };
        };
index c043aca..93fce8f 100644 (file)
@@ -8,6 +8,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1028a-rdb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1043a-rdb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-frwy.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-rdb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1088a-qds.dtb
@@ -21,8 +22,13 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb
 
 dtb-$(CONFIG_ARCH_MXC) += imx8mm-evk.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mn-ddr4-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mq-hummingboard-pulse.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-librem5-devkit.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mq-nitrogen.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mq-pico-pi.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-zii-ultra-rmb3.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-zii-ultra-zest.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8qxp-ai_ml.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8qxp-mek.dtb
index ec6257a..124a7e2 100644 (file)
                        #size-cells = <0>;
                        reg = <0x0 0x2180000 0x0 0x10000>;
                        interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 0>;
+                       clocks = <&clockgen 4 3>;
                        status = "disabled";
                };
 
                        #size-cells = <0>;
                        reg = <0x0 0x2190000 0x0 0x10000>;
                        interrupts = <0 57 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 0>;
+                       clocks = <&clockgen 4 3>;
                        status = "disabled";
                };
 
index de6ef39..5e14e5a 100644 (file)
        status = "okay";
 };
 
+&esdhc {
+       status = "okay";
+};
+
+&esdhc1 {
+       status = "okay";
+};
+
 &i2c0 {
        status = "okay";
 
index 9fb9113..1a69221 100644 (file)
        };
 };
 
+&esdhc {
+       sd-uhs-sdr104;
+       sd-uhs-sdr50;
+       sd-uhs-sdr25;
+       sd-uhs-sdr12;
+       status = "okay";
+};
+
+&esdhc1 {
+       mmc-hs200-1_8v;
+       status = "okay";
+};
+
 &i2c0 {
        status = "okay";
 
index 7975519..b139b29 100644 (file)
@@ -29,6 +29,7 @@
                        clocks = <&clockgen 1 0>;
                        next-level-cache = <&l2>;
                        cpu-idle-states = <&CPU_PW20>;
+                       #cooling-cells = <2>;
                };
 
                cpu1: cpu@1 {
@@ -39,6 +40,7 @@
                        clocks = <&clockgen 1 0>;
                        next-level-cache = <&l2>;
                        cpu-idle-states = <&CPU_PW20>;
+                       #cooling-cells = <2>;
                };
 
                l2: l2-cache {
                clock-output-names = "sysclk";
        };
 
-       dpclk: clock-dp {
+       osc_27m: clock-osc-27m {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                clock-frequency = <27000000>;
-               clock-output-names= "dpclk";
+               clock-output-names = "phy_27m";
+       };
+
+       dpclk: clock-controller@f1f0000 {
+               compatible = "fsl,ls1028a-plldig";
+               reg = <0x0 0xf1f0000 0x0 0xffff>;
+               #clock-cells = <1>;
+               clocks = <&osc_27m>;
        };
 
        aclk: clock-axi {
                        #size-cells = <0>;
                        reg = <0x0 0x2000000 0x0 0x10000>;
                        interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 1>;
+                       clocks = <&clockgen 4 3>;
                        status = "disabled";
                };
 
                        #size-cells = <0>;
                        reg = <0x0 0x2010000 0x0 0x10000>;
                        interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 1>;
+                       clocks = <&clockgen 4 3>;
                        status = "disabled";
                };
 
                        #size-cells = <0>;
                        reg = <0x0 0x2020000 0x0 0x10000>;
                        interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 1>;
+                       clocks = <&clockgen 4 3>;
                        status = "disabled";
                };
 
                        #size-cells = <0>;
                        reg = <0x0 0x2030000 0x0 0x10000>;
                        interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 1>;
+                       clocks = <&clockgen 4 3>;
                        status = "disabled";
                };
 
                        #size-cells = <0>;
                        reg = <0x0 0x2040000 0x0 0x10000>;
                        interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 1>;
+                       clocks = <&clockgen 4 3>;
                        status = "disabled";
                };
 
                        #size-cells = <0>;
                        reg = <0x0 0x2050000 0x0 0x10000>;
                        interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 1>;
+                       clocks = <&clockgen 4 3>;
                        status = "disabled";
                };
 
                        #size-cells = <0>;
                        reg = <0x0 0x2060000 0x0 0x10000>;
                        interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 1>;
+                       clocks = <&clockgen 4 3>;
                        status = "disabled";
                };
 
                        #size-cells = <0>;
                        reg = <0x0 0x2070000 0x0 0x10000>;
                        interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 1>;
+                       clocks = <&clockgen 4 3>;
+                       status = "disabled";
+               };
+
+               esdhc: mmc@2140000 {
+                       compatible = "fsl,ls1028a-esdhc", "fsl,esdhc";
+                       reg = <0x0 0x2140000 0x0 0x10000>;
+                       interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-frequency = <0>; /* fixed up by bootloader */
+                       clocks = <&clockgen 2 1>;
+                       voltage-ranges = <1800 1800 3300 3300>;
+                       sdhci,auto-cmd12;
+                       little-endian;
+                       bus-width = <4>;
+                       status = "disabled";
+               };
+
+               esdhc1: mmc@2150000 {
+                       compatible = "fsl,ls1028a-esdhc", "fsl,esdhc";
+                       reg = <0x0 0x2150000 0x0 0x10000>;
+                       interrupts = <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-frequency = <0>; /* fixed up by bootloader */
+                       clocks = <&clockgen 2 1>;
+                       voltage-ranges = <1800 1800 3300 3300>;
+                       sdhci,auto-cmd12;
+                       broken-cd;
+                       little-endian;
+                       bus-width = <4>;
                        status = "disabled";
                };
 
                };
 
                gpio1: gpio@2300000 {
-                       compatible = "fsl,qoriq-gpio";
+                       compatible = "fsl,ls1028a-gpio","fsl,qoriq-gpio";
                        reg = <0x0 0x2300000 0x0 0x10000>;
                        interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
+                       little-endian;
                };
 
                gpio2: gpio@2310000 {
-                       compatible = "fsl,qoriq-gpio";
+                       compatible = "fsl,ls1028a-gpio","fsl,qoriq-gpio";
                        reg = <0x0 0x2310000 0x0 0x10000>;
                        interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
+                       little-endian;
                };
 
                gpio3: gpio@2320000 {
-                       compatible = "fsl,qoriq-gpio";
+                       compatible = "fsl,ls1028a-gpio","fsl,qoriq-gpio";
                        reg = <0x0 0x2320000 0x0 0x10000>;
                        interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
+                       little-endian;
                };
 
                usb0: usb@3100000 {
                        status = "disabled";
                };
 
+               tmu: tmu@1f00000 {
+                       compatible = "fsl,qoriq-tmu";
+                       reg = <0x0 0x1f80000 0x0 0x10000>;
+                       interrupts = <0 23 0x4>;
+                       fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x70061>;
+                       fsl,tmu-calibration = <0x00000000 0x00000024
+                                              0x00000001 0x0000002b
+                                              0x00000002 0x00000031
+                                              0x00000003 0x00000038
+                                              0x00000004 0x0000003f
+                                              0x00000005 0x00000045
+                                              0x00000006 0x0000004c
+                                              0x00000007 0x00000053
+                                              0x00000008 0x00000059
+                                              0x00000009 0x00000060
+                                              0x0000000a 0x00000066
+                                              0x0000000b 0x0000006d
+
+                                              0x00010000 0x0000001c
+                                              0x00010001 0x00000024
+                                              0x00010002 0x0000002c
+                                              0x00010003 0x00000035
+                                              0x00010004 0x0000003d
+                                              0x00010005 0x00000045
+                                              0x00010006 0x0000004d
+                                              0x00010007 0x00000045
+                                              0x00010008 0x0000005e
+                                              0x00010009 0x00000066
+                                              0x0001000a 0x0000006e
+
+                                              0x00020000 0x00000018
+                                              0x00020001 0x00000022
+                                              0x00020002 0x0000002d
+                                              0x00020003 0x00000038
+                                              0x00020004 0x00000043
+                                              0x00020005 0x0000004d
+                                              0x00020006 0x00000058
+                                              0x00020007 0x00000063
+                                              0x00020008 0x0000006e
+
+                                              0x00030000 0x00000010
+                                              0x00030001 0x0000001c
+                                              0x00030002 0x00000029
+                                              0x00030003 0x00000036
+                                              0x00030004 0x00000042
+                                              0x00030005 0x0000004f
+                                              0x00030006 0x0000005b
+                                              0x00030007 0x00000068>;
+                       little-endian;
+                       #thermal-sensor-cells = <1>;
+               };
+
+               thermal-zones {
+                       core-cluster {
+                               polling-delay-passive = <1000>;
+                               polling-delay = <5000>;
+                               thermal-sensors = <&tmu 0>;
+
+                               trips {
+                                       core_cluster_alert: core-cluster-alert {
+                                               temperature = <85000>;
+                                               hysteresis = <2000>;
+                                               type = "passive";
+                                       };
+
+                                       core_cluster_crit: core-cluster-crit {
+                                               temperature = <95000>;
+                                               hysteresis = <2000>;
+                                               type = "critical";
+                                       };
+                               };
+
+                               cooling-maps {
+                                       map0 {
+                                               trip = <&core_cluster_alert>;
+                                               cooling-device =
+                                                       <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                       <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                                       };
+                               };
+                       };
+               };
+
                pcie@1f0000000 { /* Integrated Endpoint Root Complex */
                        compatible = "pci-host-ecam-generic";
                        reg = <0x01 0xf0000000 0x0 0x100000>;
                interrupts = <0 222 IRQ_TYPE_LEVEL_HIGH>,
                             <0 223 IRQ_TYPE_LEVEL_HIGH>;
                interrupt-names = "DE", "SE";
-               clocks = <&dpclk>, <&aclk>, <&aclk>, <&pclk>;
+               clocks = <&dpclk 0>, <&aclk>, <&aclk>, <&pclk>;
                clock-names = "pxlclk", "mclk", "aclk", "pclk";
                arm,malidp-output-port-lines = /bits/ 8 <8 8 8>;
+               arm,malidp-arqos-value = <0xd000d000>;
 
                port {
                        dp0_out: endpoint {
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-frwy.dts
new file mode 100644 (file)
index 0000000..3595be0
--- /dev/null
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Device Tree Include file for Freescale Layerscape-1046A family SoC.
+ *
+ * Copyright 2019 NXP.
+ *
+ */
+
+/dts-v1/;
+
+#include "fsl-ls1046a.dtsi"
+
+/ {
+       model = "LS1046A FRWY Board";
+       compatible = "fsl,ls1046a-frwy", "fsl,ls1046a";
+
+       aliases {
+               serial0 = &duart0;
+               serial1 = &duart1;
+               serial2 = &duart2;
+               serial3 = &duart3;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       sb_3v3: regulator-sb3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "LT8642SEV-3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+};
+
+&duart0 {
+       status = "okay";
+};
+
+&duart1 {
+       status = "okay";
+};
+
+&duart2 {
+       status = "okay";
+};
+
+&duart3 {
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+
+       i2c-mux@77 {
+               compatible = "nxp,pca9546";
+               reg = <0x77>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               i2c@0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0>;
+
+                       power-monitor@40 {
+                               compatible = "ti,ina220";
+                               reg = <0x40>;
+                               shunt-resistor = <1000>;
+                       };
+
+                       temperature-sensor@4c {
+                               compatible = "nxp,sa56004";
+                               reg = <0x4c>;
+                               vcc-supply = <&sb_3v3>;
+                       };
+
+                       rtc@51 {
+                               compatible = "nxp,pcf2129";
+                               reg = <0x51>;
+                       };
+
+                       eeprom@52 {
+                               compatible = "atmel,24c512";
+                               reg = <0x52>;
+                       };
+
+                       eeprom@53 {
+                               compatible = "atmel,24c512";
+                               reg = <0x53>;
+                       };
+
+               };
+       };
+};
+
+&ifc {
+       #address-cells = <2>;
+       #size-cells = <1>;
+       /* NAND Flash */
+       ranges = <0x0 0x0 0x0 0x7e800000 0x00010000>;
+       status = "okay";
+
+       nand@0,0 {
+               compatible = "fsl,ifc-nand";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0x0 0x0 0x10000>;
+       };
+
+};
+
+#include "fsl-ls1046-post.dtsi"
+
+&fman0 {
+       ethernet@e0000 {
+               phy-handle = <&qsgmii_phy4>;
+               phy-connection-type = "qsgmii";
+       };
+
+       ethernet@e8000 {
+               phy-handle = <&qsgmii_phy2>;
+               phy-connection-type = "qsgmii";
+       };
+
+       ethernet@ea000 {
+               phy-handle = <&qsgmii_phy1>;
+               phy-connection-type = "qsgmii";
+       };
+
+       ethernet@f2000 {
+               phy-handle = <&qsgmii_phy3>;
+               phy-connection-type = "qsgmii";
+       };
+
+       mdio@fd000 {
+               qsgmii_phy1: ethernet-phy@1c {
+                       reg = <0x1c>;
+               };
+
+               qsgmii_phy2: ethernet-phy@1d {
+                       reg = <0x1d>;
+               };
+
+               qsgmii_phy3: ethernet-phy@1e {
+                       reg = <0x1e>;
+               };
+
+               qsgmii_phy4: ethernet-phy@1f {
+                       reg = <0x1f>;
+               };
+       };
+};
index 6f48d21..120e62d 100644 (file)
        compatible = "fsl,ls1088a-qds", "fsl,ls1088a";
 };
 
+&dspi {
+       bus-num = <0>;
+       status = "okay";
+
+       flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <1000000>;
+       };
+
+       flash@1 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               spi-cpol;
+               spi-cpha;
+               spi-max-frequency = <3500000>;
+               reg = <1>;
+       };
+
+       flash@2 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               spi-cpol;
+               spi-cpha;
+               spi-max-frequency = <3500000>;
+               reg = <2>;
+       };
+};
+
 &i2c0 {
        status = "okay";
 
index dacd8cf..d1469b0 100644 (file)
                        #thermal-sensor-cells = <1>;
                };
 
+               dspi: spi@2100000 {
+                       compatible = "fsl,ls1088a-dspi",
+                                    "fsl,ls1021a-v1.0-dspi";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x0 0x2100000 0x0 0x10000>;
+                       interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-names = "dspi";
+                       clocks = <&clockgen 4 1>;
+                       spi-num-chipselects = <6>;
+                       status = "disabled";
+               };
+
                duart0: serial@21c0500 {
                        compatible = "fsl,ns16550", "ns16550a";
                        reg = <0x0 0x21c0500 0x0 0x100>;
                };
 
                gpio0: gpio@2300000 {
-                       compatible = "fsl,qoriq-gpio";
+                       compatible = "fsl,ls1088a-gpio", "fsl,qoriq-gpio";
                        reg = <0x0 0x2300000 0x0 0x10000>;
                        interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
+                       little-endian;
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
                };
 
                gpio1: gpio@2310000 {
-                       compatible = "fsl,qoriq-gpio";
+                       compatible = "fsl,ls1088a-gpio", "fsl,qoriq-gpio";
                        reg = <0x0 0x2310000 0x0 0x10000>;
                        interrupts = <0 36 IRQ_TYPE_LEVEL_HIGH>;
+                       little-endian;
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
                };
 
                gpio2: gpio@2320000 {
-                       compatible = "fsl,qoriq-gpio";
+                       compatible = "fsl,ls1088a-gpio", "fsl,qoriq-gpio";
                        reg = <0x0 0x2320000 0x0 0x10000>;
                        interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
+                       little-endian;
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
                };
 
                gpio3: gpio@2330000 {
-                       compatible = "fsl,qoriq-gpio";
+                       compatible = "fsl,ls1088a-gpio", "fsl,qoriq-gpio";
                        reg = <0x0 0x2330000 0x0 0x10000>;
                        interrupts = <0 37 IRQ_TYPE_LEVEL_HIGH>;
+                       little-endian;
                        gpio-controller;
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #size-cells = <0>;
                        reg = <0x0 0x2000000 0x0 0x10000>;
                        interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 3>;
+                       clocks = <&clockgen 4 7>;
                        status = "disabled";
                };
 
                        #size-cells = <0>;
                        reg = <0x0 0x2010000 0x0 0x10000>;
                        interrupts = <0 34 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 3>;
+                       clocks = <&clockgen 4 7>;
                        status = "disabled";
                };
 
                        #size-cells = <0>;
                        reg = <0x0 0x2020000 0x0 0x10000>;
                        interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 3>;
+                       clocks = <&clockgen 4 7>;
                        status = "disabled";
                };
 
                        #size-cells = <0>;
                        reg = <0x0 0x2030000 0x0 0x10000>;
                        interrupts = <0 35 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&clockgen 4 3>;
+                       clocks = <&clockgen 4 7>;
                        status = "disabled";
                };
 
                                     <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
                };
 
+               console@8340020 {
+                       compatible = "fsl,dpaa2-console";
+                       reg = <0x00000000 0x08340020 0 0x2>;
+               };
+
                ptp-timer@8b95000 {
                        compatible = "fsl,dpaa2-ptp";
                        reg = <0x0 0x8b95000 0x0 0x100>;
index 3ace919..64101c9 100644 (file)
                        };
                };
 
+               console@8340020 {
+                       compatible = "fsl,dpaa2-console";
+                       reg = <0x00000000 0x08340020 0 0x2>;
+               };
+
                ptp-timer@8b95000 {
                        compatible = "fsl,dpaa2-ptp";
                        reg = <0x0 0x8b95000 0x0 0x100>;
index e6fdba3..408e0ec 100644 (file)
                        reg = <0x0 0x2000000 0x0 0x10000>;
                        interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "i2c";
-                       clocks = <&clockgen 4 7>;
+                       clocks = <&clockgen 4 15>;
                        scl-gpio = <&gpio2 15 GPIO_ACTIVE_HIGH>;
                        status = "disabled";
                };
                        reg = <0x0 0x2010000 0x0 0x10000>;
                        interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "i2c";
-                       clocks = <&clockgen 4 7>;
+                       clocks = <&clockgen 4 15>;
                        status = "disabled";
                };
 
                        reg = <0x0 0x2020000 0x0 0x10000>;
                        interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "i2c";
-                       clocks = <&clockgen 4 7>;
+                       clocks = <&clockgen 4 15>;
                        status = "disabled";
                };
 
                        reg = <0x0 0x2030000 0x0 0x10000>;
                        interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "i2c";
-                       clocks = <&clockgen 4 7>;
+                       clocks = <&clockgen 4 15>;
                        status = "disabled";
                };
 
                        reg = <0x0 0x2040000 0x0 0x10000>;
                        interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "i2c";
-                       clocks = <&clockgen 4 7>;
+                       clocks = <&clockgen 4 15>;
                        scl-gpio = <&gpio2 16 GPIO_ACTIVE_HIGH>;
                        status = "disabled";
                };
                        reg = <0x0 0x2050000 0x0 0x10000>;
                        interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "i2c";
-                       clocks = <&clockgen 4 7>;
+                       clocks = <&clockgen 4 15>;
                        status = "disabled";
                };
 
                        reg = <0x0 0x2060000 0x0 0x10000>;
                        interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "i2c";
-                       clocks = <&clockgen 4 7>;
+                       clocks = <&clockgen 4 15>;
                        status = "disabled";
                };
 
                        reg = <0x0 0x2070000 0x0 0x10000>;
                        interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
                        clock-names = "i2c";
-                       clocks = <&clockgen 4 7>;
+                       clocks = <&clockgen 4 15>;
                        status = "disabled";
                };
 
                        dma-coherent;
                };
 
+               console@8340020 {
+                       compatible = "fsl,dpaa2-console";
+                       reg = <0x00000000 0x08340020 0 0x2>;
+               };
+
                ptp-timer@8b95000 {
                        compatible = "fsl,dpaa2-ptp";
                        reg = <0x0 0x8b95000 0x0 0x100>;
index ee7f2b2..f7a15f3 100644 (file)
@@ -5,6 +5,7 @@
 
 /dts-v1/;
 
+#include <dt-bindings/usb/pd.h>
 #include "imx8mm.dtsi"
 
 / {
@@ -89,9 +90,6 @@
                ethphy0: ethernet-phy@0 {
                        compatible = "ethernet-phy-ieee802.3-c22";
                        reg = <0>;
-                       at803x,led-act-blind-workaround;
-                       at803x,eee-okay;
-                       at803x,vddio-1p8v;
                };
        };
 };
        status = "okay";
 };
 
+&usbotg1 {
+       dr_mode = "otg";
+       hnp-disable;
+       srp-disable;
+       adp-disable;
+       usb-role-switch;
+       status = "okay";
+
+       port {
+               usb1_drd_sw: endpoint {
+                       remote-endpoint = <&typec1_dr_sw>;
+               };
+       };
+};
+
 &usdhc2 {
        pinctrl-names = "default", "state_100mhz", "state_200mhz";
        pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
        };
 };
 
+&i2c2 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       ptn5110: tcpc@50 {
+               compatible = "nxp,ptn5110";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_typec1>;
+               reg = <0x50>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <11 8>;
+               status = "okay";
+
+               port {
+                       typec1_dr_sw: endpoint {
+                               remote-endpoint = <&usb1_drd_sw>;
+                       };
+               };
+
+               typec1_con: connector {
+                       compatible = "usb-c-connector";
+                       label = "USB-C";
+                       power-role = "dual";
+                       data-role = "dual";
+                       try-power-role = "sink";
+                       source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+                       sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
+                                    PDO_VAR(5000, 20000, 3000)>;
+                       op-sink-microwatt = <15000000>;
+                       self-powered;
+               };
+       };
+};
+
 &iomuxc {
        pinctrl-names = "default";
 
                >;
        };
 
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX8MM_IOMUXC_I2C2_SCL_I2C2_SCL                  0x400001c3
+                       MX8MM_IOMUXC_I2C2_SDA_I2C2_SDA                  0x400001c3
+               >;
+       };
+
        pinctrl_pmic: pmicirq {
                fsl,pins = <
                        MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3               0x41
                >;
        };
 
+       pinctrl_typec1: typec1grp {
+               fsl,pins = <
+                       MX8MM_IOMUXC_SD1_STROBE_GPIO2_IO11      0x159
+               >;
+       };
+
        pinctrl_uart2: uart2grp {
                fsl,pins = <
                        MX8MM_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
index 232a741..984ea7b 100644 (file)
                #address-cells = <1>;
                #size-cells = <0>;
 
+               idle-states {
+                       entry-method = "psci";
+
+                       cpu_pd_wait: cpu-pd-wait {
+                               compatible = "arm,idle-state";
+                               arm,psci-suspend-param = <0x0010033>;
+                               local-timer-stop;
+                               entry-latency-us = <1000>;
+                               exit-latency-us = <700>;
+                               min-residency-us = <2700>;
+                       };
+               };
+
                A53_0: cpu@0 {
                        device_type = "cpu";
                        compatible = "arm,cortex-a53";
@@ -55,6 +68,7 @@
                        operating-points-v2 = <&a53_opp_table>;
                        nvmem-cells = <&cpu_speed_grade>;
                        nvmem-cell-names = "speed_grade";
+                       cpu-idle-states = <&cpu_pd_wait>;
                };
 
                A53_1: cpu@1 {
@@ -66,6 +80,7 @@
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        operating-points-v2 = <&a53_opp_table>;
+                       cpu-idle-states = <&cpu_pd_wait>;
                };
 
                A53_2: cpu@2 {
@@ -77,6 +92,7 @@
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        operating-points-v2 = <&a53_opp_table>;
+                       cpu-idle-states = <&cpu_pd_wait>;
                };
 
                A53_3: cpu@3 {
                        enable-method = "psci";
                        next-level-cache = <&A53_L2>;
                        operating-points-v2 = <&a53_opp_table>;
+                       cpu-idle-states = <&cpu_pd_wait>;
                };
 
                A53_L2: l2-cache0 {
                        opp-microvolt = <850000>;
                        opp-supported-hw = <0xe>, <0x7>;
                        clock-latency-ns = <150000>;
+                       opp-suspend;
                };
 
                opp-1600000000 {
                        opp-microvolt = <900000>;
                        opp-supported-hw = <0xc>, <0x7>;
                        clock-latency-ns = <150000>;
+                       opp-suspend;
                };
 
                opp-1800000000 {
                        opp-hz = /bits/ 64 <1800000000>;
                        opp-microvolt = <1000000>;
-                       /* Consumer only but rely on speed grading */
-                       opp-supported-hw = <0x8>, <0x7>;
+                       opp-supported-hw = <0x8>, <0x3>;
                        clock-latency-ns = <150000>;
+                       opp-suspend;
                };
        };
 
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 10 30>;
                        };
 
                        gpio2: gpio@30210000 {
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 40 21>;
                        };
 
                        gpio3: gpio@30220000 {
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 61 26>;
                        };
 
                        gpio4: gpio@30230000 {
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 87 32>;
                        };
 
                        gpio5: gpio@30240000 {
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 119 30>;
                        };
 
                        wdog1: watchdog@30280000 {
                                         <&clk_ext3>, <&clk_ext4>;
                                clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
                                              "clk_ext3", "clk_ext4";
+                               assigned-clocks = <&clk IMX8MM_CLK_NOC>,
+                                               <&clk IMX8MM_CLK_AUDIO_AHB>,
+                                               <&clk IMX8MM_CLK_IPG_AUDIO_ROOT>,
+                                               <&clk IMX8MM_SYS_PLL3>,
+                                               <&clk IMX8MM_VIDEO_PLL1>;
+                               assigned-clock-parents = <&clk IMX8MM_SYS_PLL3_OUT>,
+                                                        <&clk IMX8MM_SYS_PLL1_800M>;
+                               assigned-clock-rates = <0>,
+                                                       <400000000>,
+                                                       <400000000>,
+                                                       <750000000>,
+                                                       <594000000>;
                        };
 
                        src: reset-controller@30390000 {
-                               compatible = "fsl,imx8mm-src", "syscon";
+                               compatible = "fsl,imx8mm-src", "fsl,imx8mq-src", "syscon";
                                reg = <0x30390000 0x10000>;
                                interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
                                #reset-cells = <1>;
                                interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX8MM_CLK_USB1_CTRL_ROOT>;
                                clock-names = "usb1_ctrl_root_clk";
-                               assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>,
-                                                 <&clk IMX8MM_CLK_USB_CORE_REF>;
-                               assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>,
-                                                        <&clk IMX8MM_SYS_PLL1_100M>;
+                               assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>;
+                               assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>;
                                fsl,usbphy = <&usbphynop1>;
                                fsl,usbmisc = <&usbmisc1 0>;
                                status = "disabled";
                                interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX8MM_CLK_USB1_CTRL_ROOT>;
                                clock-names = "usb1_ctrl_root_clk";
-                               assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>,
-                                                 <&clk IMX8MM_CLK_USB_CORE_REF>;
-                               assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>,
-                                                        <&clk IMX8MM_SYS_PLL1_100M>;
+                               assigned-clocks = <&clk IMX8MM_CLK_USB_BUS>;
+                               assigned-clock-parents = <&clk IMX8MM_SYS_PLL2_500M>;
                                fsl,usbphy = <&usbphynop2>;
                                fsl,usbmisc = <&usbmisc2 0>;
                                status = "disabled";
                        interrupt-controller;
                        interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
                };
+
+               ddr-pmu@3d800000 {
+                       compatible = "fsl,imx8mm-ddr-pmu", "fsl,imx8m-ddr-pmu";
+                       reg = <0x3d800000 0x400000>;
+                       interrupt-parent = <&gic>;
+                       interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+               };
        };
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts b/arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts
new file mode 100644 (file)
index 0000000..11c705d
--- /dev/null
@@ -0,0 +1,348 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2019 NXP
+ */
+
+/dts-v1/;
+
+#include "imx8mn.dtsi"
+
+/ {
+       model = "NXP i.MX8MNano DDR4 EVK board";
+       compatible = "fsl,imx8mn-ddr4-evk", "fsl,imx8mn";
+
+       chosen {
+               stdout-path = &uart2;
+       };
+
+       reg_usdhc2_vmmc: regulator-usdhc2 {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>;
+               regulator-name = "VSD_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+};
+
+&A53_0 {
+       cpu-supply = <&buck2_reg>;
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+
+       pinctrl_fec1: fec1grp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_ENET_MDC_ENET1_MDC         0x3
+                       MX8MN_IOMUXC_ENET_MDIO_ENET1_MDIO       0x3
+                       MX8MN_IOMUXC_ENET_TD3_ENET1_RGMII_TD3   0x1f
+                       MX8MN_IOMUXC_ENET_TD2_ENET1_RGMII_TD2   0x1f
+                       MX8MN_IOMUXC_ENET_TD1_ENET1_RGMII_TD1   0x1f
+                       MX8MN_IOMUXC_ENET_TD0_ENET1_RGMII_TD0   0x1f
+                       MX8MN_IOMUXC_ENET_RD3_ENET1_RGMII_RD3   0x91
+                       MX8MN_IOMUXC_ENET_RD2_ENET1_RGMII_RD2   0x91
+                       MX8MN_IOMUXC_ENET_RD1_ENET1_RGMII_RD1   0x91
+                       MX8MN_IOMUXC_ENET_RD0_ENET1_RGMII_RD0   0x91
+                       MX8MN_IOMUXC_ENET_TXC_ENET1_RGMII_TXC   0x1f
+                       MX8MN_IOMUXC_ENET_RXC_ENET1_RGMII_RXC   0x91
+                       MX8MN_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL     0x91
+                       MX8MN_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL     0x1f
+                       MX8MN_IOMUXC_SAI2_RXC_GPIO4_IO22        0x19
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_I2C1_SCL_I2C1_SCL          0x400001c3
+                       MX8MN_IOMUXC_I2C1_SDA_I2C1_SDA          0x400001c3
+               >;
+       };
+
+       pinctrl_pmic: pmicirq {
+               fsl,pins = <
+                       MX8MN_IOMUXC_GPIO1_IO03_GPIO1_IO3       0x41
+               >;
+       };
+
+       pinctrl_reg_usdhc2_vmmc: regusdhc2vmmc {
+               fsl,pins = <
+                       MX8MN_IOMUXC_SD2_RESET_B_GPIO2_IO19     0x41
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
+                       MX8MN_IOMUXC_UART2_TXD_UART2_DCE_TX     0x140
+               >;
+       };
+
+       pinctrl_usdhc2_gpio: usdhc2grpgpio {
+               fsl,pins = <
+                       MX8MN_IOMUXC_GPIO1_IO15_GPIO1_IO15      0x1c4
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK         0x190
+                       MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD         0x1d0
+                       MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0     0x1d0
+                       MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1     0x1d0
+                       MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2     0x1d0
+                       MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3     0x1d0
+                       MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT  0x1d0
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+               fsl,pins = <
+                       MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK         0x194
+                       MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD         0x1d4
+                       MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0     0x1d4
+                       MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1     0x1d4
+                       MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2     0x1d4
+                       MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3     0x1d4
+                       MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT  0x1d0
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+               fsl,pins = <
+                       MX8MN_IOMUXC_SD2_CLK_USDHC2_CLK         0x196
+                       MX8MN_IOMUXC_SD2_CMD_USDHC2_CMD         0x1d6
+                       MX8MN_IOMUXC_SD2_DATA0_USDHC2_DATA0     0x1d6
+                       MX8MN_IOMUXC_SD2_DATA1_USDHC2_DATA1     0x1d6
+                       MX8MN_IOMUXC_SD2_DATA2_USDHC2_DATA2     0x1d6
+                       MX8MN_IOMUXC_SD2_DATA3_USDHC2_DATA3     0x1d6
+                       MX8MN_IOMUXC_GPIO1_IO04_USDHC2_VSELECT  0x1d0
+               >;
+       };
+
+       pinctrl_usdhc3: usdhc3grp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK               0x40000190
+                       MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD               0x1d0
+                       MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0           0x1d0
+                       MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1           0x1d0
+                       MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2           0x1d0
+                       MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3           0x1d0
+                       MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4             0x1d0
+                       MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5            0x1d0
+                       MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6            0x1d0
+                       MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7              0x1d0
+                       MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE           0x190
+               >;
+       };
+
+       pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+               fsl,pins = <
+                       MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK               0x40000194
+                       MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD               0x1d4
+                       MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0           0x1d4
+                       MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1           0x1d4
+                       MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2           0x1d4
+                       MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3           0x1d4
+                       MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4             0x1d4
+                       MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5            0x1d4
+                       MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6            0x1d4
+                       MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7              0x1d4
+                       MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE           0x194
+               >;
+       };
+
+       pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+               fsl,pins = <
+                       MX8MN_IOMUXC_NAND_WE_B_USDHC3_CLK               0x40000196
+                       MX8MN_IOMUXC_NAND_WP_B_USDHC3_CMD               0x1d6
+                       MX8MN_IOMUXC_NAND_DATA04_USDHC3_DATA0           0x1d6
+                       MX8MN_IOMUXC_NAND_DATA05_USDHC3_DATA1           0x1d6
+                       MX8MN_IOMUXC_NAND_DATA06_USDHC3_DATA2           0x1d6
+                       MX8MN_IOMUXC_NAND_DATA07_USDHC3_DATA3           0x1d6
+                       MX8MN_IOMUXC_NAND_RE_B_USDHC3_DATA4             0x1d6
+                       MX8MN_IOMUXC_NAND_CE2_B_USDHC3_DATA5            0x1d6
+                       MX8MN_IOMUXC_NAND_CE3_B_USDHC3_DATA6            0x1d6
+                       MX8MN_IOMUXC_NAND_CLE_USDHC3_DATA7              0x1d6
+                       MX8MN_IOMUXC_NAND_CE1_B_USDHC3_STROBE           0x196
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B            0xc6
+               >;
+       };
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
+       phy-mode = "rgmii-id";
+       phy-handle = <&ethphy0>;
+       fsl,magic-packet;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@0 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <0>;
+                       at803x,led-act-blind-workaround;
+                       at803x,eee-disabled;
+                       at803x,vddio-1p8v;
+               };
+       };
+};
+
+&i2c1 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pmic@4b {
+               compatible = "rohm,bd71847";
+               reg = <0x4b>;
+               pinctrl-0 = <&pinctrl_pmic>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <3 GPIO_ACTIVE_LOW>;
+               rohm,reset-snvs-powered;
+
+               regulators {
+                       buck1_reg: BUCK1 {
+                               regulator-name = "BUCK1";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <1250>;
+                       };
+
+                       buck2_reg: BUCK2 {
+                               regulator-name = "BUCK2";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <1250>;
+                       };
+
+                       buck3_reg: BUCK3 {
+                               // BUCK5 in datasheet
+                               regulator-name = "BUCK3";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1350000>;
+                       };
+
+                       buck4_reg: BUCK4 {
+                               // BUCK6 in datasheet
+                               regulator-name = "BUCK4";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       buck5_reg: BUCK5 {
+                               // BUCK7 in datasheet
+                               regulator-name = "BUCK5";
+                               regulator-min-microvolt = <1605000>;
+                               regulator-max-microvolt = <1995000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       buck6_reg: BUCK6 {
+                               // BUCK8 in datasheet
+                               regulator-name = "BUCK6";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1400000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo1_reg: LDO1 {
+                               regulator-name = "LDO1";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo2_reg: LDO2 {
+                               regulator-name = "LDO2";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo3_reg: LDO3 {
+                               regulator-name = "LDO3";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo4_reg: LDO4 {
+                               regulator-name = "LDO4";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo6_reg: LDO6 {
+                               regulator-name = "LDO6";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
+&snvs_pwrkey {
+       status = "okay";
+};
+
+&uart2 { /* console */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&usdhc2 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+       cd-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
+       bus-width = <4>;
+       vmmc-supply = <&reg_usdhc2_vmmc>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn.dtsi b/arch/arm64/boot/dts/freescale/imx8mn.dtsi
new file mode 100644 (file)
index 0000000..785f4c4
--- /dev/null
@@ -0,0 +1,758 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2019 NXP
+ */
+
+#include <dt-bindings/clock/imx8mn-clock.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+#include "imx8mn-pinfunc.h"
+
+/ {
+       compatible = "fsl,imx8mn";
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               ethernet0 = &fec1;
+               gpio0 = &gpio1;
+               gpio1 = &gpio2;
+               gpio2 = &gpio3;
+               gpio3 = &gpio4;
+               gpio4 = &gpio5;
+               i2c0 = &i2c1;
+               i2c1 = &i2c2;
+               i2c2 = &i2c3;
+               i2c3 = &i2c4;
+               mmc0 = &usdhc1;
+               mmc1 = &usdhc2;
+               mmc2 = &usdhc3;
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+               serial3 = &uart4;
+               spi0 = &ecspi1;
+               spi1 = &ecspi2;
+               spi2 = &ecspi3;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               A53_0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x0>;
+                       clock-latency = <61036>;
+                       clocks = <&clk IMX8MN_CLK_ARM>;
+                       enable-method = "psci";
+                       next-level-cache = <&A53_L2>;
+                       operating-points-v2 = <&a53_opp_table>;
+                       nvmem-cells = <&cpu_speed_grade>;
+                       nvmem-cell-names = "speed_grade";
+               };
+
+               A53_1: cpu@1 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x1>;
+                       clock-latency = <61036>;
+                       clocks = <&clk IMX8MN_CLK_ARM>;
+                       enable-method = "psci";
+                       next-level-cache = <&A53_L2>;
+                       operating-points-v2 = <&a53_opp_table>;
+               };
+
+               A53_2: cpu@2 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x2>;
+                       clock-latency = <61036>;
+                       clocks = <&clk IMX8MN_CLK_ARM>;
+                       enable-method = "psci";
+                       next-level-cache = <&A53_L2>;
+                       operating-points-v2 = <&a53_opp_table>;
+               };
+
+               A53_3: cpu@3 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a53";
+                       reg = <0x3>;
+                       clock-latency = <61036>;
+                       clocks = <&clk IMX8MN_CLK_ARM>;
+                       enable-method = "psci";
+                       next-level-cache = <&A53_L2>;
+                       operating-points-v2 = <&a53_opp_table>;
+               };
+
+               A53_L2: l2-cache0 {
+                       compatible = "cache";
+               };
+       };
+
+       a53_opp_table: opp-table {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-1200000000 {
+                       opp-hz = /bits/ 64 <1200000000>;
+                       opp-microvolt = <850000>;
+                       opp-supported-hw = <0xb00>, <0x7>;
+                       clock-latency-ns = <150000>;
+                       opp-suspend;
+               };
+
+               opp-1400000000 {
+                       opp-hz = /bits/ 64 <1400000000>;
+                       opp-microvolt = <950000>;
+                       opp-supported-hw = <0x300>, <0x7>;
+                       clock-latency-ns = <150000>;
+                       opp-suspend;
+               };
+
+               opp-1500000000 {
+                       opp-hz = /bits/ 64 <1500000000>;
+                       opp-microvolt = <1000000>;
+                       opp-supported-hw = <0x100>, <0x3>;
+                       clock-latency-ns = <150000>;
+                       opp-suspend;
+               };
+       };
+
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0x0 0x40000000 0 0x80000000>;
+       };
+
+       osc_32k: clock-osc-32k {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               clock-output-names = "osc_32k";
+       };
+
+       osc_24m: clock-osc-24m {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <24000000>;
+               clock-output-names = "osc_24m";
+       };
+
+       clk_ext1: clock-ext1 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <133000000>;
+               clock-output-names = "clk_ext1";
+       };
+
+       clk_ext2: clock-ext2 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <133000000>;
+               clock-output-names = "clk_ext2";
+       };
+
+       clk_ext3: clock-ext3 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <133000000>;
+               clock-output-names = "clk_ext3";
+       };
+
+       clk_ext4: clock-ext4 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency= <133000000>;
+               clock-output-names = "clk_ext4";
+       };
+
+       psci {
+               compatible = "arm,psci-1.0";
+               method = "smc";
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>,
+                            <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>;
+               clock-frequency = <8000000>;
+               arm,no-tick-in-suspend;
+       };
+
+       soc@0 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x0 0x0 0x3e000000>;
+
+               aips1: bus@30000000 {
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       reg = <0x30000000 0x400000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       gpio1: gpio@30200000 {
+                               compatible = "fsl,imx8mn-gpio", "fsl,imx35-gpio";
+                               reg = <0x30200000 0x10000>;
+                               interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_GPIO1_ROOT>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 10 30>;
+                       };
+
+                       gpio2: gpio@30210000 {
+                               compatible = "fsl,imx8mn-gpio", "fsl,imx35-gpio";
+                               reg = <0x30210000 0x10000>;
+                               interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_GPIO2_ROOT>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 40 21>;
+                       };
+
+                       gpio3: gpio@30220000 {
+                               compatible = "fsl,imx8mn-gpio", "fsl,imx35-gpio";
+                               reg = <0x30220000 0x10000>;
+                               interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_GPIO3_ROOT>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 61 26>;
+                       };
+
+                       gpio4: gpio@30230000 {
+                               compatible = "fsl,imx8mn-gpio", "fsl,imx35-gpio";
+                               reg = <0x30230000 0x10000>;
+                               interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_GPIO4_ROOT>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 21 108 11>;
+                       };
+
+                       gpio5: gpio@30240000 {
+                               compatible = "fsl,imx8mn-gpio", "fsl,imx35-gpio";
+                               reg = <0x30240000 0x10000>;
+                               interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_GPIO5_ROOT>;
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 119 30>;
+                       };
+
+                       wdog1: watchdog@30280000 {
+                               compatible = "fsl,imx8mn-wdt", "fsl,imx21-wdt";
+                               reg = <0x30280000 0x10000>;
+                               interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_WDOG1_ROOT>;
+                               status = "disabled";
+                       };
+
+                       wdog2: watchdog@30290000 {
+                               compatible = "fsl,imx8mn-wdt", "fsl,imx21-wdt";
+                               reg = <0x30290000 0x10000>;
+                               interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_WDOG2_ROOT>;
+                               status = "disabled";
+                       };
+
+                       wdog3: watchdog@302a0000 {
+                               compatible = "fsl,imx8mn-wdt", "fsl,imx21-wdt";
+                               reg = <0x302a0000 0x10000>;
+                               interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_WDOG3_ROOT>;
+                               status = "disabled";
+                       };
+
+                       sdma3: dma-controller@302b0000 {
+                               compatible = "fsl,imx8mn-sdma", "fsl,imx7d-sdma";
+                               reg = <0x302b0000 0x10000>;
+                               interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_SDMA3_ROOT>,
+                                <&clk IMX8MN_CLK_SDMA3_ROOT>;
+                               clock-names = "ipg", "ahb";
+                               #dma-cells = <3>;
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
+                       };
+
+                       sdma2: dma-controller@302c0000 {
+                               compatible = "fsl,imx8mn-sdma", "fsl,imx7d-sdma";
+                               reg = <0x302c0000 0x10000>;
+                               interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_SDMA2_ROOT>,
+                                        <&clk IMX8MN_CLK_SDMA2_ROOT>;
+                               clock-names = "ipg", "ahb";
+                               #dma-cells = <3>;
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
+                       };
+
+                       iomuxc: pinctrl@30330000 {
+                               compatible = "fsl,imx8mn-iomuxc";
+                               reg = <0x30330000 0x10000>;
+                       };
+
+                       gpr: iomuxc-gpr@30340000 {
+                               compatible = "fsl,imx8mn-iomuxc-gpr", "syscon";
+                               reg = <0x30340000 0x10000>;
+                       };
+
+                       ocotp: ocotp-ctrl@30350000 {
+                               compatible = "fsl,imx8mn-ocotp", "fsl,imx7d-ocotp", "syscon";
+                               reg = <0x30350000 0x10000>;
+                               clocks = <&clk IMX8MN_CLK_OCOTP_ROOT>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               cpu_speed_grade: speed-grade@10 {
+                                       reg = <0x10 4>;
+                               };
+                       };
+
+                       anatop: anatop@30360000 {
+                               compatible = "fsl,imx8mn-anatop", "fsl,imx8mm-anatop",
+                                            "syscon", "simple-bus";
+                               reg = <0x30360000 0x10000>;
+                       };
+
+                       snvs: snvs@30370000 {
+                               compatible = "fsl,sec-v4.0-mon","syscon", "simple-mfd";
+                               reg = <0x30370000 0x10000>;
+
+                               snvs_rtc: snvs-rtc-lp {
+                                       compatible = "fsl,sec-v4.0-mon-rtc-lp";
+                                       regmap = <&snvs>;
+                                       offset = <0x34>;
+                                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+                                                    <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
+                                       clock-names = "snvs-rtc";
+                               };
+
+                               snvs_pwrkey: snvs-powerkey {
+                                       compatible = "fsl,sec-v4.0-pwrkey";
+                                       regmap = <&snvs>;
+                                       interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                                       linux,keycode = <KEY_POWER>;
+                                       wakeup-source;
+                                       status = "disabled";
+                               };
+                       };
+
+                       clk: clock-controller@30380000 {
+                               compatible = "fsl,imx8mn-ccm";
+                               reg = <0x30380000 0x10000>;
+                               #clock-cells = <1>;
+                               clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>,
+                                        <&clk_ext3>, <&clk_ext4>;
+                               clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2",
+                                             "clk_ext3", "clk_ext4";
+                       };
+
+                       src: reset-controller@30390000 {
+                               compatible = "fsl,imx8mn-src", "syscon";
+                               reg = <0x30390000 0x10000>;
+                               interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+                               #reset-cells = <1>;
+                       };
+               };
+
+               aips2: bus@30400000 {
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       reg = <0x30400000 0x400000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       pwm1: pwm@30660000 {
+                               compatible = "fsl,imx8mn-pwm", "fsl,imx27-pwm";
+                               reg = <0x30660000 0x10000>;
+                               interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_PWM1_ROOT>,
+                                       <&clk IMX8MN_CLK_PWM1_ROOT>;
+                               clock-names = "ipg", "per";
+                               #pwm-cells = <2>;
+                               status = "disabled";
+                       };
+
+                       pwm2: pwm@30670000 {
+                               compatible = "fsl,imx8mn-pwm", "fsl,imx27-pwm";
+                               reg = <0x30670000 0x10000>;
+                               interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_PWM2_ROOT>,
+                                        <&clk IMX8MN_CLK_PWM2_ROOT>;
+                               clock-names = "ipg", "per";
+                               #pwm-cells = <2>;
+                               status = "disabled";
+                       };
+
+                       pwm3: pwm@30680000 {
+                               compatible = "fsl,imx8mn-pwm", "fsl,imx27-pwm";
+                               reg = <0x30680000 0x10000>;
+                               interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_PWM3_ROOT>,
+                                        <&clk IMX8MN_CLK_PWM3_ROOT>;
+                               clock-names = "ipg", "per";
+                               #pwm-cells = <2>;
+                               status = "disabled";
+                       };
+
+                       pwm4: pwm@30690000 {
+                               compatible = "fsl,imx8mn-pwm", "fsl,imx27-pwm";
+                               reg = <0x30690000 0x10000>;
+                               interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_PWM4_ROOT>,
+                                        <&clk IMX8MN_CLK_PWM4_ROOT>;
+                               clock-names = "ipg", "per";
+                               #pwm-cells = <2>;
+                               status = "disabled";
+                       };
+               };
+
+               aips3: bus@30800000 {
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       reg = <0x30800000 0x400000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       ecspi1: spi@30820000 {
+                               compatible = "fsl,imx8mn-ecspi", "fsl,imx51-ecspi";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x30820000 0x10000>;
+                               interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_ECSPI1_ROOT>,
+                                        <&clk IMX8MN_CLK_ECSPI1_ROOT>;
+                               clock-names = "ipg", "per";
+                               dmas = <&sdma1 0 7 1>, <&sdma1 1 7 2>;
+                               dma-names = "rx", "tx";
+                               status = "disabled";
+                       };
+
+                       ecspi2: spi@30830000 {
+                               compatible = "fsl,imx8mn-ecspi", "fsl,imx51-ecspi";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x30830000 0x10000>;
+                               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_ECSPI2_ROOT>,
+                                        <&clk IMX8MN_CLK_ECSPI2_ROOT>;
+                               clock-names = "ipg", "per";
+                               dmas = <&sdma1 2 7 1>, <&sdma1 3 7 2>;
+                               dma-names = "rx", "tx";
+                               status = "disabled";
+                       };
+
+                       ecspi3: spi@30840000 {
+                               compatible = "fsl,imx8mn-ecspi", "fsl,imx51-ecspi";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x30840000 0x10000>;
+                               interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_ECSPI3_ROOT>,
+                                        <&clk IMX8MN_CLK_ECSPI3_ROOT>;
+                               clock-names = "ipg", "per";
+                               dmas = <&sdma1 4 7 1>, <&sdma1 5 7 2>;
+                               dma-names = "rx", "tx";
+                               status = "disabled";
+                       };
+
+                       uart1: serial@30860000 {
+                               compatible = "fsl,imx8mn-uart", "fsl,imx6q-uart";
+                               reg = <0x30860000 0x10000>;
+                               interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_UART1_ROOT>,
+                                        <&clk IMX8MN_CLK_UART1_ROOT>;
+                               clock-names = "ipg", "per";
+                               dmas = <&sdma1 22 4 0>, <&sdma1 23 4 0>;
+                               dma-names = "rx", "tx";
+                               status = "disabled";
+                       };
+
+                       uart3: serial@30880000 {
+                               compatible = "fsl,imx8mn-uart", "fsl,imx6q-uart";
+                               reg = <0x30880000 0x10000>;
+                               interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_UART3_ROOT>,
+                                        <&clk IMX8MN_CLK_UART3_ROOT>;
+                               clock-names = "ipg", "per";
+                               dmas = <&sdma1 26 4 0>, <&sdma1 27 4 0>;
+                               dma-names = "rx", "tx";
+                               status = "disabled";
+                       };
+
+                       uart2: serial@30890000 {
+                               compatible = "fsl,imx8mn-uart", "fsl,imx6q-uart";
+                               reg = <0x30890000 0x10000>;
+                               interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_UART2_ROOT>,
+                                        <&clk IMX8MN_CLK_UART2_ROOT>;
+                               clock-names = "ipg", "per";
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@30a20000 {
+                               compatible = "fsl,imx8mn-i2c", "fsl,imx21-i2c";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x30a20000 0x10000>;
+                               interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_I2C1_ROOT>;
+                               status = "disabled";
+                       };
+
+                       i2c2: i2c@30a30000 {
+                               compatible = "fsl,imx8mn-i2c", "fsl,imx21-i2c";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x30a30000 0x10000>;
+                               interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_I2C2_ROOT>;
+                               status = "disabled";
+                       };
+
+                       i2c3: i2c@30a40000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx8mn-i2c", "fsl,imx21-i2c";
+                               reg = <0x30a40000 0x10000>;
+                               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_I2C3_ROOT>;
+                               status = "disabled";
+                       };
+
+                       i2c4: i2c@30a50000 {
+                               compatible = "fsl,imx8mn-i2c", "fsl,imx21-i2c";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0x30a50000 0x10000>;
+                               interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_I2C4_ROOT>;
+                               status = "disabled";
+                       };
+
+                       uart4: serial@30a60000 {
+                               compatible = "fsl,imx8mn-uart", "fsl,imx6q-uart";
+                               reg = <0x30a60000 0x10000>;
+                               interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_UART4_ROOT>,
+                                        <&clk IMX8MN_CLK_UART4_ROOT>;
+                               clock-names = "ipg", "per";
+                               dmas = <&sdma1 28 4 0>, <&sdma1 29 4 0>;
+                               dma-names = "rx", "tx";
+                               status = "disabled";
+                       };
+
+                       usdhc1: mmc@30b40000 {
+                               compatible = "fsl,imx8mn-usdhc", "fsl,imx7d-usdhc";
+                               reg = <0x30b40000 0x10000>;
+                               interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_DUMMY>,
+                                        <&clk IMX8MN_CLK_NAND_USDHC_BUS>,
+                                        <&clk IMX8MN_CLK_USDHC1_ROOT>;
+                               clock-names = "ipg", "ahb", "per";
+                               assigned-clocks = <&clk IMX8MN_CLK_USDHC1>;
+                               assigned-clock-rates = <400000000>;
+                               fsl,tuning-start-tap = <20>;
+                               fsl,tuning-step= <2>;
+                               bus-width = <4>;
+                               status = "disabled";
+                       };
+
+                       usdhc2: mmc@30b50000 {
+                               compatible = "fsl,imx8mn-usdhc", "fsl,imx7d-usdhc";
+                               reg = <0x30b50000 0x10000>;
+                               interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_DUMMY>,
+                                        <&clk IMX8MN_CLK_NAND_USDHC_BUS>,
+                                        <&clk IMX8MN_CLK_USDHC2_ROOT>;
+                               clock-names = "ipg", "ahb", "per";
+                               fsl,tuning-start-tap = <20>;
+                               fsl,tuning-step= <2>;
+                               bus-width = <4>;
+                               status = "disabled";
+                       };
+
+                       usdhc3: mmc@30b60000 {
+                               compatible = "fsl,imx8mn-usdhc", "fsl,imx7d-usdhc";
+                               reg = <0x30b60000 0x10000>;
+                               interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_DUMMY>,
+                                        <&clk IMX8MN_CLK_NAND_USDHC_BUS>,
+                                        <&clk IMX8MN_CLK_USDHC3_ROOT>;
+                               clock-names = "ipg", "ahb", "per";
+                               assigned-clocks = <&clk IMX8MN_CLK_USDHC3_ROOT>;
+                               assigned-clock-rates = <400000000>;
+                               fsl,tuning-start-tap = <20>;
+                               fsl,tuning-step= <2>;
+                               bus-width = <4>;
+                               status = "disabled";
+                       };
+
+                       sdma1: dma-controller@30bd0000 {
+                               compatible = "fsl,imx8mn-sdma", "fsl,imx7d-sdma";
+                               reg = <0x30bd0000 0x10000>;
+                               interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_SDMA1_ROOT>,
+                                        <&clk IMX8MN_CLK_SDMA1_ROOT>;
+                               clock-names = "ipg", "ahb";
+                               #dma-cells = <3>;
+                               fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
+                       };
+
+                       fec1: ethernet@30be0000 {
+                               compatible = "fsl,imx8mn-fec", "fsl,imx6sx-fec";
+                               reg = <0x30be0000 0x10000>;
+                               interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_ENET1_ROOT>,
+                                        <&clk IMX8MN_CLK_ENET1_ROOT>,
+                                        <&clk IMX8MN_CLK_ENET_TIMER>,
+                                        <&clk IMX8MN_CLK_ENET_REF>,
+                                        <&clk IMX8MN_CLK_ENET_PHY_REF>;
+                               clock-names = "ipg", "ahb", "ptp",
+                                             "enet_clk_ref", "enet_out";
+                               assigned-clocks = <&clk IMX8MN_CLK_ENET_AXI>,
+                                                 <&clk IMX8MN_CLK_ENET_TIMER>,
+                                                 <&clk IMX8MN_CLK_ENET_REF>,
+                                                 <&clk IMX8MN_CLK_ENET_TIMER>;
+                               assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_266M>,
+                                                        <&clk IMX8MN_SYS_PLL2_100M>,
+                                                        <&clk IMX8MN_SYS_PLL2_125M>;
+                               assigned-clock-rates = <0>, <0>, <125000000>, <100000000>;
+                               fsl,num-tx-queues = <3>;
+                               fsl,num-rx-queues = <3>;
+                               status = "disabled";
+                       };
+
+               };
+
+               aips4: bus@32c00000 {
+                       compatible = "fsl,aips-bus", "simple-bus";
+                       reg = <0x32c00000 0x400000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       usbotg1: usb@32e40000 {
+                               compatible = "fsl,imx8mn-usb", "fsl,imx7d-usb";
+                               reg = <0x32e40000 0x200>;
+                               interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_USB1_CTRL_ROOT>;
+                               clock-names = "usb1_ctrl_root_clk";
+                               assigned-clocks = <&clk IMX8MN_CLK_USB_BUS>,
+                                                 <&clk IMX8MN_CLK_USB_CORE_REF>;
+                               assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>,
+                                                        <&clk IMX8MN_SYS_PLL1_100M>;
+                               fsl,usbphy = <&usbphynop1>;
+                               fsl,usbmisc = <&usbmisc1 0>;
+                               status = "disabled";
+                       };
+
+                       usbmisc1: usbmisc@32e40200 {
+                               compatible = "fsl,imx8mn-usbmisc", "fsl,imx7d-usbmisc";
+                               #index-cells = <1>;
+                               reg = <0x32e40200 0x200>;
+                       };
+
+                       usbotg2: usb@32e50000 {
+                               compatible = "fsl,imx8mn-usb", "fsl,imx7d-usb";
+                               reg = <0x32e50000 0x200>;
+                               interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_USB1_CTRL_ROOT>;
+                               clock-names = "usb1_ctrl_root_clk";
+                               assigned-clocks = <&clk IMX8MN_CLK_USB_BUS>,
+                                                 <&clk IMX8MN_CLK_USB_CORE_REF>;
+                               assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>,
+                                                        <&clk IMX8MN_SYS_PLL1_100M>;
+                               fsl,usbphy = <&usbphynop2>;
+                               fsl,usbmisc = <&usbmisc2 0>;
+                               status = "disabled";
+                       };
+
+                       usbmisc2: usbmisc@32e50200 {
+                               compatible = "fsl,imx8mn-usbmisc", "fsl,imx7d-usbmisc";
+                               #index-cells = <1>;
+                               reg = <0x32e50200 0x200>;
+                       };
+
+               };
+
+               dma_apbh: dma-controller@33000000 {
+                       compatible = "fsl,imx7d-dma-apbh", "fsl,imx28-dma-apbh";
+                       reg = <0x33000000 0x2000>;
+                       interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+                       #dma-cells = <1>;
+                       dma-channels = <4>;
+                       clocks = <&clk IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK>;
+               };
+
+               gpmi: nand-controller@33002000 {
+                       compatible = "fsl,imx8mn-gpmi-nand", "fsl,imx7d-gpmi-nand";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x33002000 0x2000>, <0x33004000 0x4000>;
+                       reg-names = "gpmi-nand", "bch";
+                       interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "bch";
+                       clocks = <&clk IMX8MN_CLK_NAND_ROOT>,
+                                <&clk IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK>;
+                       clock-names = "gpmi_io", "gpmi_bch_apb";
+                       dmas = <&dma_apbh 0>;
+                       dma-names = "rx-tx";
+                       status = "disabled";
+               };
+
+               gic: interrupt-controller@38800000 {
+                       compatible = "arm,gic-v3";
+                       reg = <0x38800000 0x10000>,
+                             <0x38880000 0xc0000>;
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+               };
+       };
+
+       usbphynop1: usbphynop1 {
+               compatible = "usb-nop-xceiv";
+               clocks = <&clk IMX8MN_CLK_USB_PHY_REF>;
+               assigned-clocks = <&clk IMX8MN_CLK_USB_PHY_REF>;
+               assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_100M>;
+               clock-names = "main_clk";
+       };
+
+       usbphynop2: usbphynop2 {
+               compatible = "usb-nop-xceiv";
+               clocks = <&clk IMX8MN_CLK_USB_PHY_REF>;
+               assigned-clocks = <&clk IMX8MN_CLK_USB_PHY_REF>;
+               assigned-clock-parents = <&clk IMX8MN_SYS_PLL1_100M>;
+               clock-names = "main_clk";
+       };
+};
index e3df9b8..0595812 100644 (file)
 &sai2 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_sai2>;
-       assigned-clocks = <&clk IMX8MQ_CLK_SAI2>;
-       assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>;
-       assigned-clock-rates = <24576000>;
+       assigned-clocks = <&clk IMX8MQ_AUDIO_PLL1_BYPASS>, <&clk IMX8MQ_CLK_SAI2>;
+       assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1>, <&clk IMX8MQ_AUDIO_PLL1_OUT>;
+       assigned-clock-rates = <0>, <24576000>;
        status = "okay";
 };
 
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts b/arch/arm64/boot/dts/freescale/imx8mq-hummingboard-pulse.dts
new file mode 100644 (file)
index 0000000..f52e872
--- /dev/null
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2018 Jon Nettleton <jon@solid-run.com>
+ */
+
+/dts-v1/;
+
+#include "dt-bindings/usb/pd.h"
+#include "imx8mq-sr-som.dtsi"
+
+/ {
+       model = "SolidRun i.MX8MQ HummingBoard Pulse";
+       compatible = "solidrun,hummingboard-pulse", "fsl,imx8mq";
+
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       reg_usdhc2_vmmc: regulator-usdhc2-vmmc {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_usdhc2_vmmc>;
+               regulator-name = "VSD_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio1 13 GPIO_ACTIVE_LOW>;
+       };
+
+       reg_v_5v0: regulator-v-5v0 {
+               compatible = "regulator-fixed";
+               regulator-name = "v_5v0";
+               regulator-max-microvolt = <5000000>;
+               regulator-min-microvolt = <5000000>;
+               regulator-always-on;
+       };
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       clock-frequency = <100000>;
+       status = "okay";
+
+       typec_ptn5100: usb-typec@50 {
+               compatible = "nxp,ptn5110";
+               reg = <0x50>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_typec>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <6 IRQ_TYPE_LEVEL_LOW>;
+
+               connector {
+                       compatible = "usb-c-connector";
+                       label = "USB-C";
+                       data-role = "dual";
+                       power-role = "dual";
+                       try-power-role = "sink";
+                       source-pdos = <PDO_FIXED(5000, 2000,
+                                                PDO_FIXED_USB_COMM |
+                                                PDO_FIXED_SUSPEND |
+                                                PDO_FIXED_EXTPOWER)>;
+                       sink-pdos = <PDO_FIXED(5000, 2000,
+                                              PDO_FIXED_USB_COMM |
+                                              PDO_FIXED_SUSPEND |
+                                              PDO_FIXED_EXTPOWER)
+                                    PDO_FIXED(9000, 2000,
+                                              PDO_FIXED_USB_COMM |
+                                              PDO_FIXED_SUSPEND |
+                                              PDO_FIXED_EXTPOWER)>;
+                       op-sink-microwatt = <9000000>;
+
+                       port {
+                               typec1_dr_sw: endpoint {
+                                       remote-endpoint = <&usb1_drd_sw>;
+                               };
+                       };
+               };
+       };
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       clock-frequency = <100000>;
+       status = "okay";
+
+       rtc@69 {
+               compatible = "abracon,ab1805";
+               reg = <0x69>;
+               abracon,tc-diode = "schottky";
+               abracon,tc-resistor = <3>;
+       };
+};
+
+&uart2 { /* J35 header */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       assigned-clocks = <&clk IMX8MQ_CLK_UART2>;
+       assigned-clock-parents = <&clk IMX8MQ_CLK_25M>;
+       status = "okay";
+};
+
+&uart3 { /* Mikrobus */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
+       assigned-clocks = <&clk IMX8MQ_CLK_UART3>;
+       assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
+       uart-has-rtscts;
+       status = "okay";
+};
+
+&usdhc2 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+       cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&reg_usdhc2_vmmc>;
+       status = "okay";
+};
+
+&usb_dwc3_0 {
+       dr_mode = "otg";
+       status = "okay";
+
+       port {
+               usb1_drd_sw: endpoint {
+                       remote-endpoint = <&typec1_dr_sw>;
+               };
+       };
+};
+
+&usb_dwc3_1 {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&usb3_phy0 {
+       status = "okay";
+};
+
+&usb3_phy1 {
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       pinctrl_hog: hoggrp {
+               fsl,pins = <
+                       /* MikroBus Analog */
+                       MX8MQ_IOMUXC_NAND_DATA05_GPIO3_IO11             0x41
+                       /* MikroBus Reset */
+                       MX8MQ_IOMUXC_SAI2_RXD0_GPIO4_IO23               0x41
+                       /*
+                        * The following 2 pins need to be commented out and
+                        * reconfigured to enable RTS/CTS on UART3
+                        */
+                       /* MikroBus PWM */
+                       MX8MQ_IOMUXC_ECSPI1_MISO_GPIO5_IO8              0x41
+                       /* MikroBus INT */
+                       MX8MQ_IOMUXC_ECSPI1_SS0_GPIO5_IO9               0x41
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL          0x4000007f
+                       MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA          0x4000007f
+               >;
+       };
+
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL          0x4000007f
+                       MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA          0x4000007f
+               >;
+       };
+
+       pinctrl_typec: typecgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_NAND_RE_B_GPIO3_IO15       0x16
+                       MX8MQ_IOMUXC_GPIO1_IO06_GPIO1_IO6       0x17059
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX             0x49
+                       MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX             0x49
+               >;
+       };
+
+       pinctrl_uart3: uart3grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART3_TXD_UART3_DCE_TX             0x49
+                       MX8MQ_IOMUXC_UART3_RXD_UART3_DCE_RX             0x49
+                       /*
+                        * These pins are by default GPIO on the Mikro Bus
+                        * Header. To use RTS/CTS on UART3 comment them out
+                        * of the hoggrp and enable them here
+                        */
+                       /* MX8MQ_IOMUXC_ECSPI1_MISO_UART3_DCE_CTS_B     0x49 */
+                       /* MX8MQ_IOMUXC_ECSPI1_SS0_UART3_DCE_RTS_B      0x49 */
+               >;
+       };
+
+       pinctrl_usdhc2_gpio: usdhc2grpgpio {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12        0x41
+               >;
+       };
+
+       pinctrl_usdhc2_vmmc: usdhc2vmmcgpio {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO13_GPIO1_IO13      0x41
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x83
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xc3
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xc3
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x8d
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xcd
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xcd
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xcd
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xcd
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xcd
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x9f
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xdf
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xdf
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xdf
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xdf
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xdf
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+};
index 5179e22..683a110 100644 (file)
        assigned-clock-rates = <786432000>, <722534400>;
 };
 
+&dphy {
+       status = "okay";
+};
+
 &fec1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_fec1>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts b/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts
new file mode 100644 (file)
index 0000000..c832bf0
--- /dev/null
@@ -0,0 +1,405 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright 2018 Boundary Devices
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "imx8mq.dtsi"
+
+/ {
+       model = "Boundary Devices i.MX8MQ Nitrogen8M";
+       compatible = "boundary,imx8mq-nitrogen8m", "fsl,imx8mq";
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0x00000000 0x40000000 0 0x80000000>;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_keys>;
+
+               power {
+                       label = "Power Button";
+                       gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_POWER>;
+                       wakeup-source;
+               };
+       };
+
+       reg_vref_0v9: regulator-vref-0v9 {
+               compatible = "regulator-fixed";
+               regulator-name = "vref-0v9";
+               regulator-min-microvolt = <900000>;
+               regulator-max-microvolt = <900000>;
+       };
+
+       reg_vref_1v8: regulator-vref-1v8 {
+               compatible = "regulator-fixed";
+               regulator-name = "vref-1v8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
+       reg_vref_2v5: regulator-vref-2v5 {
+               compatible = "regulator-fixed";
+               regulator-name = "vref-2v5";
+               regulator-min-microvolt = <2500000>;
+               regulator-max-microvolt = <2500000>;
+       };
+
+       reg_vref_3v3: regulator-vref-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vref-3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       reg_vref_5v: regulator-vref-5v {
+               compatible = "regulator-fixed";
+               regulator-name = "vref-5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+};
+
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
+       phy-mode = "rgmii-id";
+       phy-handle = <&ethphy0>;
+       fsl,magic-packet;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@4 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <4>;
+                       interrupts-extended = <&gpio1 11 IRQ_TYPE_LEVEL_LOW>;
+               };
+       };
+};
+
+&i2c1 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       i2cmux@70 {
+               compatible = "nxp,pca9546";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_i2c1_pca9546>;
+               reg = <0x70>;
+               reset-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               i2c1a: i2c1@0 {
+                       reg = <0>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       reg_arm_dram: regulator@60 {
+                               compatible = "fcs,fan53555";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_reg_arm_dram>;
+                               reg = <0x60>;
+                               regulator-min-microvolt =  <900000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-always-on;
+                               vsel-gpios = <&gpio3 24 GPIO_ACTIVE_HIGH>;
+                       };
+               };
+
+               i2c1b: i2c1@1 {
+                       reg = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       reg_dram_1p1v: regulator@60 {
+                               compatible = "fcs,fan53555";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_reg_dram_1p1v>;
+                               reg = <0x60>;
+                               regulator-min-microvolt = <1100000>;
+                               regulator-max-microvolt = <1100000>;
+                               regulator-always-on;
+                               vsel-gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>;
+                       };
+               };
+
+               i2c1c: i2c1@2 {
+                       reg = <2>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       reg_soc_gpu_vpu: regulator@60 {
+                               compatible = "fcs,fan53555";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_reg_soc_gpu_vpu>;
+                               reg = <0x60>;
+                               regulator-min-microvolt =  <900000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-always-on;
+                               vsel-gpios = <&gpio2 20 GPIO_ACTIVE_HIGH>;
+                       };
+               };
+
+               i2c1d: i2c1@3 {
+                       reg = <3>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       rtc@68 {
+                               compatible = "microcrystal,rv4162";
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&pinctrl_i2c1d_rv4162>;
+                               reg = <0x68>;
+                               interrupts-extended = <&gpio1 6 IRQ_TYPE_LEVEL_LOW>;
+                               wakeup-source;
+                       };
+               };
+       };
+};
+
+&uart1 { /* console */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       assigned-clocks = <&clk IMX8MQ_CLK_UART1>;
+       assigned-clock-parents = <&clk IMX8MQ_CLK_25M>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       assigned-clocks = <&clk IMX8MQ_CLK_UART2>;
+       assigned-clock-parents = <&clk IMX8MQ_CLK_25M>;
+       status = "okay";
+};
+
+&usdhc1 {
+       bus-width = <8>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       non-removable;
+       vmmc-supply = <&reg_vref_1v8>;
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       pinctrl_hog: hoggrp {
+               fsl,pins = <
+                       /* J17 connector, odd */
+                       MX8MQ_IOMUXC_SAI1_RXFS_GPIO4_IO0                0x19    /* Pin 19 */
+                       MX8MQ_IOMUXC_SAI1_RXC_GPIO4_IO1                 0x19    /* Pin 21 */
+                       MX8MQ_IOMUXC_SAI1_RXD1_GPIO4_IO3                0x19    /* Pin 23 */
+                       MX8MQ_IOMUXC_SAI1_RXD2_GPIO4_IO4                0x19    /* Pin 25 */
+                       MX8MQ_IOMUXC_SAI1_RXD3_GPIO4_IO5                0x19    /* Pin 27 */
+                       MX8MQ_IOMUXC_SAI1_RXD4_GPIO4_IO6                0x19    /* Pin 29 */
+                       MX8MQ_IOMUXC_SAI1_RXD5_GPIO4_IO7                0x19    /* Pin 31 */
+                       MX8MQ_IOMUXC_SAI1_RXD6_GPIO4_IO8                0x19    /* Pin 33 */
+                       MX8MQ_IOMUXC_SAI1_RXD7_GPIO4_IO9                0x19    /* Pin 35 */
+                       MX8MQ_IOMUXC_SAI1_TXD1_GPIO4_IO13               0x19    /* Pin 39 */
+                       MX8MQ_IOMUXC_SAI1_TXD2_GPIO4_IO14               0x19    /* Pin 41 */
+                       MX8MQ_IOMUXC_SAI1_TXD3_GPIO4_IO15               0x19    /* Pin 43 */
+                       MX8MQ_IOMUXC_SAI1_TXD4_GPIO4_IO16               0x19    /* Pin 45 */
+                       MX8MQ_IOMUXC_SAI1_TXD5_GPIO4_IO17               0x19    /* Pin 47 */
+                       MX8MQ_IOMUXC_SAI1_TXD6_GPIO4_IO18               0x19    /* Pin 49 */
+                       MX8MQ_IOMUXC_SAI1_TXD7_GPIO4_IO19               0x19    /* Pin 51 */
+
+                       /* J17 connector, even */
+                       MX8MQ_IOMUXC_SAI3_RXFS_GPIO4_IO28               0x19    /* Pin 44 */
+                       MX8MQ_IOMUXC_SAI3_RXC_GPIO4_IO29                0x19    /* Pin 48 */
+                       MX8MQ_IOMUXC_GPIO1_IO10_GPIO1_IO10              0x19    /* Pin 50 */
+                       MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3               0x19    /* Pin 54 */
+                       MX8MQ_IOMUXC_GPIO1_IO05_GPIO1_IO5               0x19    /* Pin 56 */
+
+                       /* J18 connector, odd */
+                       MX8MQ_IOMUXC_NAND_CE3_B_GPIO3_IO4               0x19    /* Pin 41 */
+                       MX8MQ_IOMUXC_NAND_CLE_GPIO3_IO5                 0x19    /* Pin 43 */
+                       MX8MQ_IOMUXC_NAND_READY_B_GPIO3_IO16            0x19    /* Pin 45 */
+                       MX8MQ_IOMUXC_NAND_DATA05_GPIO3_IO11             0x19    /* Pin 47 */
+                       MX8MQ_IOMUXC_NAND_WP_B_GPIO3_IO18               0x19    /* Pin 49 */
+                       MX8MQ_IOMUXC_NAND_DQS_GPIO3_IO14                0x19    /* Pin 53 */
+
+                       /* J18 connector, even */
+                       MX8MQ_IOMUXC_NAND_ALE_GPIO3_IO0                 0x19    /* Pin 32 */
+                       MX8MQ_IOMUXC_NAND_CE0_B_GPIO3_IO1               0x19    /* Pin 36 */
+                       MX8MQ_IOMUXC_NAND_DATA00_GPIO3_IO6              0x19    /* Pin 38 */
+                       MX8MQ_IOMUXC_NAND_DATA01_GPIO3_IO7              0x19    /* Pin 40 */
+                       MX8MQ_IOMUXC_NAND_DATA02_GPIO3_IO8              0x19    /* Pin 42 */
+                       MX8MQ_IOMUXC_NAND_DATA03_GPIO3_IO9              0x19    /* Pin 44 */
+                       MX8MQ_IOMUXC_NAND_DATA04_GPIO3_IO10             0x19    /* Pin 46 */
+
+                       /* J13 Pin 2, WL_WAKE */
+                       MX8MQ_IOMUXC_SAI5_RXD2_GPIO3_IO23               0xd6
+                       /* J13 Pin 4, WL_IRQ, not needed for Silex */
+                       MX8MQ_IOMUXC_SAI5_RXD0_GPIO3_IO21               0xd6
+                       /* J13 pin 9, unused */
+                       MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12                0x19
+                       /* J13 Pin 41, BT_CLK_REQ */
+                       MX8MQ_IOMUXC_SAI5_RXD1_GPIO3_IO22               0xd6
+                       /* J13 Pin 42, BT_HOST_WAKE */
+                       MX8MQ_IOMUXC_SAI5_MCLK_GPIO3_IO25               0xd6
+
+                       /* Clock for both CSI1 and CSI2 */
+                       MX8MQ_IOMUXC_GPIO1_IO15_CCMSRCGPCMIX_CLKO2      0x07
+                       /* test points */
+                       MX8MQ_IOMUXC_GPIO1_IO04_GPIO1_IO4               0xc1    /* TP87 */
+               >;
+       };
+
+       pinctrl_fec1: fec1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC                 0x3
+                       MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO               0x23
+                       MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL     0x1f
+                       MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC           0x1f
+                       MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0           0x1f
+                       MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1           0x1f
+                       MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2           0x1f
+                       MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3           0x1f
+                       MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL     0x91
+                       MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC           0x91
+                       MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0           0x91
+                       MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1           0x91
+                       MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2           0x91
+                       MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3           0x91
+                       MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9               0x19
+                       MX8MQ_IOMUXC_GPIO1_IO11_GPIO1_IO11              0x59
+               >;
+       };
+
+       pinctrl_gpio_keys: gpio-keysgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO07_GPIO1_IO7               0x19
+               >;
+       };
+
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL                  0x4000007f
+                       MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA                  0x4000007f
+               >;
+       };
+
+       pinctrl_i2c1_pca9546: i2c1-pca9546grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO08_GPIO1_IO8               0x49
+               >;
+       };
+
+       pinctrl_i2c1d_rv4162: i2c1d-rv4162grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO06_GPIO1_IO6               0x49
+               >;
+       };
+
+       pinctrl_reg_arm_dram: reg-arm-dramgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SAI5_RXD3_GPIO3_IO24       0x16
+               >;
+       };
+
+       pinctrl_reg_dram_1p1v: reg-dram-1p1vgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_STROBE_GPIO2_IO11      0x16
+               >;
+       };
+
+       pinctrl_reg_soc_gpu_vpu: reg-soc-gpu-vpugrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_WP_GPIO2_IO20          0x16
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX             0x45
+                       MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX             0x45
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX             0x45
+                       MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX             0x45
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x83
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xc3
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xc3
+                       MX8MQ_IOMUXC_SD1_RESET_B_GPIO2_IO10             0x41
+               >;
+       };
+
+       pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x8d
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xcd
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xcd
+               >;
+       };
+
+       pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x9f
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xdf
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xdf
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+               MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B    0xc6
+               >;
+       };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts b/arch/arm64/boot/dts/freescale/imx8mq-pico-pi.dts
new file mode 100644 (file)
index 0000000..8a4aee2
--- /dev/null
@@ -0,0 +1,413 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 Wandboard, Org.
+ * Copyright 2017 NXP
+ *
+ * Author: Richard Hu <hakahu@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "imx8mq.dtsi"
+
+/ {
+       model = "TechNexion PICO-PI-8M";
+       compatible = "technexion,pico-pi-imx8m", "fsl,imx8mq";
+
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       pmic_osc: clock-pmic {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               clock-output-names = "pmic_osc";
+       };
+
+       reg_usb_otg_vbus: regulator-usb-otg-vbus {
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_otg_vbus>;
+               compatible = "regulator-fixed";
+               regulator-name = "usb_otg_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio3 14 GPIO_ACTIVE_LOW>;
+       };
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1 &pinctrl_enet_3v3>;
+       phy-mode = "rgmii-id";
+       phy-handle = <&ethphy0>;
+       fsl,magic-packet;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@1 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <1>;
+               };
+       };
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pmic: pmic@4b {
+               reg = <0x4b>;
+               compatible = "rohm,bd71837";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pmic>;
+               clocks = <&pmic_osc>;
+               clock-names = "osc";
+               clock-output-names = "pmic_clk";
+               interrupt-parent = <&gpio1>;
+               interrupts = <3 GPIO_ACTIVE_LOW>;
+               interrupt-names = "irq";
+
+               regulators {
+                       buck1: BUCK1 {
+                               regulator-name = "buck1";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               regulator-ramp-delay = <1250>;
+                               rohm,dvs-run-voltage = <900000>;
+                               rohm,dvs-idle-voltage = <850000>;
+                               rohm,dvs-suspend-voltage = <800000>;
+                       };
+
+                       buck2: BUCK2 {
+                               regulator-name = "buck2";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               regulator-ramp-delay = <1250>;
+                               rohm,dvs-run-voltage = <1000000>;
+                               rohm,dvs-idle-voltage = <900000>;
+                       };
+
+                       buck3: BUCK3 {
+                               regulator-name = "buck3";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               rohm,dvs-run-voltage = <1000000>;
+                       };
+
+                       buck4: BUCK4 {
+                               regulator-name = "buck4";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               rohm,dvs-run-voltage = <1000000>;
+                       };
+
+                       buck5: BUCK5 {
+                               regulator-name = "buck5";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-boot-on;
+                       };
+
+                       buck6: BUCK6 {
+                               regulator-name = "buck6";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                       };
+
+                       buck7: BUCK7 {
+                               regulator-name = "buck7";
+                               regulator-min-microvolt = <1605000>;
+                               regulator-max-microvolt = <1995000>;
+                               regulator-boot-on;
+                       };
+
+                       buck8: BUCK8 {
+                               regulator-name = "buck8";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1400000>;
+                               regulator-boot-on;
+                       };
+
+                       ldo1: LDO1 {
+                               regulator-name = "ldo1";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo2: LDO2 {
+                               regulator-name = "ldo2";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo3: LDO3 {
+                               regulator-name = "ldo3";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                       };
+
+                       ldo4: LDO4 {
+                               regulator-name = "ldo4";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                       };
+
+                       ldo5: LDO5 {
+                               regulator-name = "ldo5";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                       };
+
+                       ldo6: LDO6 {
+                               regulator-name = "ldo6";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                       };
+
+                       ldo7: LDO7 {
+                               regulator-name = "ldo7";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                       };
+               };
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+};
+
+&uart1 { /* console */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
+&usdhc2 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>;
+       pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>;
+       bus-width = <4>;
+       cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&usb3_phy0 {
+       status = "okay";
+};
+
+&usb3_phy1 {
+       status = "okay";
+};
+
+&usb_dwc3_1 {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_enet_3v3: enet3v3grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO00_GPIO1_IO0       0x19
+               >;
+       };
+
+       pinctrl_fec1: fec1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC         0x3
+                       MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO       0x23
+                       MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3   0x1f
+                       MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2   0x1f
+                       MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1   0x1f
+                       MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0   0x1f
+                       MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3   0x91
+                       MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2   0x91
+                       MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1   0x91
+                       MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0   0x91
+                       MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC   0x1f
+                       MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC   0x91
+                       MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL     0x91
+                       MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL     0x1f
+                       MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9       0x19
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL                  0x4000007f
+                       MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA                  0x4000007f
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL                  0x4000007f
+                       MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA                  0x4000007f
+               >;
+       };
+
+       pinctrl_otg_vbus: otgvbusgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_NAND_DQS_GPIO3_IO14                0x19   /* USB OTG VBUS Enable */
+               >;
+       };
+
+       pinctrl_pmic: pmicirq {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3       0x41
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX             0x49
+                       MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX             0x49
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX             0x49
+                       MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX             0x49
+                       MX8MQ_IOMUXC_UART4_RXD_UART2_DCE_CTS_B          0x49
+                       MX8MQ_IOMUXC_UART4_TXD_UART2_DCE_RTS_B          0x49
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x83
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xc3
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xc3
+                       MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE           0x83
+               >;
+       };
+
+       pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x85
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xc5
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xc5
+                       MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE           0x85
+               >;
+       };
+
+       pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x87
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xc7
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xc7
+                       MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE           0x87
+               >;
+       };
+
+       pinctrl_usdhc2_gpio: usdhc2grpgpio {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12        0x41
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x83
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xc3
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xc3
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x85
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xc5
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xc5
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xc5
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xc5
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xc5
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x87
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xc7
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xc7
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xc7
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xc7
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xc7
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
+               >;
+       };
+};
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-sr-som.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-sr-som.dtsi
new file mode 100644 (file)
index 0000000..d7f03c6
--- /dev/null
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (C) 2018 Jon Nettleton <jon@solid-run.com>
+ */
+
+#include "imx8mq.dtsi"
+
+/ {
+       reg_vdd_3v3: regulator-vdd-3v3 {
+               compatible = "regulator-fixed";
+               regulator-always-on;
+               regulator-name = "vdd_3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
+       phy-mode = "rgmii-id";
+       phy-handle = <&ethphy0>;
+       phy-reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+       phy-reset-duration = <2>;
+       fsl,magic-packet;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@4 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <4>;
+               };
+       };
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       clock-frequency = <400000>;
+       status = "okay";
+
+       pmic: pmic@8 {
+               compatible = "fsl,pfuze100";
+               reg = <0x08>;
+
+               regulators {
+                       sw1a_reg: sw1ab {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                       };
+
+                       sw1c_reg: sw1c {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3ab {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                               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-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                               regulator-always-on;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen4_reg: vgen4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vgen5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+               };
+       };
+};
+
+&pgc_gpu{
+       power-supply = <&sw1a_reg>;
+};
+
+&pgc_vpu {
+       power-supply = <&sw1c_reg>;
+};
+
+&qspi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_qspi>;
+       status = "okay";
+
+       /* SPI flash; not assembled by default */
+       spi_flash: flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0>;
+               compatible = "micron,n25q256a", "jedec,spi-nor";
+               spi-max-frequency = <29000000>;
+               status = "disabled";
+       };
+};
+
+&uart1 { /* console */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       assigned-clocks = <&clk IMX8MQ_CLK_UART1>;
+       assigned-clock-parents = <&clk IMX8MQ_CLK_25M>;
+       assigned-clock-rates = <25000000>;
+       status = "okay";
+};
+
+&uart4 { /* ublox BT */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       assigned-clocks = <&clk IMX8MQ_CLK_UART4>;
+       assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
+       assigned-clock-rates = <80000000>;
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+       bus-width = <8>;
+       non-removable;
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_fec1: fec1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC         0x3
+                       MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO       0x23
+                       MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3   0x1f
+                       MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2   0x1f
+                       MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1   0x1f
+                       MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0   0x1f
+                       MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3   0x91
+                       MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2   0x91
+                       MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1   0x91
+                       MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0   0x91
+                       MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC   0x1f
+                       MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC   0x91
+                       MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL     0x91
+                       MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL     0x1f
+                       MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9       0x19
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL                  0x4000007f
+                       MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA                  0x4000007f
+               >;
+       };
+
+       pinctrl_pcie0: pcie0grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C4_SCL_PCIE1_CLKREQ_B    0x74
+                       MX8MQ_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5    0x16
+                       MX8MQ_IOMUXC_SAI2_RXFS_GPIO4_IO21       0x16
+               >;
+       };
+
+       pinctrl_qspi: qspigrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_NAND_ALE_QSPI_A_SCLK       0x82
+                       MX8MQ_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B    0x82
+                       MX8MQ_IOMUXC_NAND_DATA00_QSPI_A_DATA0   0x82
+                       MX8MQ_IOMUXC_NAND_DATA01_QSPI_A_DATA1   0x82
+                       MX8MQ_IOMUXC_NAND_DATA02_QSPI_A_DATA2   0x82
+                       MX8MQ_IOMUXC_NAND_DATA03_QSPI_A_DATA3   0x82
+
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX             0x49
+                       MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX             0x49
+                       MX8MQ_IOMUXC_NAND_CE1_B_GPIO3_IO2               0x19
+               >;
+       };
+
+       pinctrl_uart4: uart4grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART4_TXD_UART4_DCE_TX             0x49
+                       MX8MQ_IOMUXC_UART4_RXD_UART4_DCE_RX             0x49
+                       MX8MQ_IOMUXC_SAI3_TXD_GPIO5_IO1                 0x19
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x83
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xc3
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xc3
+                       MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE           0x83
+                       MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B         0xc1
+               >;
+       };
+
+       pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x8d
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xcd
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xcd
+                       MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE           0x8d
+                       MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B         0xc1
+               >;
+       };
+
+       pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x9f
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xdf
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xdf
+                       MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE           0x9f
+                       MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B         0xc1
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
+               >;
+       };
+};
index 7a1706f..af99473 100644 (file)
                regulator-always-on;
        };
 
-       reg_5p0_user_usb: regulator-5p0-user-usb {
-               compatible = "regulator-fixed";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_reg_user_usb>;
-               vin-supply = <&reg_5p0_main>;
-               regulator-name = "5V_USER_USB";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               gpio = <&gpio3 12 GPIO_ACTIVE_LOW>;
-               startup-delay-us = <1000>;
-       };
-
        reg_usdhc2_vmmc: regulator-vsd-3v3 {
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_reg_usdhc2>;
                line-name = "usb-mode1";
        };
 
+       usb-pwr {
+               gpio-hog;
+               gpios = <12 GPIO_ACTIVE_LOW>;
+               output-high;
+               line-name = "usb-pwr-ctrl-en-n";
+       };
+
        usb-mode2 {
                gpio-hog;
                gpios = <13 GPIO_ACTIVE_HIGH>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
+
+       ucs1002: charger@32 {
+               compatible = "microchip,ucs1002";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ucs1002>;
+               reg = <0x32>;
+               interrupt-parent = <&gpio3>;
+               interrupts = <17 IRQ_TYPE_EDGE_BOTH>,
+                            <18 IRQ_TYPE_EDGE_BOTH>;
+               interrupt-names = "a_det", "alert";
+       };
 };
 
 &i2c2 {
 };
 
 &usb3_phy0 {
-       vbus-supply = <&reg_5p0_user_usb>;
+       vbus-supply = <&ucs1002>;
        status = "okay";
 };
 
                fsl,pins = <
                        MX8MQ_IOMUXC_NAND_DATA04_GPIO3_IO10             0x6
                        MX8MQ_IOMUXC_NAND_DATA05_GPIO3_IO11             0x6
+                       MX8MQ_IOMUXC_NAND_DATA06_GPIO3_IO12             0x6
                        MX8MQ_IOMUXC_NAND_DATA07_GPIO3_IO13             0x6
                >;
        };
                >;
        };
 
-       pinctrl_reg_user_usb: reguserusbgrp {
-               fsl,pins = <
-                       MX8MQ_IOMUXC_NAND_DATA06_GPIO3_IO12             0x6
-               >;
-       };
-
        pinctrl_switch_irq: switchgrp {
                fsl,pins = <
                        MX8MQ_IOMUXC_GPIO1_IO15_GPIO1_IO15              0x41
                >;
        };
 
+       pinctrl_ucs1002: ucs1002grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_NAND_WE_B_GPIO3_IO17               0x41
+                       MX8MQ_IOMUXC_NAND_WP_B_GPIO3_IO18               0x41
+               >;
+       };
+
        pinctrl_usbhub: usbhubgrp {
                fsl,pins = <
                        MX8MQ_IOMUXC_SAI5_MCLK_GPIO3_IO25               0x41
index 52aae34..046a0c8 100644 (file)
                        /* Industrial only */
                        opp-supported-hw = <0xf>, <0x4>;
                        clock-latency-ns = <150000>;
+                       opp-suspend;
                };
 
                opp-1000000000 {
                        /* Consumer only */
                        opp-supported-hw = <0xe>, <0x3>;
                        clock-latency-ns = <150000>;
+                       opp-suspend;
                };
 
                opp-1300000000 {
                        opp-hz = /bits/ 64 <1300000000>;
                        opp-microvolt = <1000000>;
-                       opp-supported-hw = <0xc>, <0x7>;
+                       opp-supported-hw = <0xc>, <0x4>;
                        clock-latency-ns = <150000>;
+                       opp-suspend;
                };
 
                opp-1500000000 {
                        opp-hz = /bits/ 64 <1500000000>;
                        opp-microvolt = <1000000>;
-                       /* Consumer only but rely on speed grading */
-                       opp-supported-hw = <0x8>, <0x7>;
+                       opp-supported-hw = <0x8>, <0x3>;
                        clock-latency-ns = <150000>;
+                       opp-suspend;
                };
        };
 
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 10 30>;
                        };
 
                        gpio2: gpio@30210000 {
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 40 21>;
                        };
 
                        gpio3: gpio@30220000 {
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 61 26>;
                        };
 
                        gpio4: gpio@30230000 {
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 87 32>;
                        };
 
                        gpio5: gpio@30240000 {
                                #gpio-cells = <2>;
                                interrupt-controller;
                                #interrupt-cells = <2>;
+                               gpio-ranges = <&iomuxc 0 119 30>;
                        };
 
                        tmu: tmu@30260000 {
                                compatible = "fsl,imx8mq-tmu";
                                reg = <0x30260000 0x10000>;
                                interrupt = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_TMU_ROOT>;
                                little-endian;
                                fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x70061>;
                                fsl,tmu-calibration = <0x00000000 0x00000023
                        };
 
                        iomuxc_gpr: syscon@30340000 {
-                               compatible = "fsl,imx8mq-iomuxc-gpr", "fsl,imx6q-iomuxc-gpr", "syscon";
+                               compatible = "fsl,imx8mq-iomuxc-gpr", "fsl,imx6q-iomuxc-gpr",
+                                            "syscon", "simple-mfd";
                                reg = <0x30340000 0x10000>;
+
+                               mux: mux-controller {
+                                       compatible = "mmio-mux";
+                                       #mux-control-cells = <1>;
+                                       mux-reg-masks = <0x34 0x00000004>; /* MIPI_MUX_SEL */
+                               };
                        };
 
                        ocotp: ocotp-ctrl@30350000 {
                                status = "disabled";
                        };
 
+                       dphy: dphy@30a00300 {
+                               compatible = "fsl,imx8mq-mipi-dphy";
+                               reg = <0x30a00300 0x100>;
+                               clocks = <&clk IMX8MQ_CLK_DSI_PHY_REF>;
+                               clock-names = "phy_ref";
+                               assigned-clocks = <&clk IMX8MQ_CLK_DSI_PHY_REF>;
+                               assigned-clock-parents = <&clk IMX8MQ_VIDEO_PLL1_OUT>;
+                               assigned-clock-rates = <24000000>;
+                               #phy-cells = <0>;
+                               power-domains = <&pgc_mipi>;
+                               status = "disabled";
+                       };
+
                        i2c1: i2c@30a20000 {
                                compatible = "fsl,imx8mq-i2c", "fsl,imx21-i2c";
                                reg = <0x30a20000 0x10000>;
                usb_dwc3_0: usb@38100000 {
                        compatible = "fsl,imx8mq-dwc3", "snps,dwc3";
                        reg = <0x38100000 0x10000>;
-                       clocks = <&clk IMX8MQ_CLK_USB_BUS>,
+                       clocks = <&clk IMX8MQ_CLK_USB1_CTRL_ROOT>,
                                 <&clk IMX8MQ_CLK_USB_CORE_REF>,
-                                <&clk IMX8MQ_CLK_USB1_CTRL_ROOT>;
+                                <&clk IMX8MQ_CLK_32K>;
                        clock-names = "bus_early", "ref", "suspend";
                        assigned-clocks = <&clk IMX8MQ_CLK_USB_BUS>,
                                          <&clk IMX8MQ_CLK_USB_CORE_REF>;
                usb_dwc3_1: usb@38200000 {
                        compatible = "fsl,imx8mq-dwc3", "snps,dwc3";
                        reg = <0x38200000 0x10000>;
-                       clocks = <&clk IMX8MQ_CLK_USB_BUS>,
+                       clocks = <&clk IMX8MQ_CLK_USB2_CTRL_ROOT>,
                                 <&clk IMX8MQ_CLK_USB_CORE_REF>,
-                                <&clk IMX8MQ_CLK_USB2_CTRL_ROOT>;
+                                <&clk IMX8MQ_CLK_32K>;
                        clock-names = "bus_early", "ref", "suspend";
                        assigned-clocks = <&clk IMX8MQ_CLK_USB_BUS>,
                                          <&clk IMX8MQ_CLK_USB_CORE_REF>;
                        interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-parent = <&gic>;
                };
+
+               ddr-pmu@3d800000 {
+                       compatible = "fsl,imx8mq-ddr-pmu", "fsl,imx8m-ddr-pmu";
+                       reg = <0x3d800000 0x400000>;
+                       interrupt-parent = <&gic>;
+                       interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+               };
        };
 };
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-ai_ml.dts b/arch/arm64/boot/dts/freescale/imx8qxp-ai_ml.dts
new file mode 100644 (file)
index 0000000..91eef97
--- /dev/null
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2018 Einfochips
+ * Copyright 2019 Linaro Ltd.
+ */
+
+/dts-v1/;
+
+#include "imx8qxp.dtsi"
+
+/ {
+       model = "Einfochips i.MX8QXP AI_ML";
+       compatible = "einfochips,imx8qxp-ai_ml", "fsl,imx8qxp";
+
+       aliases {
+               serial1 = &adma_lpuart1;
+               serial2 = &adma_lpuart2;
+               serial3 = &adma_lpuart3;
+       };
+
+       chosen {
+               stdout-path = &adma_lpuart2;
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x00000000 0x80000000 0 0x80000000>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_leds>;
+
+               user-led1 {
+                       label = "green:user1";
+                       gpios = <&lsio_gpio4 16 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               user-led2 {
+                       label = "green:user2";
+                       gpios = <&lsio_gpio0 6 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "none";
+               };
+
+               user-led3 {
+                       label = "green:user3";
+                       gpios = <&lsio_gpio0 7 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "mmc1";
+                       default-state = "off";
+               };
+
+               user-led4 {
+                       label = "green:user4";
+                       gpios = <&lsio_gpio4 21 GPIO_ACTIVE_HIGH>;
+                       panic-indicator;
+                       linux,default-trigger = "none";
+               };
+
+               wlan-active-led {
+                       label = "yellow:wlan";
+                       gpios = <&lsio_gpio4 17 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "phy0tx";
+                       default-state = "off";
+               };
+
+               bt-active-led {
+                       label = "blue:bt";
+                       gpios = <&lsio_gpio4 18 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "hci0-power";
+                       default-state = "off";
+               };
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_wifi_reg_on>;
+               reset-gpios = <&lsio_gpio3 24 GPIO_ACTIVE_LOW>;
+       };
+};
+
+/* BT */
+&adma_lpuart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpuart0>;
+       uart-has-rtscts;
+       status = "okay";
+};
+
+/* LS-UART0 */
+&adma_lpuart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpuart1>;
+       status = "okay";
+};
+
+/* Debug */
+&adma_lpuart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpuart2>;
+       status = "okay";
+};
+
+/* PCI-E UART */
+&adma_lpuart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpuart3>;
+       status = "okay";
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
+       phy-mode = "rgmii-id";
+       phy-handle = <&ethphy0>;
+       fsl,magic-packet;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy0: ethernet-phy@0 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <0>;
+               };
+       };
+};
+
+/* WiFi */
+&usdhc1 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       bus-width = <4>;
+       no-sd;
+       non-removable;
+       mmc-pwrseq = <&sdio_pwrseq>;
+       status = "okay";
+
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+       };
+};
+
+/* SD */
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       bus-width = <4>;
+       cd-gpios = <&lsio_gpio4 22 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_fec1: fec1grp {
+               fsl,pins = <
+                       IMX8QXP_ENET0_MDC_CONN_ENET0_MDC                        0x06000020
+                       IMX8QXP_ENET0_MDIO_CONN_ENET0_MDIO                      0x06000020
+                       IMX8QXP_ENET0_RGMII_TX_CTL_CONN_ENET0_RGMII_TX_CTL      0x06000020
+                       IMX8QXP_ENET0_RGMII_TXC_CONN_ENET0_RGMII_TXC            0x06000020
+                       IMX8QXP_ENET0_RGMII_TXD0_CONN_ENET0_RGMII_TXD0          0x06000020
+                       IMX8QXP_ENET0_RGMII_TXD1_CONN_ENET0_RGMII_TXD1          0x06000020
+                       IMX8QXP_ENET0_RGMII_TXD2_CONN_ENET0_RGMII_TXD2          0x06000020
+                       IMX8QXP_ENET0_RGMII_TXD3_CONN_ENET0_RGMII_TXD3          0x06000020
+                       IMX8QXP_ENET0_RGMII_RXC_CONN_ENET0_RGMII_RXC            0x06000020
+                       IMX8QXP_ENET0_RGMII_RX_CTL_CONN_ENET0_RGMII_RX_CTL      0x06000020
+                       IMX8QXP_ENET0_RGMII_RXD0_CONN_ENET0_RGMII_RXD0          0x06000020
+                       IMX8QXP_ENET0_RGMII_RXD1_CONN_ENET0_RGMII_RXD1          0x06000020
+                       IMX8QXP_ENET0_RGMII_RXD2_CONN_ENET0_RGMII_RXD2          0x06000020
+                       IMX8QXP_ENET0_RGMII_RXD3_CONN_ENET0_RGMII_RXD3          0x06000020
+               >;
+       };
+
+       pinctrl_leds: ledsgrp{
+               fsl,pins = <
+                       IMX8QXP_ESAI0_TX2_RX3_LSIO_GPIO0_IO06                   0x00000021
+                       IMX8QXP_ESAI0_TX3_RX2_LSIO_GPIO0_IO07                   0x00000021
+                       IMX8QXP_EMMC0_DATA7_LSIO_GPIO4_IO16                     0x00000021
+                       IMX8QXP_USDHC1_WP_LSIO_GPIO4_IO21                       0x00000021
+                       IMX8QXP_EMMC0_STROBE_LSIO_GPIO4_IO17                    0x00000021
+                       IMX8QXP_EMMC0_RESET_B_LSIO_GPIO4_IO18                   0x00000021
+               >;
+       };
+
+       pinctrl_lpuart0: lpuart0grp {
+               fsl,pins = <
+                       IMX8QXP_UART0_RX_ADMA_UART0_RX                          0X06000020
+                       IMX8QXP_UART0_TX_ADMA_UART0_TX                          0X06000020
+                       IMX8QXP_FLEXCAN0_TX_ADMA_UART0_CTS_B                    0x06000020
+                       IMX8QXP_FLEXCAN0_RX_ADMA_UART0_RTS_B                    0x06000020
+               >;
+       };
+
+       pinctrl_lpuart1: lpuart1grp {
+               fsl,pins = <
+                       IMX8QXP_UART1_RX_ADMA_UART1_RX                          0X06000020
+                       IMX8QXP_UART1_TX_ADMA_UART1_TX                          0X06000020
+               >;
+       };
+
+       pinctrl_lpuart2: lpuart2grp {
+               fsl,pins = <
+                       IMX8QXP_UART2_RX_ADMA_UART2_RX                          0X06000020
+                       IMX8QXP_UART2_TX_ADMA_UART2_TX                          0X06000020
+               >;
+       };
+
+       pinctrl_lpuart3: lpuart3grp {
+               fsl,pins = <
+                       IMX8QXP_FLEXCAN2_RX_ADMA_UART3_RX                       0X06000020
+                       IMX8QXP_FLEXCAN2_TX_ADMA_UART3_TX                       0X06000020
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       IMX8QXP_EMMC0_CLK_CONN_EMMC0_CLK                        0x06000041
+                       IMX8QXP_EMMC0_CMD_CONN_EMMC0_CMD                        0x00000021
+                       IMX8QXP_EMMC0_DATA0_CONN_EMMC0_DATA0                    0x00000021
+                       IMX8QXP_EMMC0_DATA1_CONN_EMMC0_DATA1                    0x00000021
+                       IMX8QXP_EMMC0_DATA2_CONN_EMMC0_DATA2                    0x00000021
+                       IMX8QXP_EMMC0_DATA3_CONN_EMMC0_DATA3                    0x00000021
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       IMX8QXP_USDHC1_CLK_CONN_USDHC1_CLK                      0x06000041
+                       IMX8QXP_USDHC1_CMD_CONN_USDHC1_CMD                      0x00000021
+                       IMX8QXP_USDHC1_DATA0_CONN_USDHC1_DATA0                  0x00000021
+                       IMX8QXP_USDHC1_DATA1_CONN_USDHC1_DATA1                  0x00000021
+                       IMX8QXP_USDHC1_DATA2_CONN_USDHC1_DATA2                  0x00000021
+                       IMX8QXP_USDHC1_DATA3_CONN_USDHC1_DATA3                  0x00000021
+                       IMX8QXP_USDHC1_VSELECT_CONN_USDHC1_VSELECT              0x00000021
+                       IMX8QXP_USDHC1_CD_B_LSIO_GPIO4_IO22                     0x00000021
+               >;
+       };
+
+       pinctrl_wifi_reg_on: wifiregongrp {
+               fsl,pins = <
+                       IMX8QXP_QSPI0B_SS1_B_LSIO_GPIO3_IO24                    0x00000021
+               >;
+       };
+};
index bfdada2..1946805 100644 (file)
                >;
        };
 };
+
+&adma_dsp {
+       status = "okay";
+};
index 05fa0b7..1133b41 100644 (file)
@@ -30,6 +30,9 @@
                mmc2 = &usdhc3;
                mu1 = &lsio_mu1;
                serial0 = &adma_lpuart0;
+               serial1 = &adma_lpuart1;
+               serial2 = &adma_lpuart2;
+               serial3 = &adma_lpuart3;
        };
 
        cpus {
                interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
        };
 
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               dsp_reserved: dsp@92400000 {
+                       reg = <0 0x92400000 0 0x2000000>;
+                       no-map;
+               };
+       };
+
        pmu {
                compatible = "arm,armv8-pmuv3";
                interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
                        #clock-cells = <1>;
                };
 
+               adma_dsp: dsp@596e8000 {
+                       compatible = "fsl,imx8qxp-dsp";
+                       reg = <0x596e8000 0x88000>;
+                       clocks = <&adma_lpcg IMX_ADMA_LPCG_DSP_IPG_CLK>,
+                               <&adma_lpcg IMX_ADMA_LPCG_OCRAM_IPG_CLK>,
+                               <&adma_lpcg IMX_ADMA_LPCG_DSP_CORE_CLK>;
+                       clock-names = "ipg", "ocram", "core";
+                       power-domains = <&pd IMX_SC_R_MU_13A>,
+                               <&pd IMX_SC_R_MU_13B>,
+                               <&pd IMX_SC_R_DSP>,
+                               <&pd IMX_SC_R_DSP_RAM>;
+                       mbox-names = "txdb0", "txdb1",
+                               "rxdb0", "rxdb1";
+                       mboxes = <&lsio_mu13 2 0>,
+                               <&lsio_mu13 2 1>,
+                               <&lsio_mu13 3 0>,
+                               <&lsio_mu13 3 1>;
+                       memory-region = <&dsp_reserved>;
+                       status = "disabled";
+               };
+
                adma_lpuart0: serial@5a060000 {
                        compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
                        reg = <0x5a060000 0x1000>;
                        interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-parent = <&gic>;
-                       clocks = <&adma_lpcg IMX_ADMA_LPCG_UART0_BAUD_CLK>;
-                       clock-names = "ipg";
+                       clocks = <&adma_lpcg IMX_ADMA_LPCG_UART0_IPG_CLK>,
+                                <&adma_lpcg IMX_ADMA_LPCG_UART0_BAUD_CLK>;
+                       clock-names = "ipg", "baud";
                        power-domains = <&pd IMX_SC_R_UART_0>;
                        status = "disabled";
                };
                        reg = <0x5a070000 0x1000>;
                        interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-parent = <&gic>;
-                       clocks = <&adma_lpcg IMX_ADMA_LPCG_UART1_BAUD_CLK>;
-                       clock-names = "ipg";
+                       clocks = <&adma_lpcg IMX_ADMA_LPCG_UART1_IPG_CLK>,
+                                <&adma_lpcg IMX_ADMA_LPCG_UART1_BAUD_CLK>;
+                       clock-names = "ipg", "baud";
                        power-domains = <&pd IMX_SC_R_UART_1>;
                        status = "disabled";
                };
                        reg = <0x5a080000 0x1000>;
                        interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-parent = <&gic>;
-                       clocks = <&adma_lpcg IMX_ADMA_LPCG_UART2_BAUD_CLK>;
-                       clock-names = "ipg";
+                       clocks = <&adma_lpcg IMX_ADMA_LPCG_UART2_IPG_CLK>,
+                                <&adma_lpcg IMX_ADMA_LPCG_UART2_BAUD_CLK>;
+                       clock-names = "ipg", "baud";
                        power-domains = <&pd IMX_SC_R_UART_2>;
                        status = "disabled";
                };
                        reg = <0x5a090000 0x1000>;
                        interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-parent = <&gic>;
-                       clocks = <&adma_lpcg IMX_ADMA_LPCG_UART3_BAUD_CLK>;
-                       clock-names = "ipg";
+                       clocks = <&adma_lpcg IMX_ADMA_LPCG_UART3_IPG_CLK>,
+                                <&adma_lpcg IMX_ADMA_LPCG_UART3_BAUD_CLK>;
+                       clock-names = "ipg", "baud";
                        power-domains = <&pd IMX_SC_R_UART_3>;
                        status = "disabled";
                };
index e4ceb3a..36abc25 100644 (file)
                        #dma-cells = <1>;
                        #dma-channels = <8>;
                        #dma-requests = <32>;
+                       resets = <&rst DMA_RESET>, <&rst DMA_OCP_RESET>;
+                       reset-names = "dma", "dma-ocp";
                };
 
                rst: rstmgr@ffd11000 {
index f43c431..7f69e3d 100644 (file)
                                clocks = <&nb_periph_clk 15>;
                        };
 
+                       rwtm: mailbox@b0000 {
+                               compatible = "marvell,armada-3700-rwtm-mailbox";
+                               reg = <0xb0000 0x100>;
+                               interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
+                               #mbox-cells = <1>;
+                       };
+
                        sdhci1: sdhci@d0000 {
                                compatible = "marvell,armada-3700-sdhci",
                                             "marvell,sdhci-xenon";
index f34ee87..a7eb4e7 100644 (file)
                gpio = <&expander0 1 GPIO_ACTIVE_HIGH>;
                vin-supply = <&cp0_exp_usb3_1_current_regulator>;
        };
-
-       cp0_usb3_0_phy: cp0-usb3-0-phy {
-               compatible = "usb-nop-xceiv";
-               vcc-supply = <&cp0_reg_usb3_0_vbus>;
-       };
-
-       cp0_usb3_1_phy: cp0-usb3-1-phy {
-               compatible = "usb-nop-xceiv";
-               vcc-supply = <&cp0_reg_usb3_1_vbus>;
-       };
 };
 
 &i2c0 {
 
 &cp0_pcie2 {
        status = "okay";
+       phys = <&cp0_comphy5 2>;
+       phy-names = "cp0-pcie2-x1-phy";
 };
 
 &cp0_i2c0 {
 
 &cp0_sata0 {
        status = "okay";
+
+       sata-port@1 {
+               phys = <&cp0_comphy3 1>;
+               phy-names = "cp0-sata0-1-phy";
+       };
+};
+
+&cp0_comphy1 {
+       cp0_usbh0_con: connector {
+               compatible = "usb-a-connector";
+               phy-supply = <&cp0_reg_usb3_0_vbus>;
+       };
 };
 
 &cp0_usb3_0 {
-       usb-phy = <&cp0_usb3_0_phy>;
+       phys = <&cp0_comphy1 0>;
+       phy-names = "cp0-usb3h0-comphy";
        status = "okay";
 };
 
+&cp0_comphy4 {
+       cp0_usbh1_con: connector {
+               compatible = "usb-a-connector";
+               phy-supply = <&cp0_reg_usb3_1_vbus>;
+       };
+};
+
 &cp0_usb3_1 {
-       usb-phy = <&cp0_usb3_1_phy>;
+       phys = <&cp0_comphy4 1>;
+       phy-names = "cp0-usb3h1-comphy";
        status = "okay";
 };
 
index f275d94..bd88149 100644 (file)
                status = "okay";
        };
 
-       usb3h0_phy: usb3_phy0 {
-               compatible = "usb-nop-xceiv";
-               vcc-supply = <&v_5v0_usb3_hst_vbus>;
-       };
-
        sfp_cp0_eth0: sfp-cp0-eth0 {
                compatible = "sff,sfp";
                i2c-bus = <&cp0_i2c1>;
        pinctrl-names = "default";
        pinctrl-0 = <&cp0_pci0_reset_pins &cp0_wlan_disable_pins>;
        reset-gpios = <&cp0_gpio2 0 GPIO_ACTIVE_LOW>;
+       phys = <&cp0_comphy0 0>;
+       phy-names = "cp0-pcie0-x1-phy";
        status = "okay";
 };
 
 &cp1_sata0 {
        pinctrl-0 = <&cp0_pci1_reset_pins>;
        status = "okay";
+
+       sata-port@1 {
+               phys = <&cp1_comphy0 1>;
+               phy-names = "cp1-sata0-1-phy";
+       };
 };
 
 &cp1_mdio {
        };
 };
 
+&cp1_comphy2 {
+       cp1_usbh0_con: connector {
+               compatible = "usb-a-connector";
+               phy-supply = <&v_5v0_usb3_hst_vbus>;
+       };
+};
+
 &cp1_usb3_0 {
-       usb-phy = <&usb3h0_phy>;
+       phys = <&cp1_comphy2 0>;
+       phy-names = "cp1-usb3h0-comphy";
        status = "okay";
 };
index d6e9c01..09fb525 100644 (file)
                vcc-supply = <&cp0_reg_usb3_0_vbus>;
        };
 
-       cp0_usb3_1_phy: cp0-usb3-1-phy {
-               compatible = "usb-nop-xceiv";
-               vcc-supply = <&cp0_reg_usb3_1_vbus>;
-       };
-
        cp1_reg_usb3_0_vbus: cp1-usb3-0-vbus {
                compatible = "regulator-fixed";
                regulator-name = "cp1-usb3h0-vbus";
 
 /* CON6 on CP0 expansion */
 &cp0_pcie0 {
+       phys = <&cp0_comphy0 0>;
+       phy-names = "cp0-pcie0-x1-phy";
        status = "okay";
 };
 
 /* CON5 on CP0 expansion */
 &cp0_pcie2 {
+       phys = <&cp0_comphy5 2>;
+       phy-names = "cp0-pcie2-x1-phy";
        status = "okay";
 };
 
 /* CON4 on CP0 expansion */
 &cp0_sata0 {
        status = "okay";
+
+       sata-port@0 {
+               phys = <&cp0_comphy1 0>;
+               phy-names = "cp0-sata0-0-phy";
+       };
+       sata-port@1 {
+               phys = <&cp0_comphy3 1>;
+               phy-names = "cp0-sata0-1-phy";
+       };
 };
 
 /* CON9 on CP0 expansion */
        status = "okay";
 };
 
+&cp0_comphy4 {
+       cp0_usbh1_con: connector {
+               compatible = "usb-a-connector";
+               phy-supply = <&cp0_reg_usb3_1_vbus>;
+       };
+};
+
 /* CON10 on CP0 expansion */
 &cp0_usb3_1 {
-       usb-phy = <&cp0_usb3_1_phy>;
+       phys = <&cp0_comphy4 1>;
+       phy-names = "cp0-usb3h1-comphy";
        status = "okay";
 };
 
 
 /* CON6 on CP1 expansion */
 &cp1_pcie0 {
+       phys = <&cp1_comphy0 0>;
+       phy-names = "cp1-pcie0-x1-phy";
        status = "okay";
 };
 
 /* CON7 on CP1 expansion */
 &cp1_pcie1 {
+       phys = <&cp1_comphy4 1>;
+       phy-names = "cp1-pcie1-x1-phy";
        status = "okay";
 };
 
 /* CON5 on CP1 expansion */
 &cp1_pcie2 {
+       phys = <&cp1_comphy5 2>;
+       phy-names = "cp1-pcie2-x1-phy";
        status = "okay";
 };
 
 /* CON4 on CP1 expansion */
 &cp1_sata0 {
        status = "okay";
+
+       sata-port@0 {
+               phys = <&cp1_comphy1 0>;
+               phy-names = "cp1-sata0-0-phy";
+       };
+       sata-port@1 {
+               phys = <&cp1_comphy3 1>;
+               phy-names = "cp1-sata0-1-phy";
+       };
 };
 
 /* CON9 on CP1 expansion */
index 205071b..d250f4b 100644 (file)
                status = "okay";
        };
 
-       usb3h0_phy: usb3_phy0 {
-               compatible = "usb-nop-xceiv";
-               vcc-supply = <&v_5v0_usb3_hst_vbus>;
-       };
-
        sfp_eth0: sfp-eth0 {
                /* CON15,16 - CPM lane 4 */
                compatible = "sff,sfp";
        reset-gpios = <&cp0_gpio2 20 GPIO_ACTIVE_LOW>;
        ranges = <0x81000000 0x0 0xf9010000 0x0 0xf9010000 0x0 0x10000
                  0x82000000 0x0 0xc0000000 0x0 0xc0000000 0x0 0x20000000>;
+       phys = <&cp0_comphy0 0>, <&cp0_comphy1 0>,
+              <&cp0_comphy2 0>, <&cp0_comphy3 0>;
+       phy-names = "cp0-pcie0-x4-lane0-phy", "cp0-pcie0-x4-lane1-phy",
+                   "cp0-pcie0-x4-lane2-phy", "cp0-pcie0-x4-lane3-phy";
        status = "okay";
 };
 
 };
 
 &cp0_sata0 {
-       /* CPM Lane 0 - U29 */
        status = "okay";
+
+       /* CPM Lane 5 - U29 */
+       sata-port@1 {
+               phys = <&cp0_comphy5 1>;
+               phy-names = "cp0-sata0-1-phy";
+       };
 };
 
 &cp0_sdhci0 {
 };
 
 &cp1_sata0 {
+       status = "okay";
+
        /* CPS Lane 1 - U32 */
+       sata-port@0 {
+               phys = <&cp1_comphy1 0>;
+               phy-names = "cp1-sata0-0-phy";
+       };
+
        /* CPS Lane 3 - U31 */
-       status = "okay";
+       sata-port@1 {
+               phys = <&cp1_comphy3 1>;
+               phy-names = "cp1-sata0-1-phy";
+       };
 };
 
 &cp1_spi1 {
        };
 };
 
+&cp1_comphy2 {
+       cp1_usbh0_con: connector {
+               compatible = "usb-a-connector";
+               phy-supply = <&v_5v0_usb3_hst_vbus>;
+       };
+};
+
 &cp1_usb3_0 {
        /* CPS Lane 2 - CON7 */
-       usb-phy = <&usb3h0_phy>;
+       phys = <&cp1_comphy2 0>;
+       phy-names = "cp1-usb3h0-comphy";
        status = "okay";
 };
index ea13ae7..c25bc65 100644 (file)
@@ -21,6 +21,7 @@
                        reg = <0x000>;
                        enable-method = "psci";
                        #cooling-cells = <2>;
+                       clocks = <&cpu_clk 0>;
                };
                cpu1: cpu@1 {
                        device_type = "cpu";
@@ -28,6 +29,7 @@
                        reg = <0x001>;
                        enable-method = "psci";
                        #cooling-cells = <2>;
+                       clocks = <&cpu_clk 0>;
                };
                cpu2: cpu@100 {
                        device_type = "cpu";
@@ -35,6 +37,7 @@
                        reg = <0x100>;
                        enable-method = "psci";
                        #cooling-cells = <2>;
+                       clocks = <&cpu_clk 1>;
                };
                cpu3: cpu@101 {
                        device_type = "cpu";
@@ -42,7 +45,7 @@
                        reg = <0x101>;
                        enable-method = "psci";
                        #cooling-cells = <2>;
+                       clocks = <&cpu_clk 1>;
                };
        };
-
 };
index 96228f9..d06dd19 100644 (file)
                                #address-cells = <1>;
                                #size-cells = <1>;
 
+                               cpu_clk: clock-cpu@278 {
+                                       compatible = "marvell,ap806-cpu-clock";
+                                       clocks = <&ap_clk 0>, <&ap_clk 1>;
+                                       #clock-cells = <1>;
+                                       reg = <0x278 0xa30>;
+                               };
+
                                ap_thermal: thermal-sensor@80 {
                                        compatible = "marvell,armada-ap806-thermal";
                                        reg = <0x80 0x10>;
index f71afb1..d819449 100644 (file)
                        compatible = "marvell,comphy-cp110";
                        reg = <0x120000 0x6000>;
                        marvell,system-controller = <&CP110_LABEL(syscon0)>;
+                       clocks = <&CP110_LABEL(clk) 1 5>, <&CP110_LABEL(clk) 1 6>,
+                                <&CP110_LABEL(clk) 1 18>;
+                       clock-names = "mg_clk", "mg_core_clk", "axi_clk";
                        #address-cells = <1>;
                        #size-cells = <0>;
 
                        interrupts = <107 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&CP110_LABEL(clk) 1 15>,
                                 <&CP110_LABEL(clk) 1 16>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
                        status = "disabled";
+
+                       sata-port@0 {
+                               reg = <0>;
+                       };
+
+                       sata-port@1 {
+                               reg = <1>;
+                       };
                };
 
                CP110_LABEL(xor0): xor@6a0000 {
index d8e555c..1fb195c 100644 (file)
        status = "okay";
 };
 
+&i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c_pins_0>;
+       status = "okay";
+       clock-frequency = <100000>;
+};
+
+&i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c_pins_1>;
+       status = "okay";
+       clock-frequency = <100000>;
+};
+
+&i2c2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c_pins_2>;
+       status = "okay";
+       clock-frequency = <100000>;
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c_pins_3>;
+       status = "okay";
+       clock-frequency = <100000>;
+};
+
+&i2c4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c_pins_4>;
+       status = "okay";
+       clock-frequency = <1000000>;
+};
+
+&i2c5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c_pins_5>;
+       status = "okay";
+       clock-frequency = <1000000>;
+};
+
 &pio {
+       i2c_pins_0: i2c0{
+               pins_i2c{
+                       pinmux = <PINMUX_GPIO82__FUNC_SDA0>,
+                                <PINMUX_GPIO83__FUNC_SCL0>;
+                       mediatek,pull-up-adv = <3>;
+                       mediatek,drive-strength-adv = <00>;
+               };
+       };
+
+       i2c_pins_1: i2c1{
+               pins_i2c{
+                       pinmux = <PINMUX_GPIO81__FUNC_SDA1>,
+                                <PINMUX_GPIO84__FUNC_SCL1>;
+                       mediatek,pull-up-adv = <3>;
+                       mediatek,drive-strength-adv = <00>;
+               };
+       };
+
+       i2c_pins_2: i2c2{
+               pins_i2c{
+                       pinmux = <PINMUX_GPIO103__FUNC_SCL2>,
+                                <PINMUX_GPIO104__FUNC_SDA2>;
+                       mediatek,pull-up-adv = <3>;
+                       mediatek,drive-strength-adv = <00>;
+               };
+       };
+
+       i2c_pins_3: i2c3{
+               pins_i2c{
+                       pinmux = <PINMUX_GPIO50__FUNC_SCL3>,
+                                <PINMUX_GPIO51__FUNC_SDA3>;
+                       mediatek,pull-up-adv = <3>;
+                       mediatek,drive-strength-adv = <00>;
+               };
+       };
+
+       i2c_pins_4: i2c4{
+               pins_i2c{
+                       pinmux = <PINMUX_GPIO105__FUNC_SCL4>,
+                                <PINMUX_GPIO106__FUNC_SDA4>;
+                       mediatek,pull-up-adv = <3>;
+                       mediatek,drive-strength-adv = <00>;
+               };
+       };
+
+       i2c_pins_5: i2c5{
+               pins_i2c{
+                       pinmux = <PINMUX_GPIO48__FUNC_SCL5>,
+                                <PINMUX_GPIO49__FUNC_SDA5>;
+                       mediatek,pull-up-adv = <3>;
+                       mediatek,drive-strength-adv = <00>;
+               };
+       };
+
        spi_pins_0: spi0{
                pins_spi{
                        pinmux = <PINMUX_GPIO85__FUNC_SPI0_MI>,
index c2749c4..97f84aa 100644 (file)
        #address-cells = <2>;
        #size-cells = <2>;
 
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+               i2c4 = &i2c4;
+               i2c5 = &i2c5;
+               i2c6 = &i2c6;
+               i2c7 = &i2c7;
+               i2c8 = &i2c8;
+               i2c9 = &i2c9;
+               i2c10 = &i2c10;
+               i2c11 = &i2c11;
+       };
+
        cpus {
                #address-cells = <1>;
                #size-cells = <0>;
                        compatible = "mediatek,mt8183-pwrap";
                        reg = <0 0x1000d000 0 0x1000>;
                        reg-names = "pwrap";
-                       interrupts = <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&topckgen CLK_TOP_MUX_PMICSPI>,
                                 <&infracfg CLK_INFRA_PMIC_AP>;
                        clock-names = "spi", "wrap";
                        status = "disabled";
                };
 
+               i2c6: i2c@11005000 {
+                       compatible = "mediatek,mt8183-i2c";
+                       reg = <0 0x11005000 0 0x1000>,
+                             <0 0x11000600 0 0x80>;
+                       interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_I2C6>,
+                                <&infracfg CLK_INFRA_AP_DMA>;
+                       clock-names = "main", "dma";
+                       clock-div = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c0: i2c@11007000 {
+                       compatible = "mediatek,mt8183-i2c";
+                       reg = <0 0x11007000 0 0x1000>,
+                             <0 0x11000080 0 0x80>;
+                       interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_I2C0>,
+                                <&infracfg CLK_INFRA_AP_DMA>;
+                       clock-names = "main", "dma";
+                       clock-div = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c4: i2c@11008000 {
+                       compatible = "mediatek,mt8183-i2c";
+                       reg = <0 0x11008000 0 0x1000>,
+                             <0 0x11000100 0 0x80>;
+                       interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_I2C1>,
+                                <&infracfg CLK_INFRA_AP_DMA>,
+                                <&infracfg CLK_INFRA_I2C1_ARBITER>;
+                       clock-names = "main", "dma","arb";
+                       clock-div = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c2: i2c@11009000 {
+                       compatible = "mediatek,mt8183-i2c";
+                       reg = <0 0x11009000 0 0x1000>,
+                             <0 0x11000280 0 0x80>;
+                       interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_I2C2>,
+                                <&infracfg CLK_INFRA_AP_DMA>,
+                                <&infracfg CLK_INFRA_I2C2_ARBITER>;
+                       clock-names = "main", "dma", "arb";
+                       clock-div = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
                spi0: spi@1100a000 {
                        compatible = "mediatek,mt8183-spi";
                        #address-cells = <1>;
                        status = "disabled";
                };
 
+               i2c3: i2c@1100f000 {
+                       compatible = "mediatek,mt8183-i2c";
+                       reg = <0 0x1100f000 0 0x1000>,
+                             <0 0x11000400 0 0x80>;
+                       interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_I2C3>,
+                                <&infracfg CLK_INFRA_AP_DMA>;
+                       clock-names = "main", "dma";
+                       clock-div = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
                spi1: spi@11010000 {
                        compatible = "mediatek,mt8183-spi";
                        #address-cells = <1>;
                        status = "disabled";
                };
 
+               i2c1: i2c@11011000 {
+                       compatible = "mediatek,mt8183-i2c";
+                       reg = <0 0x11011000 0 0x1000>,
+                             <0 0x11000480 0 0x80>;
+                       interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_I2C4>,
+                                <&infracfg CLK_INFRA_AP_DMA>;
+                       clock-names = "main", "dma";
+                       clock-div = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
                spi2: spi@11012000 {
                        compatible = "mediatek,mt8183-spi";
                        #address-cells = <1>;
                        status = "disabled";
                };
 
+               i2c9: i2c@11014000 {
+                       compatible = "mediatek,mt8183-i2c";
+                       reg = <0 0x11014000 0 0x1000>,
+                             <0 0x11000180 0 0x80>;
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_I2C1_IMM>,
+                                <&infracfg CLK_INFRA_AP_DMA>,
+                                <&infracfg CLK_INFRA_I2C1_ARBITER>;
+                       clock-names = "main", "dma", "arb";
+                       clock-div = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c10: i2c@11015000 {
+                       compatible = "mediatek,mt8183-i2c";
+                       reg = <0 0x11015000 0 0x1000>,
+                             <0 0x11000300 0 0x80>;
+                       interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_I2C2_IMM>,
+                                <&infracfg CLK_INFRA_AP_DMA>,
+                                <&infracfg CLK_INFRA_I2C2_ARBITER>;
+                       clock-names = "main", "dma", "arb";
+                       clock-div = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c5: i2c@11016000 {
+                       compatible = "mediatek,mt8183-i2c";
+                       reg = <0 0x11016000 0 0x1000>,
+                             <0 0x11000500 0 0x80>;
+                       interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_I2C5>,
+                                <&infracfg CLK_INFRA_AP_DMA>,
+                                <&infracfg CLK_INFRA_I2C5_ARBITER>;
+                       clock-names = "main", "dma", "arb";
+                       clock-div = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c11: i2c@11017000 {
+                       compatible = "mediatek,mt8183-i2c";
+                       reg = <0 0x11017000 0 0x1000>,
+                             <0 0x11000580 0 0x80>;
+                       interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_I2C5_IMM>,
+                                <&infracfg CLK_INFRA_AP_DMA>,
+                                <&infracfg CLK_INFRA_I2C5_ARBITER>;
+                       clock-names = "main", "dma", "arb";
+                       clock-div = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
                spi4: spi@11018000 {
                        compatible = "mediatek,mt8183-spi";
                        #address-cells = <1>;
                        status = "disabled";
                };
 
+               i2c7: i2c@1101a000 {
+                       compatible = "mediatek,mt8183-i2c";
+                       reg = <0 0x1101a000 0 0x1000>,
+                             <0 0x11000680 0 0x80>;
+                       interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_I2C7>,
+                                <&infracfg CLK_INFRA_AP_DMA>;
+                       clock-names = "main", "dma";
+                       clock-div = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
+               i2c8: i2c@1101b000 {
+                       compatible = "mediatek,mt8183-i2c";
+                       reg = <0 0x1101b000 0 0x1000>,
+                             <0 0x11000700 0 0x80>;
+                       interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&infracfg CLK_INFRA_I2C8>,
+                                <&infracfg CLK_INFRA_AP_DMA>;
+                       clock-names = "main", "dma";
+                       clock-div = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
                audiosys: syscon@11220000 {
                        compatible = "mediatek,mt8183-audiosys", "syscon";
                        reg = <0 0x11220000 0 0x1000>;
index 0a7e5df..6498a1e 100644 (file)
@@ -3,14 +3,22 @@ dtb-$(CONFIG_ARCH_QCOM)       += apq8016-sbc.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += apq8096-db820c.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += ipq8074-hk01.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += msm8916-mtp.dtb
+dtb-$(CONFIG_ARCH_QCOM)        += msm8916-longcheer-l8150.dtb
+dtb-$(CONFIG_ARCH_QCOM)        += msm8916-samsung-a3u-eur.dtb
+dtb-$(CONFIG_ARCH_QCOM)        += msm8916-samsung-a5u-eur.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
+dtb-$(CONFIG_ARCH_QCOM)        += msm8998-asus-novago-tp370ql.dtb
+dtb-$(CONFIG_ARCH_QCOM)        += msm8998-hp-envy-x2.dtb
+dtb-$(CONFIG_ARCH_QCOM)        += msm8998-lenovo-miix-630.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += msm8998-mtp.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sdm845-cheza-r1.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sdm845-cheza-r2.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sdm845-cheza-r3.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sdm845-db845c.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sdm845-mtp.dtb
+dtb-$(CONFIG_ARCH_QCOM)        += sdm850-lenovo-yoga-c630.dtb
+dtb-$(CONFIG_ARCH_QCOM)        += sm8150-mtp.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += qcs404-evb-1000.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += qcs404-evb-4000.dtb
diff --git a/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts b/arch/arm64/boot/dts/qcom/msm8916-longcheer-l8150.dts
new file mode 100644 (file)
index 0000000..2b28e38
--- /dev/null
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8916.dtsi"
+#include "pm8916.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       model = "Longcheer L8150";
+       compatible = "longcheer,l8150", "qcom,msm8916-v1-qrd/9-v1", "qcom,msm8916";
+
+       aliases {
+               serial0 = &blsp1_uart2;
+       };
+
+       chosen {
+               stdout-path = "serial0";
+       };
+
+       soc {
+               sdhci@7824000 {
+                       status = "okay";
+
+                       vmmc-supply = <&pm8916_l8>;
+                       vqmmc-supply = <&pm8916_l5>;
+
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>;
+                       pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>;
+               };
+
+               sdhci@7864000 {
+                       status = "okay";
+
+                       vmmc-supply = <&pm8916_l11>;
+                       vqmmc-supply = <&pm8916_l12>;
+
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on>;
+                       pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off>;
+
+                       non-removable;
+               };
+
+               serial@78b0000 {
+                       status = "okay";
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&blsp1_uart2_default>;
+                       pinctrl-1 = <&blsp1_uart2_sleep>;
+               };
+
+               usb@78d9000 {
+                       status = "okay";
+                       dr_mode = "peripheral";
+                       extcon = <&usb_vbus>;
+
+                       hnp-disable;
+                       srp-disable;
+                       adp-disable;
+
+                       ulpi {
+                               phy {
+                                       extcon = <&usb_vbus>;
+                                       v1p8-supply = <&pm8916_l7>;
+                                       v3p3-supply = <&pm8916_l13>;
+                               };
+                       };
+               };
+
+               /*
+                * Attempting to enable these devices causes a "synchronous
+                * external abort". Suspected cause is that the debug power
+                * domain is not enabled by default on this device.
+                * Disable these devices for now to avoid the crash.
+                *
+                * See: https://lore.kernel.org/linux-arm-msm/20190618202623.GA53651@gerhold.net/
+                */
+               tpiu@820000 { status = "disabled"; };
+               funnel@821000 { status = "disabled"; };
+               replicator@824000 { status = "disabled"; };
+               etf@825000 { status = "disabled"; };
+               etr@826000 { status = "disabled"; };
+               funnel@841000 { status = "disabled"; };
+               debug@850000 { status = "disabled"; };
+               debug@852000 { status = "disabled"; };
+               debug@854000 { status = "disabled"; };
+               debug@856000 { status = "disabled"; };
+               etm@85c000 { status = "disabled"; };
+               etm@85d000 { status = "disabled"; };
+               etm@85e000 { status = "disabled"; };
+               etm@85f000 { status = "disabled"; };
+       };
+
+       // FIXME: Use extcon device provided by charger driver when available
+       usb_vbus: usb-vbus {
+               compatible = "linux,extcon-usb-gpio";
+               vbus-gpio = <&msmgpio 62 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&usb_vbus_default>;
+       };
+};
+
+&msmgpio {
+       usb_vbus_default: usb-vbus-default {
+               pinmux {
+                       function = "gpio";
+                       pins = "gpio62";
+               };
+               pinconf {
+                       pins = "gpio62";
+                       bias-pull-up;
+               };
+       };
+};
+
+&smd_rpm_regulators {
+       vdd_l1_l2_l3-supply = <&pm8916_s3>;
+       vdd_l4_l5_l6-supply = <&pm8916_s4>;
+       vdd_l7-supply = <&pm8916_s4>;
+
+       s1 {
+               regulator-min-microvolt = <500000>;
+               regulator-max-microvolt = <1300000>;
+       };
+
+       s3 {
+               regulator-min-microvolt = <1200000>;
+               regulator-max-microvolt = <1300000>;
+       };
+
+       s4 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <2100000>;
+       };
+
+       l1 {
+               regulator-min-microvolt = <1225000>;
+               regulator-max-microvolt = <1225000>;
+       };
+
+       l2 {
+               regulator-min-microvolt = <1200000>;
+               regulator-max-microvolt = <1200000>;
+       };
+
+       l3 {
+               regulator-min-microvolt = <500000>;
+               regulator-max-microvolt = <1287500>;
+       };
+
+       l4 {
+               regulator-min-microvolt = <2050000>;
+               regulator-max-microvolt = <2050000>;
+       };
+
+       l5 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
+       l6 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
+       l7 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
+       l8 {
+               regulator-min-microvolt = <2850000>;
+               regulator-max-microvolt = <2900000>;
+       };
+
+       l9 {
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       l10 {
+               regulator-min-microvolt = <2700000>;
+               regulator-max-microvolt = <2800000>;
+       };
+
+       l11 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <2950000>;
+               regulator-allow-set-load;
+               regulator-system-load = <200000>;
+       };
+
+       l12 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <2950000>;
+       };
+
+       l13 {
+               regulator-min-microvolt = <3075000>;
+               regulator-max-microvolt = <3075000>;
+       };
+
+       l14 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       l15 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       l16 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       l17 {
+               regulator-min-microvolt = <2850000>;
+               regulator-max-microvolt = <2850000>;
+       };
+
+       l18 {
+               regulator-min-microvolt = <2700000>;
+               regulator-max-microvolt = <2700000>;
+       };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi b/arch/arm64/boot/dts/qcom/msm8916-samsung-a2015-common.dtsi
new file mode 100644 (file)
index 0000000..e675ff4
--- /dev/null
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "msm8916.dtsi"
+#include "pm8916.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+       aliases {
+               serial0 = &blsp1_uart2;
+       };
+
+       chosen {
+               stdout-path = "serial0";
+       };
+
+       soc {
+               sdhci@7824000 {
+                       status = "okay";
+
+                       vmmc-supply = <&pm8916_l8>;
+                       vqmmc-supply = <&pm8916_l5>;
+
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on>;
+                       pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off>;
+               };
+
+               sdhci@7864000 {
+                       status = "okay";
+
+                       vmmc-supply = <&pm8916_l11>;
+                       vqmmc-supply = <&pm8916_l12>;
+
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+                       pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+                       cd-gpios = <&msmgpio 38 GPIO_ACTIVE_LOW>;
+               };
+
+               serial@78b0000 {
+                       status = "okay";
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&blsp1_uart2_default>;
+                       pinctrl-1 = <&blsp1_uart2_sleep>;
+               };
+
+               usb@78d9000 {
+                       status = "okay";
+                       extcon = <&muic>, <&muic>;
+
+                       hnp-disable;
+                       srp-disable;
+                       adp-disable;
+
+                       ulpi {
+                               phy {
+                                       extcon = <&muic>;
+                                       v1p8-supply = <&pm8916_l7>;
+                                       v3p3-supply = <&pm8916_l13>;
+                               };
+                       };
+               };
+
+               /*
+                * Attempting to enable these devices causes a "synchronous
+                * external abort". Suspected cause is that the debug power
+                * domain is not enabled by default on this device.
+                * Disable these devices for now to avoid the crash.
+                *
+                * See: https://lore.kernel.org/linux-arm-msm/20190618202623.GA53651@gerhold.net/
+                */
+               tpiu@820000 { status = "disabled"; };
+               funnel@821000 { status = "disabled"; };
+               replicator@824000 { status = "disabled"; };
+               etf@825000 { status = "disabled"; };
+               etr@826000 { status = "disabled"; };
+               funnel@841000 { status = "disabled"; };
+               debug@850000 { status = "disabled"; };
+               debug@852000 { status = "disabled"; };
+               debug@854000 { status = "disabled"; };
+               debug@856000 { status = "disabled"; };
+               etm@85c000 { status = "disabled"; };
+               etm@85d000 { status = "disabled"; };
+               etm@85e000 { status = "disabled"; };
+               etm@85f000 { status = "disabled"; };
+       };
+
+       i2c-muic {
+               compatible = "i2c-gpio";
+               sda-gpios = <&msmgpio 105 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+               scl-gpios = <&msmgpio 106 (GPIO_ACTIVE_HIGH|GPIO_OPEN_DRAIN)>;
+
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               muic: sm5502@25 {
+                       compatible = "siliconmitus,sm5502-muic";
+
+                       reg = <0x25>;
+                       interrupt-parent = <&msmgpio>;
+                       interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&muic_int_default>;
+               };
+       };
+};
+
+&msmgpio {
+       muic_int_default: muic_int_default {
+               pinmux {
+                       function = "gpio";
+                       pins = "gpio12";
+               };
+               pinconf {
+                       pins = "gpio12";
+                       drive-strength = <2>;
+                       bias-disable;
+               };
+       };
+};
+
+&smd_rpm_regulators {
+       vdd_l1_l2_l3-supply = <&pm8916_s3>;
+       vdd_l4_l5_l6-supply = <&pm8916_s4>;
+       vdd_l7-supply = <&pm8916_s4>;
+
+       s1 {
+               regulator-min-microvolt = <500000>;
+               regulator-max-microvolt = <1300000>;
+       };
+
+       s3 {
+               regulator-min-microvolt = <1200000>;
+               regulator-max-microvolt = <1300000>;
+       };
+
+       s4 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <2100000>;
+       };
+
+       l1 {
+               regulator-min-microvolt = <1225000>;
+               regulator-max-microvolt = <1225000>;
+       };
+
+       l2 {
+               regulator-min-microvolt = <1200000>;
+               regulator-max-microvolt = <1200000>;
+       };
+
+       l3 {
+               regulator-min-microvolt = <500000>;
+               regulator-max-microvolt = <1287500>;
+       };
+
+       l4 {
+               regulator-min-microvolt = <2050000>;
+               regulator-max-microvolt = <2050000>;
+       };
+
+       l5 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
+       l6 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
+       l7 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+       };
+
+       l8 {
+               regulator-min-microvolt = <2850000>;
+               regulator-max-microvolt = <2900000>;
+       };
+
+       l9 {
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       l10 {
+               regulator-min-microvolt = <2700000>;
+               regulator-max-microvolt = <2800000>;
+       };
+
+       l11 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <2950000>;
+               regulator-allow-set-load;
+               regulator-system-load = <200000>;
+       };
+
+       l12 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <2950000>;
+       };
+
+       l13 {
+               regulator-min-microvolt = <3075000>;
+               regulator-max-microvolt = <3075000>;
+       };
+
+       l14 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       l15 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       l16 {
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
+       l17 {
+               regulator-min-microvolt = <2850000>;
+               regulator-max-microvolt = <2850000>;
+       };
+
+       l18 {
+               regulator-min-microvolt = <2700000>;
+               regulator-max-microvolt = <2700000>;
+       };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a3u-eur.dts
new file mode 100644 (file)
index 0000000..d10f7ac
--- /dev/null
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8916-samsung-a2015-common.dtsi"
+
+/ {
+       model = "Samsung Galaxy A3U (EUR)";
+       compatible = "samsung,a3u-eur", "qcom,msm8916";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts b/arch/arm64/boot/dts/qcom/msm8916-samsung-a5u-eur.dts
new file mode 100644 (file)
index 0000000..1aa59da
--- /dev/null
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+/dts-v1/;
+
+#include "msm8916-samsung-a2015-common.dtsi"
+
+/ {
+       model = "Samsung Galaxy A5U (EUR)";
+       compatible = "samsung,a5u-eur", "qcom,msm8916";
+};
index 96c0a48..87f4d9c 100644 (file)
                        reg = <0x300000 0x90000>;
                };
 
+               stm@3002000 {
+                       compatible = "arm,coresight-stm", "arm,primecell";
+                       reg = <0x3002000 0x1000>,
+                             <0x8280000 0x180000>;
+                       reg-names = "stm-base", "stm-stimulus-base";
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       out-ports {
+                               port {
+                                       stm_out: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel0_in>;
+                                       };
+                               };
+                       };
+               };
+
+               tpiu@3020000 {
+                       compatible = "arm,coresight-tpiu", "arm,primecell";
+                       reg = <0x3020000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               port {
+                                       tpiu_in: endpoint {
+                                               remote-endpoint =
+                                                 <&replicator_out1>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@3021000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x3021000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@7 {
+                                       reg = <7>;
+                                       funnel0_in: endpoint {
+                                               remote-endpoint =
+                                                 <&stm_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               port {
+                                       funnel0_out: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_in0>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@3022000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x3022000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@6 {
+                                       reg = <6>;
+                                       funnel1_in: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_merge_funnel_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               port {
+                                       funnel1_out: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_in1>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@3023000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x3023000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+
+                       out-ports {
+                               port {
+                                       funnel2_out: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_in2>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@3025000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x3025000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       merge_funnel_in0: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel0_out>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       merge_funnel_in1: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel1_out>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       merge_funnel_in2: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel2_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               port {
+                                       merge_funnel_out: endpoint {
+                                               remote-endpoint =
+                                                 <&etf_in>;
+                                       };
+                               };
+                       };
+               };
+
+               replicator@3026000 {
+                       compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+                       reg = <0x3026000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               port {
+                                       replicator_in: endpoint {
+                                               remote-endpoint =
+                                                 <&etf_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       replicator_out0: endpoint {
+                                               remote-endpoint =
+                                                 <&etr_in>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       replicator_out1: endpoint {
+                                               remote-endpoint =
+                                                 <&tpiu_in>;
+                                       };
+                               };
+                       };
+               };
+
+               etf@3027000 {
+                       compatible = "arm,coresight-tmc", "arm,primecell";
+                       reg = <0x3027000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               port {
+                                       etf_in: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               port {
+                                       etf_out: endpoint {
+                                               remote-endpoint =
+                                                 <&replicator_in>;
+                                       };
+                               };
+                       };
+               };
+
+               etr@3028000 {
+                       compatible = "arm,coresight-tmc", "arm,primecell";
+                       reg = <0x3028000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+                       arm,scatter-gather;
+
+                       in-ports {
+                               port {
+                                       etr_in: endpoint {
+                                               remote-endpoint =
+                                                 <&replicator_out0>;
+                                       };
+                               };
+                       };
+               };
+
+               debug@3810000 {
+                       compatible = "arm,coresight-cpu-debug", "arm,primecell";
+                       reg = <0x3810000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>;
+                       clock-names = "apb_pclk";
+
+                       cpu = <&CPU0>;
+               };
+
+               etm@3840000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x3840000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU0>;
+
+                       out-ports {
+                               port {
+                                       etm0_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel0_in0>;
+                                       };
+                               };
+                       };
+               };
+
+               debug@3910000 {
+                       compatible = "arm,coresight-cpu-debug", "arm,primecell";
+                       reg = <0x3910000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>;
+                       clock-names = "apb_pclk";
+
+                       cpu = <&CPU1>;
+               };
+
+               etm@3940000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x3940000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU1>;
+
+                       out-ports {
+                               port {
+                                       etm1_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel0_in1>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@39b0000 { /* APSS Funnel 0 */
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x39b0000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       apss_funnel0_in0: endpoint {
+                                               remote-endpoint = <&etm0_out>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       apss_funnel0_in1: endpoint {
+                                               remote-endpoint = <&etm1_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               port {
+                                       apss_funnel0_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_merge_funnel_in0>;
+                                       };
+                               };
+                       };
+               };
+
+               debug@3a10000 {
+                       compatible = "arm,coresight-cpu-debug", "arm,primecell";
+                       reg = <0x3a10000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>;
+                       clock-names = "apb_pclk";
+
+                       cpu = <&CPU2>;
+               };
+
+               etm@3a40000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x3a40000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU2>;
+
+                       out-ports {
+                               port {
+                                       etm2_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel1_in0>;
+                                       };
+                               };
+                       };
+               };
+
+               debug@3b10000 {
+                       compatible = "arm,coresight-cpu-debug", "arm,primecell";
+                       reg = <0x3b10000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>;
+                       clock-names = "apb_pclk";
+
+                       cpu = <&CPU3>;
+               };
+
+               etm@3b40000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x3b40000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU3>;
+
+                       out-ports {
+                               port {
+                                       etm3_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel1_in1>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@3bb0000 { /* APSS Funnel 1 */
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x3bb0000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       apss_funnel1_in0: endpoint {
+                                               remote-endpoint = <&etm2_out>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       apss_funnel1_in1: endpoint {
+                                               remote-endpoint = <&etm3_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               port {
+                                       apss_funnel1_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_merge_funnel_in1>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@3bc0000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x3bc0000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       apss_merge_funnel_in0: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel0_out>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       apss_merge_funnel_in1: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel1_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               port {
+                                       apss_merge_funnel_out: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel1_in>;
+                                       };
+                               };
+                       };
+               };
+
                kryocc: clock-controller@6400000 {
                        compatible = "qcom,apcc-msm8996";
                        reg = <0x6400000 0x90000>;
                        };
                };
 
-               vfe_smmu: arm,smmu@da0000 {
+               vfe_smmu: iommu@da0000 {
                        compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
                        reg = <0xda0000 0x10000>;
 
                        };
                };
 
-               adreno_smmu: arm,smmu@b40000 {
+               adreno_smmu: iommu@b40000 {
                        compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
                        reg = <0xb40000 0x10000>;
 
                        power-domains = <&mmcc GPU_GDSC>;
                };
 
-               mdp_smmu: arm,smmu@d00000 {
+               mdp_smmu: iommu@d00000 {
                        compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
                        reg = <0xd00000 0x10000>;
 
                        power-domains = <&mmcc MDSS_GDSC>;
                };
 
-               lpass_q6_smmu: arm,smmu-lpass_q6@1600000 {
+               lpass_q6_smmu: iommu@1600000 {
                        compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
                        reg = <0x1600000 0x20000>;
                        #iommu-cells = <1>;
                                              "ref";
                        };
                };
+
+               venus_smmu: arm,smmu-venus@d40000 {
+                       compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
+                       reg = <0xd40000 0x20000>;
+                       #global-interrupts = <1>;
+                       interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 338 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 339 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 340 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&mmcc MMAGIC_VIDEO_GDSC>;
+                       clocks = <&mmcc SMMU_VIDEO_AHB_CLK>,
+                                <&mmcc SMMU_VIDEO_AXI_CLK>;
+                       clock-names = "iface", "bus";
+                       #iommu-cells = <1>;
+                       status = "okay";
+               };
+
+               video-codec@c00000 {
+                       compatible = "qcom,msm8996-venus";
+                       reg = <0x00c00000 0xff000>;
+                       interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&mmcc VENUS_GDSC>;
+                       clocks = <&mmcc VIDEO_CORE_CLK>,
+                                <&mmcc VIDEO_AHB_CLK>,
+                                <&mmcc VIDEO_AXI_CLK>,
+                                <&mmcc VIDEO_MAXI_CLK>;
+                       clock-names = "core", "iface", "bus", "mbus";
+                       iommus = <&venus_smmu 0x00>,
+                                <&venus_smmu 0x01>,
+                                <&venus_smmu 0x0a>,
+                                <&venus_smmu 0x07>,
+                                <&venus_smmu 0x0e>,
+                                <&venus_smmu 0x0f>,
+                                <&venus_smmu 0x08>,
+                                <&venus_smmu 0x09>,
+                                <&venus_smmu 0x0b>,
+                                <&venus_smmu 0x0c>,
+                                <&venus_smmu 0x0d>,
+                                <&venus_smmu 0x10>,
+                                <&venus_smmu 0x11>,
+                                <&venus_smmu 0x21>,
+                                <&venus_smmu 0x28>,
+                                <&venus_smmu 0x29>,
+                                <&venus_smmu 0x2b>,
+                                <&venus_smmu 0x2c>,
+                                <&venus_smmu 0x2d>,
+                                <&venus_smmu 0x31>;
+                       memory-region = <&venus_region>;
+                       status = "okay";
+
+                       video-decoder {
+                               compatible = "venus-decoder";
+                               clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
+                               clock-names = "core";
+                               power-domains = <&mmcc VENUS_CORE0_GDSC>;
+                       };
+
+                       video-encoder {
+                               compatible = "venus-encoder";
+                               clocks = <&mmcc VIDEO_SUBCORE1_CLK>;
+                               clock-names = "core";
+                               power-domains = <&mmcc VENUS_CORE1_GDSC>;
+                       };
+               };
        };
 
        sound: sound {
diff --git a/arch/arm64/boot/dts/qcom/msm8998-asus-novago-tp370ql.dts b/arch/arm64/boot/dts/qcom/msm8998-asus-novago-tp370ql.dts
new file mode 100644 (file)
index 0000000..db5821b
--- /dev/null
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019, Jeffrey Hugo. All rights reserved. */
+
+/dts-v1/;
+
+#include "msm8998-clamshell.dtsi"
+
+/ {
+       model = "Asus NovaGo TP370QL";
+       compatible = "asus,novago-tp370ql", "qcom,msm8998";
+};
+
+&blsp1_i2c6 {
+       status = "okay";
+
+       touchpad@15 {
+               compatible = "hid-over-i2c";
+               interrupt-parent = <&tlmm>;
+               interrupts = <0x7b IRQ_TYPE_LEVEL_LOW>;
+               reg = <0x15>;
+               hid-descr-addr = <0x0001>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&touchpad>;
+       };
+
+       keyboard@3a {
+               compatible = "hid-over-i2c";
+               interrupt-parent = <&tlmm>;
+               interrupts = <0x25 IRQ_TYPE_LEVEL_LOW>;
+               reg = <0x3a>;
+               hid-descr-addr = <0x0001>;
+       };
+};
+
+&sdhc2 {
+       cd-gpios = <&tlmm 95 GPIO_ACTIVE_HIGH>;
+};
+
+&tlmm {
+       touchpad: touchpad {
+               config {
+                       pins = "gpio123";
+                       bias-pull-up;
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8998-clamshell.dtsi b/arch/arm64/boot/dts/qcom/msm8998-clamshell.dtsi
new file mode 100644 (file)
index 0000000..9682d4d
--- /dev/null
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019, Jeffrey Hugo. All rights reserved. */
+
+/*
+ * Common include for MSM8998 clamshell devices, ie the Lenovo Miix 630,
+ * Asus NovaGo TP370QL, and HP Envy x2.  All three devices are basically the
+ * same, with differences in peripherals.
+ */
+
+#include "msm8998.dtsi"
+#include "pm8998.dtsi"
+#include "pm8005.dtsi"
+
+/ {
+       chosen {
+       };
+
+       vph_pwr: vph-pwr-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vph_pwr";
+               regulator-always-on;
+               regulator-boot-on;
+       };
+};
+
+&qusb2phy {
+       status = "okay";
+
+       vdda-pll-supply = <&vreg_l12a_1p8>;
+       vdda-phy-dpdm-supply = <&vreg_l24a_3p075>;
+};
+
+&rpm_requests {
+       pm8998-regulators {
+               compatible = "qcom,rpm-pm8998-regulators";
+
+               vdd_s1-supply = <&vph_pwr>;
+               vdd_s2-supply = <&vph_pwr>;
+               vdd_s3-supply = <&vph_pwr>;
+               vdd_s4-supply = <&vph_pwr>;
+               vdd_s5-supply = <&vph_pwr>;
+               vdd_s6-supply = <&vph_pwr>;
+               vdd_s7-supply = <&vph_pwr>;
+               vdd_s8-supply = <&vph_pwr>;
+               vdd_s9-supply = <&vph_pwr>;
+               vdd_s10-supply = <&vph_pwr>;
+               vdd_s11-supply = <&vph_pwr>;
+               vdd_s12-supply = <&vph_pwr>;
+               vdd_s13-supply = <&vph_pwr>;
+               vdd_l1_l27-supply = <&vreg_s7a_1p025>;
+               vdd_l2_l8_l17-supply = <&vreg_s3a_1p35>;
+               vdd_l3_l11-supply = <&vreg_s7a_1p025>;
+               vdd_l4_l5-supply = <&vreg_s7a_1p025>;
+               vdd_l6-supply = <&vreg_s5a_2p04>;
+               vdd_l7_l12_l14_l15-supply = <&vreg_s5a_2p04>;
+               vdd_l9-supply = <&vph_pwr>;
+               vdd_l10_l23_l25-supply = <&vph_pwr>;
+               vdd_l13_l19_l21-supply = <&vph_pwr>;
+               vdd_l16_l28-supply = <&vph_pwr>;
+               vdd_l18_l22-supply = <&vph_pwr>;
+               vdd_l20_l24-supply = <&vph_pwr>;
+               vdd_l26-supply = <&vreg_s3a_1p35>;
+               vdd_lvs1_lvs2-supply = <&vreg_s4a_1p8>;
+
+               vreg_s3a_1p35: s3 {
+                       regulator-min-microvolt = <1352000>;
+                       regulator-max-microvolt = <1352000>;
+               };
+               vreg_s4a_1p8: s4 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-allow-set-load;
+               };
+               vreg_s5a_2p04: s5 {
+                       regulator-min-microvolt = <1904000>;
+                       regulator-max-microvolt = <2040000>;
+               };
+               vreg_s7a_1p025: s7 {
+                       regulator-min-microvolt = <900000>;
+                       regulator-max-microvolt = <1028000>;
+               };
+               vreg_l1a_0p875: l1 {
+                       regulator-min-microvolt = <880000>;
+                       regulator-max-microvolt = <880000>;
+                       regulator-allow-set-load;
+               };
+               vreg_l2a_1p2: l2 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-allow-set-load;
+               };
+               vreg_l3a_1p0: l3 {
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+               };
+               vreg_l5a_0p8: l5 {
+                       regulator-min-microvolt = <800000>;
+                       regulator-max-microvolt = <800000>;
+               };
+               vreg_l6a_1p8: l6 {
+                       regulator-min-microvolt = <1808000>;
+                       regulator-max-microvolt = <1808000>;
+               };
+               vreg_l7a_1p8: l7 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l8a_1p2: l8 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+               vreg_l9a_1p8: l9 {
+                       regulator-min-microvolt = <1808000>;
+                       regulator-max-microvolt = <2960000>;
+               };
+               vreg_l10a_1p8: l10 {
+                       regulator-min-microvolt = <1808000>;
+                       regulator-max-microvolt = <2960000>;
+               };
+               vreg_l11a_1p0: l11 {
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+               };
+               vreg_l12a_1p8: l12 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l13a_2p95: l13 {
+                       regulator-min-microvolt = <1808000>;
+                       regulator-max-microvolt = <2960000>;
+               };
+               vreg_l14a_1p88: l14 {
+                       regulator-min-microvolt = <1880000>;
+                       regulator-max-microvolt = <1880000>;
+               };
+               vreg_15a_1p8: l15 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l16a_2p7: l16 {
+                       regulator-min-microvolt = <2704000>;
+                       regulator-max-microvolt = <2704000>;
+               };
+               vreg_l17a_1p3: l17 {
+                       regulator-min-microvolt = <1304000>;
+                       regulator-max-microvolt = <1304000>;
+               };
+               vreg_l18a_2p7: l18 {
+                       regulator-min-microvolt = <2704000>;
+                       regulator-max-microvolt = <2704000>;
+               };
+               vreg_l19a_3p0: l19 {
+                       regulator-min-microvolt = <3008000>;
+                       regulator-max-microvolt = <3008000>;
+               };
+               vreg_l20a_2p95: l20 {
+                       regulator-min-microvolt = <2960000>;
+                       regulator-max-microvolt = <2960000>;
+                       regulator-allow-set-load;
+               };
+               vreg_l21a_2p95: l21 {
+                       regulator-min-microvolt = <2960000>;
+                       regulator-max-microvolt = <2960000>;
+                       regulator-allow-set-load;
+                       regulator-system-load = <800000>;
+               };
+               vreg_l22a_2p85: l22 {
+                       regulator-min-microvolt = <2864000>;
+                       regulator-max-microvolt = <2864000>;
+               };
+               vreg_l23a_3p3: l23 {
+                       regulator-min-microvolt = <3312000>;
+                       regulator-max-microvolt = <3312000>;
+               };
+               vreg_l24a_3p075: l24 {
+                       regulator-min-microvolt = <3088000>;
+                       regulator-max-microvolt = <3088000>;
+               };
+               vreg_l25a_3p3: l25 {
+                       regulator-min-microvolt = <3104000>;
+                       regulator-max-microvolt = <3312000>;
+               };
+               vreg_l26a_1p2: l26 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+               vreg_l28_3p0: l28 {
+                       regulator-min-microvolt = <3008000>;
+                       regulator-max-microvolt = <3008000>;
+               };
+
+               vreg_lvs1a_1p8: lvs1 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               vreg_lvs2a_1p8: lvs2 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+       };
+};
+
+&tlmm {
+       gpio-reserved-ranges = <0 4>, <81 4>;
+
+       touchpad: touchpad {
+               config {
+                       pins = "gpio123";
+                       bias-pull-up;           /* pull up */
+               };
+       };
+};
+
+&sdhc2 {
+       status = "okay";
+
+       vmmc-supply = <&vreg_l21a_2p95>;
+       vqmmc-supply = <&vreg_l13a_2p95>;
+
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&sdc2_clk_on  &sdc2_cmd_on  &sdc2_data_on  &sdc2_cd_on>;
+       pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+};
+
+&usb3 {
+       status = "okay";
+};
+
+&usb3_dwc3 {
+       dr_mode = "host"; /* Force to host until we have Type-C hooked up */
+};
+
+&usb3phy {
+       status = "okay";
+
+       vdda-phy-supply = <&vreg_l1a_0p875>;
+       vdda-pll-supply = <&vreg_l2a_1p2>;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8998-hp-envy-x2.dts b/arch/arm64/boot/dts/qcom/msm8998-hp-envy-x2.dts
new file mode 100644 (file)
index 0000000..2407312
--- /dev/null
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019, Jeffrey Hugo. All rights reserved. */
+
+/dts-v1/;
+
+#include "msm8998-clamshell.dtsi"
+
+/ {
+       model = "HP Envy x2";
+       compatible = "hp,envy-x2", "qcom,msm8998";
+};
+
+&blsp1_i2c6 {
+       status = "okay";
+
+       keyboard@3a {
+               compatible = "hid-over-i2c";
+               interrupt-parent = <&tlmm>;
+               interrupts = <0x79 IRQ_TYPE_LEVEL_LOW>;
+               reg = <0x3a>;
+               hid-descr-addr = <0x0001>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&touchpad>;
+       };
+};
+
+&sdhc2 {
+       cd-gpios = <&tlmm 95 GPIO_ACTIVE_LOW>;
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8998-lenovo-miix-630.dts b/arch/arm64/boot/dts/qcom/msm8998-lenovo-miix-630.dts
new file mode 100644 (file)
index 0000000..407c6a3
--- /dev/null
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019, Jeffrey Hugo. All rights reserved. */
+
+/dts-v1/;
+
+#include "msm8998-clamshell.dtsi"
+
+/ {
+       model = "Lenovo Miix 630";
+       compatible = "lenovo,miix-630", "qcom,msm8998";
+};
+
+&blsp1_i2c6 {
+       status = "okay";
+
+       keyboard@3a {
+               compatible = "hid-over-i2c";
+               interrupt-parent = <&tlmm>;
+               interrupts = <0x79 IRQ_TYPE_LEVEL_LOW>;
+               reg = <0x3a>;
+               hid-descr-addr = <0x0001>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&touchpad>;
+       };
+};
+
+&sdhc2 {
+       cd-gpios = <&tlmm 95 GPIO_ACTIVE_HIGH>;
+};
index c13ed7a..c6f8143 100644 (file)
                ranges = <0 0 0 0xffffffff>;
                compatible = "simple-bus";
 
-               rpm_msg_ram: memory@68000 {
+               gcc: clock-controller@100000 {
+                       compatible = "qcom,gcc-msm8998";
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       #power-domain-cells = <1>;
+                       reg = <0x00100000 0xb0000>;
+               };
+
+               rpm_msg_ram: memory@778000 {
                        compatible = "qcom,rpm-msg-ram";
-                       reg = <0x778000 0x7000>;
+                       reg = <0x00778000 0x7000>;
                };
 
                qfprom: qfprom@780000 {
                        compatible = "qcom,qfprom";
-                       reg = <0x780000 0x621c>;
+                       reg = <0x00780000 0x621c>;
                        #address-cells = <1>;
                        #size-cells = <1>;
 
                        };
                };
 
-               gcc: clock-controller@100000 {
-                       compatible = "qcom,gcc-msm8998";
-                       #clock-cells = <1>;
-                       #reset-cells = <1>;
-                       #power-domain-cells = <1>;
-                       reg = <0x100000 0xb0000>;
-               };
-
-               tlmm: pinctrl@3400000 {
-                       compatible = "qcom,msm8998-pinctrl";
-                       reg = <0x3400000 0xc00000>;
-                       interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
-                       gpio-controller;
-                       #gpio-cells = <0x2>;
-                       interrupt-controller;
-                       #interrupt-cells = <0x2>;
-               };
-
-               spmi_bus: spmi@800f000 {
-                       compatible = "qcom,spmi-pmic-arb";
-                       reg =   <0x800f000 0x1000>,
-                               <0x8400000 0x1000000>,
-                               <0x9400000 0x1000000>,
-                               <0xa400000 0x220000>,
-                               <0x800a000 0x3000>;
-                       reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
-                       interrupt-names = "periph_irq";
-                       interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>;
-                       qcom,ee = <0>;
-                       qcom,channel = <0>;
-                       #address-cells = <2>;
-                       #size-cells = <0>;
-                       interrupt-controller;
-                       #interrupt-cells = <4>;
-                       cell-index = <0>;
-               };
-
                tsens0: thermal@10ab000 {
                        compatible = "qcom,msm8998-tsens", "qcom,tsens-v2";
-                       reg = <0x10ab000 0x1000>, /* TM */
-                             <0x10aa000 0x1000>; /* SROT */
+                       reg = <0x010ab000 0x1000>, /* TM */
+                             <0x010aa000 0x1000>; /* SROT */
 
                        #qcom,sensors = <14>;
                        #thermal-sensor-cells = <1>;
 
                tsens1: thermal@10ae000 {
                        compatible = "qcom,msm8998-tsens", "qcom,tsens-v2";
-                       reg = <0x10ae000 0x1000>, /* TM */
-                             <0x10ad000 0x1000>; /* SROT */
+                       reg = <0x010ae000 0x1000>, /* TM */
+                             <0x010ad000 0x1000>; /* SROT */
 
                        #qcom,sensors = <8>;
                        #thermal-sensor-cells = <1>;
                        };
                };
 
+               ufshc: ufshc@1da4000 {
+                       compatible = "qcom,msm8998-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
+                       reg = <0x01da4000 0x2500>;
+                       interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+                       phys = <&ufsphy_lanes>;
+                       phy-names = "ufsphy";
+                       lanes-per-direction = <2>;
+                       power-domains = <&gcc UFS_GDSC>;
+                       #reset-cells = <1>;
+
+                       clock-names =
+                               "core_clk",
+                               "bus_aggr_clk",
+                               "iface_clk",
+                               "core_clk_unipro",
+                               "ref_clk",
+                               "tx_lane0_sync_clk",
+                               "rx_lane0_sync_clk",
+                               "rx_lane1_sync_clk";
+                       clocks =
+                               <&gcc GCC_UFS_AXI_CLK>,
+                               <&gcc GCC_AGGRE1_UFS_AXI_CLK>,
+                               <&gcc GCC_UFS_AHB_CLK>,
+                               <&gcc GCC_UFS_UNIPRO_CORE_CLK>,
+                               <&rpmcc RPM_SMD_LN_BB_CLK1>,
+                               <&gcc GCC_UFS_TX_SYMBOL_0_CLK>,
+                               <&gcc GCC_UFS_RX_SYMBOL_0_CLK>,
+                               <&gcc GCC_UFS_RX_SYMBOL_1_CLK>;
+                       freq-table-hz =
+                               <50000000 200000000>,
+                               <0 0>,
+                               <0 0>,
+                               <37500000 150000000>,
+                               <0 0>,
+                               <0 0>,
+                               <0 0>,
+                               <0 0>;
+
+                       resets = <&gcc GCC_UFS_BCR>;
+                       reset-names = "rst";
+               };
+
+               ufsphy: phy@1da7000 {
+                       compatible = "qcom,msm8998-qmp-ufs-phy";
+                       reg = <0x01da7000 0x18c>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       clock-names =
+                               "ref",
+                               "ref_aux";
+                       clocks =
+                               <&gcc GCC_UFS_CLKREF_CLK>,
+                               <&gcc GCC_UFS_PHY_AUX_CLK>;
+
+                       reset-names = "ufsphy";
+                       resets = <&ufshc 0>;
+
+                       ufsphy_lanes: lanes@1da7400 {
+                               reg = <0x01da7400 0x128>,
+                                     <0x01da7600 0x1fc>,
+                                     <0x01da7c00 0x1dc>,
+                                     <0x01da7800 0x128>,
+                                     <0x01da7a00 0x1fc>;
+                               #phy-cells = <0>;
+                       };
+               };
+
                tcsr_mutex_regs: syscon@1f40000 {
                        compatible = "syscon";
-                       reg = <0x1f40000 0x20000>;
+                       reg = <0x01f40000 0x20000>;
                };
 
-               apcs_glb: mailbox@9820000 {
-                       compatible = "qcom,msm8998-apcs-hmss-global";
-                       reg = <0x17911000 0x1000>;
+               tlmm: pinctrl@3400000 {
+                       compatible = "qcom,msm8998-pinctrl";
+                       reg = <0x03400000 0xc00000>;
+                       interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+                       gpio-controller;
+                       #gpio-cells = <0x2>;
+                       interrupt-controller;
+                       #interrupt-cells = <0x2>;
+               };
 
-                       #mbox-cells = <1>;
+               stm@6002000 {
+                       compatible = "arm,coresight-stm", "arm,primecell";
+                       reg = <0x06002000 0x1000>,
+                             <0x16280000 0x180000>;
+                       reg-names = "stm-base", "stm-data-base";
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       out-ports {
+                               port {
+                                       stm_out: endpoint {
+                                               remote-endpoint = <&funnel0_in7>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@6041000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x06041000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       out-ports {
+                               port {
+                                       funnel0_out: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_in0>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@7 {
+                                       reg = <7>;
+                                       funnel0_in7: endpoint {
+                                               remote-endpoint = <&stm_out>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@6042000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x06042000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       out-ports {
+                               port {
+                                       funnel1_out: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_in1>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@6 {
+                                       reg = <6>;
+                                       funnel1_in6: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_merge_funnel_out>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@6045000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x06045000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       out-ports {
+                               port {
+                                       merge_funnel_out: endpoint {
+                                               remote-endpoint =
+                                                 <&etf_in>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       merge_funnel_in0: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel0_out>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       merge_funnel_in1: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel1_out>;
+                                       };
+                               };
+                       };
+               };
+
+               replicator@6046000 {
+                       compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+                       reg = <0x06046000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       out-ports {
+                               port {
+                                       replicator_out: endpoint {
+                                               remote-endpoint = <&etr_in>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               port {
+                                       replicator_in: endpoint {
+                                               remote-endpoint = <&etf_out>;
+                                       };
+                               };
+                       };
+               };
+
+               etf@6047000 {
+                       compatible = "arm,coresight-tmc", "arm,primecell";
+                       reg = <0x06047000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       out-ports {
+                               port {
+                                       etf_out: endpoint {
+                                               remote-endpoint =
+                                                 <&replicator_in>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               port {
+                                       etf_in: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_out>;
+                                       };
+                               };
+                       };
+               };
+
+               etr@6048000 {
+                       compatible = "arm,coresight-tmc", "arm,primecell";
+                       reg = <0x06048000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+                       arm,scatter-gather;
+
+                       in-ports {
+                               port {
+                                       etr_in: endpoint {
+                                               remote-endpoint =
+                                                 <&replicator_out>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7840000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x07840000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU0>;
+
+                       out-ports {
+                               port {
+                                       etm0_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_in0>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7940000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x07940000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU1>;
+
+                       out-ports {
+                               port {
+                                       etm1_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_in1>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7a40000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x07a40000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU2>;
+
+                       out-ports {
+                               port {
+                                       etm2_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_in2>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7b40000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x07b40000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU3>;
+
+                       out-ports {
+                               port {
+                                       etm3_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_in3>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@7b60000 { /* APSS Funnel */
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x07b60000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       out-ports {
+                               port {
+                                       apss_funnel_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_merge_funnel_in>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       apss_funnel_in0: endpoint {
+                                               remote-endpoint =
+                                                 <&etm0_out>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       apss_funnel_in1: endpoint {
+                                               remote-endpoint =
+                                                 <&etm1_out>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       apss_funnel_in2: endpoint {
+                                               remote-endpoint =
+                                                 <&etm2_out>;
+                                       };
+                               };
+
+                               port@3 {
+                                       reg = <3>;
+                                       apss_funnel_in3: endpoint {
+                                               remote-endpoint =
+                                                 <&etm3_out>;
+                                       };
+                               };
+
+                               port@4 {
+                                       reg = <4>;
+                                       apss_funnel_in4: endpoint {
+                                               remote-endpoint =
+                                                 <&etm4_out>;
+                                       };
+                               };
+
+                               port@5 {
+                                       reg = <5>;
+                                       apss_funnel_in5: endpoint {
+                                               remote-endpoint =
+                                                 <&etm5_out>;
+                                       };
+                               };
+
+                               port@6 {
+                                       reg = <6>;
+                                       apss_funnel_in6: endpoint {
+                                               remote-endpoint =
+                                                 <&etm6_out>;
+                                       };
+                               };
+
+                               port@7 {
+                                       reg = <7>;
+                                       apss_funnel_in7: endpoint {
+                                               remote-endpoint =
+                                                 <&etm7_out>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@7b70000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x07b70000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       out-ports {
+                               port {
+                                       apss_merge_funnel_out: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel1_in6>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               port {
+                                       apss_merge_funnel_in: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_out>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7c40000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x07c40000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU4>;
+
+                       port{
+                               etm4_out: endpoint {
+                                       remote-endpoint = <&apss_funnel_in4>;
+                               };
+                       };
+               };
+
+               etm@7d40000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x07d40000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU5>;
+
+                       port{
+                               etm5_out: endpoint {
+                                       remote-endpoint = <&apss_funnel_in5>;
+                               };
+                       };
+               };
+
+               etm@7e40000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x07e40000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU6>;
+
+                       port{
+                               etm6_out: endpoint {
+                                       remote-endpoint = <&apss_funnel_in6>;
+                               };
+                       };
+               };
+
+               etm@7f40000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x07f40000 0x1000>;
+
+                       clocks = <&rpmcc RPM_SMD_QDSS_CLK>, <&rpmcc RPM_SMD_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU7>;
+
+                       port{
+                               etm7_out: endpoint {
+                                       remote-endpoint = <&apss_funnel_in7>;
+                               };
+                       };
+               };
+
+               spmi_bus: spmi@800f000 {
+                       compatible = "qcom,spmi-pmic-arb";
+                       reg =   <0x0800f000 0x1000>,
+                               <0x08400000 0x1000000>,
+                               <0x09400000 0x1000000>,
+                               <0x0a400000 0x220000>,
+                               <0x0800a000 0x3000>;
+                       reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
+                       interrupt-names = "periph_irq";
+                       interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>;
+                       qcom,ee = <0>;
+                       qcom,channel = <0>;
+                       #address-cells = <2>;
+                       #size-cells = <0>;
+                       interrupt-controller;
+                       #interrupt-cells = <4>;
+                       cell-index = <0>;
                };
 
                usb3: usb@a8f8800 {
 
                sdhc2: sdhci@c0a4900 {
                        compatible = "qcom,sdhci-msm-v4";
-                       reg = <0xc0a4900 0x314>, <0xc0a4000 0x800>;
+                       reg = <0x0c0a4900 0x314>, <0x0c0a4000 0x800>;
                        reg-names = "hc_mem", "core_mem";
 
                        interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
                        #size-cells = <0>;
                };
 
+               blsp2_uart1: serial@c1b0000 {
+                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+                       reg = <0x0c1b0000 0x1000>;
+                       interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>,
+                                <&gcc GCC_BLSP2_AHB_CLK>;
+                       clock-names = "core", "iface";
+                       status = "disabled";
+               };
+
                blsp2_i2c0: i2c@c1b5000 {
                        compatible = "qcom,i2c-qup-v2.2.1";
                        reg = <0x0c1b5000 0x600>;
                        #size-cells = <0>;
                };
 
-               blsp2_uart1: serial@c1b0000 {
-                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
-                       reg = <0xc1b0000 0x1000>;
-                       interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>,
-                                <&gcc GCC_BLSP2_AHB_CLK>;
-                       clock-names = "core", "iface";
-                       status = "disabled";
+               apcs_glb: mailbox@17911000 {
+                       compatible = "qcom,msm8998-apcs-hmss-global";
+                       reg = <0x17911000 0x1000>;
+
+                       #mbox-cells = <1>;
                };
 
                timer@17920000 {
                        redistributor-stride = <0x0 0x20000>;
                        interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
                };
-
-               ufshc: ufshc@1da4000 {
-                       compatible = "qcom,msm8998-ufshc", "qcom,ufshc", "jedec,ufs-2.0";
-                       reg = <0x01da4000 0x2500>;
-                       interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
-                       phys = <&ufsphy_lanes>;
-                       phy-names = "ufsphy";
-                       lanes-per-direction = <2>;
-                       power-domains = <&gcc UFS_GDSC>;
-                       #reset-cells = <1>;
-
-                       clock-names =
-                               "core_clk",
-                               "bus_aggr_clk",
-                               "iface_clk",
-                               "core_clk_unipro",
-                               "ref_clk",
-                               "tx_lane0_sync_clk",
-                               "rx_lane0_sync_clk",
-                               "rx_lane1_sync_clk";
-                       clocks =
-                               <&gcc GCC_UFS_AXI_CLK>,
-                               <&gcc GCC_AGGRE1_UFS_AXI_CLK>,
-                               <&gcc GCC_UFS_AHB_CLK>,
-                               <&gcc GCC_UFS_UNIPRO_CORE_CLK>,
-                               <&rpmcc RPM_SMD_LN_BB_CLK1>,
-                               <&gcc GCC_UFS_TX_SYMBOL_0_CLK>,
-                               <&gcc GCC_UFS_RX_SYMBOL_0_CLK>,
-                               <&gcc GCC_UFS_RX_SYMBOL_1_CLK>;
-                       freq-table-hz =
-                               <50000000 200000000>,
-                               <0 0>,
-                               <0 0>,
-                               <37500000 150000000>,
-                               <0 0>,
-                               <0 0>,
-                               <0 0>,
-                               <0 0>;
-
-                       resets = <&gcc GCC_UFS_BCR>;
-                       reset-names = "rst";
-               };
-
-               ufsphy: phy@1da7000 {
-                       compatible = "qcom,msm8998-qmp-ufs-phy";
-                       reg = <0x01da7000 0x18c>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges;
-
-                       clock-names =
-                               "ref",
-                               "ref_aux";
-                       clocks =
-                               <&gcc GCC_UFS_CLKREF_CLK>,
-                               <&gcc GCC_UFS_PHY_AUX_CLK>;
-
-                       reset-names = "ufsphy";
-                       resets = <&ufshc 0>;
-
-                       ufsphy_lanes: lanes@1da7400 {
-                               reg = <0x01da7400 0x128>,
-                                     <0x01da7600 0x1fc>,
-                                     <0x01da7c00 0x1dc>,
-                                     <0x01da7800 0x128>,
-                                     <0x01da7a00 0x1fc>;
-                               #phy-cells = <0>;
-                       };
-               };
        };
 };
 
diff --git a/arch/arm64/boot/dts/qcom/pm8150.dtsi b/arch/arm64/boot/dts/qcom/pm8150.dtsi
new file mode 100644 (file)
index 0000000..b6e3047
--- /dev/null
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019, Linaro Limited
+ */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/iio/qcom,spmi-vadc.h>
+
+&spmi_bus {
+       pm8150_0: pmic@0 {
+               compatible = "qcom,pm8150", "qcom,spmi-pmic";
+               reg = <0x0 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               pon: power-on@800 {
+                       compatible = "qcom,pm8916-pon";
+                       reg = <0x0800>;
+                       pwrkey {
+                               compatible = "qcom,pm8941-pwrkey";
+                               interrupts = <0x0 0x8 0x0 IRQ_TYPE_EDGE_BOTH>;
+                               debounce = <15625>;
+                               bias-pull-up;
+                               linux,code = <KEY_POWER>;
+
+                               status = "disabled";
+                       };
+               };
+
+               pm8150_adc: adc@3100 {
+                       compatible = "qcom,spmi-adc5";
+                       reg = <0x3100>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       #io-channel-cells = <1>;
+                       interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
+
+                       status = "disabled";
+
+                       ref-gnd@0 {
+                               reg = <ADC5_REF_GND>;
+                               qcom,pre-scaling = <1 1>;
+                               label = "ref_gnd";
+                       };
+
+                       vref-1p25@1 {
+                               reg = <ADC5_1P25VREF>;
+                               qcom,pre-scaling = <1 1>;
+                               label = "vref_1p25";
+                       };
+
+                       die-temp@6 {
+                               reg = <ADC5_DIE_TEMP>;
+                               qcom,pre-scaling = <1 1>;
+                               label = "die_temp";
+                       };
+               };
+
+               rtc@6000 {
+                       compatible = "qcom,pm8941-rtc";
+                       reg = <0x6000>;
+                       reg-names = "rtc", "alarm";
+                       interrupts = <0x0 0x61 0x1 IRQ_TYPE_NONE>;
+
+                       status = "disabled";
+               };
+
+               pm8150_gpios: gpio@c000 {
+                       compatible = "qcom,pm8150-gpio";
+                       reg = <0xc000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupts = <0x0 0xc0 0x0 IRQ_TYPE_NONE>,
+                                    <0x0 0xc1 0x0 IRQ_TYPE_NONE>,
+                                    <0x0 0xc2 0x0 IRQ_TYPE_NONE>,
+                                    <0x0 0xc3 0x0 IRQ_TYPE_NONE>,
+                                    <0x0 0xc4 0x0 IRQ_TYPE_NONE>,
+                                    <0x0 0xc5 0x0 IRQ_TYPE_NONE>,
+                                    <0x0 0xc6 0x0 IRQ_TYPE_NONE>,
+                                    <0x0 0xc7 0x0 IRQ_TYPE_NONE>,
+                                    <0x0 0xc8 0x0 IRQ_TYPE_NONE>,
+                                    <0x0 0xc9 0x0 IRQ_TYPE_NONE>,
+                                    <0x0 0xca 0x0 IRQ_TYPE_NONE>,
+                                    <0x0 0xcb 0x0 IRQ_TYPE_NONE>;
+               };
+       };
+
+       pmic@1 {
+               compatible = "qcom,pm8150", "qcom,spmi-pmic";
+               reg = <0x1 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
diff --git a/arch/arm64/boot/dts/qcom/pm8150b.dtsi b/arch/arm64/boot/dts/qcom/pm8150b.dtsi
new file mode 100644 (file)
index 0000000..322379d
--- /dev/null
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019, Linaro Limited
+ */
+
+#include <dt-bindings/iio/qcom,spmi-vadc.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+
+&spmi_bus {
+       pmic@2 {
+               compatible = "qcom,pm8150b", "qcom,spmi-pmic";
+               reg = <0x2 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               power-on@800 {
+                       compatible = "qcom,pm8916-pon";
+                       reg = <0x0800>;
+
+                       status = "disabled";
+               };
+
+               adc@3100 {
+                       compatible = "qcom,spmi-adc5";
+                       reg = <0x3100>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       #io-channel-cells = <1>;
+                       interrupts = <0x2 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
+
+                       status = "disabled";
+
+                       ref-gnd@0 {
+                               reg = <ADC5_REF_GND>;
+                               qcom,pre-scaling = <1 1>;
+                               label = "ref_gnd";
+                       };
+
+                       vref-1p25@1 {
+                               reg = <ADC5_1P25VREF>;
+                               qcom,pre-scaling = <1 1>;
+                               label = "vref_1p25";
+                       };
+
+                       die-temp@6 {
+                               reg = <ADC5_DIE_TEMP>;
+                               qcom,pre-scaling = <1 1>;
+                               label = "die_temp";
+                       };
+
+                       chg-temp@9 {
+                               reg = <ADC5_CHG_TEMP>;
+                               qcom,pre-scaling = <1 1>;
+                               label = "chg_temp";
+                       };
+               };
+
+               pm8150b_gpios: gpio@c000 {
+                       compatible = "qcom,pm8150b-gpio";
+                       reg = <0xc000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupts = <0x2 0xc0 0x0 IRQ_TYPE_NONE>,
+                                    <0x2 0xc1 0x0 IRQ_TYPE_NONE>,
+                                    <0x2 0xc2 0x0 IRQ_TYPE_NONE>,
+                                    <0x2 0xc3 0x0 IRQ_TYPE_NONE>,
+                                    <0x2 0xc4 0x0 IRQ_TYPE_NONE>,
+                                    <0x2 0xc5 0x0 IRQ_TYPE_NONE>,
+                                    <0x2 0xc6 0x0 IRQ_TYPE_NONE>,
+                                    <0x2 0xc7 0x0 IRQ_TYPE_NONE>,
+                                    <0x2 0xc8 0x0 IRQ_TYPE_NONE>,
+                                    <0x2 0xc9 0x0 IRQ_TYPE_NONE>,
+                                    <0x2 0xca 0x0 IRQ_TYPE_NONE>,
+                                    <0x2 0xcb 0x0 IRQ_TYPE_NONE>;
+               };
+       };
+
+       pmic@3 {
+               compatible = "qcom,pm8150b", "qcom,spmi-pmic";
+               reg = <0x3 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
diff --git a/arch/arm64/boot/dts/qcom/pm8150l.dtsi b/arch/arm64/boot/dts/qcom/pm8150l.dtsi
new file mode 100644 (file)
index 0000000..eb0e9a0
--- /dev/null
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019, Linaro Limited
+ */
+
+#include <dt-bindings/iio/qcom,spmi-vadc.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+
+&spmi_bus {
+       pmic@4 {
+               compatible = "qcom,pm8150l", "qcom,spmi-pmic";
+               reg = <0x4 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               power-on@800 {
+                       compatible = "qcom,pm8916-pon";
+                       reg = <0x0800>;
+
+                       status = "disabled";
+               };
+
+               adc@3100 {
+                       compatible = "qcom,spmi-adc5";
+                       reg = <0x3100>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       #io-channel-cells = <1>;
+                       interrupts = <0x4 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
+
+                       status = "disabled";
+
+                       ref-gnd@0 {
+                               reg = <ADC5_REF_GND>;
+                               qcom,pre-scaling = <1 1>;
+                               label = "ref_gnd";
+                       };
+
+                       vref-1p25@1 {
+                               reg = <ADC5_1P25VREF>;
+                               qcom,pre-scaling = <1 1>;
+                               label = "vref_1p25";
+                       };
+
+                       die-temp@6 {
+                               reg = <ADC5_DIE_TEMP>;
+                               qcom,pre-scaling = <1 1>;
+                               label = "die_temp";
+                       };
+               };
+
+               pm8150l_gpios: gpio@c000 {
+                       compatible = "qcom,pm8150l-gpio";
+                       reg = <0xc000>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupts = <0x4 0xc0 0x0 IRQ_TYPE_NONE>,
+                                    <0x4 0xc1 0x0 IRQ_TYPE_NONE>,
+                                    <0x4 0xc2 0x0 IRQ_TYPE_NONE>,
+                                    <0x4 0xc3 0x0 IRQ_TYPE_NONE>,
+                                    <0x4 0xc4 0x0 IRQ_TYPE_NONE>,
+                                    <0x4 0xc5 0x0 IRQ_TYPE_NONE>,
+                                    <0x4 0xc6 0x0 IRQ_TYPE_NONE>,
+                                    <0x4 0xc7 0x0 IRQ_TYPE_NONE>,
+                                    <0x4 0xc8 0x0 IRQ_TYPE_NONE>,
+                                    <0x4 0xc9 0x0 IRQ_TYPE_NONE>,
+                                    <0x4 0xca 0x0 IRQ_TYPE_NONE>,
+                                    <0x4 0xcb 0x0 IRQ_TYPE_NONE>;
+               };
+       };
+
+       pmic@5 {
+               compatible = "qcom,pm8150l", "qcom,spmi-pmic";
+               reg = <0x5 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
index 051a52d..dc2ce23 100644 (file)
@@ -78,7 +78,7 @@
                        #size-cells = <0>;
                        #io-channel-cells = <1>;
 
-                       adc-chan@ADC5_DIE_TEMP {
+                       adc-chan@6 {
                                reg = <ADC5_DIE_TEMP>;
                                label = "die_temp";
                        };
index 14240fe..ff40051 100644 (file)
                        #size-cells = <0>;
                        #io-channel-cells = <1>;
 
-                       ref_gnd {
+                       ref_gnd@0 {
                                reg = <ADC5_REF_GND>;
                                qcom,pre-scaling = <1 1>;
                        };
 
-                       vref_1p25 {
+                       vref_1p25@1 {
                                reg = <ADC5_1P25VREF>;
                                qcom,pre-scaling = <1 1>;
                        };
 
-                       pon_1: vph_pwr {
+                       pon_1: vph_pwr@131 {
                                reg = <ADC5_VPH_PWR>;
                                qcom,pre-scaling = <1 3>;
                        };
 
-                       die_temp {
+                       die_temp@6 {
                                reg = <ADC5_DIE_TEMP>;
                                qcom,pre-scaling = <1 1>;
                        };
 
-                       pa_therm1: thermistor1 {
+                       pa_therm1: thermistor1@77 {
                                reg = <ADC5_AMUX_THM1_100K_PU>;
                                qcom,ratiometric;
                                qcom,hw-settle-time = <200>;
                                qcom,pre-scaling = <1 1>;
                        };
 
-                       pa_therm3: thermistor3 {
+                       pa_therm3: thermistor3@79 {
                                reg = <ADC5_AMUX_THM3_100K_PU>;
                                qcom,ratiometric;
                                qcom,hw-settle-time = <200>;
                                qcom,pre-scaling = <1 1>;
                        };
 
-                       xo_therm: xo_temp {
+                       xo_therm: xo_temp@76 {
                                reg = <ADC5_XO_THERM_100K_PU>;
                                qcom,ratiometric;
                                qcom,hw-settle-time = <200>;
        pms405_1: pms405@1 {
                compatible = "qcom,spmi-pmic";
                reg = <0x1 SPMI_USID>;
-               #address-cells = <1>;
-               #size-cells = <0>;
 
                pms405_spmi_regulators: regulators {
                        compatible = "qcom,pms405-regulators";
index 11c0a71..501a733 100644 (file)
@@ -61,7 +61,9 @@
        protected-clocks = <GCC_BIMC_CDSP_CLK>,
                           <GCC_CDSP_CFG_AHB_CLK>,
                           <GCC_CDSP_BIMC_CLK_SRC>,
-                          <GCC_CDSP_TBU_CLK>;
+                          <GCC_CDSP_TBU_CLK>,
+                          <141>, /* GCC_WCSS_Q6_AHB_CLK */
+                          <142>; /* GCC_WCSS_Q6_AXIM_CLK */
 };
 
 &pms405_spmi_regulators {
 
 &wifi {
        status = "okay";
+       vdd-0.8-cx-mx-supply = <&vreg_l2_1p275>;
+       vdd-1.8-xo-supply = <&vreg_l5_1p8>;
+       vdd-1.3-rfa-supply = <&vreg_l1_1p3>;
 };
 
 /* PINCTRL - additions to nodes defined in qcs404.dtsi */
index 3d07897..a97eeb4 100644 (file)
                #size-cells = <2>;
                ranges;
 
-               memory@85600000 {
-                       reg = <0 0x85600000 0 0x90000>;
+               tz_apps_mem: memory@85900000 {
+                       reg = <0 0x85900000 0 0x500000>;
+                       no-map;
+               };
+
+               xbl_mem: memory@85e00000 {
+                       reg = <0 0x85e00000 0 0x100000>;
                        no-map;
                };
 
                        no-map;
                };
 
-               memory@86100000 {
+               tz_mem: memory@86100000 {
                        reg = <0 0x86100000 0 0x300000>;
                        no-map;
                };
 
                wlan_fw_mem: memory@86400000 {
-                       reg = <0 0x86400000 0 0x1c00000>;
+                       reg = <0 0x86400000 0 0x1100000>;
+                       no-map;
+               };
+
+               adsp_fw_mem: memory@87500000 {
+                       reg = <0 0x87500000 0 0x1a00000>;
                        no-map;
                };
 
-               adsp_fw_mem: memory@88000000 {
-                       reg = <0 0x88000000 0 0x1a00000>;
+               cdsp_fw_mem: memory@88f00000 {
+                       reg = <0 0x88f00000 0 0x600000>;
                        no-map;
                };
 
-               cdsp_fw_mem: memory@89a00000 {
-                       reg = <0 0x89a00000 0 0x600000>;
+               wlan_msa_mem: memory@89500000 {
+                       reg = <0 0x89500000 0 0x100000>;
                        no-map;
                };
 
-               wlan_msa_mem: memory@8a000000 {
-                       reg = <0 0x8a000000 0 0x100000>;
+               uefi_mem: memory@9f800000 {
+                       reg = <0 0x9f800000 0 0x800000>;
                        no-map;
                };
        };
                        thermal-sensors = <&tsens 0>;
 
                        trips {
-                               aoss_alert0: trip-point@0 {
+                               aoss_alert0: trip-point0 {
                                        temperature = <105000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens 1>;
 
                        trips {
-                               q6_hvx_alert0: trip-point@0 {
+                               q6_hvx_alert0: trip-point0 {
                                        temperature = <105000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens 2>;
 
                        trips {
-                               lpass_alert0: trip-point@0 {
+                               lpass_alert0: trip-point0 {
                                        temperature = <105000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens 3>;
 
                        trips {
-                               wlan_alert0: trip-point@0 {
+                               wlan_alert0: trip-point0 {
                                        temperature = <105000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens 4>;
 
                        trips {
-                               cluster_alert0: trip-point@0 {
+                               cluster_alert0: trip-point0 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                                };
-                               cluster_alert1: trip-point@1 {
+                               cluster_alert1: trip-point1 {
                                        temperature = <105000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens 5>;
 
                        trips {
-                               cpu0_alert0: trip-point@0 {
+                               cpu0_alert0: trip-point0 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                                };
-                               cpu0_alert1: trip-point@1 {
+                               cpu0_alert1: trip-point1 {
                                        temperature = <105000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens 6>;
 
                        trips {
-                               cpu1_alert0: trip-point@0 {
+                               cpu1_alert0: trip-point0 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                                };
-                               cpu1_alert1: trip-point@1 {
+                               cpu1_alert1: trip-point1 {
                                        temperature = <105000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens 7>;
 
                        trips {
-                               cpu2_alert0: trip-point@0 {
+                               cpu2_alert0: trip-point0 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                                };
-                               cpu2_alert1: trip-point@1 {
+                               cpu2_alert1: trip-point1 {
                                        temperature = <105000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens 8>;
 
                        trips {
-                               cpu3_alert0: trip-point@0 {
+                               cpu3_alert0: trip-point0 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                                };
-                               cpu3_alert1: trip-point@1 {
+                               cpu3_alert1: trip-point1 {
                                        temperature = <105000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens 9>;
 
                        trips {
-                               gpu_alert0: trip-point@0 {
+                               gpu_alert0: trip-point0 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "hot";
index 1ebbd56..34881c0 100644 (file)
@@ -745,7 +745,7 @@ ap_ts_i2c: &i2c14 {
         * All the hardware muxes would allow us to hook things up in different
         * ways to some potential benefit for static configurations (you could
         * achieve extra USB2 bandwidth by using two different ports for the
-        * two conenctors or possibly even get USB3 peripheral mode), but in
+        * two connectors or possibly even get USB3 peripheral mode), but in
         * each case you end up forcing to disconnect/reconnect an in-use
         * USB session in some cases depending on what you hotplug into the
         * other connector.  Thus hardcoding this as peripheral makes sense.
@@ -963,27 +963,27 @@ ap_ts_i2c: &i2c14 {
 };
 
 &pm8998_adc {
-       adc-chan@ADC5_AMUX_THM1_100K_PU {
+       adc-chan@4d {
                reg = <ADC5_AMUX_THM1_100K_PU>;
                label = "sdm_temp";
        };
 
-       adc-chan@ADC5_AMUX_THM2_100K_PU {
+       adc-chan@4e {
                reg = <ADC5_AMUX_THM2_100K_PU>;
                label = "quiet_temp";
        };
 
-       adc-chan@ADC5_AMUX_THM3_100K_PU {
+       adc-chan@4f {
                reg = <ADC5_AMUX_THM3_100K_PU>;
                label = "lte_temp_1";
        };
 
-       adc-chan@ADC5_AMUX_THM4_100K_PU {
+       adc-chan@50 {
                reg = <ADC5_AMUX_THM4_100K_PU>;
                label = "lte_temp_2";
        };
 
-       adc-chan@ADC5_AMUX_THM5_100K_PU {
+       adc-chan@51 {
                reg = <ADC5_AMUX_THM5_100K_PU>;
                label = "charger_temp";
        };
index 4babff5..f406a43 100644 (file)
                                           &LITTLE_CPU_SLEEP_1
                                           &CLUSTER_SLEEP_0>;
                        capacity-dmips-mhz = <607>;
+                       dynamic-power-coefficient = <100>;
                        qcom,freq-domain = <&cpufreq_hw 0>;
                        #cooling-cells = <2>;
                        next-level-cache = <&L2_0>;
                                           &LITTLE_CPU_SLEEP_1
                                           &CLUSTER_SLEEP_0>;
                        capacity-dmips-mhz = <607>;
+                       dynamic-power-coefficient = <100>;
                        qcom,freq-domain = <&cpufreq_hw 0>;
                        #cooling-cells = <2>;
                        next-level-cache = <&L2_100>;
                                           &LITTLE_CPU_SLEEP_1
                                           &CLUSTER_SLEEP_0>;
                        capacity-dmips-mhz = <607>;
+                       dynamic-power-coefficient = <100>;
                        qcom,freq-domain = <&cpufreq_hw 0>;
                        #cooling-cells = <2>;
                        next-level-cache = <&L2_200>;
                                           &LITTLE_CPU_SLEEP_1
                                           &CLUSTER_SLEEP_0>;
                        capacity-dmips-mhz = <607>;
+                       dynamic-power-coefficient = <100>;
                        qcom,freq-domain = <&cpufreq_hw 0>;
                        #cooling-cells = <2>;
                        next-level-cache = <&L2_300>;
                        cpu-idle-states = <&BIG_CPU_SLEEP_0
                                           &BIG_CPU_SLEEP_1
                                           &CLUSTER_SLEEP_0>;
+                       dynamic-power-coefficient = <396>;
                        qcom,freq-domain = <&cpufreq_hw 1>;
                        #cooling-cells = <2>;
                        next-level-cache = <&L2_400>;
                        cpu-idle-states = <&BIG_CPU_SLEEP_0
                                           &BIG_CPU_SLEEP_1
                                           &CLUSTER_SLEEP_0>;
+                       dynamic-power-coefficient = <396>;
                        qcom,freq-domain = <&cpufreq_hw 1>;
                        #cooling-cells = <2>;
                        next-level-cache = <&L2_500>;
                        cpu-idle-states = <&BIG_CPU_SLEEP_0
                                           &BIG_CPU_SLEEP_1
                                           &CLUSTER_SLEEP_0>;
+                       dynamic-power-coefficient = <396>;
                        qcom,freq-domain = <&cpufreq_hw 1>;
                        #cooling-cells = <2>;
                        next-level-cache = <&L2_600>;
                        cpu-idle-states = <&BIG_CPU_SLEEP_0
                                           &BIG_CPU_SLEEP_1
                                           &CLUSTER_SLEEP_0>;
+                       dynamic-power-coefficient = <396>;
                        qcom,freq-domain = <&cpufreq_hw 1>;
                        #cooling-cells = <2>;
                        next-level-cache = <&L2_700>;
                        label = "lpass";
                        qcom,remote-pid = <2>;
                        mboxes = <&apss_shared 8>;
+                       fastrpc {
+                               compatible = "qcom,fastrpc";
+                               qcom,glink-channels = "fastrpcglink-apps-dsp";
+                               label = "adsp";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               compute-cb@3 {
+                                       compatible = "qcom,fastrpc-compute-cb";
+                                       reg = <3>;
+                                       iommus = <&apps_smmu 0x1823 0x0>;
+                               };
+
+                               compute-cb@4 {
+                                       compatible = "qcom,fastrpc-compute-cb";
+                                       reg = <4>;
+                                       iommus = <&apps_smmu 0x1824 0x0>;
+                               };
+                       };
                };
        };
 
                        label = "turing";
                        qcom,remote-pid = <5>;
                        mboxes = <&apss_shared 4>;
+                       fastrpc {
+                               compatible = "qcom,fastrpc";
+                               qcom,glink-channels = "fastrpcglink-apps-dsp";
+                               label = "cdsp";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               compute-cb@1 {
+                                       compatible = "qcom,fastrpc-compute-cb";
+                                       reg = <1>;
+                                       iommus = <&apps_smmu 0x1401 0x30>;
+                               };
+
+                               compute-cb@2 {
+                                       compatible = "qcom,fastrpc-compute-cb";
+                                       reg = <2>;
+                                       iommus = <&apps_smmu 0x1402 0x30>;
+                               };
+
+                               compute-cb@3 {
+                                       compatible = "qcom,fastrpc-compute-cb";
+                                       reg = <3>;
+                                       iommus = <&apps_smmu 0x1403 0x30>;
+                               };
+
+                               compute-cb@4 {
+                                       compatible = "qcom,fastrpc-compute-cb";
+                                       reg = <4>;
+                                       iommus = <&apps_smmu 0x1404 0x30>;
+                               };
+
+                               compute-cb@5 {
+                                       compatible = "qcom,fastrpc-compute-cb";
+                                       reg = <5>;
+                                       iommus = <&apps_smmu 0x1405 0x30>;
+                               };
+
+                               compute-cb@6 {
+                                       compatible = "qcom,fastrpc-compute-cb";
+                                       reg = <6>;
+                                       iommus = <&apps_smmu 0x1406 0x30>;
+                               };
+
+                               compute-cb@7 {
+                                       compatible = "qcom,fastrpc-compute-cb";
+                                       reg = <7>;
+                                       iommus = <&apps_smmu 0x1407 0x30>;
+                               };
+
+                               compute-cb@8 {
+                                       compatible = "qcom,fastrpc-compute-cb";
+                                       reg = <8>;
+                                       iommus = <&apps_smmu 0x1408 0x30>;
+                               };
+                       };
                };
        };
 
                method = "smc";
        };
 
-       soc: soc {
+       soc: soc@0 {
                #address-cells = <2>;
                #size-cells = <2>;
                ranges = <0 0 0 0 0x10 0>;
                        };
                };
 
+               cache-controller@1100000 {
+                       compatible = "qcom,sdm845-llcc";
+                       reg = <0 0x01100000 0 0x200000>, <0 0x01300000 0 0x50000>;
+                       reg-names = "llcc_base", "llcc_broadcast_base";
+                       interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
                ufs_mem_hc: ufshc@1d84000 {
                        compatible = "qcom,sdm845-ufshc", "qcom,ufshc",
                                     "jedec,ufs-2.0";
                        clock-names = "xo";
                };
 
+               stm@6002000 {
+                       compatible = "arm,coresight-stm", "arm,primecell";
+                       reg = <0 0x06002000 0 0x1000>,
+                             <0 0x16280000 0 0x180000>;
+                       reg-names = "stm-base", "stm-stimulus-base";
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       stm_out: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel0_in7>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@6041000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0 0x06041000 0 0x1000>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       funnel0_out: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_in0>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@7 {
+                                       reg = <7>;
+                                       funnel0_in7: endpoint {
+                                               remote-endpoint = <&stm_out>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@6043000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0 0x06043000 0 0x1000>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       funnel2_out: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_in2>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@5 {
+                                       reg = <5>;
+                                       funnel2_in5: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_merge_funnel_out>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@6045000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0 0x06045000 0 0x1000>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       merge_funnel_out: endpoint {
+                                               remote-endpoint = <&etf_in>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       merge_funnel_in0: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel0_out>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       merge_funnel_in2: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel2_out>;
+                                       };
+                               };
+                       };
+               };
+
+               replicator@6046000 {
+                       compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+                       reg = <0 0x06046000 0 0x1000>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       replicator_out: endpoint {
+                                               remote-endpoint = <&etr_in>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               port {
+                                       replicator_in: endpoint {
+                                               remote-endpoint = <&etf_out>;
+                                       };
+                               };
+                       };
+               };
+
+               etf@6047000 {
+                       compatible = "arm,coresight-tmc", "arm,primecell";
+                       reg = <0 0x06047000 0 0x1000>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etf_out: endpoint {
+                                               remote-endpoint =
+                                                 <&replicator_in>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@1 {
+                                       reg = <1>;
+                                       etf_in: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_out>;
+                                       };
+                               };
+                       };
+               };
+
+               etr@6048000 {
+                       compatible = "arm,coresight-tmc", "arm,primecell";
+                       reg = <0 0x06048000 0 0x1000>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+                       arm,scatter-gather;
+
+                       in-ports {
+                               port {
+                                       etr_in: endpoint {
+                                               remote-endpoint =
+                                                 <&replicator_out>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7040000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x07040000 0 0x1000>;
+
+                       cpu = <&CPU0>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm0_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_in0>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7140000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x07140000 0 0x1000>;
+
+                       cpu = <&CPU1>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm1_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_in1>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7240000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x07240000 0 0x1000>;
+
+                       cpu = <&CPU2>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm2_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_in2>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7340000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x07340000 0 0x1000>;
+
+                       cpu = <&CPU3>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm3_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_in3>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7440000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x07440000 0 0x1000>;
+
+                       cpu = <&CPU4>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm4_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_in4>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7540000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x07540000 0 0x1000>;
+
+                       cpu = <&CPU5>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm5_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_in5>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7640000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x07640000 0 0x1000>;
+
+                       cpu = <&CPU6>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm6_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_in6>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@7740000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x07740000 0 0x1000>;
+
+                       cpu = <&CPU7>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm7_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_in7>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@7800000 { /* APSS Funnel */
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0 0x07800000 0 0x1000>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       apss_funnel_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_merge_funnel_in>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       apss_funnel_in0: endpoint {
+                                               remote-endpoint =
+                                                 <&etm0_out>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       apss_funnel_in1: endpoint {
+                                               remote-endpoint =
+                                                 <&etm1_out>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       apss_funnel_in2: endpoint {
+                                               remote-endpoint =
+                                                 <&etm2_out>;
+                                       };
+                               };
+
+                               port@3 {
+                                       reg = <3>;
+                                       apss_funnel_in3: endpoint {
+                                               remote-endpoint =
+                                                 <&etm3_out>;
+                                       };
+                               };
+
+                               port@4 {
+                                       reg = <4>;
+                                       apss_funnel_in4: endpoint {
+                                               remote-endpoint =
+                                                 <&etm4_out>;
+                                       };
+                               };
+
+                               port@5 {
+                                       reg = <5>;
+                                       apss_funnel_in5: endpoint {
+                                               remote-endpoint =
+                                                 <&etm5_out>;
+                                       };
+                               };
+
+                               port@6 {
+                                       reg = <6>;
+                                       apss_funnel_in6: endpoint {
+                                               remote-endpoint =
+                                                 <&etm6_out>;
+                                       };
+                               };
+
+                               port@7 {
+                                       reg = <7>;
+                                       apss_funnel_in7: endpoint {
+                                               remote-endpoint =
+                                                 <&etm7_out>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@7810000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0 0x07810000 0 0x1000>;
+
+                       clocks = <&aoss_qmp>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       apss_merge_funnel_out: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel2_in5>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               port {
+                                       apss_merge_funnel_in: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel_out>;
+                                       };
+                               };
+                       };
+               };
+
                sdhc_2: sdhci@8804000 {
                        compatible = "qcom,sdm845-sdhci", "qcom,sdhci-msm-v5";
                        reg = <0 0x08804000 0 0x1000>;
                        };
                };
 
+               video-codec@aa00000 {
+                       compatible = "qcom,sdm845-venus";
+                       reg = <0 0x0aa00000 0 0xff000>;
+                       interrupts = <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&videocc VENUS_GDSC>;
+                       clocks = <&videocc VIDEO_CC_VENUS_CTL_CORE_CLK>,
+                                <&videocc VIDEO_CC_VENUS_AHB_CLK>,
+                                <&videocc VIDEO_CC_VENUS_CTL_AXI_CLK>;
+                       clock-names = "core", "iface", "bus";
+                       iommus = <&apps_smmu 0x10a0 0x8>,
+                                <&apps_smmu 0x10b0 0x0>;
+                       memory-region = <&venus_mem>;
+
+                       video-core0 {
+                               compatible = "venus-decoder";
+                               clocks = <&videocc VIDEO_CC_VCODEC0_CORE_CLK>,
+                                        <&videocc VIDEO_CC_VCODEC0_AXI_CLK>;
+                               clock-names = "core", "bus";
+                               power-domains = <&videocc VCODEC0_GDSC>;
+                       };
+
+                       video-core1 {
+                               compatible = "venus-encoder";
+                               clocks = <&videocc VIDEO_CC_VCODEC1_CORE_CLK>,
+                                        <&videocc VIDEO_CC_VCODEC1_AXI_CLK>;
+                               clock-names = "core", "bus";
+                               power-domains = <&videocc VCODEC1_GDSC>;
+                       };
+               };
+
                videocc: clock-controller@ab00000 {
                        compatible = "qcom,sdm845-videocc";
                        reg = <0 0x0ab00000 0 0x10000>;
 
                                status = "disabled";
 
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
                                ports {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
                                status = "disabled";
 
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
                                ports {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
                        #clock-cells = <0>;
                        #power-domain-cells = <1>;
+
+                       cx_cdev: cx {
+                               #cooling-cells = <2>;
+                       };
+
+                       ebi_cdev: ebi {
+                               #cooling-cells = <2>;
+                       };
                };
 
                spmi_bus: spmi@c440000 {
                        rpmhcc: clock-controller {
                                compatible = "qcom,sdm845-rpmh-clk";
                                #clock-cells = <1>;
+                               clock-names = "xo";
+                               clocks = <&xo_board>;
                        };
 
                        rpmhpd: power-controller {
                        thermal-sensors = <&tsens0 1>;
 
                        trips {
-                               cpu0_alert0: trip-point@0 {
+                               cpu0_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu0_alert1: trip-point@1 {
+                               cpu0_alert1: trip-point1 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens0 2>;
 
                        trips {
-                               cpu1_alert0: trip-point@0 {
+                               cpu1_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu1_alert1: trip-point@1 {
+                               cpu1_alert1: trip-point1 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens0 3>;
 
                        trips {
-                               cpu2_alert0: trip-point@0 {
+                               cpu2_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu2_alert1: trip-point@1 {
+                               cpu2_alert1: trip-point1 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens0 4>;
 
                        trips {
-                               cpu3_alert0: trip-point@0 {
+                               cpu3_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu3_alert1: trip-point@1 {
+                               cpu3_alert1: trip-point1 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens0 7>;
 
                        trips {
-                               cpu4_alert0: trip-point@0 {
+                               cpu4_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu4_alert1: trip-point@1 {
+                               cpu4_alert1: trip-point1 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens0 8>;
 
                        trips {
-                               cpu5_alert0: trip-point@0 {
+                               cpu5_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu5_alert1: trip-point@1 {
+                               cpu5_alert1: trip-point1 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens0 9>;
 
                        trips {
-                               cpu6_alert0: trip-point@0 {
+                               cpu6_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu6_alert1: trip-point@1 {
+                               cpu6_alert1: trip-point1 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens0 10>;
 
                        trips {
-                               cpu7_alert0: trip-point@0 {
+                               cpu7_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                                };
 
-                               cpu7_alert1: trip-point@1 {
+                               cpu7_alert1: trip-point1 {
                                        temperature = <95000>;
                                        hysteresis = <2000>;
                                        type = "passive";
                        thermal-sensors = <&tsens0 0>;
 
                        trips {
-                               aoss0_alert0: trip-point@0 {
+                               aoss0_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens0 5>;
 
                        trips {
-                               cluster0_alert0: trip-point@0 {
+                               cluster0_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens0 6>;
 
                        trips {
-                               cluster1_alert0: trip-point@0 {
+                               cluster1_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens0 11>;
 
                        trips {
-                               gpu1_alert0: trip-point@0 {
+                               gpu1_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens0 12>;
 
                        trips {
-                               gpu2_alert0: trip-point@0 {
+                               gpu2_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens1 0>;
 
                        trips {
-                               aoss1_alert0: trip-point@0 {
+                               aoss1_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens1 1>;
 
                        trips {
-                               q6_modem_alert0: trip-point@0 {
+                               q6_modem_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens1 2>;
 
                        trips {
-                               mem_alert0: trip-point@0 {
+                               mem_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens1 3>;
 
                        trips {
-                               wlan_alert0: trip-point@0 {
+                               wlan_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens1 4>;
 
                        trips {
-                               q6_hvx_alert0: trip-point@0 {
+                               q6_hvx_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens1 5>;
 
                        trips {
-                               camera_alert0: trip-point@0 {
+                               camera_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens1 6>;
 
                        trips {
-                               video_alert0: trip-point@0 {
+                               video_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
                        thermal-sensors = <&tsens1 7>;
 
                        trips {
-                               modem_alert0: trip-point@0 {
+                               modem_alert0: trip-point0 {
                                        temperature = <90000>;
                                        hysteresis = <2000>;
                                        type = "hot";
diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
new file mode 100644 (file)
index 0000000..ded120d
--- /dev/null
@@ -0,0 +1,446 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Lenovo Yoga C630
+ *
+ * Copyright (c) 2019, Linaro Ltd.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sdm845.dtsi"
+#include "pm8998.dtsi"
+
+/ {
+       model = "Lenovo Yoga C630";
+       compatible = "lenovo,yoga-c630", "qcom,sdm845";
+
+       aliases {
+               hsuart0 = &uart6;
+       };
+};
+
+&apps_rsc {
+       pm8998-rpmh-regulators {
+               compatible = "qcom,pm8998-rpmh-regulators";
+               qcom,pmic-id = "a";
+
+               vdd-l2-l8-l17-supply = <&vreg_s3a_1p35>;
+               vdd-l7-l12-l14-l15-supply = <&vreg_s5a_2p04>;
+
+               vreg_s2a_1p125: smps2 {
+               };
+
+               vreg_s3a_1p35: smps3 {
+                       regulator-min-microvolt = <1352000>;
+                       regulator-max-microvolt = <1352000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_s4a_1p8: smps4 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_s5a_2p04: smps5 {
+                       regulator-min-microvolt = <2040000>;
+                       regulator-max-microvolt = <2040000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_s7a_1p025: smps7 {
+               };
+
+               vdd_qusb_hs0:
+               vdda_hp_pcie_core:
+               vdda_mipi_csi0_0p9:
+               vdda_mipi_csi1_0p9:
+               vdda_mipi_csi2_0p9:
+               vdda_mipi_dsi0_pll:
+               vdda_mipi_dsi1_pll:
+               vdda_qlink_lv:
+               vdda_qlink_lv_ck:
+               vdda_qrefs_0p875:
+               vdda_pcie_core:
+               vdda_pll_cc_ebi01:
+               vdda_pll_cc_ebi23:
+               vdda_sp_sensor:
+               vdda_ufs1_core:
+               vdda_ufs2_core:
+               vdda_usb1_ss_core:
+               vdda_usb2_ss_core:
+               vreg_l1a_0p875: ldo1 {
+                       regulator-min-microvolt = <880000>;
+                       regulator-max-microvolt = <880000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vddpx_10:
+               vreg_l2a_1p2: ldo2 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+                       regulator-always-on;
+               };
+
+               vreg_l3a_1p0: ldo3 {
+               };
+
+               vdd_wcss_cx:
+               vdd_wcss_mx:
+               vdda_wcss_pll:
+               vreg_l5a_0p8: ldo5 {
+                       regulator-min-microvolt = <800000>;
+                       regulator-max-microvolt = <800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vddpx_13:
+               vreg_l6a_1p8: ldo6 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l7a_1p8: ldo7 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l8a_1p2: ldo8 {
+               };
+
+               vreg_l9a_1p8: ldo9 {
+               };
+
+               vreg_l10a_1p8: ldo10 {
+               };
+
+               vreg_l11a_1p0: ldo11 {
+               };
+
+               vdd_qfprom:
+               vdd_qfprom_sp:
+               vdda_apc1_cs_1p8:
+               vdda_gfx_cs_1p8:
+               vdda_qrefs_1p8:
+               vdda_qusb_hs0_1p8:
+               vddpx_11:
+               vreg_l12a_1p8: ldo12 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vddpx_2:
+               vreg_l13a_2p95: ldo13 {
+               };
+
+               vreg_l14a_1p88: ldo14 {
+                       regulator-min-microvolt = <1880000>;
+                       regulator-max-microvolt = <1880000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+                       regulator-always-on;
+               };
+
+               vreg_l15a_1p8: ldo15 {
+               };
+
+               vreg_l16a_2p7: ldo16 {
+               };
+
+               vreg_l17a_1p3: ldo17 {
+                       regulator-min-microvolt = <1304000>;
+                       regulator-max-microvolt = <1304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l18a_2p7: ldo18 {
+               };
+
+               vreg_l19a_3p0: ldo19 {
+                       regulator-min-microvolt = <3100000>;
+                       regulator-max-microvolt = <3108000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l20a_2p95: ldo20 {
+                       regulator-min-microvolt = <2960000>;
+                       regulator-max-microvolt = <2960000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l21a_2p95: ldo21 {
+               };
+
+               vreg_l22a_2p85: ldo22 {
+               };
+
+               vreg_l23a_3p3: ldo23 {
+               };
+
+               vdda_qusb_hs0_3p1:
+               vreg_l24a_3p075: ldo24 {
+                       regulator-min-microvolt = <3075000>;
+                       regulator-max-microvolt = <3083000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l25a_3p3: ldo25 {
+                       regulator-min-microvolt = <3104000>;
+                       regulator-max-microvolt = <3112000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vdda_hp_pcie_1p2:
+               vdda_hv_ebi0:
+               vdda_hv_ebi1:
+               vdda_hv_ebi2:
+               vdda_hv_ebi3:
+               vdda_mipi_csi_1p25:
+               vdda_mipi_dsi0_1p2:
+               vdda_mipi_dsi1_1p2:
+               vdda_pcie_1p2:
+               vdda_ufs1_1p2:
+               vdda_ufs2_1p2:
+               vdda_usb1_ss_1p2:
+               vdda_usb2_ss_1p2:
+               vreg_l26a_1p2: ldo26 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1208000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l28a_3p0: ldo28 {
+               };
+
+               vreg_lvs1a_1p8: lvs1 {
+               };
+
+               vreg_lvs2a_1p8: lvs2 {
+               };
+       };
+};
+
+&apps_smmu {
+       /* TODO: Figure out how to survive booting with this enabled */
+       status = "disabled";
+};
+
+&gcc {
+       protected-clocks = <GCC_QSPI_CORE_CLK>,
+                          <GCC_QSPI_CORE_CLK_SRC>,
+                          <GCC_QSPI_CNOC_PERIPH_AHB_CLK>;
+};
+
+&i2c1 {
+       status = "okay";
+       clock-frequency = <400000>;
+};
+
+&i2c3 {
+       status = "okay";
+       clock-frequency = <400000>;
+
+       hid@15 {
+               compatible = "hid-over-i2c";
+               reg = <0x15>;
+               hid-descr-addr = <0x1>;
+
+               interrupts-extended = <&tlmm 37 IRQ_TYPE_EDGE_RISING>;
+       };
+
+       hid@2c {
+               compatible = "hid-over-i2c";
+               reg = <0x2c>;
+               hid-descr-addr = <0x20>;
+
+               interrupts-extended = <&tlmm 37 IRQ_TYPE_EDGE_RISING>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c2_hid_active>;
+       };
+};
+
+&i2c5 {
+       status = "okay";
+       clock-frequency = <400000>;
+
+       hid@10 {
+               compatible = "hid-over-i2c";
+               reg = <0x10>;
+               hid-descr-addr = <0x1>;
+
+               interrupts-extended = <&tlmm 125 IRQ_TYPE_EDGE_FALLING>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c6_hid_active>;
+       };
+};
+
+&i2c11 {
+       status = "okay";
+       clock-frequency = <400000>;
+
+       hid@5c {
+               compatible = "hid-over-i2c";
+               reg = <0x5c>;
+               hid-descr-addr = <0x1>;
+
+               interrupts-extended = <&tlmm 92 IRQ_TYPE_LEVEL_LOW>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&i2c12_hid_active>;
+       };
+};
+
+&qup_i2c12_default {
+       drive-strength = <2>;
+       bias-disable;
+};
+
+&qup_uart6_default {
+       pinmux {
+                pins = "gpio45", "gpio46", "gpio47", "gpio48";
+                function = "qup6";
+       };
+
+       cts {
+               pins = "gpio45";
+               bias-pull-down;
+       };
+
+       rts-tx {
+               pins = "gpio46", "gpio47";
+               drive-strength = <2>;
+               bias-disable;
+       };
+
+       rx {
+               pins = "gpio48";
+               bias-pull-up;
+       };
+};
+
+&qupv3_id_0 {
+       status = "okay";
+};
+
+&qupv3_id_1 {
+       status = "okay";
+};
+
+&tlmm {
+       gpio-reserved-ranges = <0 4>, <81 4>;
+
+       i2c2_hid_active: i2c2-hid-active {
+               pins = <37>;
+               function = "gpio";
+
+               input-enable;
+               bias-pull-up;
+               drive-strength = <2>;
+       };
+
+       i2c6_hid_active: i2c6-hid-active {
+               pins = <125>;
+               function = "gpio";
+
+               input-enable;
+               bias-pull-up;
+               drive-strength = <2>;
+       };
+
+       i2c12_hid_active: i2c12-hid-active {
+               pins = <92>;
+               function = "gpio";
+
+               input-enable;
+               bias-pull-up;
+               drive-strength = <2>;
+       };
+};
+
+&uart6 {
+       status = "okay";
+
+       bluetooth {
+               compatible = "qcom,wcn3990-bt";
+
+               vddio-supply = <&vreg_s4a_1p8>;
+               vddxo-supply = <&vreg_l7a_1p8>;
+               vddrf-supply = <&vreg_l17a_1p3>;
+               vddch0-supply = <&vreg_l25a_3p3>;
+               max-speed = <3200000>;
+       };
+};
+
+&ufs_mem_hc {
+       status = "okay";
+
+       vcc-supply = <&vreg_l20a_2p95>;
+       vcc-max-microamp = <600000>;
+};
+
+&ufs_mem_phy {
+       status = "okay";
+
+       vdda-phy-supply = <&vdda_ufs1_core>;
+       vdda-pll-supply = <&vdda_ufs1_1p2>;
+};
+
+&usb_1 {
+       status = "okay";
+};
+
+&usb_1_dwc3 {
+       dr_mode = "host";
+};
+
+&usb_1_hsphy {
+       status = "okay";
+
+       vdd-supply = <&vdda_usb1_ss_core>;
+       vdda-pll-supply = <&vdda_qusb_hs0_1p8>;
+       vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>;
+
+       qcom,imp-res-offset-value = <8>;
+       qcom,hstx-trim-value = <QUSB2_V2_HSTX_TRIM_21_6_MA>;
+       qcom,preemphasis-level = <QUSB2_V2_PREEMPHASIS_5_PERCENT>;
+       qcom,preemphasis-width = <QUSB2_V2_PREEMPHASIS_WIDTH_HALF_BIT>;
+};
+
+&usb_1_qmpphy {
+       status = "okay";
+
+       vdda-phy-supply = <&vdda_usb1_ss_1p2>;
+       vdda-pll-supply = <&vdda_usb1_ss_core>;
+};
+
+&usb_2 {
+       status = "okay";
+};
+
+&usb_2_dwc3 {
+       dr_mode = "host";
+};
+
+&usb_2_hsphy {
+       status = "okay";
+
+       vdd-supply = <&vdda_usb2_ss_core>;
+       vdda-pll-supply = <&vdda_qusb_hs0_1p8>;
+       vdda-phy-dpdm-supply = <&vdda_qusb_hs0_3p1>;
+
+       qcom,imp-res-offset-value = <8>;
+       qcom,hstx-trim-value = <QUSB2_V2_HSTX_TRIM_22_8_MA>;
+};
+
+&usb_2_qmpphy {
+       status = "okay";
+
+       vdda-phy-supply = <&vdda_usb2_ss_1p2>;
+       vdda-pll-supply = <&vdda_usb2_ss_core>;
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8150-mtp.dts b/arch/arm64/boot/dts/qcom/sm8150-mtp.dts
new file mode 100644 (file)
index 0000000..aa5de42
--- /dev/null
@@ -0,0 +1,375 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019, Linaro Limited
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sm8150.dtsi"
+#include "pm8150.dtsi"
+#include "pm8150b.dtsi"
+#include "pm8150l.dtsi"
+
+/ {
+       model = "Qualcomm Technologies, Inc. SM8150 MTP";
+       compatible = "qcom,sm8150-mtp";
+
+       aliases {
+               serial0 = &uart2;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       vph_pwr: vph-pwr-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vph_pwr";
+               regulator-min-microvolt = <3700000>;
+               regulator-max-microvolt = <3700000>;
+       };
+
+       /*
+        * Apparently RPMh does not provide support for PM8150 S4 because it
+        * is always-on; model it as a fixed regulator.
+        */
+       vreg_s4a_1p8: pm8150-s4 {
+               compatible = "regulator-fixed";
+               regulator-name = "vreg_s4a_1p8";
+
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+
+               regulator-always-on;
+               regulator-boot-on;
+
+               vin-supply = <&vph_pwr>;
+       };
+};
+
+&apps_rsc {
+       pm8150-rpmh-regulators {
+               compatible = "qcom,pm8150-rpmh-regulators";
+               qcom,pmic-id = "a";
+
+               vdd-s1-supply = <&vph_pwr>;
+               vdd-s2-supply = <&vph_pwr>;
+               vdd-s3-supply = <&vph_pwr>;
+               vdd-s4-supply = <&vph_pwr>;
+               vdd-s5-supply = <&vph_pwr>;
+               vdd-s6-supply = <&vph_pwr>;
+               vdd-s7-supply = <&vph_pwr>;
+               vdd-s8-supply = <&vph_pwr>;
+               vdd-s9-supply = <&vph_pwr>;
+               vdd-s10-supply = <&vph_pwr>;
+
+               vdd-l1-l8-l11-supply = <&vreg_s6a_0p9>;
+               vdd-l2-l10-supply = <&vreg_bob>;
+               vdd-l3-l4-l5-l18-supply = <&vreg_s6a_0p9>;
+               vdd-l6-l9-supply = <&vreg_s8c_1p3>;
+               vdd-l7-l12-l14-l15-supply = <&vreg_s5a_2p0>;
+               vdd-l13-l16-l17-supply = <&vreg_bob>;
+
+               vreg_s5a_2p0: smps5 {
+                       regulator-min-microvolt = <1904000>;
+                       regulator-max-microvolt = <2000000>;
+               };
+
+               vreg_s6a_0p9: smps6 {
+                       regulator-min-microvolt = <920000>;
+                       regulator-max-microvolt = <1128000>;
+               };
+
+               vdda_wcss_pll:
+               vreg_l1a_0p75: ldo1 {
+                       regulator-min-microvolt = <752000>;
+                       regulator-max-microvolt = <752000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vdd_pdphy:
+               vdda_usb_hs_3p1:
+               vreg_l2a_3p1: ldo2 {
+                       regulator-min-microvolt = <3072000>;
+                       regulator-max-microvolt = <3072000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l3a_0p8: ldo3 {
+                       regulator-min-microvolt = <480000>;
+                       regulator-max-microvolt = <932000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vdd_usb_hs_core:
+               vdda_csi_0_0p9:
+               vdda_csi_1_0p9:
+               vdda_csi_2_0p9:
+               vdda_csi_3_0p9:
+               vdda_dsi_0_0p9:
+               vdda_dsi_1_0p9:
+               vdda_dsi_0_pll_0p9:
+               vdda_dsi_1_pll_0p9:
+               vdda_pcie_1ln_core:
+               vdda_pcie_2ln_core:
+               vdda_pll_hv_cc_ebi01:
+               vdda_pll_hv_cc_ebi23:
+               vdda_qrefs_0p875_5:
+               vdda_sp_sensor:
+               vdda_ufs_2ln_core_1:
+               vdda_ufs_2ln_core_2:
+               vdda_usb_ss_dp_core_1:
+               vdda_usb_ss_dp_core_2:
+               vdda_qlink_lv:
+               vdda_qlink_lv_ck:
+               vreg_l5a_0p875: ldo5 {
+                       regulator-min-microvolt = <880000>;
+                       regulator-max-microvolt = <880000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l6a_1p2: ldo6 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l7a_1p8: ldo7 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vddpx_10:
+               vreg_l9a_1p2: ldo9 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l10a_2p5: ldo10 {
+                       regulator-min-microvolt = <2504000>;
+                       regulator-max-microvolt = <2960000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l11a_0p8: ldo11 {
+                       regulator-min-microvolt = <800000>;
+                       regulator-max-microvolt = <800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vdd_qfprom:
+               vdd_qfprom_sp:
+               vdda_apc_cs_1p8:
+               vdda_gfx_cs_1p8:
+               vdda_usb_hs_1p8:
+               vdda_qrefs_vref_1p8:
+               vddpx_10_a:
+               vreg_l12a_1p8: ldo12 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l13a_2p7: ldo13 {
+                       regulator-min-microvolt = <2704000>;
+                       regulator-max-microvolt = <2704000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l14a_1p8: ldo14 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1880000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l15a_1p7: ldo15 {
+                       regulator-min-microvolt = <1704000>;
+                       regulator-max-microvolt = <1704000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l16a_2p7: ldo16 {
+                       regulator-min-microvolt = <2704000>;
+                       regulator-max-microvolt = <2960000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l17a_3p0: ldo17 {
+                       regulator-min-microvolt = <2856000>;
+                       regulator-max-microvolt = <3008000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+       };
+
+       pm8150l-rpmh-regulators {
+               compatible = "qcom,pm8150l-rpmh-regulators";
+               qcom,pmic-id = "c";
+
+               vdd-s1-supply = <&vph_pwr>;
+               vdd-s2-supply = <&vph_pwr>;
+               vdd-s3-supply = <&vph_pwr>;
+               vdd-s4-supply = <&vph_pwr>;
+               vdd-s5-supply = <&vph_pwr>;
+               vdd-s6-supply = <&vph_pwr>;
+               vdd-s7-supply = <&vph_pwr>;
+               vdd-s8-supply = <&vph_pwr>;
+
+               vdd-l1-l8-supply = <&vreg_s4a_1p8>;
+               vdd-l2-l3-supply = <&vreg_s8c_1p3>;
+               vdd-l4-l5-l6-supply = <&vreg_bob>;
+               vdd-l7-l11-supply = <&vreg_bob>;
+               vdd-l9-l10-supply = <&vreg_bob>;
+
+               vdd-bob-supply = <&vph_pwr>;
+               vdd-flash-supply = <&vreg_bob>;
+               vdd-rgb-supply = <&vreg_bob>;
+
+               vreg_bob: bob {
+                       regulator-min-microvolt = <3008000>;
+                       regulator-max-microvolt = <4000000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+                       regulator-allow-bypass;
+               };
+
+               vreg_s8c_1p3: smps8 {
+                       regulator-min-microvolt = <1352000>;
+                       regulator-max-microvolt = <1352000>;
+               };
+
+               vreg_l1c_1p8: ldo1 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vdda_wcss_adcdac_1:
+               vdda_wcss_adcdac_22:
+               vreg_l2c_1p3: ldo2 {
+                       regulator-min-microvolt = <1304000>;
+                       regulator-max-microvolt = <1304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vdda_hv_ebi0:
+               vdda_hv_ebi1:
+               vdda_hv_ebi2:
+               vdda_hv_ebi3:
+               vdda_hv_refgen0:
+               vdda_qlink_hv_ck:
+               vreg_l3c_1p2: ldo3 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vddpx_5:
+               vreg_l4c_1p8: ldo4 {
+                       regulator-min-microvolt = <1704000>;
+                       regulator-max-microvolt = <2928000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vddpx_6:
+               vreg_l5c_1p8: ldo5 {
+                       regulator-min-microvolt = <1704000>;
+                       regulator-max-microvolt = <2928000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vddpx_2:
+               vreg_l6c_2p9: ldo6 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2960000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l7c_3p0: ldo7 {
+                       regulator-min-microvolt = <2856000>;
+                       regulator-max-microvolt = <3104000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l8c_1p8: ldo8 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l9c_2p9: ldo9 {
+                       regulator-min-microvolt = <2704000>;
+                       regulator-max-microvolt = <2960000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l10c_3p3: ldo10 {
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3312000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l11c_3p3: ldo11 {
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3312000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+       };
+
+       pm8009-rpmh-regulators {
+               compatible = "qcom,pm8009-rpmh-regulators";
+               qcom,pmic-id = "f";
+
+               vdd-s1-supply = <&vph_pwr>;
+               vdd-s2-supply = <&vreg_bob>;
+
+               vdd-l2-supply = <&vreg_s8c_1p3>;
+               vdd-l5-l6-supply = <&vreg_bob>;
+
+               vreg_l2f_1p2: ldo2 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l5f_2p85: ldo5 {
+                       regulator-min-microvolt = <2800000>;
+                       regulator-max-microvolt = <2800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+               };
+
+               vreg_l6f_2p85: ldo6 {
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>;
+                       regulator-min-microvolt = <2856000>;
+                       regulator-max-microvolt = <2856000>;
+               };
+       };
+};
+
+&qupv3_id_1 {
+       status = "okay";
+};
+
+&pon {
+       pwrkey {
+               status = "okay";
+       };
+
+       resin {
+               compatible = "qcom,pm8941-resin";
+               interrupts = <0x0 0x8 0x1 IRQ_TYPE_EDGE_BOTH>;
+               debounce = <15625>;
+               bias-pull-up;
+               linux,code = <KEY_VOLUMEDOWN>;
+       };
+};
+
+&tlmm {
+       gpio-reserved-ranges = <0 4>, <126 4>;
+};
+
+&uart2 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi
new file mode 100644 (file)
index 0000000..8f23fca
--- /dev/null
@@ -0,0 +1,482 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2019, Linaro Limited
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+
+/ {
+       interrupt-parent = <&intc>;
+
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       chosen { };
+
+       clocks {
+               xo_board: xo-board {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <38400000>;
+                       clock-output-names = "xo_board";
+               };
+
+               sleep_clk: sleep-clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <32764>;
+                       clock-output-names = "sleep_clk";
+               };
+       };
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               CPU0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "qcom,kryo485";
+                       reg = <0x0 0x0>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_0>;
+                       L2_0: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                               L3_0: l3-cache {
+                                     compatible = "cache";
+                               };
+                       };
+               };
+
+               CPU1: cpu@100 {
+                       device_type = "cpu";
+                       compatible = "qcom,kryo485";
+                       reg = <0x0 0x100>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_100>;
+                       L2_100: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+
+               };
+
+               CPU2: cpu@200 {
+                       device_type = "cpu";
+                       compatible = "qcom,kryo485";
+                       reg = <0x0 0x200>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_200>;
+                       L2_200: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+
+               CPU3: cpu@300 {
+                       device_type = "cpu";
+                       compatible = "qcom,kryo485";
+                       reg = <0x0 0x300>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_300>;
+                       L2_300: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+
+               CPU4: cpu@400 {
+                       device_type = "cpu";
+                       compatible = "qcom,kryo485";
+                       reg = <0x0 0x400>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_400>;
+                       L2_400: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+
+               CPU5: cpu@500 {
+                       device_type = "cpu";
+                       compatible = "qcom,kryo485";
+                       reg = <0x0 0x500>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_500>;
+                       L2_500: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+
+               CPU6: cpu@600 {
+                       device_type = "cpu";
+                       compatible = "qcom,kryo485";
+                       reg = <0x0 0x600>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_600>;
+                       L2_600: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+
+               CPU7: cpu@700 {
+                       device_type = "cpu";
+                       compatible = "qcom,kryo485";
+                       reg = <0x0 0x700>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_700>;
+                       L2_700: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+       };
+
+       firmware {
+               scm: scm {
+                       compatible = "qcom,scm-sm8150", "qcom,scm";
+                       #reset-cells = <1>;
+               };
+       };
+
+       tcsr_mutex: hwlock {
+               compatible = "qcom,tcsr-mutex";
+               syscon = <&tcsr_mutex_regs 0 0x1000>;
+               #hwlock-cells = <1>;
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               /* We expect the bootloader to fill in the size */
+               reg = <0x0 0x80000000 0x0 0x0>;
+       };
+
+       pmu {
+               compatible = "arm,armv8-pmuv3";
+               interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       psci {
+               compatible = "arm,psci-1.0";
+               method = "smc";
+       };
+
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               hyp_mem: memory@85700000 {
+                       reg = <0x0 0x85700000 0x0 0x600000>;
+                       no-map;
+               };
+
+               xbl_mem: memory@85d00000 {
+                       reg = <0x0 0x85d00000 0x0 0x140000>;
+                       no-map;
+               };
+
+               aop_mem: memory@85f00000 {
+                       reg = <0x0 0x85f00000 0x0 0x20000>;
+                       no-map;
+               };
+
+               aop_cmd_db: memory@85f20000 {
+                       compatible = "qcom,cmd-db";
+                       reg = <0x0 0x85f20000 0x0 0x20000>;
+                       no-map;
+               };
+
+               smem_mem: memory@86000000 {
+                       reg = <0x0 0x86000000 0x0 0x200000>;
+                       no-map;
+               };
+
+               tz_mem: memory@86200000 {
+                       reg = <0x0 0x86200000 0x0 0x3900000>;
+                       no-map;
+               };
+
+               rmtfs_mem: memory@89b00000 {
+                       compatible = "qcom,rmtfs-mem";
+                       reg = <0x0 0x89b00000 0x0 0x200000>;
+                       no-map;
+
+                       qcom,client-id = <1>;
+                       qcom,vmid = <15>;
+               };
+
+               camera_mem: memory@8b700000 {
+                       reg = <0x0 0x8b700000 0x0 0x500000>;
+                       no-map;
+               };
+
+               wlan_mem: memory@8bc00000 {
+                       reg = <0x0 0x8bc00000 0x0 0x180000>;
+                       no-map;
+               };
+
+               npu_mem: memory@8bd80000 {
+                       reg = <0x0 0x8bd80000 0x0 0x80000>;
+                       no-map;
+               };
+
+               adsp_mem: memory@8be00000 {
+                       reg = <0x0 0x8be00000 0x0 0x1a00000>;
+                       no-map;
+               };
+
+               mpss_mem: memory@8d800000 {
+                       reg = <0x0 0x8d800000 0x0 0x9600000>;
+                       no-map;
+               };
+
+               venus_mem: memory@96e00000 {
+                       reg = <0x0 0x96e00000 0x0 0x500000>;
+                       no-map;
+               };
+
+               slpi_mem: memory@97300000 {
+                       reg = <0x0 0x97300000 0x0 0x1400000>;
+                       no-map;
+               };
+
+               ipa_fw_mem: memory@98700000 {
+                       reg = <0x0 0x98700000 0x0 0x10000>;
+                       no-map;
+               };
+
+               ipa_gsi_mem: memory@98710000 {
+                       reg = <0x0 0x98710000 0x0 0x5000>;
+                       no-map;
+               };
+
+               gpu_mem: memory@98715000 {
+                       reg = <0x0 0x98715000 0x0 0x2000>;
+                       no-map;
+               };
+
+               spss_mem: memory@98800000 {
+                       reg = <0x0 0x98800000 0x0 0x100000>;
+                       no-map;
+               };
+
+               cdsp_mem: memory@98900000 {
+                       reg = <0x0 0x98900000 0x0 0x1400000>;
+                       no-map;
+               };
+
+               qseecom_mem: memory@9e400000 {
+                       reg = <0x0 0x9e400000 0x0 0x1400000>;
+                       no-map;
+               };
+       };
+
+       smem {
+               compatible = "qcom,smem";
+               memory-region = <&smem_mem>;
+               hwlocks = <&tcsr_mutex 3>;
+       };
+
+       soc: soc@0 {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges = <0 0 0 0 0x10 0>;
+               dma-ranges = <0 0 0 0 0x10 0>;
+               compatible = "simple-bus";
+
+               gcc: clock-controller@100000 {
+                       compatible = "qcom,gcc-sm8150";
+                       reg = <0x0 0x00100000 0x0 0x1f0000>;
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       #power-domain-cells = <1>;
+                       clock-names = "bi_tcxo",
+                                     "sleep_clk";
+                       clocks = <&rpmhcc RPMH_CXO_CLK>,
+                                <&sleep_clk>;
+               };
+
+               qupv3_id_1: geniqup@ac0000 {
+                       compatible = "qcom,geni-se-qup";
+                       reg = <0x0 0x00ac0000 0x0 0x6000>;
+                       clock-names = "m-ahb", "s-ahb";
+                       clocks = <&gcc 123>,
+                                <&gcc 124>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+                       status = "disabled";
+
+                       uart2: serial@a90000 {
+                               compatible = "qcom,geni-debug-uart";
+                               reg = <0x0 0x00a90000 0x0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc 105>;
+                               interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+               };
+
+               tcsr_mutex_regs: syscon@1f40000 {
+                       compatible = "syscon";
+                       reg = <0x0 0x01f40000 0x0 0x40000>;
+               };
+
+               tlmm: pinctrl@3100000 {
+                       compatible = "qcom,sm8150-pinctrl";
+                       reg = <0x0 0x03100000 0x0 0x300000>,
+                             <0x0 0x03500000 0x0 0x300000>,
+                             <0x0 0x03900000 0x0 0x300000>,
+                             <0x0 0x03D00000 0x0 0x300000>;
+                       reg-names = "west", "east", "north", "south";
+                       interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+                       gpio-ranges = <&tlmm 0 0 175>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+
+               aoss_qmp: power-controller@c300000 {
+                       compatible = "qcom,sm8150-aoss-qmp";
+                       reg = <0x0 0x0c300000 0x0 0x100000>;
+                       interrupts = <GIC_SPI 389 IRQ_TYPE_EDGE_RISING>;
+                       mboxes = <&apss_shared 0>;
+
+                       #clock-cells = <0>;
+                       #power-domain-cells = <1>;
+               };
+
+               spmi_bus: spmi@c440000 {
+                       compatible = "qcom,spmi-pmic-arb";
+                       reg = <0x0 0x0c440000 0x0 0x0001100>,
+                             <0x0 0x0c600000 0x0 0x2000000>,
+                             <0x0 0x0e600000 0x0 0x0100000>,
+                             <0x0 0x0e700000 0x0 0x00a0000>,
+                             <0x0 0x0c40a000 0x0 0x0026000>;
+                       reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
+                       interrupt-names = "periph_irq";
+                       interrupts = <GIC_SPI 481 IRQ_TYPE_LEVEL_HIGH>;
+                       qcom,ee = <0>;
+                       qcom,channel = <0>;
+                       #address-cells = <2>;
+                       #size-cells = <0>;
+                       interrupt-controller;
+                       #interrupt-cells = <4>;
+                       cell-index = <0>;
+               };
+
+               intc: interrupt-controller@17a00000 {
+                       compatible = "arm,gic-v3";
+                       interrupt-controller;
+                       #interrupt-cells = <3>;
+                       reg = <0x0 0x17a00000 0x0 0x10000>,     /* GICD */
+                             <0x0 0x17a60000 0x0 0x100000>;    /* GICR * 8 */
+                       interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               apss_shared: mailbox@17c00000 {
+                       compatible = "qcom,sm8150-apss-shared";
+                       reg = <0x0 0x17c00000 0x0 0x1000>;
+                       #mbox-cells = <1>;
+               };
+
+               timer@17c20000 {
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+                       compatible = "arm,armv7-timer-mem";
+                       reg = <0x0 0x17c20000 0x0 0x1000>;
+                       clock-frequency = <19200000>;
+
+                       frame@17c21000{
+                               frame-number = <0>;
+                               interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x0 0x17c21000 0x0 0x1000>,
+                                     <0x0 0x17c22000 0x0 0x1000>;
+                       };
+
+                       frame@17c23000 {
+                               frame-number = <1>;
+                               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x0 0x17c23000 0x0 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17c25000 {
+                               frame-number = <2>;
+                               interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x0 0x17c25000 0x0 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17c27000 {
+                               frame-number = <3>;
+                               interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x0 0x17c26000 0x0 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17c29000 {
+                               frame-number = <4>;
+                               interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x0 0x17c29000 0x0 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17c2b000 {
+                               frame-number = <5>;
+                               interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x0 0x17c2b000 0x0 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17c2d000 {
+                               frame-number = <6>;
+                               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x0 0x17c2d000 0x0 0x1000>;
+                               status = "disabled";
+                       };
+               };
+
+               apps_rsc: rsc@18200000 {
+                       label = "apps_rsc";
+                       compatible = "qcom,rpmh-rsc";
+                       reg = <0x0 0x18200000 0x0 0x10000>,
+                             <0x0 0x18210000 0x0 0x10000>,
+                             <0x0 0x18220000 0x0 0x10000>;
+                       reg-names = "drv-0", "drv-1", "drv-2";
+                       interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                       qcom,tcs-offset = <0xd00>;
+                       qcom,drv-id = <2>;
+                       qcom,tcs-config = <ACTIVE_TCS  2>,
+                                         <SLEEP_TCS   1>,
+                                         <WAKE_TCS    1>,
+                                         <CONTROL_TCS 0>;
+
+                       rpmhcc: clock-controller {
+                               compatible = "qcom,sm8150-rpmh-clk";
+                               #clock-cells = <1>;
+                               clock-names = "xo";
+                               clocks = <&xo_board>;
+                       };
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 1 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 2 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 3 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 0 IRQ_TYPE_LEVEL_LOW>;
+       };
+};
index 3311a98..3e376d2 100644 (file)
@@ -10,6 +10,7 @@
 / {
        aliases {
                serial0 = &scif2;
+               serial1 = &hscif0;
        };
 
        chosen {
        leds {
                compatible = "gpio-leds";
 
+               bt_active_led {
+                       label = "blue:bt";
+                       gpios = <&gpio7  0 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "hci0-power";
+                       default-state = "off";
+               };
+
                led0 {
                        gpios = <&gpio6 11 GPIO_ACTIVE_HIGH>;
                };
                led3 {
                        gpios = <&gpio0  0 GPIO_ACTIVE_HIGH>;
                };
+
+               wlan_active_led {
+                       label = "yellow:wlan";
+                       gpios = <&gpio7  1 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "phy0tx";
+                       default-state = "off";
+               };
        };
 
        reg_1p8v: regulator0 {
                regulator-always-on;
        };
 
+       sound_card: sound {
+               compatible = "audio-graph-card";
+
+               label = "rcar-sound";
+
+               dais = <&rsnd_port0>;
+       };
+
        vbus0_usb2: regulator-vbus0-usb2 {
                compatible = "regulator-fixed";
 
                          1800000 0>;
        };
 
+       wlan_en_reg: regulator-wlan_en {
+               compatible = "regulator-fixed";
+               regulator-name = "wlan-en-regulator";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               startup-delay-us = <70000>;
+
+               gpio = <&gpio_expander 1 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
        x302_clk: x302-clock {
                compatible = "fixed-clock";
                #clock-cells = <0>;
        };
 };
 
+&audio_clk_a {
+       clock-frequency = <22579200>;
+};
+
 &du {
        clocks = <&cpg CPG_MOD 724>,
                 <&cpg CPG_MOD 723>,
                                remote-endpoint = <&hdmi0_con>;
                        };
                };
+               port@2 {
+                       reg = <2>;
+                       dw_hdmi0_snd_in: endpoint {
+                               remote-endpoint = <&rsnd_endpoint0>;
+                       };
+               };
+       };
+};
+
+&hscif0 {
+       pinctrl-0 = <&hscif0_pins>;
+       pinctrl-names = "default";
+
+       uart-has-rtscts;
+       status = "okay";
+
+       bluetooth {
+               compatible = "ti,wl1837-st";
+               enable-gpios = <&gpio_expander 2 GPIO_ACTIVE_HIGH>;
        };
 };
 
        clock-frequency = <400000>;
        status = "okay";
 
+       gpio_expander: gpio@20 {
+               compatible = "onnn,pca9654";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
        versaclock5: clock-generator@6a {
                compatible = "idt,5p49v5923";
                reg = <0x6a>;
        pinctrl-0 = <&scif_clk_pins>;
        pinctrl-names = "default";
 
+       hscif0_pins: hscif0 {
+               groups = "hscif0_data", "hscif0_ctrl";
+               function = "hscif0";
+       };
+
        scif2_pins: scif2 {
                groups = "scif2_data_a";
                function = "scif2";
                power-source = <1800>;
        };
 
+       sdhi2_pins: sd2 {
+               groups = "sdhi2_data4", "sdhi2_ctrl";
+               function = "sdhi2";
+               power-source = <1800>;
+       };
+
        sdhi3_pins: sd3 {
                groups = "sdhi3_data8", "sdhi3_ctrl", "sdhi3_ds";
                function = "sdhi3";
                power-source = <1800>;
        };
 
+       sound_clk_pins: sound_clk {
+               groups = "audio_clk_a_a";
+               function = "audio_clk";
+       };
+
        usb0_pins: usb0 {
                groups = "usb0";
                function = "usb0";
        };
 };
 
+&rcar_sound {
+       pinctrl-0 = <&sound_clk_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+
+       /* Single DAI */
+       #sound-dai-cells = <0>;
+
+       ports {
+               rsnd_port0: port@0 {
+                       rsnd_endpoint0: endpoint {
+                               remote-endpoint = <&dw_hdmi0_snd_in>;
+
+                               dai-format = "i2s";
+                               bitclock-master = <&rsnd_endpoint0>;
+                               frame-master = <&rsnd_endpoint0>;
+
+                               playback = <&ssi2>;
+                       };
+               };
+       };
+};
+
 &rwdt {
        timeout-sec = <60>;
        status = "okay";
        status = "okay";
 };
 
+&sdhi2 {
+       status = "okay";
+       pinctrl-0 = <&sdhi2_pins>;
+       pinctrl-names = "default";
+
+       vmmc-supply = <&wlan_en_reg>;
+       bus-width = <4>;
+       non-removable;
+       cap-power-off-card;
+       keep-power-in-suspend;
+
+       #address-cells = <1>;
+       #size-cells = <0>;
+       wlcore: wlcore@2 {
+               compatible = "ti,wl1837";
+               reg = <2>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <5 IRQ_TYPE_LEVEL_HIGH>;
+       };
+};
+
 &sdhi3 {
        pinctrl-0 = <&sdhi3_pins>;
        pinctrl-1 = <&sdhi3_pins>;
        mmc-hs200-1_8v;
        non-removable;
        fixed-emmc-driver-type = <1>;
+       status = "okay";
 };
 
 &usb_extal_clk {
index 07a6eea..4280b19 100644 (file)
        };
 };
 
+&can0 {
+       pinctrl-0 = <&can0_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&can1 {
+       pinctrl-0 = <&can1_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
 &pciec0 {
        status = "okay";
 };
                        drive-strength = <12>;
                };
        };
+
+       can0_pins: can0 {
+               groups = "can0_data_a";
+               function = "can0";
+       };
+
+       can1_pins: can1 {
+               groups = "can1_data";
+               function = "can1";
+       };
 };
index f209457..06c7c84 100644 (file)
                                 <&cpg CPG_CORE R8A774A1_CLK_CANFD>,
                                 <&can_clk>;
                        clock-names = "clkp1", "clkp2", "can_clk";
+                       assigned-clocks = <&cpg CPG_CORE R8A774A1_CLK_CANFD>;
+                       assigned-clock-rates = <40000000>;
                        power-domains = <&sysc R8A774A1_PD_ALWAYS_ON>;
                        resets = <&cpg 916>;
                        status = "disabled";
                                 <&cpg CPG_CORE R8A774A1_CLK_CANFD>,
                                 <&can_clk>;
                        clock-names = "clkp1", "clkp2", "can_clk";
+                       assigned-clocks = <&cpg CPG_CORE R8A774A1_CLK_CANFD>;
+                       assigned-clock-rates = <40000000>;
                        power-domains = <&sysc R8A774A1_PD_ALWAYS_ON>;
                        resets = <&cpg 915>;
                        status = "disabled";
                };
 
+               canfd: can@e66c0000 {
+                       compatible = "renesas,r8a774a1-canfd",
+                                    "renesas,rcar-gen3-canfd";
+                       reg = <0 0xe66c0000 0 0x8000>;
+                       interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 914>,
+                                <&cpg CPG_CORE R8A774A1_CLK_CANFD>,
+                                <&can_clk>;
+                       clock-names = "fck", "canfd", "can_clk";
+                       assigned-clocks = <&cpg CPG_CORE R8A774A1_CLK_CANFD>;
+                       assigned-clock-rates = <40000000>;
+                       power-domains = <&sysc R8A774A1_PD_ALWAYS_ON>;
+                       resets = <&cpg 914>;
+                       status = "disabled";
+
+                       channel0 {
+                               status = "disabled";
+                       };
+
+                       channel1 {
+                               status = "disabled";
+                       };
+               };
+
                pwm0: pwm@e6e30000 {
                        compatible = "renesas,pwm-r8a774a1", "renesas,pwm-rcar";
                        reg = <0 0xe6e30000 0 0x8>;
                                <0 0xec5a0000 0 0x100>,  /* ADG */
                                <0 0xec540000 0 0x1000>, /* SSIU */
                                <0 0xec541000 0 0x280>,  /* SSI */
-                               <0 0xec740000 0 0x200>;  /* Audio DMAC peri peri*/
+                               <0 0xec760000 0 0x200>;  /* Audio DMAC peri peri*/
                        reg-names = "scu", "adg", "ssiu", "ssi", "audmapp";
 
                        clocks = <&cpg CPG_MOD 1005>,
                                      "ssi.1", "ssi.0";
                        status = "disabled";
 
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               port@0 {
+                                       reg = <0>;
+                               };
+                               port@1 {
+                                       reg = <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 { };
+                       };
+
                        rcar_sound,dvc {
                                dvc0: dvc-0 {
                                        dmas = <&audma1 0xbc>;
                                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 { };
-                       };
-
                        rcar_sound,src {
                                src0: src-0 {
                                        interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
                        rcar_sound,ssi {
                                ssi0: ssi-0 {
                                        interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x01>, <&audma1 0x02>, <&audma0 0x15>, <&audma1 0x16>;
-                                       dma-names = "rx", "tx", "rxu", "txu";
+                                       dmas = <&audma0 0x01>, <&audma1 0x02>;
+                                       dma-names = "rx", "tx";
                                };
                                ssi1: ssi-1 {
                                        interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x03>, <&audma1 0x04>, <&audma0 0x49>, <&audma1 0x4a>;
-                                       dma-names = "rx", "tx", "rxu", "txu";
+                                       dmas = <&audma0 0x03>, <&audma1 0x04>;
+                                       dma-names = "rx", "tx";
                                };
                                ssi2: ssi-2 {
                                        interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x05>, <&audma1 0x06>, <&audma0 0x63>, <&audma1 0x64>;
-                                       dma-names = "rx", "tx", "rxu", "txu";
+                                       dmas = <&audma0 0x05>, <&audma1 0x06>;
+                                       dma-names = "rx", "tx";
                                };
                                ssi3: ssi-3 {
                                        interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x07>, <&audma1 0x08>, <&audma0 0x6f>, <&audma1 0x70>;
-                                       dma-names = "rx", "tx", "rxu", "txu";
+                                       dmas = <&audma0 0x07>, <&audma1 0x08>;
+                                       dma-names = "rx", "tx";
                                };
                                ssi4: ssi-4 {
                                        interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x09>, <&audma1 0x0a>, <&audma0 0x71>, <&audma1 0x72>;
-                                       dma-names = "rx", "tx", "rxu", "txu";
+                                       dmas = <&audma0 0x09>, <&audma1 0x0a>;
+                                       dma-names = "rx", "tx";
                                };
                                ssi5: ssi-5 {
                                        interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x0b>, <&audma1 0x0c>, <&audma0 0x73>, <&audma1 0x74>;
-                                       dma-names = "rx", "tx", "rxu", "txu";
+                                       dmas = <&audma0 0x0b>, <&audma1 0x0c>;
+                                       dma-names = "rx", "tx";
                                };
                                ssi6: ssi-6 {
                                        interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x0d>, <&audma1 0x0e>, <&audma0 0x75>, <&audma1 0x76>;
-                                       dma-names = "rx", "tx", "rxu", "txu";
+                                       dmas = <&audma0 0x0d>, <&audma1 0x0e>;
+                                       dma-names = "rx", "tx";
                                };
                                ssi7: ssi-7 {
                                        interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x0f>, <&audma1 0x10>, <&audma0 0x79>, <&audma1 0x7a>;
-                                       dma-names = "rx", "tx", "rxu", "txu";
+                                       dmas = <&audma0 0x0f>, <&audma1 0x10>;
+                                       dma-names = "rx", "tx";
                                };
                                ssi8: ssi-8 {
                                        interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x11>, <&audma1 0x12>, <&audma0 0x7b>, <&audma1 0x7c>;
-                                       dma-names = "rx", "tx", "rxu", "txu";
+                                       dmas = <&audma0 0x11>, <&audma1 0x12>;
+                                       dma-names = "rx", "tx";
                                };
                                ssi9: ssi-9 {
                                        interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x13>, <&audma1 0x14>, <&audma0 0x7d>, <&audma1 0x7e>;
-                                       dma-names = "rx", "tx", "rxu", "txu";
+                                       dmas = <&audma0 0x13>, <&audma1 0x14>;
+                                       dma-names = "rx", "tx";
                                };
                        };
 
-                       ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-                               port@0 {
-                                       reg = <0>;
+                       rcar_sound,ssiu {
+                               ssiu00: ssiu-0 {
+                                       dmas = <&audma0 0x15>, <&audma1 0x16>;
+                                       dma-names = "rx", "tx";
                                };
-                               port@1 {
-                                       reg = <1>;
+                               ssiu01: ssiu-1 {
+                                       dmas = <&audma0 0x35>, <&audma1 0x36>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu02: ssiu-2 {
+                                       dmas = <&audma0 0x37>, <&audma1 0x38>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu03: ssiu-3 {
+                                       dmas = <&audma0 0x47>, <&audma1 0x48>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu04: ssiu-4 {
+                                       dmas = <&audma0 0x3F>, <&audma1 0x40>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu05: ssiu-5 {
+                                       dmas = <&audma0 0x43>, <&audma1 0x44>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu06: ssiu-6 {
+                                       dmas = <&audma0 0x4F>, <&audma1 0x50>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu07: ssiu-7 {
+                                       dmas = <&audma0 0x53>, <&audma1 0x54>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu10: ssiu-8 {
+                                       dmas = <&audma0 0x49>, <&audma1 0x4a>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu11: ssiu-9 {
+                                       dmas = <&audma0 0x4B>, <&audma1 0x4C>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu12: ssiu-10 {
+                                       dmas = <&audma0 0x57>, <&audma1 0x58>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu13: ssiu-11 {
+                                       dmas = <&audma0 0x59>, <&audma1 0x5A>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu14: ssiu-12 {
+                                       dmas = <&audma0 0x5F>, <&audma1 0x60>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu15: ssiu-13 {
+                                       dmas = <&audma0 0xC3>, <&audma1 0xC4>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu16: ssiu-14 {
+                                       dmas = <&audma0 0xC7>, <&audma1 0xC8>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu17: ssiu-15 {
+                                       dmas = <&audma0 0xCB>, <&audma1 0xCC>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu20: ssiu-16 {
+                                       dmas = <&audma0 0x63>, <&audma1 0x64>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu21: ssiu-17 {
+                                       dmas = <&audma0 0x67>, <&audma1 0x68>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu22: ssiu-18 {
+                                       dmas = <&audma0 0x6B>, <&audma1 0x6C>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu23: ssiu-19 {
+                                       dmas = <&audma0 0x6D>, <&audma1 0x6E>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu24: ssiu-20 {
+                                       dmas = <&audma0 0xCF>, <&audma1 0xCE>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu25: ssiu-21 {
+                                       dmas = <&audma0 0xEB>, <&audma1 0xEC>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu26: ssiu-22 {
+                                       dmas = <&audma0 0xED>, <&audma1 0xEE>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu27: ssiu-23 {
+                                       dmas = <&audma0 0xEF>, <&audma1 0xF0>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu30: ssiu-24 {
+                                       dmas = <&audma0 0x6f>, <&audma1 0x70>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu31: ssiu-25 {
+                                       dmas = <&audma0 0x21>, <&audma1 0x22>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu32: ssiu-26 {
+                                       dmas = <&audma0 0x23>, <&audma1 0x24>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu33: ssiu-27 {
+                                       dmas = <&audma0 0x25>, <&audma1 0x26>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu34: ssiu-28 {
+                                       dmas = <&audma0 0x27>, <&audma1 0x28>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu35: ssiu-29 {
+                                       dmas = <&audma0 0x29>, <&audma1 0x2A>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu36: ssiu-30 {
+                                       dmas = <&audma0 0x2B>, <&audma1 0x2C>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu37: ssiu-31 {
+                                       dmas = <&audma0 0x2D>, <&audma1 0x2E>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu40: ssiu-32 {
+                                       dmas =  <&audma0 0x71>, <&audma1 0x72>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu41: ssiu-33 {
+                                       dmas = <&audma0 0x17>, <&audma1 0x18>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu42: ssiu-34 {
+                                       dmas = <&audma0 0x19>, <&audma1 0x1A>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu43: ssiu-35 {
+                                       dmas = <&audma0 0x1B>, <&audma1 0x1C>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu44: ssiu-36 {
+                                       dmas = <&audma0 0x1D>, <&audma1 0x1E>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu45: ssiu-37 {
+                                       dmas = <&audma0 0x1F>, <&audma1 0x20>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu46: ssiu-38 {
+                                       dmas = <&audma0 0x31>, <&audma1 0x32>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu47: ssiu-39 {
+                                       dmas = <&audma0 0x33>, <&audma1 0x34>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu50: ssiu-40 {
+                                       dmas = <&audma0 0x73>, <&audma1 0x74>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu60: ssiu-41 {
+                                       dmas = <&audma0 0x75>, <&audma1 0x76>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu70: ssiu-42 {
+                                       dmas = <&audma0 0x79>, <&audma1 0x7a>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu80: ssiu-43 {
+                                       dmas = <&audma0 0x7b>, <&audma1 0x7c>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu90: ssiu-44 {
+                                       dmas = <&audma0 0x7d>, <&audma1 0x7e>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu91: ssiu-45 {
+                                       dmas = <&audma0 0x7F>, <&audma1 0x80>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu92: ssiu-46 {
+                                       dmas = <&audma0 0x81>, <&audma1 0x82>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu93: ssiu-47 {
+                                       dmas = <&audma0 0x83>, <&audma1 0x84>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu94: ssiu-48 {
+                                       dmas = <&audma0 0xA3>, <&audma1 0xA4>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu95: ssiu-49 {
+                                       dmas = <&audma0 0xA5>, <&audma1 0xA6>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu96: ssiu-50 {
+                                       dmas = <&audma0 0xA7>, <&audma1 0xA8>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssiu97: ssiu-51 {
+                                       dmas = <&audma0 0xA9>, <&audma1 0xAA>;
+                                       dma-names = "rx", "tx";
                                };
                        };
                };
                        thermal-sensors = <&tsc 2>;
                        sustainable-power = <3874>;
 
+                       cooling-maps {
+                               map0 {
+                                       trip = <&target>;
+                                       cooling-device = <&a57_0 0 2>;
+                                       contribution = <1024>;
+                               };
+                               map1 {
+                                       trip = <&target>;
+                                       cooling-device = <&a53_0 0 2>;
+                                       contribution = <1024>;
+                               };
+                       };
                        trips {
                                target: trip-point1 {
                                        temperature = <100000>;
                                        type = "critical";
                                };
                        };
-                       cooling-maps {
-                               map0 {
-                                       trip = <&target>;
-                                       cooling-device = <&a57_0 0 2>;
-                                       contribution = <1024>;
-                               };
-                               map1 {
-                                       trip = <&target>;
-                                       cooling-device = <&a53_0 0 2>;
-                                       contribution = <1024>;
-                               };
-                       };
                };
        };
 
index 46a77ee..c99b1de 100644 (file)
                reg = <0x0 0x48000000 0x0 0x78000000>;
        };
 
+       reg_12p0v: regulator-12p0v {
+               compatible = "regulator-fixed";
+               regulator-name = "D12.0V";
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
        sound: sound {
                compatible = "simple-audio-card";
 
                simple-audio-card,bitclock-master = <&sndcpu>;
                simple-audio-card,frame-master = <&sndcpu>;
 
-               sndcpu: simple-audio-card,cpu {
-                       sound-dai = <&rcar_sound>;
-               };
-
                sndcodec: simple-audio-card,codec {
                        sound-dai = <&tda19988>;
                };
+
+               sndcpu: simple-audio-card,cpu {
+                       sound-dai = <&rcar_sound>;
+               };
        };
 
        vcc_sdhi0: regulator-vcc-sdhi0 {
                function = "du";
        };
 
-       i2c1_pins: i2c1 {
-               groups = "i2c1_b";
-               function = "i2c1";
-       };
-
        hscif2_pins: hscif2 {
                groups = "hscif2_data_a", "hscif2_ctrl_a";
                function = "hscif2";
        };
 
+       i2c1_pins: i2c1 {
+               groups = "i2c1_b";
+               function = "i2c1";
+       };
+
        scif2_pins: scif2 {
                groups = "scif2_data_a";
                function = "scif2";
                power-source = <1800>;
        };
 
-       sound_pins: sound {
-               groups = "ssi01239_ctrl", "ssi0_data";
-               function = "ssi";
-       };
-
        sound_clk_pins: sound_clk {
                groups = "audio_clkout1_a";
                function = "audio_clk";
        };
 
+       sound_pins: sound {
+               groups = "ssi01239_ctrl", "ssi0_data";
+               function = "ssi";
+       };
+
        usb30_pins: usb30 {
                groups = "usb30", "usb30_id";
                function = "usb30";
index e7b5bf2..a1c2de9 100644 (file)
                                 <&cpg CPG_CORE R8A774C0_CLK_CANFD>,
                                 <&can_clk>;
                        clock-names = "clkp1", "clkp2", "can_clk";
+                       assigned-clocks = <&cpg CPG_CORE R8A774C0_CLK_CANFD>;
+                       assigned-clock-rates = <40000000>;
                        power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
                        resets = <&cpg 916>;
                        status = "disabled";
                                 <&cpg CPG_CORE R8A774C0_CLK_CANFD>,
                                 <&can_clk>;
                        clock-names = "clkp1", "clkp2", "can_clk";
+                       assigned-clocks = <&cpg CPG_CORE R8A774C0_CLK_CANFD>;
+                       assigned-clock-rates = <40000000>;
                        power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
                        resets = <&cpg 915>;
                        status = "disabled";
                                      "ssi.1", "ssi.0";
                        status = "disabled";
 
+                       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 { };
+                       };
+
                        rcar_sound,dvc {
                                dvc0: dvc-0 {
                                        dmas = <&audma0 0xbc>;
                                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 { };
-                       };
-
                        rcar_sound,src {
                                src0: src-0 {
                                        interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
                        renesas,fcp = <&fcpvb0>;
                };
 
-               fcpvb0: fcp@fe96f000 {
-                       compatible = "renesas,fcpv";
-                       reg = <0 0xfe96f000 0 0x200>;
-                       clocks = <&cpg CPG_MOD 607>;
+               vspd0: vsp@fea20000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfea20000 0 0x7000>;
+                       interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 623>;
                        power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
-                       resets = <&cpg 607>;
-                       iommus = <&ipmmu_vp0 5>;
+                       resets = <&cpg 623>;
+                       renesas,fcp = <&fcpvd0>;
+               };
+
+               vspd1: vsp@fea28000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfea28000 0 0x7000>;
+                       interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 622>;
+                       power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+                       resets = <&cpg 622>;
+                       renesas,fcp = <&fcpvd1>;
                };
 
                vspi0: vsp@fe9a0000 {
                        renesas,fcp = <&fcpvi0>;
                };
 
-               fcpvi0: fcp@fe9af000 {
+               fcpvb0: fcp@fe96f000 {
                        compatible = "renesas,fcpv";
-                       reg = <0 0xfe9af000 0 0x200>;
-                       clocks = <&cpg CPG_MOD 611>;
-                       power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
-                       resets = <&cpg 611>;
-                       iommus = <&ipmmu_vp0 8>;
-               };
-
-               vspd0: vsp@fea20000 {
-                       compatible = "renesas,vsp2";
-                       reg = <0 0xfea20000 0 0x7000>;
-                       interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 623>;
+                       reg = <0 0xfe96f000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 607>;
                        power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
-                       resets = <&cpg 623>;
-                       renesas,fcp = <&fcpvd0>;
+                       resets = <&cpg 607>;
+                       iommus = <&ipmmu_vp0 5>;
                };
 
                fcpvd0: fcp@fea27000 {
                        iommus = <&ipmmu_vi0 8>;
                };
 
-               vspd1: vsp@fea28000 {
-                       compatible = "renesas,vsp2";
-                       reg = <0 0xfea28000 0 0x7000>;
-                       interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 622>;
-                       power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
-                       resets = <&cpg 622>;
-                       renesas,fcp = <&fcpvd1>;
-               };
-
                fcpvd1: fcp@fea2f000 {
                        compatible = "renesas,fcpv";
                        reg = <0 0xfea2f000 0 0x200>;
                        iommus = <&ipmmu_vi0 9>;
                };
 
+               fcpvi0: fcp@fe9af000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfe9af000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 611>;
+                       power-domains = <&sysc R8A774C0_PD_ALWAYS_ON>;
+                       resets = <&cpg 611>;
+                       iommus = <&ipmmu_vp0 8>;
+               };
+
                csi40: csi2@feaa0000 {
                        compatible = "renesas,r8a774c0-csi2";
                        reg = <0 0xfeaa0000 0 0x10000>;
 
                du: display@feb00000 {
                        compatible = "renesas,du-r8a774c0";
-                       reg = <0 0xfeb00000 0 0x80000>;
+                       reg = <0 0xfeb00000 0 0x40000>;
                        interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 724>,
                                 <&cpg CPG_MOD 723>;
                        clock-names = "du.0", "du.1";
-                       vsps = <&vspd0 0 &vspd1 0>;
+                       vsps = <&vspd0 0>, <&vspd1 0>;
                        status = "disabled";
 
                        ports {
                        resets = <&cpg 727>;
                        status = "disabled";
 
+                       renesas,companion = <&lvds1>;
+
                        ports {
                                #address-cells = <1>;
                                #size-cells = <0>;
                        polling-delay = <1000>;
                        thermal-sensors = <&thermal>;
 
+                       cooling-maps {
+                       };
+
                        trips {
                                cpu-crit {
                                        temperature = <120000>;
                                        type = "critical";
                                };
                        };
-
-                       cooling-maps {
-                       };
                };
        };
 
index c1a56ea..c729686 100644 (file)
        status = "okay";
 };
 
-&sound_card {
-       dais = <&rsnd_port0     /* ak4613 */
-               &rsnd_port1     /* HDMI0  */
-               &rsnd_port2>;   /* HDMI1  */
-};
-
 &hdmi0 {
        status = "okay";
 
        status = "okay";
 };
 
+&pfc {
+       usb2_pins: usb2 {
+               groups = "usb2";
+               function = "usb2";
+       };
+};
+
 &rcar_sound {
        ports {
                /* rsnd_port0 is on salvator-common */
        };
 };
 
-&pfc {
-       usb2_pins: usb2 {
-               groups = "usb2";
-               function = "usb2";
-       };
-};
-
 &sata {
        status = "okay";
 };
 
+&sound_card {
+       dais = <&rsnd_port0     /* ak4613 */
+               &rsnd_port1     /* HDMI0  */
+               &rsnd_port2>;   /* HDMI1  */
+};
+
 &usb2_phy2 {
        pinctrl-0 = <&usb2_pins>;
        pinctrl-names = "default";
index 40d10da..e4650ae 100644 (file)
@@ -7,22 +7,75 @@
 
 #include "r8a7795.dtsi"
 
-&soc {
-       xhci1: usb@ee040000 {
-               compatible = "renesas,xhci-r8a7795", "renesas,rcar-gen3-xhci";
-               reg = <0 0xee040000 0 0xc00>;
-               interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&cpg CPG_MOD 327>;
-               power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-               resets = <&cpg 327>;
-               status = "disabled";
-       };
+&audma0 {
+       iommus = <&ipmmu_mp1 0>, <&ipmmu_mp1 1>,
+              <&ipmmu_mp1 2>, <&ipmmu_mp1 3>,
+              <&ipmmu_mp1 4>, <&ipmmu_mp1 5>,
+              <&ipmmu_mp1 6>, <&ipmmu_mp1 7>,
+              <&ipmmu_mp1 8>, <&ipmmu_mp1 9>,
+              <&ipmmu_mp1 10>, <&ipmmu_mp1 11>,
+              <&ipmmu_mp1 12>, <&ipmmu_mp1 13>,
+              <&ipmmu_mp1 14>, <&ipmmu_mp1 15>;
+};
 
-       /delete-node/ mmu@febe0000;
-       /delete-node/ mmu@fe980000;
-       /delete-node/ mmu@fd950000;
-       /delete-node/ mmu@fd960000;
-       /delete-node/ mmu@fd970000;
+&audma1 {
+       iommus = <&ipmmu_mp1 16>, <&ipmmu_mp1 17>,
+              <&ipmmu_mp1 18>, <&ipmmu_mp1 19>,
+              <&ipmmu_mp1 20>, <&ipmmu_mp1 21>,
+              <&ipmmu_mp1 22>, <&ipmmu_mp1 23>,
+              <&ipmmu_mp1 24>, <&ipmmu_mp1 25>,
+              <&ipmmu_mp1 26>, <&ipmmu_mp1 27>,
+              <&ipmmu_mp1 28>, <&ipmmu_mp1 29>,
+              <&ipmmu_mp1 30>, <&ipmmu_mp1 31>;
+};
+
+&du {
+       vsps = <&vspd0 &vspd1 &vspd2 &vspd3>;
+};
+
+&fcpvb1 {
+       iommus = <&ipmmu_vp0 7>;
+};
+
+&fcpf1 {
+       iommus = <&ipmmu_vp0 1>;
+};
+
+&fcpvi1 {
+       iommus = <&ipmmu_vp0 9>;
+};
+
+&fcpvd2 {
+       iommus = <&ipmmu_vi0 10>;
+};
+
+&gpio1 {
+       gpio-ranges = <&pfc 0 32 28>;
+};
+
+&ipmmu_vi0 {
+       renesas,ipmmu-main = <&ipmmu_mm 11>;
+};
+
+&ipmmu_vp0 {
+       renesas,ipmmu-main = <&ipmmu_mm 12>;
+};
+
+&ipmmu_vc0 {
+       renesas,ipmmu-main = <&ipmmu_mm 9>;
+};
+
+&ipmmu_vc1 {
+       renesas,ipmmu-main = <&ipmmu_mm 10>;
+};
+
+&ipmmu_rt {
+       renesas,ipmmu-main = <&ipmmu_mm 7>;
+};
+
+&soc {
+       /delete-node/ dma-controller@e6460000;
+       /delete-node/ dma-controller@e6470000;
 
        ipmmu_mp1: mmu@ec680000 {
                compatible = "renesas,ipmmu-r8a7795";
                #iommu-cells = <1>;
        };
 
-       /delete-node/ usb-phy@ee0e0200;
-       /delete-node/ usb@ee0e0100;
-       /delete-node/ usb@ee0e0000;
+       /delete-node/ mmu@fd950000;
+       /delete-node/ mmu@fd960000;
+       /delete-node/ mmu@fd970000;
+       /delete-node/ mmu@febe0000;
+       /delete-node/ mmu@fe980000;
+
+       xhci1: usb@ee040000 {
+               compatible = "renesas,xhci-r8a7795", "renesas,rcar-gen3-xhci";
+               reg = <0 0xee040000 0 0xc00>;
+               interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cpg CPG_MOD 327>;
+               power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+               resets = <&cpg 327>;
+               status = "disabled";
+       };
+
        /delete-node/ usb@e659c000;
+       /delete-node/ usb@ee0e0000;
+       /delete-node/ usb@ee0e0100;
 
-       /delete-node/ dma-controller@e6460000;
-       /delete-node/ dma-controller@e6470000;
+       /delete-node/ usb-phy@ee0e0200;
+
+       fdp1@fe948000 {
+               compatible = "renesas,fdp1";
+               reg = <0 0xfe948000 0 0x2400>;
+               interrupts = <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cpg CPG_MOD 117>;
+               power-domains = <&sysc R8A7795_PD_A3VP>;
+               resets = <&cpg 117>;
+               renesas,fcp = <&fcpf2>;
+       };
 
        fcpf2: fcp@fe952000 {
                compatible = "renesas,fcpf";
                iommus = <&ipmmu_vp0 2>;
        };
 
-       vspi2: vsp@fe9c0000 {
-               compatible = "renesas,vsp2";
-               reg = <0 0xfe9c0000 0 0x8000>;
-               interrupts = <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&cpg CPG_MOD 629>;
-               power-domains = <&sysc R8A7795_PD_A3VP>;
-               resets = <&cpg 629>;
-
-               renesas,fcp = <&fcpvi2>;
+       fcpvd3: fcp@fea3f000 {
+               compatible = "renesas,fcpv";
+               reg = <0 0xfea3f000 0 0x200>;
+               clocks = <&cpg CPG_MOD 600>;
+               power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+               resets = <&cpg 600>;
+               iommus = <&ipmmu_vi0 11>;
        };
 
        fcpvi2: fcp@fe9cf000 {
                renesas,fcp = <&fcpvd3>;
        };
 
-       fcpvd3: fcp@fea3f000 {
-               compatible = "renesas,fcpv";
-               reg = <0 0xfea3f000 0 0x200>;
-               clocks = <&cpg CPG_MOD 600>;
-               power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-               resets = <&cpg 600>;
-               iommus = <&ipmmu_vi0 11>;
-       };
-
-       fdp1@fe948000 {
-               compatible = "renesas,fdp1";
-               reg = <0 0xfe948000 0 0x2400>;
-               interrupts = <GIC_SPI 264 IRQ_TYPE_LEVEL_HIGH>;
-               clocks = <&cpg CPG_MOD 117>;
+       vspi2: vsp@fe9c0000 {
+               compatible = "renesas,vsp2";
+               reg = <0 0xfe9c0000 0 0x8000>;
+               interrupts = <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cpg CPG_MOD 629>;
                power-domains = <&sysc R8A7795_PD_A3VP>;
-               resets = <&cpg 117>;
-               renesas,fcp = <&fcpf2>;
+               resets = <&cpg 629>;
+
+               renesas,fcp = <&fcpvi2>;
        };
 
        csi21: csi2@fea90000 {
        };
 };
 
-&gpio1 {
-       gpio-ranges = <&pfc 0 32 28>;
-};
-
-&ipmmu_vi0 {
-       renesas,ipmmu-main = <&ipmmu_mm 11>;
-};
-
-&ipmmu_vp0 {
-       renesas,ipmmu-main = <&ipmmu_mm 12>;
-};
-
-&ipmmu_vc0 {
-       renesas,ipmmu-main = <&ipmmu_mm 9>;
-};
-
-&ipmmu_vc1 {
-       renesas,ipmmu-main = <&ipmmu_mm 10>;
-};
-
-&ipmmu_rt {
-       renesas,ipmmu-main = <&ipmmu_mm 7>;
-};
-
-&audma0 {
-       iommus = <&ipmmu_mp1 0>, <&ipmmu_mp1 1>,
-              <&ipmmu_mp1 2>, <&ipmmu_mp1 3>,
-              <&ipmmu_mp1 4>, <&ipmmu_mp1 5>,
-              <&ipmmu_mp1 6>, <&ipmmu_mp1 7>,
-              <&ipmmu_mp1 8>, <&ipmmu_mp1 9>,
-              <&ipmmu_mp1 10>, <&ipmmu_mp1 11>,
-              <&ipmmu_mp1 12>, <&ipmmu_mp1 13>,
-              <&ipmmu_mp1 14>, <&ipmmu_mp1 15>;
-};
-
-&audma1 {
-       iommus = <&ipmmu_mp1 16>, <&ipmmu_mp1 17>,
-              <&ipmmu_mp1 18>, <&ipmmu_mp1 19>,
-              <&ipmmu_mp1 20>, <&ipmmu_mp1 21>,
-              <&ipmmu_mp1 22>, <&ipmmu_mp1 23>,
-              <&ipmmu_mp1 24>, <&ipmmu_mp1 25>,
-              <&ipmmu_mp1 26>, <&ipmmu_mp1 27>,
-              <&ipmmu_mp1 28>, <&ipmmu_mp1 29>,
-              <&ipmmu_mp1 30>, <&ipmmu_mp1 31>;
-};
-
-&fcpvb1 {
-       iommus = <&ipmmu_vp0 7>;
-};
-
-&fcpf1 {
-       iommus = <&ipmmu_vp0 1>;
-};
-
-&fcpvi1 {
-       iommus = <&ipmmu_vp0 9>;
-};
-
-&fcpvd2 {
-       iommus = <&ipmmu_vi0 10>;
-};
-
-&du {
-       vsps = <&vspd0 &vspd1 &vspd2 &vspd3>;
-};
-
 &vin0 {
        ports {
                port@1 {
index d2d48b3..72874f6 100644 (file)
        status = "okay";
 };
 
-&sound_card {
-       dais = <&rsnd_port0     /* ak4613 */
-               &rsnd_port1     /* HDMI0  */
-               &rsnd_port2>;   /* HDMI1  */
-};
-
 &hdmi0 {
        status = "okay";
 
        status = "okay";
 };
 
+&pfc {
+       usb2_pins: usb2 {
+               groups = "usb2";
+               function = "usb2";
+       };
+};
+
 &rcar_sound {
        ports {
                /* rsnd_port0 is on salvator-common */
        };
 };
 
-&pfc {
-       usb2_pins: usb2 {
-               groups = "usb2";
-               function = "usb2";
-       };
-};
-
 &sata {
        status = "okay";
 };
 
+&sound_card {
+       dais = <&rsnd_port0     /* ak4613 */
+               &rsnd_port1     /* HDMI0  */
+               &rsnd_port2>;   /* HDMI1  */
+};
+
 &usb2_phy2 {
        pinctrl-0 = <&usb2_pins>;
        pinctrl-names = "default";
index 42101fc..36667c8 100644 (file)
        status = "okay";
 };
 
-&hsusb3 {
-       dr_mode = "otg";
-       status = "okay";
-};
-
-&sound_card {
-       dais = <&rsnd_port0     /* ak4613 */
-               &rsnd_port1     /* HDMI0  */
-               &rsnd_port2>;   /* HDMI1  */
-};
-
 &hdmi0 {
        status = "okay";
 
        remote-endpoint = <&rcar_dw_hdmi1_out>;
 };
 
+&hsusb3 {
+       dr_mode = "otg";
+       status = "okay";
+};
+
 &ohci2 {
        status = "okay";
 };
        status = "okay";
 };
 
-&rcar_sound {
-       ports {
-               /* rsnd_port0 is on salvator-common */
-               rsnd_port1: port@1 {
-                       reg = <1>;
-                       rsnd_endpoint1: endpoint {
-                               remote-endpoint = <&dw_hdmi0_snd_in>;
-
-                               dai-format = "i2s";
-                               bitclock-master = <&rsnd_endpoint1>;
-                               frame-master = <&rsnd_endpoint1>;
-
-                               playback = <&ssi2>;
-                       };
-               };
-               rsnd_port2: port@2 {
-                       reg = <2>;
-                       rsnd_endpoint2: endpoint {
-                               remote-endpoint = <&dw_hdmi1_snd_in>;
-
-                               dai-format = "i2s";
-                               bitclock-master = <&rsnd_endpoint2>;
-                               frame-master = <&rsnd_endpoint2>;
-
-                               playback = <&ssi3>;
-                       };
-               };
-       };
-};
-
 &pca9654 {
        pcie_sata_switch {
                gpio-hog;
        };
 };
 
+&rcar_sound {
+       ports {
+               /* rsnd_port0 is on salvator-common */
+               rsnd_port1: port@1 {
+                       reg = <1>;
+                       rsnd_endpoint1: endpoint {
+                               remote-endpoint = <&dw_hdmi0_snd_in>;
+
+                               dai-format = "i2s";
+                               bitclock-master = <&rsnd_endpoint1>;
+                               frame-master = <&rsnd_endpoint1>;
+
+                               playback = <&ssi2>;
+                       };
+               };
+               rsnd_port2: port@2 {
+                       reg = <2>;
+                       rsnd_endpoint2: endpoint {
+                               remote-endpoint = <&dw_hdmi1_snd_in>;
+
+                               dai-format = "i2s";
+                               bitclock-master = <&rsnd_endpoint2>;
+                               frame-master = <&rsnd_endpoint2>;
+
+                               playback = <&ssi3>;
+                       };
+               };
+       };
+};
+
 /* SW12-7 must be set 'Off' (MD12 set to 1) which is not the default! */
 &sata {
        status = "okay";
 };
 
+&sound_card {
+       dais = <&rsnd_port0     /* ak4613 */
+               &rsnd_port1     /* HDMI0  */
+               &rsnd_port2>;   /* HDMI1  */
+};
+
 &usb2_phy2 {
        pinctrl-0 = <&usb2_pins>;
        pinctrl-names = "default";
index 1745ac4..95deff6 100644 (file)
                        resets = <&cpg 820>;
                };
 
+               vspbc: vsp@fe920000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfe920000 0 0x8000>;
+                       interrupts = <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 624>;
+                       power-domains = <&sysc R8A7795_PD_A3VP>;
+                       resets = <&cpg 624>;
+
+                       renesas,fcp = <&fcpvb1>;
+               };
+
+               vspbd: vsp@fe960000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfe960000 0 0x8000>;
+                       interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 626>;
+                       power-domains = <&sysc R8A7795_PD_A3VP>;
+                       resets = <&cpg 626>;
+
+                       renesas,fcp = <&fcpvb0>;
+               };
+
+               vspd0: vsp@fea20000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfea20000 0 0x5000>;
+                       interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 623>;
+                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+                       resets = <&cpg 623>;
+
+                       renesas,fcp = <&fcpvd0>;
+               };
+
+               vspd1: vsp@fea28000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfea28000 0 0x5000>;
+                       interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 622>;
+                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+                       resets = <&cpg 622>;
+
+                       renesas,fcp = <&fcpvd1>;
+               };
+
+               vspd2: vsp@fea30000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfea30000 0 0x5000>;
+                       interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 621>;
+                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+                       resets = <&cpg 621>;
+
+                       renesas,fcp = <&fcpvd2>;
+               };
+
+               vspi0: vsp@fe9a0000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfe9a0000 0 0x8000>;
+                       interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 631>;
+                       power-domains = <&sysc R8A7795_PD_A3VP>;
+                       resets = <&cpg 631>;
+
+                       renesas,fcp = <&fcpvi0>;
+               };
+
+               vspi1: vsp@fe9b0000 {
+                       compatible = "renesas,vsp2";
+                       reg = <0 0xfe9b0000 0 0x8000>;
+                       interrupts = <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 630>;
+                       power-domains = <&sysc R8A7795_PD_A3VP>;
+                       resets = <&cpg 630>;
+
+                       renesas,fcp = <&fcpvi1>;
+               };
+
                fdp1@fe940000 {
                        compatible = "renesas,fdp1";
                        reg = <0 0xfe940000 0 0x2400>;
                        iommus = <&ipmmu_vi1 10>;
                };
 
-               vspbd: vsp@fe960000 {
-                       compatible = "renesas,vsp2";
-                       reg = <0 0xfe960000 0 0x8000>;
-                       interrupts = <GIC_SPI 266 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 626>;
-                       power-domains = <&sysc R8A7795_PD_A3VP>;
-                       resets = <&cpg 626>;
-
-                       renesas,fcp = <&fcpvb0>;
-               };
-
-               vspbc: vsp@fe920000 {
-                       compatible = "renesas,vsp2";
-                       reg = <0 0xfe920000 0 0x8000>;
-                       interrupts = <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 624>;
-                       power-domains = <&sysc R8A7795_PD_A3VP>;
-                       resets = <&cpg 624>;
-
-                       renesas,fcp = <&fcpvb1>;
-               };
-
-               vspd0: vsp@fea20000 {
-                       compatible = "renesas,vsp2";
-                       reg = <0 0xfea20000 0 0x5000>;
-                       interrupts = <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 623>;
-                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-                       resets = <&cpg 623>;
-
-                       renesas,fcp = <&fcpvd0>;
-               };
-
-               vspd1: vsp@fea28000 {
-                       compatible = "renesas,vsp2";
-                       reg = <0 0xfea28000 0 0x5000>;
-                       interrupts = <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 622>;
-                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-                       resets = <&cpg 622>;
-
-                       renesas,fcp = <&fcpvd1>;
-               };
-
-               vspd2: vsp@fea30000 {
-                       compatible = "renesas,vsp2";
-                       reg = <0 0xfea30000 0 0x5000>;
-                       interrupts = <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 621>;
-                       power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
-                       resets = <&cpg 621>;
-
-                       renesas,fcp = <&fcpvd2>;
-               };
-
-               vspi0: vsp@fe9a0000 {
-                       compatible = "renesas,vsp2";
-                       reg = <0 0xfe9a0000 0 0x8000>;
-                       interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 631>;
-                       power-domains = <&sysc R8A7795_PD_A3VP>;
-                       resets = <&cpg 631>;
-
-                       renesas,fcp = <&fcpvi0>;
-               };
-
-               vspi1: vsp@fe9b0000 {
-                       compatible = "renesas,vsp2";
-                       reg = <0 0xfe9b0000 0 0x8000>;
-                       interrupts = <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 630>;
-                       power-domains = <&sysc R8A7795_PD_A3VP>;
-                       resets = <&cpg 630>;
-
-                       renesas,fcp = <&fcpvi1>;
-               };
-
                csi20: csi2@fea80000 {
                        compatible = "renesas,r8a7795-csi2";
                        reg = <0 0xfea80000 0 0x10000>;
                                 <&cpg CPG_MOD 722>,
                                 <&cpg CPG_MOD 721>;
                        clock-names = "du.0", "du.1", "du.2", "du.3";
-                       vsps = <&vspd0 0 &vspd1 0 &vspd2 0 &vspd0 1>;
+                       vsps = <&vspd0 0>, <&vspd1 0>, <&vspd2 0>, <&vspd0 1>;
                        status = "disabled";
 
                        ports {
index 2aefa53..de37e91 100644 (file)
                      "dclkin.0", "dclkin.1", "dclkin.2";
 };
 
-&sound_card {
-       dais = <&rsnd_port0     /* ak4613 */
-               &rsnd_port1>;   /* HDMI0  */
-};
-
 &hdmi0 {
        status = "okay";
 
@@ -81,3 +76,8 @@
                };
        };
 };
+
+&sound_card {
+       dais = <&rsnd_port0     /* ak4613 */
+               &rsnd_port1>;   /* HDMI0  */
+};
index d58ede1..a1cbfef 100644 (file)
                      "dclkin.0", "dclkin.1", "dclkin.2";
 };
 
-&sound_card {
-       dais = <&rsnd_port0     /* ak4613 */
-               &rsnd_port1>;   /* HDMI0  */
-};
-
 &hdmi0 {
        status = "okay";
 
@@ -81,3 +76,8 @@
                };
        };
 };
+
+&sound_card {
+       dais = <&rsnd_port0     /* ak4613 */
+               &rsnd_port1>;   /* HDMI0  */
+};
index 26df5b8..3dc9d73 100644 (file)
                                      "ssi.1", "ssi.0";
                        status = "disabled";
 
+                       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 { };
+                       };
+
                        rcar_sound,dvc {
                                dvc0: dvc-0 {
                                        dmas = <&audma1 0xbc>;
                                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 { };
-                       };
-
                        rcar_sound,src {
                                src0: src-0 {
                                        interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
                                };
                        };
 
+                       rcar_sound,ssi {
+                               ssi0: ssi-0 {
+                                       interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x01>, <&audma1 0x02>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi1: ssi-1 {
+                                       interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x03>, <&audma1 0x04>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi2: ssi-2 {
+                                       interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x05>, <&audma1 0x06>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi3: ssi-3 {
+                                       interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x07>, <&audma1 0x08>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi4: ssi-4 {
+                                       interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x09>, <&audma1 0x0a>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi5: ssi-5 {
+                                       interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x0b>, <&audma1 0x0c>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi6: ssi-6 {
+                                       interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x0d>, <&audma1 0x0e>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi7: ssi-7 {
+                                       interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x0f>, <&audma1 0x10>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi8: ssi-8 {
+                                       interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x11>, <&audma1 0x12>;
+                                       dma-names = "rx", "tx";
+                               };
+                               ssi9: ssi-9 {
+                                       interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
+                                       dmas = <&audma0 0x13>, <&audma1 0x14>;
+                                       dma-names = "rx", "tx";
+                               };
+                       };
+
                        rcar_sound,ssiu {
                                ssiu00: ssiu-0 {
                                        dmas = <&audma0 0x15>, <&audma1 0x16>;
                                        dma-names = "rx", "tx";
                                };
                        };
-
-                       rcar_sound,ssi {
-                               ssi0: ssi-0 {
-                                       interrupts = <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x01>, <&audma1 0x02>;
-                                       dma-names = "rx", "tx";
-                               };
-                               ssi1: ssi-1 {
-                                       interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x03>, <&audma1 0x04>;
-                                       dma-names = "rx", "tx";
-                               };
-                               ssi2: ssi-2 {
-                                       interrupts = <GIC_SPI 372 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x05>, <&audma1 0x06>;
-                                       dma-names = "rx", "tx";
-                               };
-                               ssi3: ssi-3 {
-                                       interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x07>, <&audma1 0x08>;
-                                       dma-names = "rx", "tx";
-                               };
-                               ssi4: ssi-4 {
-                                       interrupts = <GIC_SPI 374 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x09>, <&audma1 0x0a>;
-                                       dma-names = "rx", "tx";
-                               };
-                               ssi5: ssi-5 {
-                                       interrupts = <GIC_SPI 375 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x0b>, <&audma1 0x0c>;
-                                       dma-names = "rx", "tx";
-                               };
-                               ssi6: ssi-6 {
-                                       interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x0d>, <&audma1 0x0e>;
-                                       dma-names = "rx", "tx";
-                               };
-                               ssi7: ssi-7 {
-                                       interrupts = <GIC_SPI 377 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x0f>, <&audma1 0x10>;
-                                       dma-names = "rx", "tx";
-                               };
-                               ssi8: ssi-8 {
-                                       interrupts = <GIC_SPI 378 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x11>, <&audma1 0x12>;
-                                       dma-names = "rx", "tx";
-                               };
-                               ssi9: ssi-9 {
-                                       interrupts = <GIC_SPI 379 IRQ_TYPE_LEVEL_HIGH>;
-                                       dmas = <&audma0 0x13>, <&audma1 0x14>;
-                                       dma-names = "rx", "tx";
-                               };
-                       };
                };
 
                audma0: dma-controller@ec700000 {
                        thermal-sensors = <&tsc 2>;
                        sustainable-power = <3874>;
 
+                       cooling-maps {
+                               map0 {
+                                       trip = <&target>;
+                                       cooling-device = <&a57_0 2 4>;
+                                       contribution = <1024>;
+                               };
+                               map1 {
+                                       trip = <&target>;
+                                       cooling-device = <&a53_0 0 2>;
+                                       contribution = <1024>;
+                               };
+                       };
                        trips {
                                target: trip-point1 {
                                        temperature = <100000>;
                                        type = "critical";
                                };
                        };
-                       cooling-maps {
-                               map0 {
-                                       trip = <&target>;
-                                       cooling-device = <&a57_0 2 4>;
-                                       contribution = <1024>;
-                               };
-                               map1 {
-                                       trip = <&target>;
-                                       cooling-device = <&a53_0 0 2>;
-                                       contribution = <1024>;
-                               };
-                       };
                };
        };
 
index 340a3c7..660a024 100644 (file)
                                remote-endpoint = <&hdmi0_con>;
                        };
                };
+               port@2 {
+                       reg = <2>;
+                       dw_hdmi0_snd_in: endpoint {
+                               remote-endpoint = <&rsnd_endpoint1>;
+                       };
+               };
        };
 };
 
 &hdmi0_con {
        remote-endpoint = <&rcar_dw_hdmi0_out>;
 };
+
+&rcar_sound {
+       ports {
+               rsnd_port1: port@1 {
+                       reg = <1>;
+                       rsnd_endpoint1: endpoint {
+                               remote-endpoint = <&dw_hdmi0_snd_in>;
+
+                               dai-format = "i2s";
+                               bitclock-master = <&rsnd_endpoint1>;
+                               frame-master = <&rsnd_endpoint1>;
+
+                               playback = <&ssi2>;
+                       };
+               };
+       };
+};
+
+&sound_card {
+       dais = <&rsnd_port0     /* ak4613 */
+               &rsnd_port1>;   /* HDMI0  */
+};
index f03a5e9..5cef646 100644 (file)
                                remote-endpoint = <&hdmi0_con>;
                        };
                };
+               port@2 {
+                       reg = <2>;
+                       dw_hdmi0_snd_in: endpoint {
+                               remote-endpoint = <&rsnd_endpoint1>;
+                       };
+               };
        };
 };
 
        };
 };
 
+&rcar_sound {
+       ports {
+               rsnd_port1: port@1 {
+                       reg = <1>;
+                       rsnd_endpoint1: endpoint {
+                               remote-endpoint = <&dw_hdmi0_snd_in>;
+
+                               dai-format = "i2s";
+                               bitclock-master = <&rsnd_endpoint1>;
+                               frame-master = <&rsnd_endpoint1>;
+
+                               playback = <&ssi2>;
+                       };
+               };
+       };
+};
+
 /* SW12-7 must be set 'Off' (MD12 set to 1) which is not the default! */
 &sata {
        status = "okay";
 };
+
+&sound_card {
+       dais = <&rsnd_port0     /* ak4613 */
+               &rsnd_port1>;   /* HDMI0  */
+};
index 131f895..4ae1632 100644 (file)
                        renesas,fcp = <&fcpvb0>;
                };
 
-               fcpvb0: fcp@fe96f000 {
-                       compatible = "renesas,fcpv";
-                       reg = <0 0xfe96f000 0 0x200>;
-                       clocks = <&cpg CPG_MOD 607>;
-                       power-domains = <&sysc R8A77965_PD_A3VP>;
-                       resets = <&cpg 607>;
-               };
-
                vspi0: vsp@fe9a0000 {
                        compatible = "renesas,vsp2";
                        reg = <0 0xfe9a0000 0 0x8000>;
                        renesas,fcp = <&fcpvi0>;
                };
 
-               fcpvi0: fcp@fe9af000 {
-                       compatible = "renesas,fcpv";
-                       reg = <0 0xfe9af000 0 0x200>;
-                       clocks = <&cpg CPG_MOD 611>;
-                       power-domains = <&sysc R8A77965_PD_A3VP>;
-                       resets = <&cpg 611>;
-               };
-
                vspd0: vsp@fea20000 {
                        compatible = "renesas,vsp2";
                        reg = <0 0xfea20000 0 0x5000>;
                        renesas,fcp = <&fcpvd0>;
                };
 
-               fcpvd0: fcp@fea27000 {
-                       compatible = "renesas,fcpv";
-                       reg = <0 0xfea27000 0 0x200>;
-                       clocks = <&cpg CPG_MOD 603>;
-                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
-                       resets = <&cpg 603>;
-               };
-
                vspd1: vsp@fea28000 {
                        compatible = "renesas,vsp2";
                        reg = <0 0xfea28000 0 0x5000>;
                        renesas,fcp = <&fcpvd1>;
                };
 
+               fcpvb0: fcp@fe96f000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfe96f000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 607>;
+                       power-domains = <&sysc R8A77965_PD_A3VP>;
+                       resets = <&cpg 607>;
+               };
+
+               fcpvd0: fcp@fea27000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfea27000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 603>;
+                       power-domains = <&sysc R8A77965_PD_ALWAYS_ON>;
+                       resets = <&cpg 603>;
+               };
+
                fcpvd1: fcp@fea2f000 {
                        compatible = "renesas,fcpv";
                        reg = <0 0xfea2f000 0 0x200>;
                        resets = <&cpg 602>;
                };
 
+               fcpvi0: fcp@fe9af000 {
+                       compatible = "renesas,fcpv";
+                       reg = <0 0xfe9af000 0 0x200>;
+                       clocks = <&cpg CPG_MOD 611>;
+                       power-domains = <&sysc R8A77965_PD_A3VP>;
+                       resets = <&cpg 611>;
+               };
+
                csi20: csi2@fea80000 {
                        compatible = "renesas,r8a77965-csi2";
                        reg = <0 0xfea80000 0 0x10000>;
                        clock-names = "du.0", "du.1", "du.3";
                        status = "disabled";
 
-                       vsps = <&vspd0 0 &vspd1 0 &vspd0 1>;
+                       vsps = <&vspd0 0>, <&vspd1 0>, <&vspd0 1>;
 
                        ports {
                                #address-cells = <1>;
index 233f26f..2afb91e 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
-       memory@48000000 {
-               device_type = "memory";
-               /* first 128MB is reserved for secure area. */
-               reg = <0x0 0x48000000 0x0 0x38000000>;
+       d3p3: regulator-fixed {
+               compatible = "regulator-fixed";
+               regulator-name = "fixed-3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
        };
 
        hdmi-out {
                };
        };
 
-       d3p3: regulator-fixed {
-               compatible = "regulator-fixed";
-               regulator-name = "fixed-3.3V";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               regulator-boot-on;
-               regulator-always-on;
-       };
-
        lvds-decoder {
                compatible = "thine,thc63lvd1024";
 
                        };
                };
        };
+
+       memory@48000000 {
+               device_type = "memory";
+               /* first 128MB is reserved for secure area. */
+               reg = <0x0 0x48000000 0x0 0x38000000>;
+       };
 };
 
 &avb {
        };
 };
 
+&du {
+       status = "okay";
+};
+
 &extal_clk {
        clock-frequency = <16666666>;
 };
        };
 };
 
+&lvds0 {
+       status = "okay";
+
+       ports {
+               port@1 {
+                       lvds0_out: endpoint {
+                               remote-endpoint = <&thc63lvd1024_in>;
+                       };
+               };
+       };
+};
+
 &pfc {
        avb_pins: avb0 {
                groups = "avb0_mdio", "avb0_rgmii", "avb0_txcrefclk";
 
        status = "okay";
 };
-
-&du {
-       status = "okay";
-};
-
-&lvds0 {
-       status = "okay";
-
-       ports {
-               port@1 {
-                       lvds0_out: endpoint {
-                               remote-endpoint = <&thc63lvd1024_in>;
-                       };
-               };
-       };
-};
index 15cc9fe..d7c7b91 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
+       hdmi-out {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con: endpoint {
+                               remote-endpoint = <&adv7511_out>;
+                       };
+               };
+       };
+
+       lvds-decoder {
+               compatible = "thine,thc63lvd1024";
+               vcc-supply = <&vcc_d3_3v>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               thc63lvd1024_in: endpoint {
+                                       remote-endpoint = <&lvds0_out>;
+                               };
+                       };
+
+                       port@2 {
+                               reg = <2>;
+                               thc63lvd1024_out: endpoint {
+                                       remote-endpoint = <&adv7511_in>;
+                               };
+                       };
+               };
+       };
+
        memory@48000000 {
                device_type = "memory";
                /* first 128MB is reserved for secure area. */
                regulator-boot-on;
                regulator-always-on;
        };
-
-       lvds-decoder {
-               compatible = "thine,thc63lvd1024";
-               vcc-supply = <&vcc_d3_3v>;
-
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       port@0 {
-                               reg = <0>;
-                               thc63lvd1024_in: endpoint {
-                                       remote-endpoint = <&lvds0_out>;
-                               };
-                       };
-
-                       port@2 {
-                               reg = <2>;
-                               thc63lvd1024_out: endpoint {
-                                       remote-endpoint = <&adv7511_in>;
-                               };
-                       };
-               };
-       };
-
-       hdmi-out {
-               compatible = "hdmi-connector";
-               type = "a";
-
-               port {
-                       hdmi_con: endpoint {
-                               remote-endpoint = <&adv7511_out>;
-                       };
-               };
-       };
 };
 
 &avb {
        clock-frequency = <32768>;
 };
 
-&pfc {
-       avb_pins: avb0 {
-               groups = "avb0_mdio", "avb0_rgmii", "avb0_txcrefclk";
-               function = "avb0";
-       };
-
-       i2c0_pins: i2c0 {
-               groups = "i2c0";
-               function = "i2c0";
-       };
-
-       mmc_pins: mmc_3_3v {
-               groups = "mmc_data8", "mmc_ctrl";
-               function = "mmc";
-               power-source = <3300>;
-       };
-
-       scif0_pins: scif0 {
-               groups = "scif0_data";
-               function = "scif0";
-       };
-};
-
 &i2c0 {
        pinctrl-0 = <&i2c0_pins>;
        pinctrl-names = "default";
        status = "okay";
 };
 
+&pfc {
+       avb_pins: avb0 {
+               groups = "avb0_mdio", "avb0_rgmii", "avb0_txcrefclk";
+               function = "avb0";
+       };
+
+       i2c0_pins: i2c0 {
+               groups = "i2c0";
+               function = "i2c0";
+       };
+
+       mmc_pins: mmc_3_3v {
+               groups = "mmc_data8", "mmc_ctrl";
+               function = "mmc";
+               power-source = <3300>;
+       };
+
+       scif0_pins: scif0 {
+               groups = "scif0_data";
+               function = "scif0";
+       };
+};
+
 &scif0 {
        pinctrl-0 = <&scif0_pins>;
        pinctrl-names = "default";
index 5b6164d..0cd3b37 100644 (file)
                        polling-delay = <1000>;
                        thermal-sensors = <&thermal>;
 
+                       cooling-maps {
+                       };
+
                        trips {
                                cpu-crit {
                                        temperature = <120000>;
                                        type = "critical";
                                };
                        };
-
-                       cooling-maps {
-                       };
                };
        };
 
index 5a7012b..3dde028 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
-       memory@48000000 {
-               device_type = "memory";
-               /* first 128MB is reserved for secure area. */
-               reg = <0 0x48000000 0 0x78000000>;
-       };
-
-       d3_3v: regulator-0 {
-               compatible = "regulator-fixed";
-               regulator-name = "D3.3V";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-               regulator-boot-on;
-               regulator-always-on;
-       };
-
-       vddq_vin01: regulator-1 {
+       d1_8v: regulator-2 {
                compatible = "regulator-fixed";
-               regulator-name = "VDDQ_VIN01";
+               regulator-name = "D1.8V";
                regulator-min-microvolt = <1800000>;
                regulator-max-microvolt = <1800000>;
                regulator-boot-on;
                regulator-always-on;
        };
 
-       d1_8v: regulator-2 {
+       d3_3v: regulator-0 {
                compatible = "regulator-fixed";
-               regulator-name = "D1.8V";
-               regulator-min-microvolt = <1800000>;
-               regulator-max-microvolt = <1800000>;
+               regulator-name = "D3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
                regulator-boot-on;
                regulator-always-on;
        };
                };
        };
 
+       memory@48000000 {
+               device_type = "memory";
+               /* first 128MB is reserved for secure area. */
+               reg = <0 0x48000000 0 0x78000000>;
+       };
+
+       vddq_vin01: regulator-1 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDQ_VIN01";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
        x1_clk: x1-clock {
                compatible = "fixed-clock";
                #clock-cells = <0>;
index dd14a41..adbfd8f 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
-       memory@48000000 {
-               device_type = "memory";
-               /* first 128MB is reserved for secure area. */
-               reg = <0 0x48000000 0 0x78000000>;
-       };
-
        hdmi-out {
                compatible = "hdmi-connector";
                type = "a";
                };
        };
 
+       memory@48000000 {
+               device_type = "memory";
+               /* first 128MB is reserved for secure area. */
+               reg = <0 0x48000000 0 0x78000000>;
+       };
+
        osc1_clk: osc1-clock {
                compatible = "fixed-clock";
                #clock-cells = <0>;
index a901a34..461a47e 100644 (file)
                        #iommu-cells = <1>;
                };
 
-               ipmmu_vc0: mmu@fe6b0000 {
+               ipmmu_vc0: mmu@fe990000 {
                        compatible = "renesas,ipmmu-r8a77980";
-                       reg = <0 0xfe6b0000 0 0x1000>;
+                       reg = <0 0xfe990000 0 0x1000>;
                        renesas,ipmmu-main = <&ipmmu_mm 12>;
                        power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
                        #iommu-cells = <1>;
index 83fc13a..b38f9d4 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
-       memory@48000000 {
-               device_type = "memory";
-               /* first 128MB is reserved for secure area. */
-               reg = <0x0 0x48000000 0x0 0x38000000>;
-       };
-
        audio_clkout: audio-clkout {
                /*
                 * This is same as <&rcar_sound 0>
                };
        };
 
-       vga {
-               compatible = "vga-connector";
-
-               port {
-                       vga_in: endpoint {
-                               remote-endpoint = <&adv7123_out>;
-                       };
-               };
-       };
-
-       vga-encoder {
-               compatible = "adi,adv7123";
-
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       port@0 {
-                               reg = <0>;
-                               adv7123_in: endpoint {
-                                       remote-endpoint = <&du_out_rgb>;
-                               };
-                       };
-                       port@1 {
-                               reg = <1>;
-                               adv7123_out: endpoint {
-                                       remote-endpoint = <&vga_in>;
-                               };
-                       };
-               };
+       memory@48000000 {
+               device_type = "memory";
+               /* first 128MB is reserved for secure area. */
+               reg = <0x0 0x48000000 0x0 0x38000000>;
        };
 
        reg_1p8v: regulator0 {
                regulator-always-on;
        };
 
-       vbus0_usb2: regulator-vbus0-usb2 {
+       reg_12p0v: regulator2 {
                compatible = "regulator-fixed";
-
-               regulator-name = "USB20_VBUS_CN";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-
-               gpio = <&gpio6 4 GPIO_ACTIVE_HIGH>;
-               enable-active-high;
+               regulator-name = "D12.0V";
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+               regulator-boot-on;
+               regulator-always-on;
        };
 
        rsnd_ak4613: sound {
                simple-audio-card,bitclock-master = <&sndcpu>;
                simple-audio-card,frame-master = <&sndcpu>;
 
-               sndcpu: simple-audio-card,cpu {
-                       sound-dai = <&rcar_sound>;
-               };
-
                sndcodec: simple-audio-card,codec {
                        sound-dai = <&ak4613>;
                };
-       };
 
-       x12_clk: x12 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <24576000>;
+               sndcpu: simple-audio-card,cpu {
+                       sound-dai = <&rcar_sound>;
+               };
        };
 
-       reg_12p0v: regulator2 {
+       vbus0_usb2: regulator-vbus0-usb2 {
                compatible = "regulator-fixed";
-               regulator-name = "D12.0V";
-               regulator-min-microvolt = <12000000>;
-               regulator-max-microvolt = <12000000>;
-               regulator-boot-on;
-               regulator-always-on;
-       };
 
-       x13_clk: x13 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <74250000>;
+               regulator-name = "USB20_VBUS_CN";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+
+               gpio = <&gpio6 4 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
        };
 
        vcc_sdhi0: regulator-vcc-sdhi0 {
                states = <3300000 1
                          1800000 0>;
        };
+
+       vga {
+               compatible = "vga-connector";
+
+               port {
+                       vga_in: endpoint {
+                               remote-endpoint = <&adv7123_out>;
+                       };
+               };
+       };
+
+       vga-encoder {
+               compatible = "adi,adv7123";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               adv7123_in: endpoint {
+                                       remote-endpoint = <&du_out_rgb>;
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               adv7123_out: endpoint {
+                                       remote-endpoint = <&vga_in>;
+                               };
+                       };
+               };
+       };
+
+       x12_clk: x12 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <24576000>;
+       };
+
+       x13_clk: x13 {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <74250000>;
+       };
 };
 
 &audio_clk_a {
                interrupt-parent = <&gpio2>;
                interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
                reset-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>;
+               /*
+                * TX clock internal delay mode is required for reliable
+                * 1Gbps communication using the KSZ9031RNX phy present on
+                * the Ebisu board, however, TX clock internal delay mode
+                * isn't supported on r8a77990.  Thus, limit speed to
+                * 100Mbps for reliable communication.
+                */
+               max-speed = <100>;
        };
 };
 
                function = "pwm5";
        };
 
+       scif2_pins: scif2 {
+               groups = "scif2_data_a";
+               function = "scif2";
+       };
+
        sdhi0_pins: sd0 {
                groups = "sdhi0_data4", "sdhi0_ctrl";
                function = "sdhi0";
                power-source = <1800>;
        };
 
-       sound_pins: sound {
-               groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data";
-               function = "ssi";
-       };
-
        sound_clk_pins: sound_clk {
                groups = "audio_clk_a", "audio_clk_b_a", "audio_clk_c_a",
                         "audio_clkout_a", "audio_clkout1_a";
                function = "audio_clk";
        };
 
-       scif2_pins: scif2 {
-               groups = "scif2_data_a";
-               function = "scif2";
+       sound_pins: sound {
+               groups = "ssi01239_ctrl", "ssi0_data", "ssi1_data";
+               function = "ssi";
        };
 
        usb0_pins: usb {
        status = "okay";
 };
 
-&ssi1 {
-       shared-pin;
-};
-
-&usb2_phy0 {
-       pinctrl-0 = <&usb0_pins>;
-       pinctrl-names = "default";
-
-       vbus-supply = <&vbus0_usb2>;
-       status = "okay";
-};
-
-&usb3_peri0 {
-       companion = <&xhci0>;
-       status = "okay";
-};
-
-&vin4 {
-       status = "okay";
-};
-
-&vin5 {
-       status = "okay";
-};
-
-&xhci0 {
-       pinctrl-0 = <&usb30_pins>;
-       pinctrl-names = "default";
-
-       status = "okay";
-};
-
 &sdhi0 {
        pinctrl-0 = <&sdhi0_pins>;
        pinctrl-1 = <&sdhi0_pins_uhs>;
        non-removable;
        status = "okay";
 };
+
+&ssi1 {
+       shared-pin;
+};
+
+&usb2_phy0 {
+       pinctrl-0 = <&usb0_pins>;
+       pinctrl-names = "default";
+
+       vbus-supply = <&vbus0_usb2>;
+       status = "okay";
+};
+
+&usb3_peri0 {
+       companion = <&xhci0>;
+       status = "okay";
+};
+
+&vin4 {
+       status = "okay";
+};
+
+&vin5 {
+       status = "okay";
+};
+
+&xhci0 {
+       pinctrl-0 = <&usb30_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
index b431866..455954c 100644 (file)
                                      "ssi.1", "ssi.0";
                        status = "disabled";
 
+                       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 { };
+                       };
+
                        rcar_sound,dvc {
                                dvc0: dvc-0 {
                                        dmas = <&audma0 0xbc>;
                                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 { };
-                       };
-
                        rcar_sound,src {
                                src0: src-0 {
                                        interrupts = <GIC_SPI 352 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 724>,
                                 <&cpg CPG_MOD 723>;
                        clock-names = "du.0", "du.1";
-                       vsps = <&vspd0 0 &vspd1 0>;
+                       resets = <&cpg 724>;
+                       reset-names = "du.0";
+                       vsps = <&vspd0 0>, <&vspd1 0>;
                        status = "disabled";
 
                        ports {
                        thermal-sensors = <&thermal 0>;
                        sustainable-power = <717>;
 
-                       trips {
-                               target: trip-point1 {
-                                       temperature = <100000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
+                       cooling-maps {
+                               map0 {
+                                       trip = <&target>;
+                                       cooling-device = <&a53_0 0 2>;
+                                       contribution = <1024>;
                                };
+                       };
 
+                       trips {
                                sensor1_crit: sensor1-crit {
                                        temperature = <120000>;
                                        hysteresis = <2000>;
                                        type = "critical";
                                };
-                       };
 
-                       cooling-maps {
-                               map0 {
-                                       trip = <&target>;
-                                       cooling-device = <&a53_0 0 2>;
-                                       contribution = <1024>;
+                               target: trip-point1 {
+                                       temperature = <100000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
                                };
                        };
                };
index 0711170..67634cb 100644 (file)
                ethernet0 = &avb;
        };
 
-       chosen {
-               bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
-               stdout-path = "serial0:115200n8";
-       };
-
        backlight: backlight {
                compatible = "pwm-backlight";
                pwms = <&pwm1 0 50000>;
                enable-gpios = <&gpio4 0 GPIO_ACTIVE_HIGH>;
        };
 
+       chosen {
+               bootargs = "ignore_loglevel rw root=/dev/nfs ip=on";
+               stdout-path = "serial0:115200n8";
+       };
+
        composite-in {
                compatible = "composite-video-connector";
 
@@ -97,7 +97,7 @@
                reg = <0x0 0x48000000 0x0 0x18000000>;
        };
 
-       reg_1p8v: regulator0 {
+       reg_1p8v: regulator-1p8v {
                compatible = "regulator-fixed";
                regulator-name = "fixed-1.8V";
                regulator-min-microvolt = <1800000>;
                regulator-always-on;
        };
 
-       reg_3p3v: regulator1 {
+       reg_3p3v: regulator-3p3v {
                compatible = "regulator-fixed";
                regulator-name = "fixed-3.3V";
                regulator-min-microvolt = <3300000>;
                regulator-always-on;
        };
 
-       reg_12p0v: regulator1 {
+       reg_12p0v: regulator-12p0v {
                compatible = "regulator-fixed";
                regulator-name = "D12.0V";
                regulator-min-microvolt = <12000000>;
                reg = <0>;
                interrupt-parent = <&gpio5>;
                interrupts = <19 IRQ_TYPE_LEVEL_LOW>;
+               /*
+                * TX clock internal delay mode is required for reliable
+                * 1Gbps communication using the KSZ9031RNX phy present on
+                * the Draak board, however, TX clock internal delay mode
+                * isn't supported on r8a77995.  Thus, limit speed to
+                * 100Mbps for reliable communication.
+                */
+               max-speed = <100>;
        };
 };
 
index 0a344eb..183fef8 100644 (file)
                        resets = <&cpg 407>;
                };
 
-               hscif0: serial@e6540000 {
-                       compatible = "renesas,hscif-r8a77995",
-                                    "renesas,rcar-gen3-hscif",
-                                    "renesas,hscif";
-                       reg = <0 0xe6540000 0 0x60>;
-                       interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 520>,
-                                <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
-                                <&scif_clk>;
-                       clock-names = "fck", "brg_int", "scif_clk";
-                       dmas = <&dmac1 0x31>, <&dmac1 0x30>,
-                              <&dmac2 0x31>, <&dmac2 0x30>;
-                       dma-names = "tx", "rx", "tx", "rx";
-                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-                       resets = <&cpg 520>;
-                       status = "disabled";
-               };
-
-               hscif3: serial@e66a0000 {
-                       compatible = "renesas,hscif-r8a77995",
-                                    "renesas,rcar-gen3-hscif",
-                                    "renesas,hscif";
-                       reg = <0 0xe66a0000 0 0x60>;
-                       interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&cpg CPG_MOD 517>,
-                                <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
-                                <&scif_clk>;
-                       clock-names = "fck", "brg_int", "scif_clk";
-                       dmas = <&dmac0 0x37>, <&dmac0 0x36>;
-                       dma-names = "tx", "rx";
-                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
-                       resets = <&cpg 517>;
-                       status = "disabled";
-               };
-
                i2c0: i2c@e6500000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                };
 
+               hscif0: serial@e6540000 {
+                       compatible = "renesas,hscif-r8a77995",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe6540000 0 0x60>;
+                       interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 520>,
+                                <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac1 0x31>, <&dmac1 0x30>,
+                              <&dmac2 0x31>, <&dmac2 0x30>;
+                       dma-names = "tx", "rx", "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 520>;
+                       status = "disabled";
+               };
+
+               hscif3: serial@e66a0000 {
+                       compatible = "renesas,hscif-r8a77995",
+                                    "renesas,rcar-gen3-hscif",
+                                    "renesas,hscif";
+                       reg = <0 0xe66a0000 0 0x60>;
+                       interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 517>,
+                                <&cpg CPG_CORE R8A77995_CLK_S3D1C>,
+                                <&scif_clk>;
+                       clock-names = "fck", "brg_int", "scif_clk";
+                       dmas = <&dmac0 0x37>, <&dmac0 0x36>;
+                       dma-names = "tx", "rx";
+                       power-domains = <&sysc R8A77995_PD_ALWAYS_ON>;
+                       resets = <&cpg 517>;
+                       status = "disabled";
+               };
+
                hsusb: usb@e6590000 {
                        compatible = "renesas,usbhs-r8a77995",
                                     "renesas,rcar-gen3-usbhs";
 
                du: display@feb00000 {
                        compatible = "renesas,du-r8a77995";
-                       reg = <0 0xfeb00000 0 0x80000>;
+                       reg = <0 0xfeb00000 0 0x40000>;
                        interrupts = <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 724>,
                                 <&cpg CPG_MOD 723>;
                        clock-names = "du.0", "du.1";
-                       vsps = <&vspd0 0 &vspd1 0>;
+                       resets = <&cpg 724>;
+                       reset-names = "du.0";
+                       vsps = <&vspd0 0>, <&vspd1 0>;
                        status = "disabled";
 
                        ports {
                        polling-delay = <1000>;
                        thermal-sensors = <&thermal>;
 
+                       cooling-maps {
+                       };
+
                        trips {
                                cpu-crit {
                                        temperature = <120000>;
                                        type = "critical";
                                };
                        };
-
-                       cooling-maps {
-                       };
                };
        };
 
index 5c2c847..21e0105 100644 (file)
                };
        };
 
+       hdmi0-out {
+               compatible = "hdmi-connector";
+               label = "HDMI0 OUT";
+               type = "a";
+
+               port {
+                       hdmi0_con: endpoint {
+                       };
+               };
+       };
+
+       hdmi1-out {
+               compatible = "hdmi-connector";
+               label = "HDMI1 OUT";
+               type = "a";
+
+               port {
+                       hdmi1_con: endpoint {
+                       };
+               };
+       };
+
        keys {
                compatible = "gpio-keys";
 
                          1800000 0>;
        };
 
-       hdmi0-out {
-               compatible = "hdmi-connector";
-               label = "HDMI0 OUT";
-               type = "a";
-
-               port {
-                       hdmi0_con: endpoint {
-                       };
-               };
-       };
-
-       hdmi1-out {
-               compatible = "hdmi-connector";
-               label = "HDMI1 OUT";
-               type = "a";
-
-               port {
-                       hdmi1_con: endpoint {
-                       };
-               };
-       };
-
        vga {
                compatible = "vga-connector";
 
                #gpio-cells = <2>;
        };
 
-       csa_vdd: adc@7c {
-               compatible = "maxim,max9611";
-               reg = <0x7c>;
-
-               shunt-resistor-micro-ohms = <5000>;
-       };
-
-       csa_dvfs: adc@7f {
-               compatible = "maxim,max9611";
-               reg = <0x7f>;
-
-               shunt-resistor-micro-ohms = <5000>;
-       };
-
        video-receiver@70 {
                compatible = "adi,adv7482";
                reg = <0x70 0x71 0x72 0x73 0x74 0x75
                        };
                };
        };
+
+       csa_vdd: adc@7c {
+               compatible = "maxim,max9611";
+               reg = <0x7c>;
+
+               shunt-resistor-micro-ohms = <5000>;
+       };
+
+       csa_dvfs: adc@7f {
+               compatible = "maxim,max9611";
+               reg = <0x7f>;
+
+               shunt-resistor-micro-ohms = <5000>;
+       };
 };
 
 &i2c_dvfs {
index 27851a7..2021777 100644 (file)
 };
 
 &i2c2 {
+       i2cswitch2: i2c-switch@71 {
+               compatible = "nxp,pca9548";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x71>;
+               reset-gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
+
+               /* Audio_SDA, Audio_SCL */
+               i2c@7 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <7>;
+
+                       pcm3168a: audio-codec@44 {
+                               #sound-dai-cells = <0>;
+                               compatible = "ti,pcm3168a";
+                               reg = <0x44>;
+                               clocks = <&clksndsel>;
+                               clock-names = "scki";
+
+                               VDD1-supply     = <&snd_3p3v>;
+                               VDD2-supply     = <&snd_3p3v>;
+                               VCCAD1-supply   = <&snd_vcc5v>;
+                               VCCAD2-supply   = <&snd_vcc5v>;
+                               VCCDA1-supply   = <&snd_vcc5v>;
+                               VCCDA2-supply   = <&snd_vcc5v>;
+
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       mclk-fs = <512>;
+                                       port@0 {
+                                               reg = <0>;
+                                               pcm3168a_endpoint_p: endpoint {
+                                                       remote-endpoint = <&rsnd_for_pcm3168a_play>;
+                                                       clocks = <&clksndsel>;
+                                               };
+                                       };
+                                       port@1 {
+                                               reg = <1>;
+                                               pcm3168a_endpoint_c: endpoint {
+                                                       remote-endpoint = <&rsnd_for_pcm3168a_capture>;
+                                                       clocks = <&clksndsel>;
+                                               };
+                                       };
+                               };
+                       };
+               };
+       };
+
        /* U11 */
        gpio_exp_74: gpio@74 {
                compatible = "ti,tca9539";
                        line-name = "Audio_Out_OFF";
                };
 
-               sd-wifi-mux {
-                       gpio-hog;
-                       gpios = <5 GPIO_ACTIVE_HIGH>;
-                       output-low;     /* Connect WL1837 */
-                       line-name = "SD WiFi mux";
-               };
-
                hub_pwen {
                        gpio-hog;
                        gpios = <6 GPIO_ACTIVE_HIGH>;
                        line-name = "HUB rst";
                };
 
+               otg_extlpn {
+                       gpio-hog;
+                       gpios = <9 GPIO_ACTIVE_HIGH>;
+                       output-high;
+                       line-name = "OTG EXTLPn";
+               };
+
                otg_offvbusn {
                        gpio-hog;
                        gpios = <8 GPIO_ACTIVE_HIGH>;
                        line-name = "OTG OFFVBUSn";
                };
 
-               otg_extlpn {
+               sd-wifi-mux {
                        gpio-hog;
-                       gpios = <9 GPIO_ACTIVE_HIGH>;
-                       output-high;
-                       line-name = "OTG EXTLPn";
+                       gpios = <5 GPIO_ACTIVE_HIGH>;
+                       output-low;     /* Connect WL1837 */
+                       line-name = "SD WiFi mux";
                };
 
                snd_rst {
                interrupt-parent = <&gpio6>;
                interrupts = <4 IRQ_TYPE_EDGE_FALLING>;
        };
+};
 
-       i2cswitch2: i2c-switch@71 {
+&i2c4 {
+       i2cswitch4: i2c-switch@71 {
                compatible = "nxp,pca9548";
                #address-cells = <1>;
                #size-cells = <0>;
                reg = <0x71>;
-               reset-gpios = <&gpio5 3 GPIO_ACTIVE_LOW>;
-
-               /* Audio_SDA, Audio_SCL */
-               i2c@7 {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       reg = <7>;
-
-                       pcm3168a: audio-codec@44 {
-                               #sound-dai-cells = <0>;
-                               compatible = "ti,pcm3168a";
-                               reg = <0x44>;
-                               clocks = <&clksndsel>;
-                               clock-names = "scki";
-
-                               VDD1-supply     = <&snd_3p3v>;
-                               VDD2-supply     = <&snd_3p3v>;
-                               VCCAD1-supply   = <&snd_vcc5v>;
-                               VCCAD2-supply   = <&snd_vcc5v>;
-                               VCCDA1-supply   = <&snd_vcc5v>;
-                               VCCDA2-supply   = <&snd_vcc5v>;
-
-                               ports {
-                                       #address-cells = <1>;
-                                       #size-cells = <0>;
-                                       mclk-fs = <512>;
-                                       port@0 {
-                                               reg = <0>;
-                                               pcm3168a_endpoint_p: endpoint {
-                                                       remote-endpoint = <&rsnd_for_pcm3168a_play>;
-                                                       clocks = <&clksndsel>;
-                                               };
-                                       };
-                                       port@1 {
-                                               reg = <1>;
-                                               pcm3168a_endpoint_c: endpoint {
-                                                       remote-endpoint = <&rsnd_for_pcm3168a_capture>;
-                                                       clocks = <&clksndsel>;
-                                               };
-                                       };
-                               };
-                       };
-               };
+               reset-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>;
        };
-};
 
-&i2c4 {
        gpio_exp_76: gpio@76 {
                compatible = "ti,tca9539";
                reg = <0x76>;
                interrupt-parent = <&gpio5>;
                interrupts = <9 IRQ_TYPE_EDGE_FALLING>;
        };
-
-       i2cswitch4: i2c-switch@71 {
-               compatible = "nxp,pca9548";
-               #address-cells = <1>;
-               #size-cells = <0>;
-               reg = <0x71>;
-               reset-gpios = <&gpio3 15 GPIO_ACTIVE_LOW>;
-       };
 };
 
 &ohci0 {
                power-source = <3300>;
        };
 
+       sound_pcm_pins: sound-pcm {
+               groups = "ssi349_ctrl", "ssi3_data", "ssi4_data";
+               function = "ssi";
+       };
+
        usb0_pins: usb0 {
                groups = "usb0";
                function = "usb0";
        };
+};
 
-       sound_pcm_pins: sound-pcm {
-               groups = "ssi349_ctrl", "ssi3_data", "ssi4_data";
-               function = "ssi";
+&rcar_sound {
+       pinctrl-0 = <&sound_pins
+                    &sound_clk_pins
+                    &sound_pcm_pins>;
+
+       ports {
+               /* rsnd_port0/1 are on salvator-common */
+               rsnd_port2: port@2 {
+                       reg = <2>;
+                       rsnd_for_pcm3168a_play: endpoint {
+                               remote-endpoint = <&pcm3168a_endpoint_p>;
+
+                               dai-format = "i2s";
+                               bitclock-master = <&rsnd_for_pcm3168a_play>;
+                               frame-master = <&rsnd_for_pcm3168a_play>;
+                               dai-tdm-slot-num = <8>;
+
+                               playback = <&ssi3>;
+                       };
+               };
+               rsnd_port3: port@3 {
+                       reg = <3>;
+                       rsnd_for_pcm3168a_capture: endpoint {
+                               remote-endpoint = <&pcm3168a_endpoint_c>;
+
+                               dai-format = "i2s";
+                               bitclock-master = <&rsnd_for_pcm3168a_capture>;
+                               frame-master = <&rsnd_for_pcm3168a_capture>;
+                               dai-tdm-slot-num = <6>;
+
+                               capture  = <&ssi4>;
+                       };
+               };
        };
 };
 
        };
 };
 
-&usb2_phy0 {
-       pinctrl-0 = <&usb0_pins>;
-       pinctrl-names = "default";
-
-       status = "okay";
-};
-
-&xhci0 {
-       status = "okay";
-};
-
 &sound_card {
        dais = <&rsnd_port0     /* ak4613 */
                &rsnd_port1     /* HDMI0  */
                >;
 };
 
-&rcar_sound {
-       pinctrl-0 = <&sound_pins
-                    &sound_clk_pins
-                    &sound_pcm_pins>;
-
-       ports {
-               /* rsnd_port0/1 are on salvator-common */
-               rsnd_port2: port@2 {
-                       reg = <2>;
-                       rsnd_for_pcm3168a_play: endpoint {
-                               remote-endpoint = <&pcm3168a_endpoint_p>;
-
-                               dai-format = "i2s";
-                               bitclock-master = <&rsnd_for_pcm3168a_play>;
-                               frame-master = <&rsnd_for_pcm3168a_play>;
-                               dai-tdm-slot-num = <8>;
-
-                               playback = <&ssi3>;
-                       };
-               };
-               rsnd_port3: port@3 {
-                       reg = <3>;
-                       rsnd_for_pcm3168a_capture: endpoint {
-                               remote-endpoint = <&pcm3168a_endpoint_c>;
+&ssi4 {
+       shared-pin;
+};
 
-                               dai-format = "i2s";
-                               bitclock-master = <&rsnd_for_pcm3168a_capture>;
-                               frame-master = <&rsnd_for_pcm3168a_capture>;
-                               dai-tdm-slot-num = <6>;
+&usb2_phy0 {
+       pinctrl-0 = <&usb0_pins>;
+       pinctrl-names = "default";
 
-                               capture  = <&ssi4>;
-                       };
-               };
-       };
+       status = "okay";
 };
 
-&ssi4 {
-       shared-pin;
+&xhci0 {
+       status = "okay";
 };
index 7e498b4..3ef8917 100644 (file)
        };
 };
 
+&rwdt {
+       timeout-sec = <60>;
+       status = "okay";
+};
+
 &scif2 {
        pinctrl-0 = <&scif2_pins>;
        pinctrl-names = "default";
 
        status = "okay";
 };
-
-&rwdt {
-       timeout-sec = <60>;
-       status = "okay";
-};
index daa2c78..1f18a93 100644 (file)
@@ -20,6 +20,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-hugsun-x99.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge-captain.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-khadas-edge-v.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-leez-p710.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopc-t4.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-m4.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-nanopi-neo4.dtb
index 7cfd5ca..62936b4 100644 (file)
 
        vcc_host_5v: vcc-host-5v-regulator {
                compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>;
+               gpio = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>;
                pinctrl-names = "default";
-               pinctrl-0 = <&usb30_host_drv>;
+               pinctrl-0 = <&usb20_host_drv>;
                regulator-name = "vcc_host_5v";
                regulator-always-on;
                regulator-boot-on;
                        rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
                };
        };
-
-       usb3 {
-               usb30_host_drv: usb30-host-drv {
-                       rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
 };
 
 &sdmmc {
index e9fefd8..31cc154 100644 (file)
                        };
                        pd_vpu@RK3328_PD_VPU {
                                reg = <RK3328_PD_VPU>;
+                               clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
                        };
                };
 
                status = "disabled";
        };
 
+       vpu: video-codec@ff350000 {
+               compatible = "rockchip,rk3328-vpu";
+               reg = <0x0 0xff350000 0x0 0x800>;
+               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "vdpu";
+               clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
+               clock-names = "aclk", "hclk";
+               iommus = <&vpu_mmu>;
+               power-domains = <&power RK3328_PD_VPU>;
+       };
+
        vpu_mmu: iommu@ff350800 {
                compatible = "rockchip,iommu";
                reg = <0x0 0xff350800 0x0 0x40>;
                clocks = <&cru ACLK_VPU>, <&cru HCLK_VPU>;
                clock-names = "aclk", "iface";
                #iommu-cells = <0>;
-               status = "disabled";
+               power-domains = <&power RK3328_PD_VPU>;
        };
 
        rkvdec_mmu: iommu@ff360480 {
                         <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
                clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
+               max-frequency = <150000000>;
                status = "disabled";
        };
 
                         <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
                clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
+               max-frequency = <150000000>;
                status = "disabled";
        };
 
                         <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
                clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
+               max-frequency = <150000000>;
                status = "disabled";
        };
 
index 3e2272b..e152b0c 100644 (file)
                backlight = <&backlight>;
                power-supply = <&pp3300_disp>;
 
+               panel-timing {
+                       clock-frequency = <266604720>;
+                       hactive = <2400>;
+                       hfront-porch = <48>;
+                       hback-porch = <84>;
+                       hsync-len = <32>;
+                       hsync-active = <0>;
+                       vactive = <1600>;
+                       vfront-porch = <3>;
+                       vback-porch = <120>;
+                       vsync-len = <10>;
+                       vsync-active = <0>;
+               };
+
                port {
                        panel_in_edp: endpoint {
                                remote-endpoint = <&edp_out_panel>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts b/arch/arm64/boot/dts/rockchip/rk3399-leez-p710.dts
new file mode 100644 (file)
index 0000000..73be38a
--- /dev/null
@@ -0,0 +1,645 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Andy Yan <andy.yan@gmail.com>
+ */
+
+/dts-v1/;
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3399.dtsi"
+#include "rk3399-opp.dtsi"
+
+/ {
+       model = "Leez RK3399 P710";
+       compatible = "leez,p710", "rockchip,rk3399";
+
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       clkin_gmac: external-gmac-clock {
+               compatible = "fixed-clock";
+               clock-frequency = <125000000>;
+               clock-output-names = "clkin_gmac";
+               #clock-cells = <0>;
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&rk808 1>;
+               clock-names = "ext_clock";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wifi_reg_on_h>;
+               reset-gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>;
+       };
+
+       dc5v_adp: dc5v-adp {
+               compatible = "regulator-fixed";
+               regulator-name = "dc5v_adapter";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+       };
+
+       vcc3v3_lan: vcc3v3-lan {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_lan";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vim-supply = <&vcc3v3_sys>;
+       };
+
+       vcc3v3_sys: vcc3v3-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc5v0_host0: vcc5v0_host1: vcc5v0-host {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v0_host";
+               regulator-boot-on;
+               regulator-always-on;
+               regulator-min-microvolt = <5500000>;
+               regulator-max-microvolt = <5500000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc5v0_host3: vcc5v0-host3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v0_host3";
+               enable-active-high;
+               gpio = <&gpio2 RK_PA2 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_host3_en>;
+               regulator-always-on;
+               vin-supply = <&vcc5v0_sys>;
+       };
+
+       vcc5v0_sys: vcc5v0-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v0_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&dc5v_adp>;
+       };
+
+       vdd_log: vdd-log {
+               compatible = "pwm-regulator";
+               pwms = <&pwm2 0 25000 1>;
+               regulator-name = "vdd_log";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <800000>;
+               regulator-max-microvolt = <1400000>;
+               vin-supply = <&vcc5v0_sys>;
+       };
+};
+
+&cpu_l0 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l1 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l2 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_l3 {
+       cpu-supply = <&vdd_cpu_l>;
+};
+
+&cpu_b0 {
+       cpu-supply = <&vdd_cpu_b>;
+};
+
+&cpu_b1 {
+       cpu-supply = <&vdd_cpu_b>;
+};
+
+&emmc_phy {
+       status = "okay";
+};
+
+&gmac {
+       assigned-clocks = <&cru SCLK_RMII_SRC>;
+       assigned-clock-parents = <&clkin_gmac>;
+       clock_in_out = "input";
+       phy-supply = <&vcc3v3_lan>;
+       phy-mode = "rgmii";
+       pinctrl-names = "default";
+       pinctrl-0 = <&rgmii_pins>;
+       snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
+       snps,reset-active-low;
+       snps,reset-delays-us = <0 10000 50000>;
+       tx_delay = <0x28>;
+       rx_delay = <0x11>;
+       status = "okay";
+};
+
+&gpu {
+       mali-supply = <&vdd_gpu>;
+       status = "okay";
+};
+
+&hdmi {
+       ddc-i2c-bus = <&i2c7>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&hdmi_cec>;
+       status = "okay";
+};
+
+&hdmi_sound {
+       status = "okay";
+};
+
+&i2c0 {
+       clock-frequency = <400000>;
+       i2c-scl-rising-time-ns = <168>;
+       i2c-scl-falling-time-ns = <4>;
+       status = "okay";
+
+       rk808: pmic@1b {
+               compatible = "rockchip,rk808";
+               reg = <0x1b>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <21 IRQ_TYPE_LEVEL_LOW>;
+               #clock-cells = <1>;
+               clock-output-names = "xin32k", "rk808-clkout2";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int_l>;
+               rockchip,system-power-controller;
+               wakeup-source;
+
+               vcc1-supply = <&vcc5v0_sys>;
+               vcc2-supply = <&vcc5v0_sys>;
+               vcc3-supply = <&vcc5v0_sys>;
+               vcc4-supply = <&vcc5v0_sys>;
+               vcc6-supply = <&vcc5v0_sys>;
+               vcc7-supply = <&vcc5v0_sys>;
+               vcc8-supply = <&vcc3v3_sys>;
+               vcc9-supply = <&vcc5v0_sys>;
+               vcc10-supply = <&vcc5v0_sys>;
+               vcc11-supply = <&vcc5v0_sys>;
+               vcc12-supply = <&vcc3v3_sys>;
+               vddio-supply = <&vcc_1v8>;
+
+               regulators {
+                       vdd_center: DCDC_REG1 {
+                               regulator-name = "vdd_center";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vdd_cpu_l: DCDC_REG2 {
+                               regulator-name = "vdd_cpu_l";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-ramp-delay = <6001>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_ddr: DCDC_REG3 {
+                               regulator-name = "vcc_ddr";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc_1v8: DCDC_REG4 {
+                               regulator-name = "vcc_1v8";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vcc1v8_dvp: LDO_REG1 {
+                               regulator-name = "vcc1v8_dvp";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc1v8_hdmi: LDO_REG2 {
+                               regulator-name = "vcc1v8_hdmi";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcca_1v8: LDO_REG3 {
+                               regulator-name = "vcca_1v8";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                               };
+                       };
+
+                       vccio_sd: LDO_REG4 {
+                               regulator-name = "vccio_sd";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+
+                       vcca3v0_codec: LDO_REG5 {
+                               regulator-name = "vcca3v0_codec";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_1v5: LDO_REG6 {
+                               regulator-name = "vcc_1v5";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1500000>;
+                               };
+                       };
+
+                       vcc0v9_hdmi: LDO_REG7 {
+                               regulator-name = "vcc0v9_hdmi";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_3v0: LDO_REG8 {
+                               regulator-name = "vcc_3v0";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3000000>;
+                               };
+                       };
+               };
+       };
+
+       vdd_cpu_b: regulator@40 {
+               compatible = "silergy,syr827";
+               reg = <0x40>;
+               fcs,suspend-voltage-selector = <1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vsel1_gpio>;
+               regulator-name = "vdd_cpu_b";
+               regulator-min-microvolt = <712500>;
+               regulator-max-microvolt = <1500000>;
+               regulator-ramp-delay = <1000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc5v0_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+
+       vdd_gpu: regulator@41 {
+               compatible = "silergy,syr828";
+               reg = <0x41>;
+               fcs,suspend-voltage-selector = <1>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vsel2_gpio>;
+               regulator-name = "vdd_gpu";
+               regulator-min-microvolt = <712500>;
+               regulator-max-microvolt = <1500000>;
+               regulator-ramp-delay = <1000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc5v0_sys>;
+
+               regulator-state-mem {
+                       regulator-off-in-suspend;
+               };
+       };
+};
+
+&i2c1 {
+       i2c-scl-rising-time-ns = <300>;
+       i2c-scl-falling-time-ns = <15>;
+       status = "okay";
+};
+
+&i2c3 {
+       i2c-scl-rising-time-ns = <450>;
+       i2c-scl-falling-time-ns = <15>;
+       status = "okay";
+};
+
+&i2c4 {
+       i2c-scl-rising-time-ns = <600>;
+       i2c-scl-falling-time-ns = <20>;
+       status = "okay";
+};
+
+&i2c7 {
+       status = "okay";
+};
+
+&i2s0 {
+       rockchip,playback-channels = <8>;
+       rockchip,capture-channels = <8>;
+       status = "okay";
+};
+
+&i2s1 {
+       rockchip,playback-channels = <2>;
+       rockchip,capture-channels = <2>;
+       status = "okay";
+};
+
+&i2s2 {
+       status = "okay";
+};
+
+&io_domains {
+       status = "okay";
+
+       bt656-supply = <&vcc1v8_dvp>;
+       audio-supply = <&vcc_1v8>;
+       sdmmc-supply = <&vccio_sd>;
+       gpio1830-supply = <&vcc_3v0>;
+};
+
+&pmu_io_domains {
+       status = "okay";
+       pmu1830-supply = <&vcc_3v0>;
+};
+
+&pinctrl {
+       bt {
+               bt_reg_on_h: bt-reg-on-h {
+                       rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               bt_host_wake_l: bt-host-wake-l {
+                       rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               bt_wake_l: bt-wake-l {
+                       rockchip,pins = <2 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pmic {
+               pmic_int_l: pmic-int-l {
+                       rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               vsel1_gpio: vsel1-gpio {
+                       rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+
+               vsel2_gpio: vsel2-gpio {
+                       rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+       };
+
+       usb2 {
+               vcc5v0_host3_en: vcc5v0-host3-en {
+                       rockchip,pins = <2 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       wifi {
+               wifi_reg_on_h: wifi-reg-on-h {
+                       rockchip,pins =
+                               <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               wifi_host_wake_l: wifi-host-wake-l {
+                       rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&saradc {
+       status = "okay";
+
+       vref-supply = <&vcc_1v8>;
+};
+
+&sdio0 {
+       #address-cells = <1>;
+       #size-cells = <0>;
+       bus-width = <4>;
+       clock-frequency = <50000000>;
+       cap-sdio-irq;
+       cap-sd-highspeed;
+       keep-power-in-suspend;
+       mmc-pwrseq = <&sdio_pwrseq>;
+       non-removable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
+       sd-uhs-sdr104;
+       status = "okay";
+
+       brcmf: wifi@1 {
+               compatible = "brcm,bcm4329-fmac";
+               reg = <1>;
+               interrupt-parent = <&gpio0>;
+               interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>;
+               interrupt-names = "host-wake";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wifi_host_wake_l>;
+       };
+};
+
+&sdhci {
+       bus-width = <8>;
+       mmc-hs400-1_8v;
+       mmc-hs400-enhanced-strobe;
+       non-removable;
+       status = "okay";
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+       disable-wp;
+       max-frequency = <150000000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdmmc_clk &sdmmc_cd &sdmmc_cmd &sdmmc_bus4>;
+       status = "okay";
+};
+
+&tcphy0 {
+       status = "okay";
+};
+
+&tcphy1 {
+       status = "okay";
+};
+
+&tsadc {
+       status = "okay";
+
+       /* tshut mode 0:CRU 1:GPIO */
+       rockchip,hw-tshut-mode = <1>;
+       /* tshut polarity 0:LOW 1:HIGH */
+       rockchip,hw-tshut-polarity = <1>;
+};
+
+&u2phy0 {
+       status = "okay";
+
+       u2phy0_otg: otg-port {
+               status = "okay";
+       };
+
+       u2phy0_host: host-port {
+               phy-supply = <&vcc5v0_host0>;
+               status = "okay";
+       };
+};
+
+&u2phy1 {
+       status = "okay";
+
+       u2phy1_otg: otg-port {
+               status = "okay";
+       };
+
+       u2phy1_host: host-port {
+               phy-supply = <&vcc5v0_host1>;
+               status = "okay";
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+       status = "okay";
+
+       bluetooth {
+               compatible = "brcm,bcm43438-bt";
+               clocks = <&rk808 1>;
+               clock-names = "ext_clock";
+               device-wakeup-gpios = <&gpio2 RK_PD2 GPIO_ACTIVE_HIGH>;
+               host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
+               shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_reg_on_h>;
+       };
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&usb_host0_ehci {
+       status = "okay";
+};
+
+&usb_host0_ohci {
+       status = "okay";
+};
+
+&usb_host1_ehci {
+       status = "okay";
+};
+
+&usb_host1_ohci {
+       status = "okay";
+};
+
+&usbdrd3_0 {
+       status = "okay";
+};
+
+&usbdrd_dwc3_0 {
+       status = "okay";
+       dr_mode = "otg";
+};
+
+&usbdrd3_1 {
+       status = "okay";
+};
+
+&usbdrd_dwc3_1 {
+       status = "okay";
+       dr_mode = "host";
+};
+
+&vopb {
+       status = "okay";
+};
+
+&vopb_mmu {
+       status = "okay";
+};
+
+&vopl {
+       status = "okay";
+};
+
+&vopl_mmu {
+       status = "okay";
+};
index eb55940..0401d4e 100644 (file)
                };
        };
 
+       fan: pwm-fan {
+               compatible = "pwm-fan";
+               #cooling-cells = <2>;
+               fan-supply = <&vcc12v_dcin>;
+               pwms = <&pwm1 0 50000 0>;
+       };
+
        sdio_pwrseq: sdio-pwrseq {
                compatible = "mmc-pwrseq-simple";
                clocks = <&rk808 1>;
        status = "okay";
 };
 
+&pwm1 {
+       status = "okay";
+};
+
 &pwm2 {
        status = "okay";
 };
        status = "okay";
 };
 
+&spi1 {
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <10000000>;
+       };
+};
+
 &tcphy0 {
        status = "okay";
 };
index 0e58ef0..8e05c39 100644 (file)
@@ -72,6 +72,7 @@ CONFIG_RANDOMIZE_BASE=y
 CONFIG_HIBERNATION=y
 CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y
 CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_STAT=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=m
@@ -84,6 +85,7 @@ CONFIG_ACPI_CPPC_CPUFREQ=m
 CONFIG_ARM_ARMADA_37XX_CPUFREQ=y
 CONFIG_ARM_SCPI_CPUFREQ=y
 CONFIG_ARM_IMX_CPUFREQ_DT=m
+CONFIG_ARM_RASPBERRYPI_CPUFREQ=m
 CONFIG_ARM_TEGRA186_CPUFREQ=y
 CONFIG_ARM_SCPI_PROTOCOL=y
 CONFIG_RASPBERRYPI_FIRMWARE=y
@@ -95,6 +97,7 @@ CONFIG_IMX_SCU_PD=y
 CONFIG_ACPI=y
 CONFIG_ACPI_APEI=y
 CONFIG_ACPI_APEI_GHES=y
+CONFIG_ACPI_APEI_PCIEAER=y
 CONFIG_ACPI_APEI_MEMORY_FAILURE=y
 CONFIG_ACPI_APEI_EINJ=y
 CONFIG_VIRTUALIZATION=y
@@ -196,6 +199,8 @@ CONFIG_PCIE_HISI_STB=y
 CONFIG_PCIE_TEGRA194=m
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_FW_LOADER_USER_HELPER=y
+CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y
 CONFIG_HISILICON_LPC=y
 CONFIG_SIMPLE_PM_BUS=y
 CONFIG_MTD=y
@@ -366,6 +371,7 @@ CONFIG_I2C_IMX_LPI2C=y
 CONFIG_I2C_MESON=y
 CONFIG_I2C_MV64XXX=y
 CONFIG_I2C_PXA=y
+CONFIG_I2C_QCOM_GENI=m
 CONFIG_I2C_QUP=y
 CONFIG_I2C_RK3X=y
 CONFIG_I2C_SH_MOBILE=y
@@ -392,6 +398,7 @@ CONFIG_SPMI=y
 CONFIG_PINCTRL_SINGLE=y
 CONFIG_PINCTRL_MAX77620=y
 CONFIG_PINCTRL_IMX8MM=y
+CONFIG_PINCTRL_IMX8MN=y
 CONFIG_PINCTRL_IMX8MQ=y
 CONFIG_PINCTRL_IMX8QXP=y
 CONFIG_PINCTRL_IPQ8074=y
@@ -403,6 +410,7 @@ CONFIG_PINCTRL_QCS404=y
 CONFIG_PINCTRL_QDF2XXX=y
 CONFIG_PINCTRL_QCOM_SPMI_PMIC=y
 CONFIG_PINCTRL_SDM845=y
+CONFIG_PINCTRL_SM8150=y
 CONFIG_GPIO_DWAPB=y
 CONFIG_GPIO_MB86S7X=y
 CONFIG_GPIO_PL061=y
@@ -445,6 +453,7 @@ CONFIG_UNIPHIER_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_ARM_SP805_WATCHDOG=y
 CONFIG_S3C2410_WATCHDOG=y
+CONFIG_DW_WATCHDOG=y
 CONFIG_SUNXI_WATCHDOG=m
 CONFIG_IMX2_WDT=y
 CONFIG_IMX_SC_WDT=m
@@ -489,6 +498,7 @@ CONFIG_RC_CORE=m
 CONFIG_RC_DECODERS=y
 CONFIG_RC_DEVICES=y
 CONFIG_IR_MESON=m
+CONFIG_IR_SUNXI=m
 CONFIG_MEDIA_SUPPORT=m
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
@@ -526,11 +536,13 @@ CONFIG_DRM_RCAR_DU=m
 CONFIG_DRM_SUN4I=m
 CONFIG_DRM_SUN8I_DW_HDMI=m
 CONFIG_DRM_SUN8I_MIXER=m
+CONFIG_DRM_MSM=m
 CONFIG_DRM_TEGRA=m
 CONFIG_DRM_PANEL_SIMPLE=m
 CONFIG_DRM_SII902X=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_VC4=m
+CONFIG_DRM_ETNAVIV=m
 CONFIG_DRM_HISI_HIBMC=m
 CONFIG_DRM_HISI_KIRIN=m
 CONFIG_DRM_MESON=m
@@ -539,6 +551,7 @@ CONFIG_DRM_LIMA=m
 CONFIG_DRM_PANFROST=m
 CONFIG_FB=y
 CONFIG_FB_MODE_HELPERS=y
+CONFIG_FB_EFI=y
 CONFIG_BACKLIGHT_GENERIC=m
 CONFIG_BACKLIGHT_PWM=m
 CONFIG_BACKLIGHT_LP855X=m
@@ -558,6 +571,7 @@ CONFIG_SND_SOC_ROCKCHIP_RT5645=m
 CONFIG_SND_SOC_RK3399_GRU_SOUND=m
 CONFIG_SND_SOC_SAMSUNG=y
 CONFIG_SND_SOC_RCAR=m
+CONFIG_SND_SUN4I_SPDIF=m
 CONFIG_SND_SOC_AK4613=m
 CONFIG_SND_SOC_ES7134=m
 CONFIG_SND_SOC_ES7241=m
@@ -651,6 +665,7 @@ CONFIG_DMADEVICES=y
 CONFIG_FSL_EDMA=y
 CONFIG_DMA_BCM2835=m
 CONFIG_DMA_SUN6I=m
+CONFIG_IMX_SDMA=y
 CONFIG_K3_DMA=y
 CONFIG_MV_XOR=y
 CONFIG_MV_XOR_V2=y
@@ -676,11 +691,15 @@ CONFIG_COMMON_CLK_CS2000_CP=y
 CONFIG_COMMON_CLK_S2MPS11=y
 CONFIG_CLK_QORIQ=y
 CONFIG_COMMON_CLK_PWM=y
+CONFIG_CLK_RASPBERRYPI=m
 CONFIG_CLK_IMX8MM=y
+CONFIG_CLK_IMX8MN=y
 CONFIG_CLK_IMX8MQ=y
 CONFIG_CLK_IMX8QXP=y
 CONFIG_TI_SCI_CLK=y
 CONFIG_COMMON_CLK_QCOM=y
+CONFIG_QCOM_A53PLL=y
+CONFIG_QCOM_CLK_APCS_MSM8916=y
 CONFIG_QCOM_CLK_SMD_RPM=y
 CONFIG_QCOM_CLK_RPMH=y
 CONFIG_IPQ_GCC_8074=y
@@ -690,6 +709,7 @@ CONFIG_MSM_MMCC_8996=y
 CONFIG_MSM_GCC_8998=y
 CONFIG_QCS_GCC_404=y
 CONFIG_SDM_GCC_845=y
+CONFIG_SM_GCC_8150=y
 CONFIG_HWSPINLOCK=y
 CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_ARM_MHU=y
@@ -768,6 +788,7 @@ CONFIG_PHY_HISTB_COMBPHY=y
 CONFIG_PHY_HISI_INNO_USB2=y
 CONFIG_PHY_MVEBU_CP110_COMPHY=y
 CONFIG_PHY_QCOM_QMP=m
+CONFIG_PHY_QCOM_QUSB2=m
 CONFIG_PHY_QCOM_USB_HS=y
 CONFIG_PHY_RCAR_GEN3_PCIE=y
 CONFIG_PHY_RCAR_GEN3_USB2=y
@@ -780,6 +801,7 @@ CONFIG_PHY_ROCKCHIP_TYPEC=y
 CONFIG_PHY_UNIPHIER_USB2=y
 CONFIG_PHY_UNIPHIER_USB3=y
 CONFIG_PHY_TEGRA_XUSB=y
+CONFIG_FSL_IMX8_DDR_PMU=m
 CONFIG_HISI_PMU=y
 CONFIG_QCOM_L2_PMU=y
 CONFIG_QCOM_L3_PMU=y
index e3a15c7..b8cf7c8 100644 (file)
@@ -124,17 +124,6 @@ alternative_endif
        .endm
 
 /*
- * Sanitise a 64-bit bounded index wrt speculation, returning zero if out
- * of bounds.
- */
-       .macro  mask_nospec64, idx, limit, tmp
-       sub     \tmp, \idx, \limit
-       bic     \tmp, \tmp, \idx
-       and     \idx, \idx, \tmp, asr #63
-       csdb
-       .endm
-
-/*
  * NOP sequence
  */
        .macro  nops, num
@@ -350,6 +339,13 @@ alternative_endif
        .endm
 
 /*
+ * tcr_set_t1sz - update TCR.T1SZ
+ */
+       .macro  tcr_set_t1sz, valreg, t1sz
+       bfi     \valreg, \t1sz, #TCR_T1SZ_OFFSET, #TCR_TxSZ_WIDTH
+       .endm
+
+/*
  * tcr_compute_pa_size - set TCR.(I)PS to the highest supported
  * ID_AA64MMFR0_EL1.PARange value
  *
@@ -538,9 +534,13 @@ USER(\label, ic    ivau, \tmp2)                    // invalidate I line PoU
  * In future this may be nop'ed out when dealing with 52-bit kernel VAs.
  *     ttbr: Value of ttbr to set, modified.
  */
-       .macro  offset_ttbr1, ttbr
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
+       .macro  offset_ttbr1, ttbr, tmp
+#ifdef CONFIG_ARM64_VA_BITS_52
+       mrs_s   \tmp, SYS_ID_AA64MMFR2_EL1
+       and     \tmp, \tmp, #(0xf << ID_AA64MMFR2_LVA_SHIFT)
+       cbnz    \tmp, .Lskipoffs_\@
        orr     \ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
+.Lskipoffs_\@ :
 #endif
        .endm
 
@@ -550,7 +550,7 @@ USER(\label, ic     ivau, \tmp2)                    // invalidate I line PoU
  * to be nop'ed out when dealing with 52-bit kernel VAs.
  */
        .macro  restore_ttbr1, ttbr
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
+#ifdef CONFIG_ARM64_VA_BITS_52
        bic     \ttbr, \ttbr, #TTBR1_BADDR_4852_OFFSET
 #endif
        .endm
index 657b045..9543b5e 100644 (file)
 #include <linux/types.h>
 
 #include <asm/barrier.h>
+#include <asm/cmpxchg.h>
 #include <asm/lse.h>
 
-#ifdef __KERNEL__
-
-#define __ARM64_IN_ATOMIC_IMPL
-
-#if defined(CONFIG_ARM64_LSE_ATOMICS) && defined(CONFIG_AS_LSE)
-#include <asm/atomic_lse.h>
-#else
-#include <asm/atomic_ll_sc.h>
-#endif
-
-#undef __ARM64_IN_ATOMIC_IMPL
-
-#include <asm/cmpxchg.h>
+#define ATOMIC_OP(op)                                                  \
+static inline void arch_##op(int i, atomic_t *v)                       \
+{                                                                      \
+       __lse_ll_sc_body(op, i, v);                                     \
+}
+
+ATOMIC_OP(atomic_andnot)
+ATOMIC_OP(atomic_or)
+ATOMIC_OP(atomic_xor)
+ATOMIC_OP(atomic_add)
+ATOMIC_OP(atomic_and)
+ATOMIC_OP(atomic_sub)
+
+#undef ATOMIC_OP
+
+#define ATOMIC_FETCH_OP(name, op)                                      \
+static inline int arch_##op##name(int i, atomic_t *v)                  \
+{                                                                      \
+       return __lse_ll_sc_body(op##name, i, v);                        \
+}
+
+#define ATOMIC_FETCH_OPS(op)                                           \
+       ATOMIC_FETCH_OP(_relaxed, op)                                   \
+       ATOMIC_FETCH_OP(_acquire, op)                                   \
+       ATOMIC_FETCH_OP(_release, op)                                   \
+       ATOMIC_FETCH_OP(        , op)
+
+ATOMIC_FETCH_OPS(atomic_fetch_andnot)
+ATOMIC_FETCH_OPS(atomic_fetch_or)
+ATOMIC_FETCH_OPS(atomic_fetch_xor)
+ATOMIC_FETCH_OPS(atomic_fetch_add)
+ATOMIC_FETCH_OPS(atomic_fetch_and)
+ATOMIC_FETCH_OPS(atomic_fetch_sub)
+ATOMIC_FETCH_OPS(atomic_add_return)
+ATOMIC_FETCH_OPS(atomic_sub_return)
+
+#undef ATOMIC_FETCH_OP
+#undef ATOMIC_FETCH_OPS
+
+#define ATOMIC64_OP(op)                                                        \
+static inline void arch_##op(long i, atomic64_t *v)                    \
+{                                                                      \
+       __lse_ll_sc_body(op, i, v);                                     \
+}
+
+ATOMIC64_OP(atomic64_andnot)
+ATOMIC64_OP(atomic64_or)
+ATOMIC64_OP(atomic64_xor)
+ATOMIC64_OP(atomic64_add)
+ATOMIC64_OP(atomic64_and)
+ATOMIC64_OP(atomic64_sub)
+
+#undef ATOMIC64_OP
+
+#define ATOMIC64_FETCH_OP(name, op)                                    \
+static inline long arch_##op##name(long i, atomic64_t *v)              \
+{                                                                      \
+       return __lse_ll_sc_body(op##name, i, v);                        \
+}
+
+#define ATOMIC64_FETCH_OPS(op)                                         \
+       ATOMIC64_FETCH_OP(_relaxed, op)                                 \
+       ATOMIC64_FETCH_OP(_acquire, op)                                 \
+       ATOMIC64_FETCH_OP(_release, op)                                 \
+       ATOMIC64_FETCH_OP(        , op)
+
+ATOMIC64_FETCH_OPS(atomic64_fetch_andnot)
+ATOMIC64_FETCH_OPS(atomic64_fetch_or)
+ATOMIC64_FETCH_OPS(atomic64_fetch_xor)
+ATOMIC64_FETCH_OPS(atomic64_fetch_add)
+ATOMIC64_FETCH_OPS(atomic64_fetch_and)
+ATOMIC64_FETCH_OPS(atomic64_fetch_sub)
+ATOMIC64_FETCH_OPS(atomic64_add_return)
+ATOMIC64_FETCH_OPS(atomic64_sub_return)
+
+#undef ATOMIC64_FETCH_OP
+#undef ATOMIC64_FETCH_OPS
+
+static inline long arch_atomic64_dec_if_positive(atomic64_t *v)
+{
+       return __lse_ll_sc_body(atomic64_dec_if_positive, v);
+}
 
 #define ATOMIC_INIT(i) { (i) }
 
 
 #include <asm-generic/atomic-instrumented.h>
 
-#endif
-#endif
+#endif /* __ASM_ATOMIC_H */
index c8c850b..7b01214 100644 (file)
 #ifndef __ASM_ATOMIC_LL_SC_H
 #define __ASM_ATOMIC_LL_SC_H
 
-#ifndef __ARM64_IN_ATOMIC_IMPL
-#error "please don't include this file directly"
+#include <linux/stringify.h>
+
+#if IS_ENABLED(CONFIG_ARM64_LSE_ATOMICS) && IS_ENABLED(CONFIG_AS_LSE)
+#define __LL_SC_FALLBACK(asm_ops)                                      \
+"      b       3f\n"                                                   \
+"      .subsection     1\n"                                            \
+"3:\n"                                                                 \
+asm_ops "\n"                                                           \
+"      b       4f\n"                                                   \
+"      .previous\n"                                                    \
+"4:\n"
+#else
+#define __LL_SC_FALLBACK(asm_ops) asm_ops
+#endif
+
+#ifndef CONFIG_CC_HAS_K_CONSTRAINT
+#define K
 #endif
 
 /*
  * AArch64 UP and SMP safe atomic ops.  We use load exclusive and
  * store exclusive to ensure that these are atomic.  We may loop
  * to ensure that the update happens.
- *
- * NOTE: these functions do *not* follow the PCS and must explicitly
- * save any clobbered registers other than x0 (regardless of return
- * value).  This is achieved through -fcall-saved-* compiler flags for
- * this file, which unfortunately don't work on a per-function basis
- * (the optimize attribute silently ignores these options).
  */
 
-#define ATOMIC_OP(op, asm_op)                                          \
-__LL_SC_INLINE void                                                    \
-__LL_SC_PREFIX(arch_atomic_##op(int i, atomic_t *v))                   \
+#define ATOMIC_OP(op, asm_op, constraint)                              \
+static inline void                                                     \
+__ll_sc_atomic_##op(int i, atomic_t *v)                                        \
 {                                                                      \
        unsigned long tmp;                                              \
        int result;                                                     \
                                                                        \
        asm volatile("// atomic_" #op "\n"                              \
+       __LL_SC_FALLBACK(                                               \
 "      prfm    pstl1strm, %2\n"                                        \
 "1:    ldxr    %w0, %2\n"                                              \
 "      " #asm_op "     %w0, %w0, %w3\n"                                \
 "      stxr    %w1, %w0, %2\n"                                         \
-"      cbnz    %w1, 1b"                                                \
+"      cbnz    %w1, 1b\n")                                             \
        : "=&r" (result), "=&r" (tmp), "+Q" (v->counter)                \
-       : "Ir" (i));                                                    \
-}                                                                      \
-__LL_SC_EXPORT(arch_atomic_##op);
+       : __stringify(constraint) "r" (i));                             \
+}
 
-#define ATOMIC_OP_RETURN(name, mb, acq, rel, cl, op, asm_op)           \
-__LL_SC_INLINE int                                                     \
-__LL_SC_PREFIX(arch_atomic_##op##_return##name(int i, atomic_t *v))    \
+#define ATOMIC_OP_RETURN(name, mb, acq, rel, cl, op, asm_op, constraint)\
+static inline int                                                      \
+__ll_sc_atomic_##op##_return##name(int i, atomic_t *v)                 \
 {                                                                      \
        unsigned long tmp;                                              \
        int result;                                                     \
                                                                        \
        asm volatile("// atomic_" #op "_return" #name "\n"              \
+       __LL_SC_FALLBACK(                                               \
 "      prfm    pstl1strm, %2\n"                                        \
 "1:    ld" #acq "xr    %w0, %2\n"                                      \
 "      " #asm_op "     %w0, %w0, %w3\n"                                \
 "      st" #rel "xr    %w1, %w0, %2\n"                                 \
 "      cbnz    %w1, 1b\n"                                              \
-"      " #mb                                                           \
+"      " #mb )                                                         \
        : "=&r" (result), "=&r" (tmp), "+Q" (v->counter)                \
-       : "Ir" (i)                                                      \
+       : __stringify(constraint) "r" (i)                               \
        : cl);                                                          \
                                                                        \
        return result;                                                  \
-}                                                                      \
-__LL_SC_EXPORT(arch_atomic_##op##_return##name);
+}
 
-#define ATOMIC_FETCH_OP(name, mb, acq, rel, cl, op, asm_op)            \
-__LL_SC_INLINE int                                                     \
-__LL_SC_PREFIX(arch_atomic_fetch_##op##name(int i, atomic_t *v))       \
+#define ATOMIC_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint) \
+static inline int                                                      \
+__ll_sc_atomic_fetch_##op##name(int i, atomic_t *v)                    \
 {                                                                      \
        unsigned long tmp;                                              \
        int val, result;                                                \
                                                                        \
        asm volatile("// atomic_fetch_" #op #name "\n"                  \
+       __LL_SC_FALLBACK(                                               \
 "      prfm    pstl1strm, %3\n"                                        \
 "1:    ld" #acq "xr    %w0, %3\n"                                      \
 "      " #asm_op "     %w1, %w0, %w4\n"                                \
 "      st" #rel "xr    %w2, %w1, %3\n"                                 \
 "      cbnz    %w2, 1b\n"                                              \
-"      " #mb                                                           \
+"      " #mb )                                                         \
        : "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)   \
-       : "Ir" (i)                                                      \
+       : __stringify(constraint) "r" (i)                               \
        : cl);                                                          \
                                                                        \
        return result;                                                  \
-}                                                                      \
-__LL_SC_EXPORT(arch_atomic_fetch_##op##name);
+}
 
 #define ATOMIC_OPS(...)                                                        \
        ATOMIC_OP(__VA_ARGS__)                                          \
@@ -99,8 +108,8 @@ __LL_SC_EXPORT(arch_atomic_fetch_##op##name);
        ATOMIC_FETCH_OP (_acquire,        , a,  , "memory", __VA_ARGS__)\
        ATOMIC_FETCH_OP (_release,        ,  , l, "memory", __VA_ARGS__)
 
-ATOMIC_OPS(add, add)
-ATOMIC_OPS(sub, sub)
+ATOMIC_OPS(add, add, I)
+ATOMIC_OPS(sub, sub, J)
 
 #undef ATOMIC_OPS
 #define ATOMIC_OPS(...)                                                        \
@@ -110,77 +119,82 @@ ATOMIC_OPS(sub, sub)
        ATOMIC_FETCH_OP (_acquire,        , a,  , "memory", __VA_ARGS__)\
        ATOMIC_FETCH_OP (_release,        ,  , l, "memory", __VA_ARGS__)
 
-ATOMIC_OPS(and, and)
-ATOMIC_OPS(andnot, bic)
-ATOMIC_OPS(or, orr)
-ATOMIC_OPS(xor, eor)
+ATOMIC_OPS(and, and, K)
+ATOMIC_OPS(or, orr, K)
+ATOMIC_OPS(xor, eor, K)
+/*
+ * GAS converts the mysterious and undocumented BIC (immediate) alias to
+ * an AND (immediate) instruction with the immediate inverted. We don't
+ * have a constraint for this, so fall back to register.
+ */
+ATOMIC_OPS(andnot, bic, )
 
 #undef ATOMIC_OPS
 #undef ATOMIC_FETCH_OP
 #undef ATOMIC_OP_RETURN
 #undef ATOMIC_OP
 
-#define ATOMIC64_OP(op, asm_op)                                                \
-__LL_SC_INLINE void                                                    \
-__LL_SC_PREFIX(arch_atomic64_##op(s64 i, atomic64_t *v))               \
+#define ATOMIC64_OP(op, asm_op, constraint)                            \
+static inline void                                                     \
+__ll_sc_atomic64_##op(s64 i, atomic64_t *v)                            \
 {                                                                      \
        s64 result;                                                     \
        unsigned long tmp;                                              \
                                                                        \
        asm volatile("// atomic64_" #op "\n"                            \
+       __LL_SC_FALLBACK(                                               \
 "      prfm    pstl1strm, %2\n"                                        \
 "1:    ldxr    %0, %2\n"                                               \
 "      " #asm_op "     %0, %0, %3\n"                                   \
 "      stxr    %w1, %0, %2\n"                                          \
-"      cbnz    %w1, 1b"                                                \
+"      cbnz    %w1, 1b")                                               \
        : "=&r" (result), "=&r" (tmp), "+Q" (v->counter)                \
-       : "Ir" (i));                                                    \
-}                                                                      \
-__LL_SC_EXPORT(arch_atomic64_##op);
+       : __stringify(constraint) "r" (i));                             \
+}
 
-#define ATOMIC64_OP_RETURN(name, mb, acq, rel, cl, op, asm_op)         \
-__LL_SC_INLINE s64                                                     \
-__LL_SC_PREFIX(arch_atomic64_##op##_return##name(s64 i, atomic64_t *v))\
+#define ATOMIC64_OP_RETURN(name, mb, acq, rel, cl, op, asm_op, constraint)\
+static inline long                                                     \
+__ll_sc_atomic64_##op##_return##name(s64 i, atomic64_t *v)             \
 {                                                                      \
        s64 result;                                                     \
        unsigned long tmp;                                              \
                                                                        \
        asm volatile("// atomic64_" #op "_return" #name "\n"            \
+       __LL_SC_FALLBACK(                                               \
 "      prfm    pstl1strm, %2\n"                                        \
 "1:    ld" #acq "xr    %0, %2\n"                                       \
 "      " #asm_op "     %0, %0, %3\n"                                   \
 "      st" #rel "xr    %w1, %0, %2\n"                                  \
 "      cbnz    %w1, 1b\n"                                              \
-"      " #mb                                                           \
+"      " #mb )                                                         \
        : "=&r" (result), "=&r" (tmp), "+Q" (v->counter)                \
-       : "Ir" (i)                                                      \
+       : __stringify(constraint) "r" (i)                               \
        : cl);                                                          \
                                                                        \
        return result;                                                  \
-}                                                                      \
-__LL_SC_EXPORT(arch_atomic64_##op##_return##name);
+}
 
-#define ATOMIC64_FETCH_OP(name, mb, acq, rel, cl, op, asm_op)          \
-__LL_SC_INLINE s64                                                     \
-__LL_SC_PREFIX(arch_atomic64_fetch_##op##name(s64 i, atomic64_t *v))   \
+#define ATOMIC64_FETCH_OP(name, mb, acq, rel, cl, op, asm_op, constraint)\
+static inline long                                                     \
+__ll_sc_atomic64_fetch_##op##name(s64 i, atomic64_t *v)                \
 {                                                                      \
        s64 result, val;                                                \
        unsigned long tmp;                                              \
                                                                        \
        asm volatile("// atomic64_fetch_" #op #name "\n"                \
+       __LL_SC_FALLBACK(                                               \
 "      prfm    pstl1strm, %3\n"                                        \
 "1:    ld" #acq "xr    %0, %3\n"                                       \
 "      " #asm_op "     %1, %0, %4\n"                                   \
 "      st" #rel "xr    %w2, %1, %3\n"                                  \
 "      cbnz    %w2, 1b\n"                                              \
-"      " #mb                                                           \
+"      " #mb )                                                         \
        : "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter)   \
-       : "Ir" (i)                                                      \
+       : __stringify(constraint) "r" (i)                               \
        : cl);                                                          \
                                                                        \
        return result;                                                  \
-}                                                                      \
-__LL_SC_EXPORT(arch_atomic64_fetch_##op##name);
+}
 
 #define ATOMIC64_OPS(...)                                              \
        ATOMIC64_OP(__VA_ARGS__)                                        \
@@ -193,8 +207,8 @@ __LL_SC_EXPORT(arch_atomic64_fetch_##op##name);
        ATOMIC64_FETCH_OP (_acquire,, a,  , "memory", __VA_ARGS__)      \
        ATOMIC64_FETCH_OP (_release,,  , l, "memory", __VA_ARGS__)
 
-ATOMIC64_OPS(add, add)
-ATOMIC64_OPS(sub, sub)
+ATOMIC64_OPS(add, add, I)
+ATOMIC64_OPS(sub, sub, J)
 
 #undef ATOMIC64_OPS
 #define ATOMIC64_OPS(...)                                              \
@@ -204,23 +218,29 @@ ATOMIC64_OPS(sub, sub)
        ATOMIC64_FETCH_OP (_acquire,, a,  , "memory", __VA_ARGS__)      \
        ATOMIC64_FETCH_OP (_release,,  , l, "memory", __VA_ARGS__)
 
-ATOMIC64_OPS(and, and)
-ATOMIC64_OPS(andnot, bic)
-ATOMIC64_OPS(or, orr)
-ATOMIC64_OPS(xor, eor)
+ATOMIC64_OPS(and, and, L)
+ATOMIC64_OPS(or, orr, L)
+ATOMIC64_OPS(xor, eor, L)
+/*
+ * GAS converts the mysterious and undocumented BIC (immediate) alias to
+ * an AND (immediate) instruction with the immediate inverted. We don't
+ * have a constraint for this, so fall back to register.
+ */
+ATOMIC64_OPS(andnot, bic, )
 
 #undef ATOMIC64_OPS
 #undef ATOMIC64_FETCH_OP
 #undef ATOMIC64_OP_RETURN
 #undef ATOMIC64_OP
 
-__LL_SC_INLINE s64
-__LL_SC_PREFIX(arch_atomic64_dec_if_positive(atomic64_t *v))
+static inline s64
+__ll_sc_atomic64_dec_if_positive(atomic64_t *v)
 {
        s64 result;
        unsigned long tmp;
 
        asm volatile("// atomic64_dec_if_positive\n"
+       __LL_SC_FALLBACK(
 "      prfm    pstl1strm, %2\n"
 "1:    ldxr    %0, %2\n"
 "      subs    %0, %0, #1\n"
@@ -228,20 +248,19 @@ __LL_SC_PREFIX(arch_atomic64_dec_if_positive(atomic64_t *v))
 "      stlxr   %w1, %0, %2\n"
 "      cbnz    %w1, 1b\n"
 "      dmb     ish\n"
-"2:"
+"2:")
        : "=&r" (result), "=&r" (tmp), "+Q" (v->counter)
        :
        : "cc", "memory");
 
        return result;
 }
-__LL_SC_EXPORT(arch_atomic64_dec_if_positive);
 
-#define __CMPXCHG_CASE(w, sfx, name, sz, mb, acq, rel, cl)             \
-__LL_SC_INLINE u##sz                                                   \
-__LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,           \
+#define __CMPXCHG_CASE(w, sfx, name, sz, mb, acq, rel, cl, constraint) \
+static inline u##sz                                                    \
+__ll_sc__cmpxchg_case_##name##sz(volatile void *ptr,                   \
                                         unsigned long old,             \
-                                        u##sz new))                    \
+                                        u##sz new)                     \
 {                                                                      \
        unsigned long tmp;                                              \
        u##sz oldval;                                                   \
@@ -255,6 +274,7 @@ __LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,                \
                old = (u##sz)old;                                       \
                                                                        \
        asm volatile(                                                   \
+       __LL_SC_FALLBACK(                                               \
        "       prfm    pstl1strm, %[v]\n"                              \
        "1:     ld" #acq "xr" #sfx "\t%" #w "[oldval], %[v]\n"          \
        "       eor     %" #w "[tmp], %" #w "[oldval], %" #w "[old]\n"  \
@@ -262,46 +282,51 @@ __LL_SC_PREFIX(__cmpxchg_case_##name##sz(volatile void *ptr,              \
        "       st" #rel "xr" #sfx "\t%w[tmp], %" #w "[new], %[v]\n"    \
        "       cbnz    %w[tmp], 1b\n"                                  \
        "       " #mb "\n"                                              \
-       "2:"                                                            \
+       "2:")                                                           \
        : [tmp] "=&r" (tmp), [oldval] "=&r" (oldval),                   \
          [v] "+Q" (*(u##sz *)ptr)                                      \
-       : [old] "Kr" (old), [new] "r" (new)                             \
+       : [old] __stringify(constraint) "r" (old), [new] "r" (new)      \
        : cl);                                                          \
                                                                        \
        return oldval;                                                  \
-}                                                                      \
-__LL_SC_EXPORT(__cmpxchg_case_##name##sz);
+}
 
-__CMPXCHG_CASE(w, b,     ,  8,        ,  ,  ,         )
-__CMPXCHG_CASE(w, h,     , 16,        ,  ,  ,         )
-__CMPXCHG_CASE(w,  ,     , 32,        ,  ,  ,         )
-__CMPXCHG_CASE( ,  ,     , 64,        ,  ,  ,         )
-__CMPXCHG_CASE(w, b, acq_,  8,        , a,  , "memory")
-__CMPXCHG_CASE(w, h, acq_, 16,        , a,  , "memory")
-__CMPXCHG_CASE(w,  , acq_, 32,        , a,  , "memory")
-__CMPXCHG_CASE( ,  , acq_, 64,        , a,  , "memory")
-__CMPXCHG_CASE(w, b, rel_,  8,        ,  , l, "memory")
-__CMPXCHG_CASE(w, h, rel_, 16,        ,  , l, "memory")
-__CMPXCHG_CASE(w,  , rel_, 32,        ,  , l, "memory")
-__CMPXCHG_CASE( ,  , rel_, 64,        ,  , l, "memory")
-__CMPXCHG_CASE(w, b,  mb_,  8, dmb ish,  , l, "memory")
-__CMPXCHG_CASE(w, h,  mb_, 16, dmb ish,  , l, "memory")
-__CMPXCHG_CASE(w,  ,  mb_, 32, dmb ish,  , l, "memory")
-__CMPXCHG_CASE( ,  ,  mb_, 64, dmb ish,  , l, "memory")
+/*
+ * Earlier versions of GCC (no later than 8.1.0) appear to incorrectly
+ * handle the 'K' constraint for the value 4294967295 - thus we use no
+ * constraint for 32 bit operations.
+ */
+__CMPXCHG_CASE(w, b,     ,  8,        ,  ,  ,         , K)
+__CMPXCHG_CASE(w, h,     , 16,        ,  ,  ,         , K)
+__CMPXCHG_CASE(w,  ,     , 32,        ,  ,  ,         , K)
+__CMPXCHG_CASE( ,  ,     , 64,        ,  ,  ,         , L)
+__CMPXCHG_CASE(w, b, acq_,  8,        , a,  , "memory", K)
+__CMPXCHG_CASE(w, h, acq_, 16,        , a,  , "memory", K)
+__CMPXCHG_CASE(w,  , acq_, 32,        , a,  , "memory", K)
+__CMPXCHG_CASE( ,  , acq_, 64,        , a,  , "memory", L)
+__CMPXCHG_CASE(w, b, rel_,  8,        ,  , l, "memory", K)
+__CMPXCHG_CASE(w, h, rel_, 16,        ,  , l, "memory", K)
+__CMPXCHG_CASE(w,  , rel_, 32,        ,  , l, "memory", K)
+__CMPXCHG_CASE( ,  , rel_, 64,        ,  , l, "memory", L)
+__CMPXCHG_CASE(w, b,  mb_,  8, dmb ish,  , l, "memory", K)
+__CMPXCHG_CASE(w, h,  mb_, 16, dmb ish,  , l, "memory", K)
+__CMPXCHG_CASE(w,  ,  mb_, 32, dmb ish,  , l, "memory", K)
+__CMPXCHG_CASE( ,  ,  mb_, 64, dmb ish,  , l, "memory", L)
 
 #undef __CMPXCHG_CASE
 
 #define __CMPXCHG_DBL(name, mb, rel, cl)                               \
-__LL_SC_INLINE long                                                    \
-__LL_SC_PREFIX(__cmpxchg_double##name(unsigned long old1,              \
+static inline long                                                     \
+__ll_sc__cmpxchg_double##name(unsigned long old1,                      \
                                      unsigned long old2,               \
                                      unsigned long new1,               \
                                      unsigned long new2,               \
-                                     volatile void *ptr))              \
+                                     volatile void *ptr)               \
 {                                                                      \
        unsigned long tmp, ret;                                         \
                                                                        \
        asm volatile("// __cmpxchg_double" #name "\n"                   \
+       __LL_SC_FALLBACK(                                               \
        "       prfm    pstl1strm, %2\n"                                \
        "1:     ldxp    %0, %1, %2\n"                                   \
        "       eor     %0, %0, %3\n"                                   \
@@ -311,18 +336,18 @@ __LL_SC_PREFIX(__cmpxchg_double##name(unsigned long old1,         \
        "       st" #rel "xp    %w0, %5, %6, %2\n"                      \
        "       cbnz    %w0, 1b\n"                                      \
        "       " #mb "\n"                                              \
-       "2:"                                                            \
+       "2:")                                                           \
        : "=&r" (tmp), "=&r" (ret), "+Q" (*(unsigned long *)ptr)        \
        : "r" (old1), "r" (old2), "r" (new1), "r" (new2)                \
        : cl);                                                          \
                                                                        \
        return ret;                                                     \
-}                                                                      \
-__LL_SC_EXPORT(__cmpxchg_double##name);
+}
 
 __CMPXCHG_DBL(   ,        ,  ,         )
 __CMPXCHG_DBL(_mb, dmb ish, l, "memory")
 
 #undef __CMPXCHG_DBL
+#undef K
 
 #endif /* __ASM_ATOMIC_LL_SC_H */
index 69acb1c..c6bd87d 100644 (file)
 #ifndef __ASM_ATOMIC_LSE_H
 #define __ASM_ATOMIC_LSE_H
 
-#ifndef __ARM64_IN_ATOMIC_IMPL
-#error "please don't include this file directly"
-#endif
-
-#define __LL_SC_ATOMIC(op)     __LL_SC_CALL(arch_atomic_##op)
 #define ATOMIC_OP(op, asm_op)                                          \
-static inline void arch_atomic_##op(int i, atomic_t *v)                        \
+static inline void __lse_atomic_##op(int i, atomic_t *v)                       \
 {                                                                      \
-       register int w0 asm ("w0") = i;                                 \
-       register atomic_t *x1 asm ("x1") = v;                           \
-                                                                       \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(op),          \
-"      " #asm_op "     %w[i], %[v]\n")                                 \
-       : [i] "+r" (w0), [v] "+Q" (v->counter)                          \
-       : "r" (x1)                                                      \
-       : __LL_SC_CLOBBERS);                                            \
+       asm volatile(                                                   \
+"      " #asm_op "     %w[i], %[v]\n"                                  \
+       : [i] "+r" (i), [v] "+Q" (v->counter)                           \
+       : "r" (v));                                                     \
 }
 
 ATOMIC_OP(andnot, stclr)
@@ -36,21 +27,15 @@ ATOMIC_OP(add, stadd)
 #undef ATOMIC_OP
 
 #define ATOMIC_FETCH_OP(name, mb, op, asm_op, cl...)                   \
-static inline int arch_atomic_fetch_##op##name(int i, atomic_t *v)     \
+static inline int __lse_atomic_fetch_##op##name(int i, atomic_t *v)    \
 {                                                                      \
-       register int w0 asm ("w0") = i;                                 \
-       register atomic_t *x1 asm ("x1") = v;                           \
-                                                                       \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(                             \
-       /* LL/SC */                                                     \
-       __LL_SC_ATOMIC(fetch_##op##name),                               \
-       /* LSE atomics */                                               \
-"      " #asm_op #mb " %w[i], %w[i], %[v]")                            \
-       : [i] "+r" (w0), [v] "+Q" (v->counter)                          \
-       : "r" (x1)                                                      \
-       : __LL_SC_CLOBBERS, ##cl);                                      \
+       asm volatile(                                                   \
+"      " #asm_op #mb " %w[i], %w[i], %[v]"                             \
+       : [i] "+r" (i), [v] "+Q" (v->counter)                           \
+       : "r" (v)                                                       \
+       : cl);                                                          \
                                                                        \
-       return w0;                                                      \
+       return i;                                                       \
 }
 
 #define ATOMIC_FETCH_OPS(op, asm_op)                                   \
@@ -68,23 +53,18 @@ ATOMIC_FETCH_OPS(add, ldadd)
 #undef ATOMIC_FETCH_OPS
 
 #define ATOMIC_OP_ADD_RETURN(name, mb, cl...)                          \
-static inline int arch_atomic_add_return##name(int i, atomic_t *v)     \
+static inline int __lse_atomic_add_return##name(int i, atomic_t *v)    \
 {                                                                      \
-       register int w0 asm ("w0") = i;                                 \
-       register atomic_t *x1 asm ("x1") = v;                           \
+       u32 tmp;                                                        \
                                                                        \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(                             \
-       /* LL/SC */                                                     \
-       __LL_SC_ATOMIC(add_return##name)                                \
-       __nops(1),                                                      \
-       /* LSE atomics */                                               \
-       "       ldadd" #mb "    %w[i], w30, %[v]\n"                     \
-       "       add     %w[i], %w[i], w30")                             \
-       : [i] "+r" (w0), [v] "+Q" (v->counter)                          \
-       : "r" (x1)                                                      \
-       : __LL_SC_CLOBBERS, ##cl);                                      \
+       asm volatile(                                                   \
+       "       ldadd" #mb "    %w[i], %w[tmp], %[v]\n"                 \
+       "       add     %w[i], %w[i], %w[tmp]"                          \
+       : [i] "+r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)        \
+       : "r" (v)                                                       \
+       : cl);                                                          \
                                                                        \
-       return w0;                                                      \
+       return i;                                                       \
 }
 
 ATOMIC_OP_ADD_RETURN(_relaxed,   )
@@ -94,41 +74,26 @@ ATOMIC_OP_ADD_RETURN(        , al, "memory")
 
 #undef ATOMIC_OP_ADD_RETURN
 
-static inline void arch_atomic_and(int i, atomic_t *v)
+static inline void __lse_atomic_and(int i, atomic_t *v)
 {
-       register int w0 asm ("w0") = i;
-       register atomic_t *x1 asm ("x1") = v;
-
-       asm volatile(ARM64_LSE_ATOMIC_INSN(
-       /* LL/SC */
-       __LL_SC_ATOMIC(and)
-       __nops(1),
-       /* LSE atomics */
+       asm volatile(
        "       mvn     %w[i], %w[i]\n"
-       "       stclr   %w[i], %[v]")
-       : [i] "+&r" (w0), [v] "+Q" (v->counter)
-       : "r" (x1)
-       : __LL_SC_CLOBBERS);
+       "       stclr   %w[i], %[v]"
+       : [i] "+&r" (i), [v] "+Q" (v->counter)
+       : "r" (v));
 }
 
 #define ATOMIC_FETCH_OP_AND(name, mb, cl...)                           \
-static inline int arch_atomic_fetch_and##name(int i, atomic_t *v)      \
+static inline int __lse_atomic_fetch_and##name(int i, atomic_t *v)     \
 {                                                                      \
-       register int w0 asm ("w0") = i;                                 \
-       register atomic_t *x1 asm ("x1") = v;                           \
-                                                                       \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(                             \
-       /* LL/SC */                                                     \
-       __LL_SC_ATOMIC(fetch_and##name)                                 \
-       __nops(1),                                                      \
-       /* LSE atomics */                                               \
+       asm volatile(                                                   \
        "       mvn     %w[i], %w[i]\n"                                 \
-       "       ldclr" #mb "    %w[i], %w[i], %[v]")                    \
-       : [i] "+&r" (w0), [v] "+Q" (v->counter)                         \
-       : "r" (x1)                                                      \
-       : __LL_SC_CLOBBERS, ##cl);                                      \
+       "       ldclr" #mb "    %w[i], %w[i], %[v]"                     \
+       : [i] "+&r" (i), [v] "+Q" (v->counter)                          \
+       : "r" (v)                                                       \
+       : cl);                                                          \
                                                                        \
-       return w0;                                                      \
+       return i;                                                       \
 }
 
 ATOMIC_FETCH_OP_AND(_relaxed,   )
@@ -138,42 +103,29 @@ ATOMIC_FETCH_OP_AND(        , al, "memory")
 
 #undef ATOMIC_FETCH_OP_AND
 
-static inline void arch_atomic_sub(int i, atomic_t *v)
+static inline void __lse_atomic_sub(int i, atomic_t *v)
 {
-       register int w0 asm ("w0") = i;
-       register atomic_t *x1 asm ("x1") = v;
-
-       asm volatile(ARM64_LSE_ATOMIC_INSN(
-       /* LL/SC */
-       __LL_SC_ATOMIC(sub)
-       __nops(1),
-       /* LSE atomics */
+       asm volatile(
        "       neg     %w[i], %w[i]\n"
-       "       stadd   %w[i], %[v]")
-       : [i] "+&r" (w0), [v] "+Q" (v->counter)
-       : "r" (x1)
-       : __LL_SC_CLOBBERS);
+       "       stadd   %w[i], %[v]"
+       : [i] "+&r" (i), [v] "+Q" (v->counter)
+       : "r" (v));
 }
 
 #define ATOMIC_OP_SUB_RETURN(name, mb, cl...)                          \
-static inline int arch_atomic_sub_return##name(int i, atomic_t *v)     \
+static inline int __lse_atomic_sub_return##name(int i, atomic_t *v)    \
 {                                                                      \
-       register int w0 asm ("w0") = i;                                 \
-       register atomic_t *x1 asm ("x1") = v;                           \
+       u32 tmp;                                                        \
                                                                        \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(                             \
-       /* LL/SC */                                                     \
-       __LL_SC_ATOMIC(sub_return##name)                                \
-       __nops(2),                                                      \
-       /* LSE atomics */                                               \
+       asm volatile(                                                   \
        "       neg     %w[i], %w[i]\n"                                 \
-       "       ldadd" #mb "    %w[i], w30, %[v]\n"                     \
-       "       add     %w[i], %w[i], w30")                             \
-       : [i] "+&r" (w0), [v] "+Q" (v->counter)                         \
-       : "r" (x1)                                                      \
-       : __LL_SC_CLOBBERS , ##cl);                                     \
+       "       ldadd" #mb "    %w[i], %w[tmp], %[v]\n"                 \
+       "       add     %w[i], %w[i], %w[tmp]"                          \
+       : [i] "+&r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)       \
+       : "r" (v)                                                       \
+       : cl);                                                  \
                                                                        \
-       return w0;                                                      \
+       return i;                                                       \
 }
 
 ATOMIC_OP_SUB_RETURN(_relaxed,   )
@@ -184,23 +136,16 @@ ATOMIC_OP_SUB_RETURN(        , al, "memory")
 #undef ATOMIC_OP_SUB_RETURN
 
 #define ATOMIC_FETCH_OP_SUB(name, mb, cl...)                           \
-static inline int arch_atomic_fetch_sub##name(int i, atomic_t *v)      \
+static inline int __lse_atomic_fetch_sub##name(int i, atomic_t *v)     \
 {                                                                      \
-       register int w0 asm ("w0") = i;                                 \
-       register atomic_t *x1 asm ("x1") = v;                           \
-                                                                       \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(                             \
-       /* LL/SC */                                                     \
-       __LL_SC_ATOMIC(fetch_sub##name)                                 \
-       __nops(1),                                                      \
-       /* LSE atomics */                                               \
+       asm volatile(                                                   \
        "       neg     %w[i], %w[i]\n"                                 \
-       "       ldadd" #mb "    %w[i], %w[i], %[v]")                    \
-       : [i] "+&r" (w0), [v] "+Q" (v->counter)                         \
-       : "r" (x1)                                                      \
-       : __LL_SC_CLOBBERS, ##cl);                                      \
+       "       ldadd" #mb "    %w[i], %w[i], %[v]"                     \
+       : [i] "+&r" (i), [v] "+Q" (v->counter)                          \
+       : "r" (v)                                                       \
+       : cl);                                                          \
                                                                        \
-       return w0;                                                      \
+       return i;                                                       \
 }
 
 ATOMIC_FETCH_OP_SUB(_relaxed,   )
@@ -209,20 +154,14 @@ ATOMIC_FETCH_OP_SUB(_release,  l, "memory")
 ATOMIC_FETCH_OP_SUB(        , al, "memory")
 
 #undef ATOMIC_FETCH_OP_SUB
-#undef __LL_SC_ATOMIC
 
-#define __LL_SC_ATOMIC64(op)   __LL_SC_CALL(arch_atomic64_##op)
 #define ATOMIC64_OP(op, asm_op)                                                \
-static inline void arch_atomic64_##op(s64 i, atomic64_t *v)            \
+static inline void __lse_atomic64_##op(s64 i, atomic64_t *v)           \
 {                                                                      \
-       register s64 x0 asm ("x0") = i;                                 \
-       register atomic64_t *x1 asm ("x1") = v;                         \
-                                                                       \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(op),        \
-"      " #asm_op "     %[i], %[v]\n")                                  \
-       : [i] "+r" (x0), [v] "+Q" (v->counter)                          \
-       : "r" (x1)                                                      \
-       : __LL_SC_CLOBBERS);                                            \
+       asm volatile(                                                   \
+"      " #asm_op "     %[i], %[v]\n"                                   \
+       : [i] "+r" (i), [v] "+Q" (v->counter)                           \
+       : "r" (v));                                                     \
 }
 
 ATOMIC64_OP(andnot, stclr)
@@ -233,21 +172,15 @@ ATOMIC64_OP(add, stadd)
 #undef ATOMIC64_OP
 
 #define ATOMIC64_FETCH_OP(name, mb, op, asm_op, cl...)                 \
-static inline s64 arch_atomic64_fetch_##op##name(s64 i, atomic64_t *v) \
+static inline long __lse_atomic64_fetch_##op##name(s64 i, atomic64_t *v)\
 {                                                                      \
-       register s64 x0 asm ("x0") = i;                                 \
-       register atomic64_t *x1 asm ("x1") = v;                         \
-                                                                       \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(                             \
-       /* LL/SC */                                                     \
-       __LL_SC_ATOMIC64(fetch_##op##name),                             \
-       /* LSE atomics */                                               \
-"      " #asm_op #mb " %[i], %[i], %[v]")                              \
-       : [i] "+r" (x0), [v] "+Q" (v->counter)                          \
-       : "r" (x1)                                                      \
-       : __LL_SC_CLOBBERS, ##cl);                                      \
+       asm volatile(                                                   \
+"      " #asm_op #mb " %[i], %[i], %[v]"                               \
+       : [i] "+r" (i), [v] "+Q" (v->counter)                           \
+       : "r" (v)                                                       \
+       : cl);                                                          \
                                                                        \
-       return x0;                                                      \
+       return i;                                                       \
 }
 
 #define ATOMIC64_FETCH_OPS(op, asm_op)                                 \
@@ -265,23 +198,18 @@ ATOMIC64_FETCH_OPS(add, ldadd)
 #undef ATOMIC64_FETCH_OPS
 
 #define ATOMIC64_OP_ADD_RETURN(name, mb, cl...)                                \
-static inline s64 arch_atomic64_add_return##name(s64 i, atomic64_t *v) \
+static inline long __lse_atomic64_add_return##name(s64 i, atomic64_t *v)\
 {                                                                      \
-       register s64 x0 asm ("x0") = i;                                 \
-       register atomic64_t *x1 asm ("x1") = v;                         \
+       unsigned long tmp;                                              \
                                                                        \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(                             \
-       /* LL/SC */                                                     \
-       __LL_SC_ATOMIC64(add_return##name)                              \
-       __nops(1),                                                      \
-       /* LSE atomics */                                               \
-       "       ldadd" #mb "    %[i], x30, %[v]\n"                      \
-       "       add     %[i], %[i], x30")                               \
-       : [i] "+r" (x0), [v] "+Q" (v->counter)                          \
-       : "r" (x1)                                                      \
-       : __LL_SC_CLOBBERS, ##cl);                                      \
+       asm volatile(                                                   \
+       "       ldadd" #mb "    %[i], %x[tmp], %[v]\n"                  \
+       "       add     %[i], %[i], %x[tmp]"                            \
+       : [i] "+r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)        \
+       : "r" (v)                                                       \
+       : cl);                                                          \
                                                                        \
-       return x0;                                                      \
+       return i;                                                       \
 }
 
 ATOMIC64_OP_ADD_RETURN(_relaxed,   )
@@ -291,41 +219,26 @@ ATOMIC64_OP_ADD_RETURN(        , al, "memory")
 
 #undef ATOMIC64_OP_ADD_RETURN
 
-static inline void arch_atomic64_and(s64 i, atomic64_t *v)
+static inline void __lse_atomic64_and(s64 i, atomic64_t *v)
 {
-       register s64 x0 asm ("x0") = i;
-       register atomic64_t *x1 asm ("x1") = v;
-
-       asm volatile(ARM64_LSE_ATOMIC_INSN(
-       /* LL/SC */
-       __LL_SC_ATOMIC64(and)
-       __nops(1),
-       /* LSE atomics */
+       asm volatile(
        "       mvn     %[i], %[i]\n"
-       "       stclr   %[i], %[v]")
-       : [i] "+&r" (x0), [v] "+Q" (v->counter)
-       : "r" (x1)
-       : __LL_SC_CLOBBERS);
+       "       stclr   %[i], %[v]"
+       : [i] "+&r" (i), [v] "+Q" (v->counter)
+       : "r" (v));
 }
 
 #define ATOMIC64_FETCH_OP_AND(name, mb, cl...)                         \
-static inline s64 arch_atomic64_fetch_and##name(s64 i, atomic64_t *v)  \
+static inline long __lse_atomic64_fetch_and##name(s64 i, atomic64_t *v)        \
 {                                                                      \
-       register s64 x0 asm ("x0") = i;                                 \
-       register atomic64_t *x1 asm ("x1") = v;                         \
-                                                                       \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(                             \
-       /* LL/SC */                                                     \
-       __LL_SC_ATOMIC64(fetch_and##name)                               \
-       __nops(1),                                                      \
-       /* LSE atomics */                                               \
+       asm volatile(                                                   \
        "       mvn     %[i], %[i]\n"                                   \
-       "       ldclr" #mb "    %[i], %[i], %[v]")                      \
-       : [i] "+&r" (x0), [v] "+Q" (v->counter)                         \
-       : "r" (x1)                                                      \
-       : __LL_SC_CLOBBERS, ##cl);                                      \
+       "       ldclr" #mb "    %[i], %[i], %[v]"                       \
+       : [i] "+&r" (i), [v] "+Q" (v->counter)                          \
+       : "r" (v)                                                       \
+       : cl);                                                          \
                                                                        \
-       return x0;                                                      \
+       return i;                                                       \
 }
 
 ATOMIC64_FETCH_OP_AND(_relaxed,   )
@@ -335,42 +248,29 @@ ATOMIC64_FETCH_OP_AND(        , al, "memory")
 
 #undef ATOMIC64_FETCH_OP_AND
 
-static inline void arch_atomic64_sub(s64 i, atomic64_t *v)
+static inline void __lse_atomic64_sub(s64 i, atomic64_t *v)
 {
-       register s64 x0 asm ("x0") = i;
-       register atomic64_t *x1 asm ("x1") = v;
-
-       asm volatile(ARM64_LSE_ATOMIC_INSN(
-       /* LL/SC */
-       __LL_SC_ATOMIC64(sub)
-       __nops(1),
-       /* LSE atomics */
+       asm volatile(
        "       neg     %[i], %[i]\n"
-       "       stadd   %[i], %[v]")
-       : [i] "+&r" (x0), [v] "+Q" (v->counter)
-       : "r" (x1)
-       : __LL_SC_CLOBBERS);
+       "       stadd   %[i], %[v]"
+       : [i] "+&r" (i), [v] "+Q" (v->counter)
+       : "r" (v));
 }
 
 #define ATOMIC64_OP_SUB_RETURN(name, mb, cl...)                                \
-static inline s64 arch_atomic64_sub_return##name(s64 i, atomic64_t *v) \
+static inline long __lse_atomic64_sub_return##name(s64 i, atomic64_t *v)       \
 {                                                                      \
-       register s64 x0 asm ("x0") = i;                                 \
-       register atomic64_t *x1 asm ("x1") = v;                         \
+       unsigned long tmp;                                              \
                                                                        \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(                             \
-       /* LL/SC */                                                     \
-       __LL_SC_ATOMIC64(sub_return##name)                              \
-       __nops(2),                                                      \
-       /* LSE atomics */                                               \
+       asm volatile(                                                   \
        "       neg     %[i], %[i]\n"                                   \
-       "       ldadd" #mb "    %[i], x30, %[v]\n"                      \
-       "       add     %[i], %[i], x30")                               \
-       : [i] "+&r" (x0), [v] "+Q" (v->counter)                         \
-       : "r" (x1)                                                      \
-       : __LL_SC_CLOBBERS, ##cl);                                      \
+       "       ldadd" #mb "    %[i], %x[tmp], %[v]\n"                  \
+       "       add     %[i], %[i], %x[tmp]"                            \
+       : [i] "+&r" (i), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)       \
+       : "r" (v)                                                       \
+       : cl);                                                          \
                                                                        \
-       return x0;                                                      \
+       return i;                                                       \
 }
 
 ATOMIC64_OP_SUB_RETURN(_relaxed,   )
@@ -381,23 +281,16 @@ ATOMIC64_OP_SUB_RETURN(        , al, "memory")
 #undef ATOMIC64_OP_SUB_RETURN
 
 #define ATOMIC64_FETCH_OP_SUB(name, mb, cl...)                         \
-static inline s64 arch_atomic64_fetch_sub##name(s64 i, atomic64_t *v)  \
+static inline long __lse_atomic64_fetch_sub##name(s64 i, atomic64_t *v)        \
 {                                                                      \
-       register s64 x0 asm ("x0") = i;                                 \
-       register atomic64_t *x1 asm ("x1") = v;                         \
-                                                                       \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(                             \
-       /* LL/SC */                                                     \
-       __LL_SC_ATOMIC64(fetch_sub##name)                               \
-       __nops(1),                                                      \
-       /* LSE atomics */                                               \
+       asm volatile(                                                   \
        "       neg     %[i], %[i]\n"                                   \
-       "       ldadd" #mb "    %[i], %[i], %[v]")                      \
-       : [i] "+&r" (x0), [v] "+Q" (v->counter)                         \
-       : "r" (x1)                                                      \
-       : __LL_SC_CLOBBERS, ##cl);                                      \
+       "       ldadd" #mb "    %[i], %[i], %[v]"                       \
+       : [i] "+&r" (i), [v] "+Q" (v->counter)                          \
+       : "r" (v)                                                       \
+       : cl);                                                          \
                                                                        \
-       return x0;                                                      \
+       return i;                                                       \
 }
 
 ATOMIC64_FETCH_OP_SUB(_relaxed,   )
@@ -407,54 +300,44 @@ ATOMIC64_FETCH_OP_SUB(        , al, "memory")
 
 #undef ATOMIC64_FETCH_OP_SUB
 
-static inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
+static inline s64 __lse_atomic64_dec_if_positive(atomic64_t *v)
 {
-       register long x0 asm ("x0") = (long)v;
-
-       asm volatile(ARM64_LSE_ATOMIC_INSN(
-       /* LL/SC */
-       __LL_SC_ATOMIC64(dec_if_positive)
-       __nops(6),
-       /* LSE atomics */
-       "1:     ldr     x30, %[v]\n"
-       "       subs    %[ret], x30, #1\n"
+       unsigned long tmp;
+
+       asm volatile(
+       "1:     ldr     %x[tmp], %[v]\n"
+       "       subs    %[ret], %x[tmp], #1\n"
        "       b.lt    2f\n"
-       "       casal   x30, %[ret], %[v]\n"
-       "       sub     x30, x30, #1\n"
-       "       sub     x30, x30, %[ret]\n"
-       "       cbnz    x30, 1b\n"
-       "2:")
-       : [ret] "+&r" (x0), [v] "+Q" (v->counter)
+       "       casal   %x[tmp], %[ret], %[v]\n"
+       "       sub     %x[tmp], %x[tmp], #1\n"
+       "       sub     %x[tmp], %x[tmp], %[ret]\n"
+       "       cbnz    %x[tmp], 1b\n"
+       "2:"
+       : [ret] "+&r" (v), [v] "+Q" (v->counter), [tmp] "=&r" (tmp)
        :
-       : __LL_SC_CLOBBERS, "cc", "memory");
+       : "cc", "memory");
 
-       return x0;
+       return (long)v;
 }
 
-#undef __LL_SC_ATOMIC64
-
-#define __LL_SC_CMPXCHG(op)    __LL_SC_CALL(__cmpxchg_case_##op)
-
 #define __CMPXCHG_CASE(w, sfx, name, sz, mb, cl...)                    \
-static inline u##sz __cmpxchg_case_##name##sz(volatile void *ptr,      \
+static inline u##sz __lse__cmpxchg_case_##name##sz(volatile void *ptr, \
                                              u##sz old,                \
                                              u##sz new)                \
 {                                                                      \
        register unsigned long x0 asm ("x0") = (unsigned long)ptr;      \
        register u##sz x1 asm ("x1") = old;                             \
        register u##sz x2 asm ("x2") = new;                             \
+       unsigned long tmp;                                              \
                                                                        \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(                             \
-       /* LL/SC */                                                     \
-       __LL_SC_CMPXCHG(name##sz)                                       \
-       __nops(2),                                                      \
-       /* LSE atomics */                                               \
-       "       mov     " #w "30, %" #w "[old]\n"                       \
-       "       cas" #mb #sfx "\t" #w "30, %" #w "[new], %[v]\n"        \
-       "       mov     %" #w "[ret], " #w "30")                        \
-       : [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr)             \
+       asm volatile(                                                   \
+       "       mov     %" #w "[tmp], %" #w "[old]\n"                   \
+       "       cas" #mb #sfx "\t%" #w "[tmp], %" #w "[new], %[v]\n"    \
+       "       mov     %" #w "[ret], %" #w "[tmp]"                     \
+       : [ret] "+r" (x0), [v] "+Q" (*(unsigned long *)ptr),            \
+         [tmp] "=&r" (tmp)                                             \
        : [old] "r" (x1), [new] "r" (x2)                                \
-       : __LL_SC_CLOBBERS, ##cl);                                      \
+       : cl);                                                          \
                                                                        \
        return x0;                                                      \
 }
@@ -476,13 +359,10 @@ __CMPXCHG_CASE(w, h,  mb_, 16, al, "memory")
 __CMPXCHG_CASE(w,  ,  mb_, 32, al, "memory")
 __CMPXCHG_CASE(x,  ,  mb_, 64, al, "memory")
 
-#undef __LL_SC_CMPXCHG
 #undef __CMPXCHG_CASE
 
-#define __LL_SC_CMPXCHG_DBL(op)        __LL_SC_CALL(__cmpxchg_double##op)
-
 #define __CMPXCHG_DBL(name, mb, cl...)                                 \
-static inline long __cmpxchg_double##name(unsigned long old1,          \
+static inline long __lse__cmpxchg_double##name(unsigned long old1,     \
                                         unsigned long old2,            \
                                         unsigned long new1,            \
                                         unsigned long new2,            \
@@ -496,20 +376,16 @@ static inline long __cmpxchg_double##name(unsigned long old1,             \
        register unsigned long x3 asm ("x3") = new2;                    \
        register unsigned long x4 asm ("x4") = (unsigned long)ptr;      \
                                                                        \
-       asm volatile(ARM64_LSE_ATOMIC_INSN(                             \
-       /* LL/SC */                                                     \
-       __LL_SC_CMPXCHG_DBL(name)                                       \
-       __nops(3),                                                      \
-       /* LSE atomics */                                               \
+       asm volatile(                                                   \
        "       casp" #mb "\t%[old1], %[old2], %[new1], %[new2], %[v]\n"\
        "       eor     %[old1], %[old1], %[oldval1]\n"                 \
        "       eor     %[old2], %[old2], %[oldval2]\n"                 \
-       "       orr     %[old1], %[old1], %[old2]")                     \
+       "       orr     %[old1], %[old1], %[old2]"                      \
        : [old1] "+&r" (x0), [old2] "+&r" (x1),                         \
          [v] "+Q" (*(unsigned long *)ptr)                              \
        : [new1] "r" (x2), [new2] "r" (x3), [ptr] "r" (x4),             \
          [oldval1] "r" (oldval1), [oldval2] "r" (oldval2)              \
-       : __LL_SC_CLOBBERS, ##cl);                                      \
+       : cl);                                                          \
                                                                        \
        return x0;                                                      \
 }
@@ -517,7 +393,6 @@ static inline long __cmpxchg_double##name(unsigned long old1,               \
 __CMPXCHG_DBL(   ,   )
 __CMPXCHG_DBL(_mb, al, "memory")
 
-#undef __LL_SC_CMPXCHG_DBL
 #undef __CMPXCHG_DBL
 
 #endif /* __ASM_ATOMIC_LSE_H */
index 64eeaa4..43da6dd 100644 (file)
@@ -78,7 +78,7 @@ static inline u32 cache_type_cwg(void)
        return (read_cpuid_cachetype() >> CTR_CWG_SHIFT) & CTR_CWG_MASK;
 }
 
-#define __read_mostly __attribute__((__section__(".data..read_mostly")))
+#define __read_mostly __section(.data..read_mostly)
 
 static inline int cache_line_size_of_cpu(void)
 {
index 7a299a2..a1398f2 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/build_bug.h>
 #include <linux/compiler.h>
 
-#include <asm/atomic.h>
 #include <asm/barrier.h>
 #include <asm/lse.h>
 
@@ -104,6 +103,50 @@ __XCHG_GEN(_mb)
 #define arch_xchg_release(...) __xchg_wrapper(_rel, __VA_ARGS__)
 #define arch_xchg(...)         __xchg_wrapper( _mb, __VA_ARGS__)
 
+#define __CMPXCHG_CASE(name, sz)                       \
+static inline u##sz __cmpxchg_case_##name##sz(volatile void *ptr,      \
+                                             u##sz old,                \
+                                             u##sz new)                \
+{                                                                      \
+       return __lse_ll_sc_body(_cmpxchg_case_##name##sz,               \
+                               ptr, old, new);                         \
+}
+
+__CMPXCHG_CASE(    ,  8)
+__CMPXCHG_CASE(    , 16)
+__CMPXCHG_CASE(    , 32)
+__CMPXCHG_CASE(    , 64)
+__CMPXCHG_CASE(acq_,  8)
+__CMPXCHG_CASE(acq_, 16)
+__CMPXCHG_CASE(acq_, 32)
+__CMPXCHG_CASE(acq_, 64)
+__CMPXCHG_CASE(rel_,  8)
+__CMPXCHG_CASE(rel_, 16)
+__CMPXCHG_CASE(rel_, 32)
+__CMPXCHG_CASE(rel_, 64)
+__CMPXCHG_CASE(mb_,  8)
+__CMPXCHG_CASE(mb_, 16)
+__CMPXCHG_CASE(mb_, 32)
+__CMPXCHG_CASE(mb_, 64)
+
+#undef __CMPXCHG_CASE
+
+#define __CMPXCHG_DBL(name)                                            \
+static inline long __cmpxchg_double##name(unsigned long old1,          \
+                                        unsigned long old2,            \
+                                        unsigned long new1,            \
+                                        unsigned long new2,            \
+                                        volatile void *ptr)            \
+{                                                                      \
+       return __lse_ll_sc_body(_cmpxchg_double##name,                  \
+                               old1, old2, new1, new2, ptr);           \
+}
+
+__CMPXCHG_DBL(   )
+__CMPXCHG_DBL(_mb)
+
+#undef __CMPXCHG_DBL
+
 #define __CMPXCHG_GEN(sfx)                                             \
 static inline unsigned long __cmpxchg##sfx(volatile void *ptr,         \
                                           unsigned long old,           \
index fb8ad46..b0d53a2 100644 (file)
@@ -4,7 +4,6 @@
  */
 #ifndef __ASM_COMPAT_H
 #define __ASM_COMPAT_H
-#ifdef __KERNEL__
 #ifdef CONFIG_COMPAT
 
 /*
@@ -215,5 +214,4 @@ static inline int is_compat_thread(struct thread_info *thread)
 }
 
 #endif /* CONFIG_COMPAT */
-#endif /* __KERNEL__ */
 #endif /* __ASM_COMPAT_H */
index c09d633..86aabf1 100644 (file)
@@ -23,6 +23,8 @@
  * @cpu_boot:  Boots a cpu into the kernel.
  * @cpu_postboot: Optionally, perform any post-boot cleanup or necesary
  *             synchronisation. Called from the cpu being booted.
+ * @cpu_can_disable: Determines whether a CPU can be disabled based on
+ *             mechanism-specific information.
  * @cpu_disable: Prepares a cpu to die. May fail for some mechanism-specific
  *             reason, which will cause the hot unplug to be aborted. Called
  *             from the cpu to be killed.
@@ -42,6 +44,7 @@ struct cpu_operations {
        int             (*cpu_boot)(unsigned int);
        void            (*cpu_postboot)(void);
 #ifdef CONFIG_HOTPLUG_CPU
+       bool            (*cpu_can_disable)(unsigned int cpu);
        int             (*cpu_disable)(unsigned int cpu);
        void            (*cpu_die)(unsigned int cpu);
        int             (*cpu_kill)(unsigned int cpu);
index c96ffa4..9cde5d2 100644 (file)
@@ -289,9 +289,16 @@ struct arm64_cpu_capabilities {
        u16 type;
        bool (*matches)(const struct arm64_cpu_capabilities *caps, int scope);
        /*
-        * Take the appropriate actions to enable this capability for this CPU.
-        * For each successfully booted CPU, this method is called for each
-        * globally detected capability.
+        * Take the appropriate actions to configure this capability
+        * for this CPU. If the capability is detected by the kernel
+        * this will be called on all the CPUs in the system,
+        * including the hotplugged CPUs, regardless of whether the
+        * capability is available on that specific CPU. This is
+        * useful for some capabilities (e.g, working around CPU
+        * errata), where all the CPUs must take some action (e.g,
+        * changing system control/configuration). Thus, if an action
+        * is required only if the CPU has the capability, then the
+        * routine must check it before taking any action.
         */
        void (*cpu_enable)(const struct arm64_cpu_capabilities *cap);
        union {
@@ -363,21 +370,6 @@ cpucap_multi_entry_cap_matches(const struct arm64_cpu_capabilities *entry,
        return false;
 }
 
-/*
- * Take appropriate action for all matching entries in the shared capability
- * entry.
- */
-static inline void
-cpucap_multi_entry_cap_cpu_enable(const struct arm64_cpu_capabilities *entry)
-{
-       const struct arm64_cpu_capabilities *caps;
-
-       for (caps = entry->match_list; caps->matches; caps++)
-               if (caps->matches(caps, SCOPE_LOCAL_CPU) &&
-                   caps->cpu_enable)
-                       caps->cpu_enable(caps);
-}
-
 extern DECLARE_BITMAP(cpu_hwcaps, ARM64_NCAPS);
 extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
 extern struct static_key_false arm64_const_caps_ready;
index e7d4663..b1454d1 100644 (file)
 #define MIDR_CPU_MODEL_MASK (MIDR_IMPLEMENTOR_MASK | MIDR_PARTNUM_MASK | \
                             MIDR_ARCHITECTURE_MASK)
 
-#define MIDR_IS_CPU_MODEL_RANGE(midr, model, rv_min, rv_max)           \
-({                                                                     \
-       u32 _model = (midr) & MIDR_CPU_MODEL_MASK;                      \
-       u32 rv = (midr) & (MIDR_REVISION_MASK | MIDR_VARIANT_MASK);     \
-                                                                       \
-       _model == (model) && rv >= (rv_min) && rv <= (rv_max);          \
- })
-
 #define ARM_CPU_IMP_ARM                        0x41
 #define ARM_CPU_IMP_APM                        0x50
 #define ARM_CPU_IMP_CAVIUM             0x43
@@ -159,10 +151,19 @@ struct midr_range {
 #define MIDR_REV(m, v, r) MIDR_RANGE(m, v, r, v, r)
 #define MIDR_ALL_VERSIONS(m) MIDR_RANGE(m, 0, 0, 0xf, 0xf)
 
+static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
+                                          u32 rv_max)
+{
+       u32 _model = midr & MIDR_CPU_MODEL_MASK;
+       u32 rv = midr & (MIDR_REVISION_MASK | MIDR_VARIANT_MASK);
+
+       return _model == model && rv >= rv_min && rv <= rv_max;
+}
+
 static inline bool is_midr_in_range(u32 midr, struct midr_range const *range)
 {
-       return MIDR_IS_CPU_MODEL_RANGE(midr, range->model,
-                                range->rv_min, range->rv_max);
+       return midr_is_cpu_model_range(midr, range->model,
+                                      range->rv_min, range->rv_max);
 }
 
 static inline bool
index d8ec5bb..7619f47 100644 (file)
@@ -5,8 +5,6 @@
 #ifndef __ASM_DEBUG_MONITORS_H
 #define __ASM_DEBUG_MONITORS_H
 
-#ifdef __KERNEL__
-
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <asm/brk-imm.h>
@@ -128,5 +126,4 @@ static inline int reinstall_suspended_bps(struct pt_regs *regs)
 int aarch32_break_handler(struct pt_regs *regs);
 
 #endif /* __ASSEMBLY */
-#endif /* __KERNEL__ */
 #endif /* __ASM_DEBUG_MONITORS_H */
index bdcb092..fb3e504 100644 (file)
@@ -5,8 +5,6 @@
 #ifndef __ASM_DMA_MAPPING_H
 #define __ASM_DMA_MAPPING_H
 
-#ifdef __KERNEL__
-
 #include <linux/types.h>
 #include <linux/vmalloc.h>
 
@@ -27,5 +25,4 @@ static inline bool is_device_dma_coherent(struct device *dev)
        return dev->dma_coherent;
 }
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_DMA_MAPPING_H */
index 76a1447..b54d3a8 100644 (file)
@@ -79,7 +79,7 @@ static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base)
 
 /*
  * On arm64, we have to ensure that the initrd ends up in the linear region,
- * which is a 1 GB aligned region of size '1UL << (VA_BITS - 1)' that is
+ * which is a 1 GB aligned region of size '1UL << (VA_BITS_MIN - 1)' that is
  * guaranteed to cover the kernel Image.
  *
  * Since the EFI stub is part of the kernel Image, we can relax the
@@ -90,7 +90,7 @@ static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base)
 static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base,
                                                    unsigned long image_addr)
 {
-       return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS - 1));
+       return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS_MIN - 1));
 }
 
 #define efi_call_early(f, ...)         sys_table_arg->boottime->f(__VA_ARGS__)
index 65ac184..cb29253 100644 (file)
@@ -34,7 +34,8 @@
 #define ESR_ELx_EC_SMC64       (0x17)  /* EL2 and above */
 #define ESR_ELx_EC_SYS64       (0x18)
 #define ESR_ELx_EC_SVE         (0x19)
-/* Unallocated EC: 0x1A - 0x1E */
+#define ESR_ELx_EC_ERET                (0x1a)  /* EL2 only */
+/* Unallocated EC: 0x1b - 0x1E */
 #define ESR_ELx_EC_IMP_DEF     (0x1f)  /* EL3 only */
 #define ESR_ELx_EC_IABT_LOW    (0x20)
 #define ESR_ELx_EC_IABT_CUR    (0x21)
index ed57b76..a17393f 100644 (file)
@@ -30,4 +30,6 @@ static inline u32 disr_to_esr(u64 disr)
        return esr;
 }
 
+asmlinkage void enter_from_user_mode(void);
+
 #endif /* __ASM_EXCEPTION_H */
index b6a2c35..59f10dd 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/stddef.h>
 #include <linux/types.h>
 
-#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
+#ifdef CONFIG_COMPAT
 /* Masks for extracting the FPSR and FPCR from the FPSCR */
 #define VFP_FPSCR_STAT_MASK    0xf800009f
 #define VFP_FPSCR_CTRL_MASK    0x07f79f00
index 6211e31..6cc26a1 100644 (file)
@@ -5,8 +5,6 @@
 #ifndef __ASM_FUTEX_H
 #define __ASM_FUTEX_H
 
-#ifdef __KERNEL__
-
 #include <linux/futex.h>
 #include <linux/uaccess.h>
 
@@ -129,5 +127,4 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *_uaddr,
        return ret;
 }
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_FUTEX_H */
index db9ab76..bc7aaed 100644 (file)
@@ -10,8 +10,6 @@
 #include <asm/sysreg.h>
 #include <asm/virt.h>
 
-#ifdef __KERNEL__
-
 struct arch_hw_breakpoint_ctrl {
        u32 __reserved  : 19,
        len             : 8,
@@ -156,5 +154,4 @@ static inline int get_num_wrps(void)
                                                ID_AA64DFR0_WRPS_SHIFT);
 }
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_BREAKPOINT_H */
index 7ed9262..323cb30 100644 (file)
@@ -8,8 +8,6 @@
 #ifndef __ASM_IO_H
 #define __ASM_IO_H
 
-#ifdef __KERNEL__
-
 #include <linux/types.h>
 
 #include <asm/byteorder.h>
@@ -97,7 +95,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 ({                                                                     \
        unsigned long tmp;                                              \
                                                                        \
-       rmb();                                                          \
+       dma_rmb();                                                              \
                                                                        \
        /*                                                              \
         * Create a dummy control dependency from the IO read to any    \
@@ -111,7 +109,7 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 })
 
 #define __io_par(v)            __iormb(v)
-#define __iowmb()              wmb()
+#define __iowmb()              dma_wmb()
 
 /*
  * Relaxed I/O memory access primitives. These follow the Device memory
@@ -165,14 +163,13 @@ extern void __memset_io(volatile void __iomem *, int, size_t);
  * I/O memory mapping functions.
  */
 extern void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot);
-extern void __iounmap(volatile void __iomem *addr);
+extern void iounmap(volatile void __iomem *addr);
 extern void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size);
 
 #define ioremap(addr, size)            __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
 #define ioremap_nocache(addr, size)    __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
 #define ioremap_wc(addr, size)         __ioremap((addr), (size), __pgprot(PROT_NORMAL_NC))
 #define ioremap_wt(addr, size)         __ioremap((addr), (size), __pgprot(PROT_DEVICE_nGnRE))
-#define iounmap                                __iounmap
 
 /*
  * PCI configuration space mapping function.
@@ -207,5 +204,4 @@ extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
 
 extern int devmem_is_allowed(unsigned long pfn);
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_IO_H */
index 7872f26..1a59f0e 100644 (file)
@@ -5,8 +5,6 @@
 #ifndef __ASM_IRQFLAGS_H
 #define __ASM_IRQFLAGS_H
 
-#ifdef __KERNEL__
-
 #include <asm/alternative.h>
 #include <asm/ptrace.h>
 #include <asm/sysreg.h>
@@ -128,5 +126,4 @@ static inline void arch_local_irq_restore(unsigned long flags)
                : "memory");
 }
 
-#endif
-#endif
+#endif /* __ASM_IRQFLAGS_H */
index b52aacd..b0dc4ab 100644 (file)
  * KASAN_SHADOW_START: beginning of the kernel virtual addresses.
  * KASAN_SHADOW_END: KASAN_SHADOW_START + 1/N of kernel virtual addresses,
  * where N = (1 << KASAN_SHADOW_SCALE_SHIFT).
- */
-#define KASAN_SHADOW_START      (VA_START)
-#define KASAN_SHADOW_END        (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)
-
-/*
+ *
+ * KASAN_SHADOW_OFFSET:
  * This value is used to map an address to the corresponding shadow
  * address by the following formula:
  *     shadow_addr = (address >> KASAN_SHADOW_SCALE_SHIFT) + KASAN_SHADOW_OFFSET
@@ -33,8 +30,8 @@
  *      KASAN_SHADOW_OFFSET = KASAN_SHADOW_END -
  *                             (1ULL << (64 - KASAN_SHADOW_SCALE_SHIFT))
  */
-#define KASAN_SHADOW_OFFSET     (KASAN_SHADOW_END - (1ULL << \
-                                       (64 - KASAN_SHADOW_SCALE_SHIFT)))
+#define _KASAN_SHADOW_START(va)        (KASAN_SHADOW_END - (1UL << ((va) - KASAN_SHADOW_SCALE_SHIFT)))
+#define KASAN_SHADOW_START      _KASAN_SHADOW_START(vabits_actual)
 
 void kasan_init(void);
 void kasan_copy_shadow(pgd_t *pgdir);
index 8262325..80b3882 100644 (file)
@@ -2,56 +2,47 @@
 #ifndef __ASM_LSE_H
 #define __ASM_LSE_H
 
+#include <asm/atomic_ll_sc.h>
+
 #if defined(CONFIG_AS_LSE) && defined(CONFIG_ARM64_LSE_ATOMICS)
 
 #include <linux/compiler_types.h>
 #include <linux/export.h>
+#include <linux/jump_label.h>
 #include <linux/stringify.h>
 #include <asm/alternative.h>
+#include <asm/atomic_lse.h>
 #include <asm/cpucaps.h>
 
-#ifdef __ASSEMBLER__
-
-.arch_extension        lse
-
-.macro alt_lse, llsc, lse
-       alternative_insn "\llsc", "\lse", ARM64_HAS_LSE_ATOMICS
-.endm
-
-#else  /* __ASSEMBLER__ */
-
 __asm__(".arch_extension       lse");
 
-/* Move the ll/sc atomics out-of-line */
-#define __LL_SC_INLINE         notrace
-#define __LL_SC_PREFIX(x)      __ll_sc_##x
-#define __LL_SC_EXPORT(x)      EXPORT_SYMBOL(__LL_SC_PREFIX(x))
+extern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS];
+extern struct static_key_false arm64_const_caps_ready;
+
+static inline bool system_uses_lse_atomics(void)
+{
+       return (static_branch_likely(&arm64_const_caps_ready)) &&
+               static_branch_likely(&cpu_hwcap_keys[ARM64_HAS_LSE_ATOMICS]);
+}
 
-/* Macro for constructing calls to out-of-line ll/sc atomics */
-#define __LL_SC_CALL(op)       "bl\t" __stringify(__LL_SC_PREFIX(op)) "\n"
-#define __LL_SC_CLOBBERS       "x16", "x17", "x30"
+#define __lse_ll_sc_body(op, ...)                                      \
+({                                                                     \
+       system_uses_lse_atomics() ?                                     \
+               __lse_##op(__VA_ARGS__) :                               \
+               __ll_sc_##op(__VA_ARGS__);                              \
+})
 
 /* In-line patching at runtime */
 #define ARM64_LSE_ATOMIC_INSN(llsc, lse)                               \
        ALTERNATIVE(llsc, lse, ARM64_HAS_LSE_ATOMICS)
 
-#endif /* __ASSEMBLER__ */
 #else  /* CONFIG_AS_LSE && CONFIG_ARM64_LSE_ATOMICS */
 
-#ifdef __ASSEMBLER__
-
-.macro alt_lse, llsc, lse
-       \llsc
-.endm
-
-#else  /* __ASSEMBLER__ */
+static inline bool system_uses_lse_atomics(void) { return false; }
 
-#define __LL_SC_INLINE         static inline
-#define __LL_SC_PREFIX(x)      x
-#define __LL_SC_EXPORT(x)
+#define __lse_ll_sc_body(op, ...)              __ll_sc_##op(__VA_ARGS__)
 
 #define ARM64_LSE_ATOMIC_INSN(llsc, lse)       llsc
 
-#endif /* __ASSEMBLER__ */
 #endif /* CONFIG_AS_LSE && CONFIG_ARM64_LSE_ATOMICS */
 #endif /* __ASM_LSE_H */
index fb04f10..b61b50b 100644 (file)
 
 #include <linux/compiler.h>
 #include <linux/const.h>
+#include <linux/sizes.h>
 #include <linux/types.h>
 #include <asm/bug.h>
 #include <asm/page-def.h>
-#include <linux/sizes.h>
 
 /*
  * Size of the PCI I/O space. This must remain a power of two so that
 /*
  * VMEMMAP_SIZE - allows the whole linear region to be covered by
  *                a struct page array
+ *
+ * If we are configured with a 52-bit kernel VA then our VMEMMAP_SIZE
+ * needs to cover the memory region from the beginning of the 52-bit
+ * PAGE_OFFSET all the way to PAGE_END for 48-bit. This allows us to
+ * keep a constant PAGE_OFFSET and "fallback" to using the higher end
+ * of the VMEMMAP where 52-bit support is not available in hardware.
  */
-#define VMEMMAP_SIZE (UL(1) << (VA_BITS - PAGE_SHIFT - 1 + STRUCT_PAGE_MAX_SHIFT))
+#define VMEMMAP_SIZE ((_PAGE_END(VA_BITS_MIN) - PAGE_OFFSET) \
+                       >> (PAGE_SHIFT - STRUCT_PAGE_MAX_SHIFT))
 
 /*
- * PAGE_OFFSET - the virtual address of the start of the linear map (top
- *              (VA_BITS - 1))
- * KIMAGE_VADDR - the virtual address of the start of the kernel image
+ * PAGE_OFFSET - the virtual address of the start of the linear map, at the
+ *               start of the TTBR1 address space.
+ * PAGE_END - the end of the linear map, where all other kernel mappings begin.
+ * KIMAGE_VADDR - the virtual address of the start of the kernel image.
  * VA_BITS - the maximum number of bits for virtual addresses.
- * VA_START - the first kernel virtual address.
  */
 #define VA_BITS                        (CONFIG_ARM64_VA_BITS)
-#define VA_START               (UL(0xffffffffffffffff) - \
-       (UL(1) << VA_BITS) + 1)
-#define PAGE_OFFSET            (UL(0xffffffffffffffff) - \
-       (UL(1) << (VA_BITS - 1)) + 1)
+#define _PAGE_OFFSET(va)       (-(UL(1) << (va)))
+#define PAGE_OFFSET            (_PAGE_OFFSET(VA_BITS))
 #define KIMAGE_VADDR           (MODULES_END)
-#define BPF_JIT_REGION_START   (VA_START + KASAN_SHADOW_SIZE)
+#define BPF_JIT_REGION_START   (KASAN_SHADOW_END)
 #define BPF_JIT_REGION_SIZE    (SZ_128M)
 #define BPF_JIT_REGION_END     (BPF_JIT_REGION_START + BPF_JIT_REGION_SIZE)
 #define MODULES_END            (MODULES_VADDR + MODULES_VSIZE)
 #define MODULES_VADDR          (BPF_JIT_REGION_END)
 #define MODULES_VSIZE          (SZ_128M)
-#define VMEMMAP_START          (PAGE_OFFSET - VMEMMAP_SIZE)
+#define VMEMMAP_START          (-VMEMMAP_SIZE - SZ_2M)
 #define PCI_IO_END             (VMEMMAP_START - SZ_2M)
 #define PCI_IO_START           (PCI_IO_END - PCI_IO_SIZE)
 #define FIXADDR_TOP            (PCI_IO_START - SZ_2M)
 
-#define KERNEL_START      _text
-#define KERNEL_END        _end
+#if VA_BITS > 48
+#define VA_BITS_MIN            (48)
+#else
+#define VA_BITS_MIN            (VA_BITS)
+#endif
+
+#define _PAGE_END(va)          (-(UL(1) << ((va) - 1)))
 
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
+#define KERNEL_START           _text
+#define KERNEL_END             _end
+
+#ifdef CONFIG_ARM64_VA_BITS_52
 #define MAX_USER_VA_BITS       52
 #else
 #define MAX_USER_VA_BITS       VA_BITS
  * significantly, so double the (minimum) stack size when they are in use.
  */
 #ifdef CONFIG_KASAN
-#define KASAN_SHADOW_SIZE      (UL(1) << (VA_BITS - KASAN_SHADOW_SCALE_SHIFT))
+#define KASAN_SHADOW_OFFSET    _AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
+#define KASAN_SHADOW_END       ((UL(1) << (64 - KASAN_SHADOW_SCALE_SHIFT)) \
+                                       + KASAN_SHADOW_OFFSET)
 #define KASAN_THREAD_SHIFT     1
 #else
-#define KASAN_SHADOW_SIZE      (0)
 #define KASAN_THREAD_SHIFT     0
-#endif
+#define KASAN_SHADOW_END       (_PAGE_END(VA_BITS_MIN))
+#endif /* CONFIG_KASAN */
 
 #define MIN_THREAD_SHIFT       (14 + KASAN_THREAD_SHIFT)
 
  * 16 KB granule: 128 level 3 entries, with contiguous bit
  * 64 KB granule:  32 level 3 entries, with contiguous bit
  */
-#define SEGMENT_ALIGN                  SZ_2M
+#define SEGMENT_ALIGN          SZ_2M
 #else
 /*
  *  4 KB granule:  16 level 3 entries, with contiguous bit
  * 16 KB granule:   4 level 3 entries, without contiguous bit
  * 64 KB granule:   1 level 3 entry
  */
-#define SEGMENT_ALIGN                  SZ_64K
+#define SEGMENT_ALIGN          SZ_64K
 #endif
 
 /*
 #endif
 
 #ifndef __ASSEMBLY__
+extern u64                     vabits_actual;
+#define PAGE_END               (_PAGE_END(vabits_actual))
 
 #include <linux/bitops.h>
 #include <linux/mmdebug.h>
 
+extern s64                     physvirt_offset;
 extern s64                     memstart_addr;
 /* PHYS_OFFSET - the physical address of the start of memory. */
 #define PHYS_OFFSET            ({ VM_BUG_ON(memstart_addr & 1); memstart_addr; })
@@ -176,9 +194,6 @@ static inline unsigned long kaslr_offset(void)
        return kimage_vaddr - KIMAGE_VADDR;
 }
 
-/* the actual size of a user virtual address */
-extern u64                     vabits_user;
-
 /*
  * Allow all memory at the discovery stage. We will clip it later.
  */
@@ -201,24 +216,24 @@ extern u64                        vabits_user;
  * pass on to access_ok(), for instance.
  */
 #define untagged_addr(addr)    \
-       ((__typeof__(addr))sign_extend64((u64)(addr), 55))
+       ((__force __typeof__(addr))sign_extend64((__force u64)(addr), 55))
 
 #ifdef CONFIG_KASAN_SW_TAGS
 #define __tag_shifted(tag)     ((u64)(tag) << 56)
-#define __tag_set(addr, tag)   (__typeof__(addr))( \
-               ((u64)(addr) & ~__tag_shifted(0xff)) | __tag_shifted(tag))
 #define __tag_reset(addr)      untagged_addr(addr)
 #define __tag_get(addr)                (__u8)((u64)(addr) >> 56)
 #else
+#define __tag_shifted(tag)     0UL
+#define __tag_reset(addr)      (addr)
+#define __tag_get(addr)                0
+#endif /* CONFIG_KASAN_SW_TAGS */
+
 static inline const void *__tag_set(const void *addr, u8 tag)
 {
-       return addr;
+       u64 __addr = (u64)addr & ~__tag_shifted(0xff);
+       return (const void *)(__addr | __tag_shifted(tag));
 }
 
-#define __tag_reset(addr)      (addr)
-#define __tag_get(addr)                0
-#endif
-
 /*
  * Physical vs virtual RAM address space conversion.  These are
  * private definitions which should NOT be used outside memory.h
@@ -227,19 +242,18 @@ static inline const void *__tag_set(const void *addr, u8 tag)
 
 
 /*
- * The linear kernel range starts in the middle of the virtual adddress
+ * The linear kernel range starts at the bottom of the virtual address
  * space. Testing the top bit for the start of the region is a
- * sufficient check.
+ * sufficient check and avoids having to worry about the tag.
  */
-#define __is_lm_address(addr)  (!!((addr) & BIT(VA_BITS - 1)))
+#define __is_lm_address(addr)  (!(((u64)addr) & BIT(vabits_actual - 1)))
 
-#define __lm_to_phys(addr)     (((addr) & ~PAGE_OFFSET) + PHYS_OFFSET)
+#define __lm_to_phys(addr)     (((addr) + physvirt_offset))
 #define __kimg_to_phys(addr)   ((addr) - kimage_voffset)
 
 #define __virt_to_phys_nodebug(x) ({                                   \
-       phys_addr_t __x = (phys_addr_t)(x);                             \
-       __is_lm_address(__x) ? __lm_to_phys(__x) :                      \
-                              __kimg_to_phys(__x);                     \
+       phys_addr_t __x = (phys_addr_t)(__tag_reset(x));                \
+       __is_lm_address(__x) ? __lm_to_phys(__x) : __kimg_to_phys(__x); \
 })
 
 #define __pa_symbol_nodebug(x) __kimg_to_phys((phys_addr_t)(x))
@@ -250,9 +264,9 @@ extern phys_addr_t __phys_addr_symbol(unsigned long x);
 #else
 #define __virt_to_phys(x)      __virt_to_phys_nodebug(x)
 #define __phys_addr_symbol(x)  __pa_symbol_nodebug(x)
-#endif
+#endif /* CONFIG_DEBUG_VIRTUAL */
 
-#define __phys_to_virt(x)      ((unsigned long)((x) - PHYS_OFFSET) | PAGE_OFFSET)
+#define __phys_to_virt(x)      ((unsigned long)((x) - physvirt_offset))
 #define __phys_to_kimg(x)      ((unsigned long)((x) + kimage_voffset))
 
 /*
@@ -286,41 +300,38 @@ static inline void *phys_to_virt(phys_addr_t x)
 #define __pa_nodebug(x)                __virt_to_phys_nodebug((unsigned long)(x))
 #define __va(x)                        ((void *)__phys_to_virt((phys_addr_t)(x)))
 #define pfn_to_kaddr(pfn)      __va((pfn) << PAGE_SHIFT)
-#define virt_to_pfn(x)      __phys_to_pfn(__virt_to_phys((unsigned long)(x)))
-#define sym_to_pfn(x)      __phys_to_pfn(__pa_symbol(x))
+#define virt_to_pfn(x)         __phys_to_pfn(__virt_to_phys((unsigned long)(x)))
+#define sym_to_pfn(x)          __phys_to_pfn(__pa_symbol(x))
 
 /*
- *  virt_to_page(k)    convert a _valid_ virtual address to struct page *
- *  virt_addr_valid(k) indicates whether a virtual address is valid
+ *  virt_to_page(x)    convert a _valid_ virtual address to struct page *
+ *  virt_addr_valid(x) indicates whether a virtual address is valid
  */
 #define ARCH_PFN_OFFSET                ((unsigned long)PHYS_PFN_OFFSET)
 
 #if !defined(CONFIG_SPARSEMEM_VMEMMAP) || defined(CONFIG_DEBUG_VIRTUAL)
-#define virt_to_page(kaddr)    pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-#define _virt_addr_valid(kaddr)        pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
+#define virt_to_page(x)                pfn_to_page(virt_to_pfn(x))
 #else
-#define __virt_to_pgoff(kaddr) (((u64)(kaddr) & ~PAGE_OFFSET) / PAGE_SIZE * sizeof(struct page))
-#define __page_to_voff(kaddr)  (((u64)(kaddr) & ~VMEMMAP_START) * PAGE_SIZE / sizeof(struct page))
-
-#define page_to_virt(page)     ({                                      \
-       unsigned long __addr =                                          \
-               ((__page_to_voff(page)) | PAGE_OFFSET);                 \
-       const void *__addr_tag =                                        \
-               __tag_set((void *)__addr, page_kasan_tag(page));        \
-       ((void *)__addr_tag);                                           \
+#define page_to_virt(x)        ({                                              \
+       __typeof__(x) __page = x;                                       \
+       u64 __idx = ((u64)__page - VMEMMAP_START) / sizeof(struct page);\
+       u64 __addr = PAGE_OFFSET + (__idx * PAGE_SIZE);                 \
+       (void *)__tag_set((const void *)__addr, page_kasan_tag(__page));\
 })
 
-#define virt_to_page(vaddr)    ((struct page *)((__virt_to_pgoff(vaddr)) | VMEMMAP_START))
+#define virt_to_page(x)        ({                                              \
+       u64 __idx = (__tag_reset((u64)x) - PAGE_OFFSET) / PAGE_SIZE;    \
+       u64 __addr = VMEMMAP_START + (__idx * sizeof(struct page));     \
+       (struct page *)__addr;                                          \
+})
+#endif /* !CONFIG_SPARSEMEM_VMEMMAP || CONFIG_DEBUG_VIRTUAL */
 
-#define _virt_addr_valid(kaddr)        pfn_valid((((u64)(kaddr) & ~PAGE_OFFSET) \
-                                          + PHYS_OFFSET) >> PAGE_SHIFT)
-#endif
-#endif
+#define virt_addr_valid(addr)  ({                                      \
+       __typeof__(addr) __addr = addr;                                 \
+       __is_lm_address(__addr) && pfn_valid(virt_to_pfn(__addr));      \
+})
 
-#define _virt_addr_is_linear(kaddr)    \
-       (__tag_reset((u64)(kaddr)) >= PAGE_OFFSET)
-#define virt_addr_valid(kaddr)         \
-       (_virt_addr_is_linear(kaddr) && _virt_addr_valid(kaddr))
+#endif /* !ASSEMBLY */
 
 /*
  * Given that the GIC architecture permits ITS implementations that can only be
@@ -335,4 +346,4 @@ static inline void *phys_to_virt(phys_addr_t x)
 
 #include <asm-generic/memory_model.h>
 
-#endif
+#endif /* __ASM_MEMORY_H */
index fd61613..f217e32 100644 (file)
@@ -126,7 +126,7 @@ extern void init_mem_pgprot(void);
 extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
                               unsigned long virt, phys_addr_t size,
                               pgprot_t prot, bool page_mappings_only);
-extern void *fixmap_remap_fdt(phys_addr_t dt_phys);
+extern void *fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot);
 extern void mark_linear_text_alias_ro(void);
 
 #define INIT_MM_CONTEXT(name)  \
index 7ed0adb..3827ff4 100644 (file)
@@ -63,7 +63,7 @@ extern u64 idmap_ptrs_per_pgd;
 
 static inline bool __cpu_uses_extended_idmap(void)
 {
-       if (IS_ENABLED(CONFIG_ARM64_USER_VA_BITS_52))
+       if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52))
                return false;
 
        return unlikely(idmap_t0sz != TCR_T0SZ(VA_BITS));
@@ -95,7 +95,7 @@ static inline void __cpu_set_tcr_t0sz(unsigned long t0sz)
        isb();
 }
 
-#define cpu_set_default_tcr_t0sz()     __cpu_set_tcr_t0sz(TCR_T0SZ(VA_BITS))
+#define cpu_set_default_tcr_t0sz()     __cpu_set_tcr_t0sz(TCR_T0SZ(vabits_actual))
 #define cpu_set_idmap_tcr_t0sz()       __cpu_set_tcr_t0sz(idmap_t0sz)
 
 /*
index 9e69068..70b323c 100644 (file)
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef __ASM_PCI_H
 #define __ASM_PCI_H
-#ifdef __KERNEL__
 
 #include <linux/types.h>
 #include <linux/slab.h>
@@ -35,5 +34,4 @@ static inline int pci_proc_domain(struct pci_bus *bus)
 }
 #endif  /* CONFIG_PCI */
 
-#endif  /* __KERNEL__ */
 #endif  /* __ASM_PCI_H */
index db92950..3df60f9 100644 (file)
 #define TTBR_BADDR_MASK_52     (((UL(1) << 46) - 1) << 2)
 #endif
 
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
+#ifdef CONFIG_ARM64_VA_BITS_52
 /* Must be at least 64-byte aligned to prevent corruption of the TTBR */
 #define TTBR1_BADDR_4852_OFFSET        (((UL(1) << (52 - PGDIR_SHIFT)) - \
                                 (UL(1) << (48 - PGDIR_SHIFT))) * 8)
index e09760e..470ba7a 100644 (file)
@@ -21,9 +21,7 @@
  *     and fixed mappings
  */
 #define VMALLOC_START          (MODULES_END)
-#define VMALLOC_END            (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
-
-#define vmemmap                        ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
+#define VMALLOC_END            (- PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
 
 #define FIRST_USER_ADDRESS     0UL
 
@@ -35,6 +33,8 @@
 #include <linux/mm_types.h>
 #include <linux/sched.h>
 
+extern struct page *vmemmap;
+
 extern void __pte_error(const char *file, int line, unsigned long val);
 extern void __pmd_error(const char *file, int line, unsigned long val);
 extern void __pud_error(const char *file, int line, unsigned long val);
@@ -220,8 +220,10 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
         * Only if the new pte is valid and kernel, otherwise TLB maintenance
         * or update_mmu_cache() have the necessary barriers.
         */
-       if (pte_valid_not_user(pte))
+       if (pte_valid_not_user(pte)) {
                dsb(ishst);
+               isb();
+       }
 }
 
 extern void __sync_icache_dcache(pte_t pteval);
@@ -484,8 +486,10 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
 
        WRITE_ONCE(*pmdp, pmd);
 
-       if (pmd_valid(pmd))
+       if (pmd_valid(pmd)) {
                dsb(ishst);
+               isb();
+       }
 }
 
 static inline void pmd_clear(pmd_t *pmdp)
@@ -543,8 +547,10 @@ static inline void set_pud(pud_t *pudp, pud_t pud)
 
        WRITE_ONCE(*pudp, pud);
 
-       if (pud_valid(pud))
+       if (pud_valid(pud)) {
                dsb(ishst);
+               isb();
+       }
 }
 
 static inline void pud_clear(pud_t *pudp)
@@ -602,6 +608,7 @@ static inline void set_pgd(pgd_t *pgdp, pgd_t pgd)
 
        WRITE_ONCE(*pgdp, pgd);
        dsb(ishst);
+       isb();
 }
 
 static inline void pgd_clear(pgd_t *pgdp)
@@ -859,8 +866,8 @@ static inline void update_mmu_cache(struct vm_area_struct *vma,
 
 #define update_mmu_cache_pmd(vma, address, pmd) do { } while (0)
 
-#define kc_vaddr_to_offset(v)  ((v) & ~VA_START)
-#define kc_offset_to_vaddr(o)  ((o) | VA_START)
+#define kc_vaddr_to_offset(v)  ((v) & ~PAGE_END)
+#define kc_offset_to_vaddr(o)  ((o) | PAGE_END)
 
 #ifdef CONFIG_ARM64_PA_BITS_52
 #define phys_to_ttbr(addr)     (((addr) | ((addr) >> 46)) & TTBR_BADDR_MASK_52)
index d328540..7a24bad 100644 (file)
@@ -69,7 +69,7 @@ extern int ptrauth_prctl_reset_keys(struct task_struct *tsk, unsigned long arg);
  * The EL0 pointer bits used by a pointer authentication code.
  * This is dependent on TBI0 being enabled, or bits 63:56 would also apply.
  */
-#define ptrauth_user_pac_mask()        GENMASK(54, vabits_user)
+#define ptrauth_user_pac_mask()        GENMASK(54, vabits_actual)
 
 /* Only valid for EL0 TTBR0 instruction pointers */
 static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr)
index 368d90a..a2ce65a 100644 (file)
@@ -9,7 +9,6 @@
 #ifndef __ASM_PROCFNS_H
 #define __ASM_PROCFNS_H
 
-#ifdef __KERNEL__
 #ifndef __ASSEMBLY__
 
 #include <asm/page.h>
@@ -25,5 +24,4 @@ extern u64 cpu_do_resume(phys_addr_t ptr, u64 idmap_ttbr);
 #include <asm/memory.h>
 
 #endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
 #endif /* __ASM_PROCFNS_H */
index 844e296..c67848c 100644 (file)
@@ -20,7 +20,6 @@
 #define NET_IP_ALIGN   0
 
 #ifndef __ASSEMBLY__
-#ifdef __KERNEL__
 
 #include <linux/build_bug.h>
 #include <linux/cache.h>
@@ -42,8 +41,8 @@
  * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area.
  */
 
-#define DEFAULT_MAP_WINDOW_64  (UL(1) << VA_BITS)
-#define TASK_SIZE_64           (UL(1) << vabits_user)
+#define DEFAULT_MAP_WINDOW_64  (UL(1) << VA_BITS_MIN)
+#define TASK_SIZE_64           (UL(1) << vabits_actual)
 
 #ifdef CONFIG_COMPAT
 #if defined(CONFIG_ARM64_64K_PAGES) && defined(CONFIG_KUSER_HELPERS)
@@ -283,8 +282,6 @@ static inline void spin_lock_prefetch(const void *ptr)
 
 #define HAVE_ARCH_PICK_MMAP_LAYOUT
 
-#endif
-
 extern unsigned long __ro_after_init signal_minsigstksz; /* sigframe size */
 extern void __init minsigstksz_setup(void);
 
@@ -306,6 +303,14 @@ extern void __init minsigstksz_setup(void);
 /* PR_PAC_RESET_KEYS prctl */
 #define PAC_RESET_KEYS(tsk, arg)       ptrauth_prctl_reset_keys(tsk, arg)
 
+#ifdef CONFIG_ARM64_TAGGED_ADDR_ABI
+/* PR_{SET,GET}_TAGGED_ADDR_CTRL prctl */
+long set_tagged_addr_ctrl(unsigned long arg);
+long get_tagged_addr_ctrl(void);
+#define SET_TAGGED_ADDR_CTRL(arg)      set_tagged_addr_ctrl(arg)
+#define GET_TAGGED_ADDR_CTRL()         get_tagged_addr_ctrl()
+#endif
+
 /*
  * For CONFIG_GCC_PLUGIN_STACKLEAK
  *
index 1dcf63a..fbebb41 100644 (file)
@@ -301,6 +301,11 @@ static inline unsigned long regs_return_value(struct pt_regs *regs)
        return regs->regs[0];
 }
 
+static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
+{
+       regs->regs[0] = rc;
+}
+
 /**
  * regs_get_kernel_argument() - get Nth function argument in kernel
  * @regs:      pt_regs of that context
index bd43d1c..7e9f163 100644 (file)
@@ -5,7 +5,6 @@
 #ifndef __ASM_SIGNAL32_H
 #define __ASM_SIGNAL32_H
 
-#ifdef __KERNEL__
 #ifdef CONFIG_COMPAT
 #include <linux/compat.h>
 
@@ -79,5 +78,4 @@ static inline void compat_setup_restart_syscall(struct pt_regs *regs)
 {
 }
 #endif /* CONFIG_COMPAT */
-#endif /* __KERNEL__ */
 #endif /* __ASM_SIGNAL32_H */
index 06ebcfe..972d196 100644 (file)
 #define SYS_FAR_EL1                    sys_reg(3, 0, 6, 0, 0)
 #define SYS_PAR_EL1                    sys_reg(3, 0, 7, 4, 0)
 
+#define SYS_PAR_EL1_F                  BIT(1)
+#define SYS_PAR_EL1_FST                        GENMASK(6, 1)
+
 /*** Statistical Profiling Extension ***/
 /* ID registers */
 #define SYS_PMSIDR_EL1                 sys_reg(3, 0, 9, 9, 7)
 #define SCTLR_EL2_RES1 ((BIT(4))  | (BIT(5))  | (BIT(11)) | (BIT(16)) | \
                         (BIT(18)) | (BIT(22)) | (BIT(23)) | (BIT(28)) | \
                         (BIT(29)))
-#define SCTLR_EL2_RES0 ((BIT(6))  | (BIT(7))  | (BIT(8))  | (BIT(9))  | \
-                        (BIT(10)) | (BIT(13)) | (BIT(14)) | (BIT(15)) | \
-                        (BIT(17)) | (BIT(20)) | (BIT(24)) | (BIT(26)) | \
-                        (BIT(27)) | (BIT(30)) | (BIT(31)) | \
-                        (0xffffefffUL << 32))
 
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #define ENDIAN_SET_EL2         SCTLR_ELx_EE
-#define ENDIAN_CLEAR_EL2       0
 #else
 #define ENDIAN_SET_EL2         0
-#define ENDIAN_CLEAR_EL2       SCTLR_ELx_EE
-#endif
-
-/* SCTLR_EL2 value used for the hyp-stub */
-#define SCTLR_EL2_SET  (SCTLR_ELx_IESB   | ENDIAN_SET_EL2   | SCTLR_EL2_RES1)
-#define SCTLR_EL2_CLEAR        (SCTLR_ELx_M      | SCTLR_ELx_A    | SCTLR_ELx_C   | \
-                        SCTLR_ELx_SA     | SCTLR_ELx_I    | SCTLR_ELx_WXN | \
-                        SCTLR_ELx_DSSBS | ENDIAN_CLEAR_EL2 | SCTLR_EL2_RES0)
-
-#if (SCTLR_EL2_SET ^ SCTLR_EL2_CLEAR) != 0xffffffffffffffffUL
-#error "Inconsistent SCTLR_EL2 set/clear bits"
 #endif
 
 /* SCTLR_EL1 specific flags. */
 
 #define SCTLR_EL1_RES1 ((BIT(11)) | (BIT(20)) | (BIT(22)) | (BIT(28)) | \
                         (BIT(29)))
-#define SCTLR_EL1_RES0  ((BIT(6))  | (BIT(10)) | (BIT(13)) | (BIT(17)) | \
-                        (BIT(27)) | (BIT(30)) | (BIT(31)) | \
-                        (0xffffefffUL << 32))
 
 #ifdef CONFIG_CPU_BIG_ENDIAN
 #define ENDIAN_SET_EL1         (SCTLR_EL1_E0E | SCTLR_ELx_EE)
-#define ENDIAN_CLEAR_EL1       0
 #else
 #define ENDIAN_SET_EL1         0
-#define ENDIAN_CLEAR_EL1       (SCTLR_EL1_E0E | SCTLR_ELx_EE)
 #endif
 
 #define SCTLR_EL1_SET  (SCTLR_ELx_M    | SCTLR_ELx_C    | SCTLR_ELx_SA   |\
                         SCTLR_EL1_DZE  | SCTLR_EL1_UCT                   |\
                         SCTLR_EL1_NTWE | SCTLR_ELx_IESB | SCTLR_EL1_SPAN |\
                         ENDIAN_SET_EL1 | SCTLR_EL1_UCI  | SCTLR_EL1_RES1)
-#define SCTLR_EL1_CLEAR        (SCTLR_ELx_A   | SCTLR_EL1_CP15BEN | SCTLR_EL1_ITD    |\
-                        SCTLR_EL1_UMA | SCTLR_ELx_WXN     | ENDIAN_CLEAR_EL1 |\
-                        SCTLR_ELx_DSSBS | SCTLR_EL1_NTWI  | SCTLR_EL1_RES0)
-
-#if (SCTLR_EL1_SET ^ SCTLR_EL1_CLEAR) != 0xffffffffffffffffUL
-#error "Inconsistent SCTLR_EL1 set/clear bits"
-#endif
 
 /* id_aa64isar0 */
 #define ID_AA64ISAR0_TS_SHIFT          52
index 180b34e..f0cec41 100644 (file)
@@ -8,8 +8,6 @@
 #ifndef __ASM_THREAD_INFO_H
 #define __ASM_THREAD_INFO_H
 
-#ifdef __KERNEL__
-
 #include <linux/compiler.h>
 
 #ifndef __ASSEMBLY__
@@ -59,29 +57,18 @@ void arch_release_task_struct(struct task_struct *tsk);
 
 #endif
 
-/*
- * thread information flags:
- *  TIF_SYSCALL_TRACE  - syscall trace active
- *  TIF_SYSCALL_TRACEPOINT - syscall tracepoint for ftrace
- *  TIF_SYSCALL_AUDIT  - syscall auditing
- *  TIF_SECCOMP                - syscall secure computing
- *  TIF_SYSCALL_EMU     - syscall emulation active
- *  TIF_SIGPENDING     - signal pending
- *  TIF_NEED_RESCHED   - rescheduling necessary
- *  TIF_NOTIFY_RESUME  - callback before returning to user
- */
-#define TIF_SIGPENDING         0
-#define TIF_NEED_RESCHED       1
+#define TIF_SIGPENDING         0       /* signal pending */
+#define TIF_NEED_RESCHED       1       /* rescheduling necessary */
 #define TIF_NOTIFY_RESUME      2       /* callback before returning to user */
 #define TIF_FOREIGN_FPSTATE    3       /* CPU's FP state is not current's */
 #define TIF_UPROBE             4       /* uprobe breakpoint or singlestep */
 #define TIF_FSCHECK            5       /* Check FS is USER_DS on return */
 #define TIF_NOHZ               7
-#define TIF_SYSCALL_TRACE      8
-#define TIF_SYSCALL_AUDIT      9
-#define TIF_SYSCALL_TRACEPOINT 10
-#define TIF_SECCOMP            11
-#define TIF_SYSCALL_EMU                12
+#define TIF_SYSCALL_TRACE      8       /* syscall trace active */
+#define TIF_SYSCALL_AUDIT      9       /* syscall auditing */
+#define TIF_SYSCALL_TRACEPOINT 10      /* syscall tracepoint for ftrace */
+#define TIF_SECCOMP            11      /* syscall secure computing */
+#define TIF_SYSCALL_EMU                12      /* syscall emulation active */
 #define TIF_MEMDIE             18      /* is terminating due to OOM killer */
 #define TIF_FREEZE             19
 #define TIF_RESTORE_SIGMASK    20
@@ -90,6 +77,7 @@ void arch_release_task_struct(struct task_struct *tsk);
 #define TIF_SVE                        23      /* Scalable Vector Extension in use */
 #define TIF_SVE_VL_INHERIT     24      /* Inherit sve_vl_onexec across exec */
 #define TIF_SSBD               25      /* Wants SSB mitigation */
+#define TIF_TAGGED_ADDR                26      /* Allow tagged user addresses */
 
 #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
@@ -121,5 +109,4 @@ void arch_release_task_struct(struct task_struct *tsk);
        .addr_limit     = KERNEL_DS,                                    \
 }
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_THREAD_INFO_H */
index 8af7a85..bc39490 100644 (file)
@@ -251,6 +251,7 @@ static inline void __flush_tlb_kernel_pgtable(unsigned long kaddr)
        dsb(ishst);
        __tlbi(vaae1is, addr);
        dsb(ish);
+       isb();
 }
 #endif
 
index 0524f24..a4d945d 100644 (file)
@@ -4,29 +4,6 @@
 
 #include <linux/cpumask.h>
 
-struct cpu_topology {
-       int thread_id;
-       int core_id;
-       int package_id;
-       int llc_id;
-       cpumask_t thread_sibling;
-       cpumask_t core_sibling;
-       cpumask_t llc_sibling;
-};
-
-extern struct cpu_topology cpu_topology[NR_CPUS];
-
-#define topology_physical_package_id(cpu)      (cpu_topology[cpu].package_id)
-#define topology_core_id(cpu)          (cpu_topology[cpu].core_id)
-#define topology_core_cpumask(cpu)     (&cpu_topology[cpu].core_sibling)
-#define topology_sibling_cpumask(cpu)  (&cpu_topology[cpu].thread_sibling)
-#define topology_llc_cpumask(cpu)      (&cpu_topology[cpu].llc_sibling)
-
-void init_cpu_topology(void);
-void store_cpu_topology(unsigned int cpuid);
-void remove_cpu_topology(unsigned int cpuid);
-const struct cpumask *cpu_coregroup_mask(int cpu);
-
 #ifdef CONFIG_NUMA
 
 struct pci_bus;
index 5a1c322..097d6bf 100644 (file)
@@ -62,6 +62,10 @@ static inline unsigned long __range_ok(const void __user *addr, unsigned long si
 {
        unsigned long ret, limit = current_thread_info()->addr_limit;
 
+       if (IS_ENABLED(CONFIG_ARM64_TAGGED_ADDR_ABI) &&
+           test_thread_flag(TIF_TAGGED_ADDR))
+               addr = untagged_addr(addr);
+
        __chk_user_ptr(addr);
        asm volatile(
        // A + B <= C + 1 for all A,B,C, in four easy steps:
@@ -215,7 +219,8 @@ static inline void uaccess_enable_not_uao(void)
 
 /*
  * Sanitise a uaccess pointer such that it becomes NULL if above the
- * current addr_limit.
+ * current addr_limit. In case the pointer is tagged (has the top byte set),
+ * untag the pointer before checking.
  */
 #define uaccess_mask_ptr(ptr) (__typeof__(ptr))__uaccess_mask_ptr(ptr)
 static inline void __user *__uaccess_mask_ptr(const void __user *ptr)
@@ -223,10 +228,11 @@ static inline void __user *__uaccess_mask_ptr(const void __user *ptr)
        void __user *safe_ptr;
 
        asm volatile(
-       "       bics    xzr, %1, %2\n"
+       "       bics    xzr, %3, %2\n"
        "       csel    %0, %1, xzr, eq\n"
        : "=&r" (safe_ptr)
-       : "r" (ptr), "r" (current_thread_info()->addr_limit)
+       : "r" (ptr), "r" (current_thread_info()->addr_limit),
+         "r" (untagged_addr(ptr))
        : "cc");
 
        csdb();
index 9c15e0a..0746842 100644 (file)
@@ -5,8 +5,6 @@
 #ifndef __ASM_VDSO_H
 #define __ASM_VDSO_H
 
-#ifdef __KERNEL__
-
 /*
  * Default link address for the vDSO.
  * Since we randomise the VDSO mapping, there's little point in trying
@@ -28,6 +26,4 @@
 
 #endif /* !__ASSEMBLY__ */
 
-#endif /* __KERNEL__ */
-
 #endif /* __ASM_VDSO_H */
index ba6dbc3..1f38bf3 100644 (file)
@@ -5,8 +5,6 @@
 #ifndef __ASM_VDSO_DATAPAGE_H
 #define __ASM_VDSO_DATAPAGE_H
 
-#ifdef __KERNEL__
-
 #ifndef __ASSEMBLY__
 
 struct vdso_data {
@@ -32,6 +30,4 @@ struct vdso_data {
 
 #endif /* !__ASSEMBLY__ */
 
-#endif /* __KERNEL__ */
-
 #endif /* __ASM_VDSO_DATAPAGE_H */
diff --git a/arch/arm64/include/uapi/asm/stat.h b/arch/arm64/include/uapi/asm/stat.h
deleted file mode 100644 (file)
index 313325f..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*
- * Copyright (C) 2012 ARM Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * 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 <asm-generic/stat.h>
index b1fdc48..9323bcc 100644 (file)
@@ -894,7 +894,7 @@ static bool has_no_hw_prefetch(const struct arm64_cpu_capabilities *entry, int _
        u32 midr = read_cpuid_id();
 
        /* Cavium ThunderX pass 1.x and 2.x */
-       return MIDR_IS_CPU_MODEL_RANGE(midr, MIDR_THUNDERX,
+       return midr_is_cpu_model_range(midr, MIDR_THUNDERX,
                MIDR_CPU_VAR_REV(0, 0),
                MIDR_CPU_VAR_REV(1, MIDR_REVISION_MASK));
 }
index d104817..e4d6af2 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/cpu_pm.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/psci.h>
 
 #include <asm/cpuidle.h>
 #include <asm/cpu_ops.h>
@@ -46,17 +47,58 @@ int arm_cpuidle_suspend(int index)
 
 #define ARM64_LPI_IS_RETENTION_STATE(arch_flags) (!(arch_flags))
 
+static int psci_acpi_cpu_init_idle(unsigned int cpu)
+{
+       int i, count;
+       struct acpi_lpi_state *lpi;
+       struct acpi_processor *pr = per_cpu(processors, cpu);
+
+       /*
+        * If the PSCI cpu_suspend function hook has not been initialized
+        * idle states must not be enabled, so bail out
+        */
+       if (!psci_ops.cpu_suspend)
+               return -EOPNOTSUPP;
+
+       if (unlikely(!pr || !pr->flags.has_lpi))
+               return -EINVAL;
+
+       count = pr->power.count - 1;
+       if (count <= 0)
+               return -ENODEV;
+
+       for (i = 0; i < count; i++) {
+               u32 state;
+
+               lpi = &pr->power.lpi_states[i + 1];
+               /*
+                * Only bits[31:0] represent a PSCI power_state while
+                * bits[63:32] must be 0x0 as per ARM ACPI FFH Specification
+                */
+               state = lpi->address;
+               if (!psci_power_state_is_valid(state)) {
+                       pr_warn("Invalid PSCI power state %#x\n", state);
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
 int acpi_processor_ffh_lpi_probe(unsigned int cpu)
 {
-       return arm_cpuidle_init(cpu);
+       return psci_acpi_cpu_init_idle(cpu);
 }
 
 int acpi_processor_ffh_lpi_enter(struct acpi_lpi_state *lpi)
 {
+       u32 state = lpi->address;
+
        if (ARM64_LPI_IS_RETENTION_STATE(lpi->arch_flags))
-               return CPU_PM_CPU_IDLE_ENTER_RETENTION(arm_cpuidle_suspend,
-                                               lpi->index);
+               return CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(psci_cpu_suspend_enter,
+                                               lpi->index, state);
        else
-               return CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, lpi->index);
+               return CPU_PM_CPU_IDLE_ENTER_PARAM(psci_cpu_suspend_enter,
+                                            lpi->index, state);
 }
 #endif
index 876055e..05933c0 100644 (file)
@@ -33,7 +33,7 @@
 DEFINE_PER_CPU(struct cpuinfo_arm64, cpu_data);
 static struct cpuinfo_arm64 boot_cpu_data;
 
-static char *icache_policy_str[] = {
+static const char *icache_policy_str[] = {
        [0 ... ICACHE_POLICY_PIPT]      = "RESERVED/UNKNOWN",
        [ICACHE_POLICY_VIPT]            = "VIPT",
        [ICACHE_POLICY_PIPT]            = "PIPT",
index 320a30d..84a8227 100644 (file)
@@ -30,9 +30,9 @@
  * Context tracking subsystem.  Used to instrument transitions
  * between user and kernel mode.
  */
-       .macro ct_user_exit
+       .macro ct_user_exit_irqoff
 #ifdef CONFIG_CONTEXT_TRACKING
-       bl      context_tracking_user_exit
+       bl      enter_from_user_mode
 #endif
        .endm
 
@@ -792,8 +792,8 @@ el0_cp15:
        /*
         * Trapped CP15 (MRC, MCR, MRRC, MCRR) instructions
         */
+       ct_user_exit_irqoff
        enable_daif
-       ct_user_exit
        mov     x0, x25
        mov     x1, sp
        bl      do_cp15instr
@@ -805,8 +805,8 @@ el0_da:
         * Data abort handling
         */
        mrs     x26, far_el1
+       ct_user_exit_irqoff
        enable_daif
-       ct_user_exit
        clear_address_tag x0, x26
        mov     x1, x25
        mov     x2, sp
@@ -818,11 +818,11 @@ el0_ia:
         */
        mrs     x26, far_el1
        gic_prio_kentry_setup tmp=x0
+       ct_user_exit_irqoff
        enable_da_f
 #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_off
 #endif
-       ct_user_exit
        mov     x0, x26
        mov     x1, x25
        mov     x2, sp
@@ -832,8 +832,8 @@ el0_fpsimd_acc:
        /*
         * Floating Point or Advanced SIMD access
         */
+       ct_user_exit_irqoff
        enable_daif
-       ct_user_exit
        mov     x0, x25
        mov     x1, sp
        bl      do_fpsimd_acc
@@ -842,8 +842,8 @@ el0_sve_acc:
        /*
         * Scalable Vector Extension access
         */
+       ct_user_exit_irqoff
        enable_daif
-       ct_user_exit
        mov     x0, x25
        mov     x1, sp
        bl      do_sve_acc
@@ -852,8 +852,8 @@ el0_fpsimd_exc:
        /*
         * Floating Point, Advanced SIMD or SVE exception
         */
+       ct_user_exit_irqoff
        enable_daif
-       ct_user_exit
        mov     x0, x25
        mov     x1, sp
        bl      do_fpsimd_exc
@@ -868,11 +868,11 @@ el0_sp_pc:
         * Stack or PC alignment exception handling
         */
        gic_prio_kentry_setup tmp=x0
+       ct_user_exit_irqoff
        enable_da_f
 #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_off
 #endif
-       ct_user_exit
        mov     x0, x26
        mov     x1, x25
        mov     x2, sp
@@ -882,8 +882,8 @@ el0_undef:
        /*
         * Undefined instruction
         */
+       ct_user_exit_irqoff
        enable_daif
-       ct_user_exit
        mov     x0, sp
        bl      do_undefinstr
        b       ret_to_user
@@ -891,8 +891,8 @@ el0_sys:
        /*
         * System instructions, for trapped cache maintenance instructions
         */
+       ct_user_exit_irqoff
        enable_daif
-       ct_user_exit
        mov     x0, x25
        mov     x1, sp
        bl      do_sysinstr
@@ -902,17 +902,18 @@ el0_dbg:
         * Debug exception handling
         */
        tbnz    x24, #0, el0_inv                // EL0 only
+       mrs     x24, far_el1
        gic_prio_kentry_setup tmp=x3
-       mrs     x0, far_el1
+       ct_user_exit_irqoff
+       mov     x0, x24
        mov     x1, x25
        mov     x2, sp
        bl      do_debug_exception
        enable_da_f
-       ct_user_exit
        b       ret_to_user
 el0_inv:
+       ct_user_exit_irqoff
        enable_daif
-       ct_user_exit
        mov     x0, sp
        mov     x1, #BAD_SYNC
        mov     x2, x25
@@ -925,13 +926,13 @@ el0_irq:
        kernel_entry 0
 el0_irq_naked:
        gic_prio_irq_setup pmr=x20, tmp=x0
+       ct_user_exit_irqoff
        enable_da_f
 
 #ifdef CONFIG_TRACE_IRQFLAGS
        bl      trace_hardirqs_off
 #endif
 
-       ct_user_exit
 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
        tbz     x22, #55, 1f
        bl      do_el0_irq_bp_hardening
@@ -958,13 +959,14 @@ ENDPROC(el1_error)
 el0_error:
        kernel_entry 0
 el0_error_naked:
-       mrs     x1, esr_el1
+       mrs     x25, esr_el1
        gic_prio_kentry_setup tmp=x2
+       ct_user_exit_irqoff
        enable_dbg
        mov     x0, sp
+       mov     x1, x25
        bl      do_serror
        enable_da_f
-       ct_user_exit
        b       ret_to_user
 ENDPROC(el0_error)
 
index 2cdacd1..989b194 100644 (file)
@@ -102,6 +102,8 @@ pe_header:
         *  x23        stext() .. start_kernel()  physical misalignment/KASLR offset
         *  x28        __create_page_tables()     callee preserved temp register
         *  x19/x20    __primary_switch()         callee preserved temp registers
+        *  x24        __primary_switch() .. relocate_kernel()
+        *                                        current RELR displacement
         */
 ENTRY(stext)
        bl      preserve_boot_args
@@ -308,15 +310,15 @@ __create_page_tables:
        adrp    x0, idmap_pg_dir
        adrp    x3, __idmap_text_start          // __pa(__idmap_text_start)
 
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
+#ifdef CONFIG_ARM64_VA_BITS_52
        mrs_s   x6, SYS_ID_AA64MMFR2_EL1
        and     x6, x6, #(0xf << ID_AA64MMFR2_LVA_SHIFT)
        mov     x5, #52
        cbnz    x6, 1f
 #endif
-       mov     x5, #VA_BITS
+       mov     x5, #VA_BITS_MIN
 1:
-       adr_l   x6, vabits_user
+       adr_l   x6, vabits_actual
        str     x5, [x6]
        dmb     sy
        dc      ivac, x6                // Invalidate potentially stale cache line
@@ -724,14 +726,22 @@ __secondary_switched:
 
        adr_l   x0, secondary_data
        ldr     x1, [x0, #CPU_BOOT_STACK]       // get secondary_data.stack
+       cbz     x1, __secondary_too_slow
        mov     sp, x1
        ldr     x2, [x0, #CPU_BOOT_TASK]
+       cbz     x2, __secondary_too_slow
        msr     sp_el0, x2
        mov     x29, #0
        mov     x30, #0
        b       secondary_start_kernel
 ENDPROC(__secondary_switched)
 
+__secondary_too_slow:
+       wfe
+       wfi
+       b       __secondary_too_slow
+ENDPROC(__secondary_too_slow)
+
 /*
  * The booting CPU updates the failed status @__early_cpu_boot_status,
  * with MMU turned off.
@@ -772,7 +782,7 @@ ENTRY(__enable_mmu)
        phys_to_ttbr x1, x1
        phys_to_ttbr x2, x2
        msr     ttbr0_el1, x2                   // load TTBR0
-       offset_ttbr1 x1
+       offset_ttbr1 x1, x3
        msr     ttbr1_el1, x1                   // load TTBR1
        isb
        msr     sctlr_el1, x0
@@ -789,8 +799,8 @@ ENTRY(__enable_mmu)
 ENDPROC(__enable_mmu)
 
 ENTRY(__cpu_secondary_check52bitva)
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
-       ldr_l   x0, vabits_user
+#ifdef CONFIG_ARM64_VA_BITS_52
+       ldr_l   x0, vabits_actual
        cmp     x0, #52
        b.ne    2f
 
@@ -834,14 +844,93 @@ __relocate_kernel:
 
 0:     cmp     x9, x10
        b.hs    1f
-       ldp     x11, x12, [x9], #24
-       ldr     x13, [x9, #-8]
-       cmp     w12, #R_AARCH64_RELATIVE
+       ldp     x12, x13, [x9], #24
+       ldr     x14, [x9, #-8]
+       cmp     w13, #R_AARCH64_RELATIVE
        b.ne    0b
-       add     x13, x13, x23                   // relocate
-       str     x13, [x11, x23]
+       add     x14, x14, x23                   // relocate
+       str     x14, [x12, x23]
        b       0b
-1:     ret
+
+1:
+#ifdef CONFIG_RELR
+       /*
+        * Apply RELR relocations.
+        *
+        * RELR is a compressed format for storing relative relocations. The
+        * encoded sequence of entries looks like:
+        * [ AAAAAAAA BBBBBBB1 BBBBBBB1 ... AAAAAAAA BBBBBB1 ... ]
+        *
+        * i.e. start with an address, followed by any number of bitmaps. The
+        * address entry encodes 1 relocation. The subsequent bitmap entries
+        * encode up to 63 relocations each, at subsequent offsets following
+        * the last address entry.
+        *
+        * The bitmap entries must have 1 in the least significant bit. The
+        * assumption here is that an address cannot have 1 in lsb. Odd
+        * addresses are not supported. Any odd addresses are stored in the RELA
+        * section, which is handled above.
+        *
+        * Excluding the least significant bit in the bitmap, each non-zero
+        * bit in the bitmap represents a relocation to be applied to
+        * a corresponding machine word that follows the base address
+        * word. The second least significant bit represents the machine
+        * word immediately following the initial address, and each bit
+        * that follows represents the next word, in linear order. As such,
+        * a single bitmap can encode up to 63 relocations in a 64-bit object.
+        *
+        * In this implementation we store the address of the next RELR table
+        * entry in x9, the address being relocated by the current address or
+        * bitmap entry in x13 and the address being relocated by the current
+        * bit in x14.
+        *
+        * Because addends are stored in place in the binary, RELR relocations
+        * cannot be applied idempotently. We use x24 to keep track of the
+        * currently applied displacement so that we can correctly relocate if
+        * __relocate_kernel is called twice with non-zero displacements (i.e.
+        * if there is both a physical misalignment and a KASLR displacement).
+        */
+       ldr     w9, =__relr_offset              // offset to reloc table
+       ldr     w10, =__relr_size               // size of reloc table
+       add     x9, x9, x11                     // __va(.relr)
+       add     x10, x9, x10                    // __va(.relr) + sizeof(.relr)
+
+       sub     x15, x23, x24                   // delta from previous offset
+       cbz     x15, 7f                         // nothing to do if unchanged
+       mov     x24, x23                        // save new offset
+
+2:     cmp     x9, x10
+       b.hs    7f
+       ldr     x11, [x9], #8
+       tbnz    x11, #0, 3f                     // branch to handle bitmaps
+       add     x13, x11, x23
+       ldr     x12, [x13]                      // relocate address entry
+       add     x12, x12, x15
+       str     x12, [x13], #8                  // adjust to start of bitmap
+       b       2b
+
+3:     mov     x14, x13
+4:     lsr     x11, x11, #1
+       cbz     x11, 6f
+       tbz     x11, #0, 5f                     // skip bit if not set
+       ldr     x12, [x14]                      // relocate bit
+       add     x12, x12, x15
+       str     x12, [x14]
+
+5:     add     x14, x14, #8                    // move to next bit's address
+       b       4b
+
+6:     /*
+        * Move to the next bitmap's address. 8 is the word size, and 63 is the
+        * number of significant bits in a bitmap entry.
+        */
+       add     x13, x13, #(8 * 63)
+       b       2b
+
+7:
+#endif
+       ret
+
 ENDPROC(__relocate_kernel)
 #endif
 
@@ -854,6 +943,9 @@ __primary_switch:
        adrp    x1, init_pg_dir
        bl      __enable_mmu
 #ifdef CONFIG_RELOCATABLE
+#ifdef CONFIG_RELR
+       mov     x24, #0                         // no RELR displacement yet
+#endif
        bl      __relocate_kernel
 #ifdef CONFIG_RANDOMIZE_BASE
        ldr     x8, =__primary_switched
index 2f4a2ce..38bcd4d 100644 (file)
  * Even switching to our copied tables will cause a changed output address at
  * each stage of the walk.
  */
-.macro break_before_make_ttbr_switch zero_page, page_table, tmp
+.macro break_before_make_ttbr_switch zero_page, page_table, tmp, tmp2
        phys_to_ttbr \tmp, \zero_page
        msr     ttbr1_el1, \tmp
        isb
        tlbi    vmalle1
        dsb     nsh
        phys_to_ttbr \tmp, \page_table
-       offset_ttbr1 \tmp
+       offset_ttbr1 \tmp, \tmp2
        msr     ttbr1_el1, \tmp
        isb
 .endm
@@ -70,7 +70,7 @@ ENTRY(swsusp_arch_suspend_exit)
         * We execute from ttbr0, change ttbr1 to our copied linear map tables
         * with a break-before-make via the zero page
         */
-       break_before_make_ttbr_switch   x5, x0, x6
+       break_before_make_ttbr_switch   x5, x0, x6, x8
 
        mov     x21, x1
        mov     x30, x2
@@ -101,7 +101,7 @@ ENTRY(swsusp_arch_suspend_exit)
        dsb     ish             /* wait for PoU cleaning to finish */
 
        /* switch to the restored kernels page tables */
-       break_before_make_ttbr_switch   x25, x21, x6
+       break_before_make_ttbr_switch   x25, x21, x6, x8
 
        ic      ialluis
        dsb     ish
index 9341fcc..e0a7fce 100644 (file)
@@ -496,7 +496,7 @@ int swsusp_arch_resume(void)
                rc = -ENOMEM;
                goto out;
        }
-       rc = copy_page_tables(tmp_pg_dir, PAGE_OFFSET, 0);
+       rc = copy_page_tables(tmp_pg_dir, PAGE_OFFSET, PAGE_END);
        if (rc)
                goto out;
 
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
new file mode 100644 (file)
index 0000000..25a2a9b
--- /dev/null
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Linker script variables to be set after section resolution, as
+ * ld.lld does not like variables assigned before SECTIONS is processed.
+ */
+#ifndef __ARM64_KERNEL_IMAGE_VARS_H
+#define __ARM64_KERNEL_IMAGE_VARS_H
+
+#ifndef LINKER_SCRIPT
+#error This file should only be included in vmlinux.lds.S
+#endif
+
+#ifdef CONFIG_EFI
+
+__efistub_stext_offset = stext - _text;
+
+/*
+ * The EFI stub has its own symbol namespace prefixed by __efistub_, to
+ * isolate it from the kernel proper. The following symbols are legally
+ * accessed by the stub, so provide some aliases to make them accessible.
+ * Only include data symbols here, or text symbols of functions that are
+ * guaranteed to be safe when executed at another offset than they were
+ * linked at. The routines below are all implemented in assembler in a
+ * position independent manner
+ */
+__efistub_memcmp               = __pi_memcmp;
+__efistub_memchr               = __pi_memchr;
+__efistub_memcpy               = __pi_memcpy;
+__efistub_memmove              = __pi_memmove;
+__efistub_memset               = __pi_memset;
+__efistub_strlen               = __pi_strlen;
+__efistub_strnlen              = __pi_strnlen;
+__efistub_strcmp               = __pi_strcmp;
+__efistub_strncmp              = __pi_strncmp;
+__efistub_strrchr              = __pi_strrchr;
+__efistub___flush_dcache_area  = __pi___flush_dcache_area;
+
+#ifdef CONFIG_KASAN
+__efistub___memcpy             = __pi_memcpy;
+__efistub___memmove            = __pi_memmove;
+__efistub___memset             = __pi_memset;
+#endif
+
+__efistub__text                        = _text;
+__efistub__end                 = _end;
+__efistub__edata               = _edata;
+__efistub_screen_info          = screen_info;
+
+#endif
+
+#endif /* __ARM64_KERNEL_IMAGE_VARS_H */
index 2b85c0d..c7d38c6 100644 (file)
        DEFINE_IMAGE_LE64(_kernel_offset_le, TEXT_OFFSET);      \
        DEFINE_IMAGE_LE64(_kernel_flags_le, __HEAD_FLAGS);
 
-#ifdef CONFIG_EFI
-
-/*
- * Use ABSOLUTE() to avoid ld.lld treating this as a relative symbol:
- * https://github.com/ClangBuiltLinux/linux/issues/561
- */
-__efistub_stext_offset = ABSOLUTE(stext - _text);
-
-/*
- * The EFI stub has its own symbol namespace prefixed by __efistub_, to
- * isolate it from the kernel proper. The following symbols are legally
- * accessed by the stub, so provide some aliases to make them accessible.
- * Only include data symbols here, or text symbols of functions that are
- * guaranteed to be safe when executed at another offset than they were
- * linked at. The routines below are all implemented in assembler in a
- * position independent manner
- */
-__efistub_memcmp               = __pi_memcmp;
-__efistub_memchr               = __pi_memchr;
-__efistub_memcpy               = __pi_memcpy;
-__efistub_memmove              = __pi_memmove;
-__efistub_memset               = __pi_memset;
-__efistub_strlen               = __pi_strlen;
-__efistub_strnlen              = __pi_strnlen;
-__efistub_strcmp               = __pi_strcmp;
-__efistub_strncmp              = __pi_strncmp;
-__efistub_strrchr              = __pi_strrchr;
-__efistub___flush_dcache_area  = __pi___flush_dcache_area;
-
-#ifdef CONFIG_KASAN
-__efistub___memcpy             = __pi_memcpy;
-__efistub___memmove            = __pi_memmove;
-__efistub___memset             = __pi_memset;
-#endif
-
-__efistub__text                        = _text;
-__efistub__end                 = _end;
-__efistub__edata               = _edata;
-__efistub_screen_info          = screen_info;
-
-#endif
-
 #endif /* __ARM64_KERNEL_IMAGE_H */
index 84b059e..d801a70 100644 (file)
@@ -26,7 +26,7 @@
 #define AARCH64_INSN_N_BIT     BIT(22)
 #define AARCH64_INSN_LSL_12    BIT(22)
 
-static int aarch64_insn_encoding_class[] = {
+static const int aarch64_insn_encoding_class[] = {
        AARCH64_INSN_CLS_UNKNOWN,
        AARCH64_INSN_CLS_UNKNOWN,
        AARCH64_INSN_CLS_UNKNOWN,
index 7080516..416f537 100644 (file)
@@ -62,9 +62,6 @@ out:
        return default_cmdline;
 }
 
-extern void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size,
-                                      pgprot_t prot);
-
 /*
  * This routine will be executed with the kernel mapped at its default virtual
  * address, and if it returns successfully, the kernel will be remapped, and
@@ -93,7 +90,7 @@ u64 __init kaslr_early_init(u64 dt_phys)
         * attempt at mapping the FDT in setup_machine()
         */
        early_fixmap_init();
-       fdt = __fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL);
+       fdt = fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL);
        if (!fdt)
                return 0;
 
@@ -116,15 +113,15 @@ u64 __init kaslr_early_init(u64 dt_phys)
        /*
         * OK, so we are proceeding with KASLR enabled. Calculate a suitable
         * kernel image offset from the seed. Let's place the kernel in the
-        * middle half of the VMALLOC area (VA_BITS - 2), and stay clear of
+        * middle half of the VMALLOC area (VA_BITS_MIN - 2), and stay clear of
         * the lower and upper quarters to avoid colliding with other
         * allocations.
         * Even if we could randomize at page granularity for 16k and 64k pages,
         * let's always round to 2 MB so we don't interfere with the ability to
         * map using contiguous PTEs
         */
-       mask = ((1UL << (VA_BITS - 2)) - 1) & ~(SZ_2M - 1);
-       offset = BIT(VA_BITS - 3) + (seed & mask);
+       mask = ((1UL << (VA_BITS_MIN - 2)) - 1) & ~(SZ_2M - 1);
+       offset = BIT(VA_BITS_MIN - 3) + (seed & mask);
 
        /* use the top 16 bits to randomize the linear region */
        memstart_offset_seed = seed >> 48;
index 2514fd6..29a9428 100644 (file)
@@ -84,7 +84,7 @@ static void *image_load(struct kimage *image,
 
        kbuf.buffer = kernel;
        kbuf.bufsz = kernel_len;
-       kbuf.mem = 0;
+       kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
        kbuf.memsz = le64_to_cpu(h->image_size);
        text_offset = le64_to_cpu(h->text_offset);
        kbuf.buf_align = MIN_KIMG_ALIGN;
index 5887133..7b08bf9 100644 (file)
@@ -27,6 +27,8 @@
 #define FDT_PROP_INITRD_END    "linux,initrd-end"
 #define FDT_PROP_BOOTARGS      "bootargs"
 #define FDT_PROP_KASLR_SEED    "kaslr-seed"
+#define FDT_PROP_RNG_SEED      "rng-seed"
+#define RNG_SEED_SIZE          128
 
 const struct kexec_file_ops * const kexec_file_loaders[] = {
        &kexec_image_ops,
@@ -102,6 +104,19 @@ static int setup_dtb(struct kimage *image,
                                FDT_PROP_KASLR_SEED);
        }
 
+       /* add rng-seed */
+       if (rng_is_initialized()) {
+               u8 rng_seed[RNG_SEED_SIZE];
+               get_random_bytes(rng_seed, RNG_SEED_SIZE);
+               ret = fdt_setprop(dtb, off, FDT_PROP_RNG_SEED, rng_seed,
+                               RNG_SEED_SIZE);
+               if (ret)
+                       goto out;
+       } else {
+               pr_notice("RNG is not initialised: omitting \"%s\" property\n",
+                               FDT_PROP_RNG_SEED);
+       }
+
 out:
        if (ret)
                return (ret == -FDT_ERR_NOSPACE) ? -ENOMEM : -EINVAL;
@@ -110,7 +125,8 @@ out:
 }
 
 /*
- * More space needed so that we can add initrd, bootargs and kaslr-seed.
+ * More space needed so that we can add initrd, bootargs, kaslr-seed, and
+ * rng-seed.
  */
 #define DTB_EXTRA_SPACE 0x1000
 
@@ -177,7 +193,7 @@ int load_other_segments(struct kimage *image,
        if (initrd) {
                kbuf.buffer = initrd;
                kbuf.bufsz = initrd_len;
-               kbuf.mem = 0;
+               kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
                kbuf.memsz = initrd_len;
                kbuf.buf_align = 0;
                /* within 1GB-aligned window of up to 32GB in size */
@@ -204,7 +220,7 @@ int load_other_segments(struct kimage *image,
        dtb_len = fdt_totalsize(dtb);
        kbuf.buffer = dtb;
        kbuf.bufsz = dtb_len;
-       kbuf.mem = 0;
+       kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
        kbuf.memsz = dtb_len;
        /* not across 2MB boundary */
        kbuf.buf_align = SZ_2M;
index 044c0ae..b182442 100644 (file)
@@ -302,7 +302,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
                /* sort by type, symbol index and addend */
                sort(rels, numrels, sizeof(Elf64_Rela), cmp_rela, NULL);
 
-               if (strncmp(secstrings + dstsec->sh_name, ".init", 5) != 0)
+               if (!str_has_prefix(secstrings + dstsec->sh_name, ".init"))
                        core_plts += count_plts(syms, rels, numrels,
                                                sechdrs[i].sh_info, dstsec);
                else
index 96e90e2..a0b4f1b 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/of.h>
 #include <linux/perf/arm_pmu.h>
 #include <linux/platform_device.h>
+#include <linux/smp.h>
 
 /* ARMv8 Cortex-A53 specific event types. */
 #define ARMV8_A53_PERFCTR_PREF_LINEFILL                                0xC2
@@ -157,7 +158,6 @@ armv8pmu_events_sysfs_show(struct device *dev,
        return sprintf(page, "event=0x%03llx\n", pmu_attr->id);
 }
 
-#define ARMV8_EVENT_ATTR_RESOLVE(m) #m
 #define ARMV8_EVENT_ATTR(name, config) \
        PMU_EVENT_ATTR(name, armv8_event_attr_##name, \
                       config, armv8pmu_events_sysfs_show)
index f674f28..03689c0 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/stddef.h>
+#include <linux/sysctl.h>
 #include <linux/unistd.h>
 #include <linux/user.h>
 #include <linux/delay.h>
@@ -38,6 +39,7 @@
 #include <trace/events/power.h>
 #include <linux/percpu.h>
 #include <linux/thread_info.h>
+#include <linux/prctl.h>
 
 #include <asm/alternative.h>
 #include <asm/arch_gicv3.h>
@@ -307,11 +309,18 @@ static void tls_thread_flush(void)
        }
 }
 
+static void flush_tagged_addr_state(void)
+{
+       if (IS_ENABLED(CONFIG_ARM64_TAGGED_ADDR_ABI))
+               clear_thread_flag(TIF_TAGGED_ADDR);
+}
+
 void flush_thread(void)
 {
        fpsimd_flush_thread();
        tls_thread_flush();
        flush_ptrace_hw_breakpoint(current);
+       flush_tagged_addr_state();
 }
 
 void release_thread(struct task_struct *dead_task)
@@ -565,3 +574,70 @@ void arch_setup_new_exec(void)
 
        ptrauth_thread_init_user(current);
 }
+
+#ifdef CONFIG_ARM64_TAGGED_ADDR_ABI
+/*
+ * Control the relaxed ABI allowing tagged user addresses into the kernel.
+ */
+static unsigned int tagged_addr_disabled;
+
+long set_tagged_addr_ctrl(unsigned long arg)
+{
+       if (is_compat_task())
+               return -EINVAL;
+       if (arg & ~PR_TAGGED_ADDR_ENABLE)
+               return -EINVAL;
+
+       /*
+        * Do not allow the enabling of the tagged address ABI if globally
+        * disabled via sysctl abi.tagged_addr_disabled.
+        */
+       if (arg & PR_TAGGED_ADDR_ENABLE && tagged_addr_disabled)
+               return -EINVAL;
+
+       update_thread_flag(TIF_TAGGED_ADDR, arg & PR_TAGGED_ADDR_ENABLE);
+
+       return 0;
+}
+
+long get_tagged_addr_ctrl(void)
+{
+       if (is_compat_task())
+               return -EINVAL;
+
+       if (test_thread_flag(TIF_TAGGED_ADDR))
+               return PR_TAGGED_ADDR_ENABLE;
+
+       return 0;
+}
+
+/*
+ * Global sysctl to disable the tagged user addresses support. This control
+ * only prevents the tagged address ABI enabling via prctl() and does not
+ * disable it for tasks that already opted in to the relaxed ABI.
+ */
+static int zero;
+static int one = 1;
+
+static struct ctl_table tagged_addr_sysctl_table[] = {
+       {
+               .procname       = "tagged_addr_disabled",
+               .mode           = 0644,
+               .data           = &tagged_addr_disabled,
+               .maxlen         = sizeof(int),
+               .proc_handler   = proc_dointvec_minmax,
+               .extra1         = &zero,
+               .extra2         = &one,
+       },
+       { }
+};
+
+static int __init tagged_addr_init(void)
+{
+       if (!register_sysctl("abi", tagged_addr_sysctl_table))
+               return -EINVAL;
+       return 0;
+}
+
+core_initcall(tagged_addr_init);
+#endif /* CONFIG_ARM64_TAGGED_ADDR_ABI */
index 85ee7d0..c9f72b2 100644 (file)
@@ -46,6 +46,11 @@ static int cpu_psci_cpu_boot(unsigned int cpu)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
+static bool cpu_psci_cpu_can_disable(unsigned int cpu)
+{
+       return !psci_tos_resident_on(cpu);
+}
+
 static int cpu_psci_cpu_disable(unsigned int cpu)
 {
        /* Fail early if we don't have CPU_OFF support */
@@ -105,14 +110,11 @@ static int cpu_psci_cpu_kill(unsigned int cpu)
 
 const struct cpu_operations cpu_psci_ops = {
        .name           = "psci",
-#ifdef CONFIG_CPU_IDLE
-       .cpu_init_idle  = psci_cpu_init_idle,
-       .cpu_suspend    = psci_cpu_suspend_enter,
-#endif
        .cpu_init       = cpu_psci_cpu_init,
        .cpu_prepare    = cpu_psci_cpu_prepare,
        .cpu_boot       = cpu_psci_cpu_boot,
 #ifdef CONFIG_HOTPLUG_CPU
+       .cpu_can_disable = cpu_psci_cpu_can_disable,
        .cpu_disable    = cpu_psci_cpu_disable,
        .cpu_die        = cpu_psci_cpu_die,
        .cpu_kill       = cpu_psci_cpu_kill,
index 3cf3b13..21176d0 100644 (file)
@@ -870,7 +870,7 @@ static int sve_set(struct task_struct *target,
                goto out;
 
        /*
-        * Apart from PT_SVE_REGS_MASK, all PT_SVE_* flags are consumed by
+        * Apart from SVE_PT_REGS_MASK, all SVE_PT_* flags are consumed by
         * sve_set_vector_length(), which will also validate them for us:
         */
        ret = sve_set_vector_length(target, header.vl,
index 9c4bad7..56f6645 100644 (file)
@@ -170,9 +170,13 @@ static void __init smp_build_mpidr_hash(void)
 
 static void __init setup_machine_fdt(phys_addr_t dt_phys)
 {
-       void *dt_virt = fixmap_remap_fdt(dt_phys);
+       int size;
+       void *dt_virt = fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL);
        const char *name;
 
+       if (dt_virt)
+               memblock_reserve(dt_phys, size);
+
        if (!dt_virt || !early_init_dt_scan(dt_virt)) {
                pr_crit("\n"
                        "Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
@@ -184,6 +188,9 @@ static void __init setup_machine_fdt(phys_addr_t dt_phys)
                        cpu_relax();
        }
 
+       /* Early fixups are done, map the FDT as read-only now */
+       fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL_RO);
+
        name = of_flat_dt_get_machine_name();
        if (!name)
                return;
@@ -357,6 +364,15 @@ void __init setup_arch(char **cmdline_p)
        }
 }
 
+static inline bool cpu_can_disable(unsigned int cpu)
+{
+#ifdef CONFIG_HOTPLUG_CPU
+       if (cpu_ops[cpu] && cpu_ops[cpu]->cpu_can_disable)
+               return cpu_ops[cpu]->cpu_can_disable(cpu);
+#endif
+       return false;
+}
+
 static int __init topology_init(void)
 {
        int i;
@@ -366,7 +382,7 @@ static int __init topology_init(void)
 
        for_each_possible_cpu(i) {
                struct cpu *cpu = &per_cpu(cpu_data.cpu, i);
-               cpu->hotpluggable = 1;
+               cpu->hotpluggable = cpu_can_disable(i);
                register_cpu(cpu, i);
        }
 
index 018a33e..dc9fe87 100644 (file)
@@ -123,7 +123,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
                 * time out.
                 */
                wait_for_completion_timeout(&cpu_running,
-                                           msecs_to_jiffies(1000));
+                                           msecs_to_jiffies(5000));
 
                if (!cpu_online(cpu)) {
                        pr_crit("CPU%u: failed to come online\n", cpu);
@@ -136,6 +136,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
 
        secondary_data.task = NULL;
        secondary_data.stack = NULL;
+       __flush_dcache_area(&secondary_data, sizeof(secondary_data));
        status = READ_ONCE(secondary_data.status);
        if (ret && status) {
 
@@ -146,6 +147,7 @@ int __cpu_up(unsigned int cpu, struct task_struct *idle)
                default:
                        pr_err("CPU%u: failed in unknown state : 0x%lx\n",
                                        cpu, status);
+                       cpus_stuck_in_kernel++;
                        break;
                case CPU_KILL_ME:
                        if (!op_cpu_kill(cpu)) {
index 76c2739..c8a3fee 100644 (file)
@@ -19,7 +19,7 @@
 #include <asm/smp_plat.h>
 
 extern void secondary_holding_pen(void);
-volatile unsigned long __section(".mmuoff.data.read")
+volatile unsigned long __section(.mmuoff.data.read)
 secondary_holding_pen_release = INVALID_HWID;
 
 static phys_addr_t cpu_release_addr[NR_CPUS];
index 0825c4a..fa9528d 100644 (file)
 #include <linux/acpi.h>
 #include <linux/arch_topology.h>
 #include <linux/cacheinfo.h>
-#include <linux/cpu.h>
-#include <linux/cpumask.h>
 #include <linux/init.h>
 #include <linux/percpu.h>
-#include <linux/node.h>
-#include <linux/nodemask.h>
-#include <linux/of.h>
-#include <linux/sched.h>
-#include <linux/sched/topology.h>
-#include <linux/slab.h>
-#include <linux/smp.h>
-#include <linux/string.h>
 
 #include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/topology.h>
 
-static int __init get_cpu_for_node(struct device_node *node)
-{
-       struct device_node *cpu_node;
-       int cpu;
-
-       cpu_node = of_parse_phandle(node, "cpu", 0);
-       if (!cpu_node)
-               return -1;
-
-       cpu = of_cpu_node_to_id(cpu_node);
-       if (cpu >= 0)
-               topology_parse_cpu_capacity(cpu_node, cpu);
-       else
-               pr_crit("Unable to find CPU node for %pOF\n", cpu_node);
-
-       of_node_put(cpu_node);
-       return cpu;
-}
-
-static int __init parse_core(struct device_node *core, int package_id,
-                            int core_id)
-{
-       char name[10];
-       bool leaf = true;
-       int i = 0;
-       int cpu;
-       struct device_node *t;
-
-       do {
-               snprintf(name, sizeof(name), "thread%d", i);
-               t = of_get_child_by_name(core, name);
-               if (t) {
-                       leaf = false;
-                       cpu = get_cpu_for_node(t);
-                       if (cpu >= 0) {
-                               cpu_topology[cpu].package_id = package_id;
-                               cpu_topology[cpu].core_id = core_id;
-                               cpu_topology[cpu].thread_id = i;
-                       } else {
-                               pr_err("%pOF: Can't get CPU for thread\n",
-                                      t);
-                               of_node_put(t);
-                               return -EINVAL;
-                       }
-                       of_node_put(t);
-               }
-               i++;
-       } while (t);
-
-       cpu = get_cpu_for_node(core);
-       if (cpu >= 0) {
-               if (!leaf) {
-                       pr_err("%pOF: Core has both threads and CPU\n",
-                              core);
-                       return -EINVAL;
-               }
-
-               cpu_topology[cpu].package_id = package_id;
-               cpu_topology[cpu].core_id = core_id;
-       } else if (leaf) {
-               pr_err("%pOF: Can't get CPU for leaf core\n", core);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int __init parse_cluster(struct device_node *cluster, int depth)
-{
-       char name[10];
-       bool leaf = true;
-       bool has_cores = false;
-       struct device_node *c;
-       static int package_id __initdata;
-       int core_id = 0;
-       int i, ret;
-
-       /*
-        * First check for child clusters; we currently ignore any
-        * information about the nesting of clusters and present the
-        * scheduler with a flat list of them.
-        */
-       i = 0;
-       do {
-               snprintf(name, sizeof(name), "cluster%d", i);
-               c = of_get_child_by_name(cluster, name);
-               if (c) {
-                       leaf = false;
-                       ret = parse_cluster(c, depth + 1);
-                       of_node_put(c);
-                       if (ret != 0)
-                               return ret;
-               }
-               i++;
-       } while (c);
-
-       /* Now check for cores */
-       i = 0;
-       do {
-               snprintf(name, sizeof(name), "core%d", i);
-               c = of_get_child_by_name(cluster, name);
-               if (c) {
-                       has_cores = true;
-
-                       if (depth == 0) {
-                               pr_err("%pOF: cpu-map children should be clusters\n",
-                                      c);
-                               of_node_put(c);
-                               return -EINVAL;
-                       }
-
-                       if (leaf) {
-                               ret = parse_core(c, package_id, core_id++);
-                       } else {
-                               pr_err("%pOF: Non-leaf cluster with core %s\n",
-                                      cluster, name);
-                               ret = -EINVAL;
-                       }
-
-                       of_node_put(c);
-                       if (ret != 0)
-                               return ret;
-               }
-               i++;
-       } while (c);
-
-       if (leaf && !has_cores)
-               pr_warn("%pOF: empty cluster\n", cluster);
-
-       if (leaf)
-               package_id++;
-
-       return 0;
-}
-
-static int __init parse_dt_topology(void)
-{
-       struct device_node *cn, *map;
-       int ret = 0;
-       int cpu;
-
-       cn = of_find_node_by_path("/cpus");
-       if (!cn) {
-               pr_err("No CPU information found in DT\n");
-               return 0;
-       }
-
-       /*
-        * When topology is provided cpu-map is essentially a root
-        * cluster with restricted subnodes.
-        */
-       map = of_get_child_by_name(cn, "cpu-map");
-       if (!map)
-               goto out;
-
-       ret = parse_cluster(map, 0);
-       if (ret != 0)
-               goto out_map;
-
-       topology_normalize_cpu_scale();
-
-       /*
-        * Check that all cores are in the topology; the SMP code will
-        * only mark cores described in the DT as possible.
-        */
-       for_each_possible_cpu(cpu)
-               if (cpu_topology[cpu].package_id == -1)
-                       ret = -EINVAL;
-
-out_map:
-       of_node_put(map);
-out:
-       of_node_put(cn);
-       return ret;
-}
-
-/*
- * cpu topology table
- */
-struct cpu_topology cpu_topology[NR_CPUS];
-EXPORT_SYMBOL_GPL(cpu_topology);
-
-const struct cpumask *cpu_coregroup_mask(int cpu)
-{
-       const cpumask_t *core_mask = cpumask_of_node(cpu_to_node(cpu));
-
-       /* Find the smaller of NUMA, core or LLC siblings */
-       if (cpumask_subset(&cpu_topology[cpu].core_sibling, core_mask)) {
-               /* not numa in package, lets use the package siblings */
-               core_mask = &cpu_topology[cpu].core_sibling;
-       }
-       if (cpu_topology[cpu].llc_id != -1) {
-               if (cpumask_subset(&cpu_topology[cpu].llc_sibling, core_mask))
-                       core_mask = &cpu_topology[cpu].llc_sibling;
-       }
-
-       return core_mask;
-}
-
-static void update_siblings_masks(unsigned int cpuid)
-{
-       struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
-       int cpu;
-
-       /* update core and thread sibling masks */
-       for_each_online_cpu(cpu) {
-               cpu_topo = &cpu_topology[cpu];
-
-               if (cpuid_topo->llc_id == cpu_topo->llc_id) {
-                       cpumask_set_cpu(cpu, &cpuid_topo->llc_sibling);
-                       cpumask_set_cpu(cpuid, &cpu_topo->llc_sibling);
-               }
-
-               if (cpuid_topo->package_id != cpu_topo->package_id)
-                       continue;
-
-               cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
-               cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
-
-               if (cpuid_topo->core_id != cpu_topo->core_id)
-                       continue;
-
-               cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
-               cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
-       }
-}
-
 void store_cpu_topology(unsigned int cpuid)
 {
        struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
@@ -296,60 +59,31 @@ topology_populated:
        update_siblings_masks(cpuid);
 }
 
-static void clear_cpu_topology(int cpu)
-{
-       struct cpu_topology *cpu_topo = &cpu_topology[cpu];
-
-       cpumask_clear(&cpu_topo->llc_sibling);
-       cpumask_set_cpu(cpu, &cpu_topo->llc_sibling);
-
-       cpumask_clear(&cpu_topo->core_sibling);
-       cpumask_set_cpu(cpu, &cpu_topo->core_sibling);
-       cpumask_clear(&cpu_topo->thread_sibling);
-       cpumask_set_cpu(cpu, &cpu_topo->thread_sibling);
-}
-
-static void __init reset_cpu_topology(void)
-{
-       unsigned int cpu;
-
-       for_each_possible_cpu(cpu) {
-               struct cpu_topology *cpu_topo = &cpu_topology[cpu];
-
-               cpu_topo->thread_id = -1;
-               cpu_topo->core_id = 0;
-               cpu_topo->package_id = -1;
-               cpu_topo->llc_id = -1;
-
-               clear_cpu_topology(cpu);
-       }
-}
-
-void remove_cpu_topology(unsigned int cpu)
+#ifdef CONFIG_ACPI
+static bool __init acpi_cpu_is_threaded(int cpu)
 {
-       int sibling;
+       int is_threaded = acpi_pptt_cpu_is_thread(cpu);
 
-       for_each_cpu(sibling, topology_core_cpumask(cpu))
-               cpumask_clear_cpu(cpu, topology_core_cpumask(sibling));
-       for_each_cpu(sibling, topology_sibling_cpumask(cpu))
-               cpumask_clear_cpu(cpu, topology_sibling_cpumask(sibling));
-       for_each_cpu(sibling, topology_llc_cpumask(cpu))
-               cpumask_clear_cpu(cpu, topology_llc_cpumask(sibling));
+       /*
+        * if the PPTT doesn't have thread information, assume a homogeneous
+        * machine and return the current CPU's thread state.
+        */
+       if (is_threaded < 0)
+               is_threaded = read_cpuid_mpidr() & MPIDR_MT_BITMASK;
 
-       clear_cpu_topology(cpu);
+       return !!is_threaded;
 }
 
-#ifdef CONFIG_ACPI
 /*
  * Propagate the topology information of the processor_topology_node tree to the
  * cpu_topology array.
  */
-static int __init parse_acpi_topology(void)
+int __init parse_acpi_topology(void)
 {
-       bool is_threaded;
        int cpu, topology_id;
 
-       is_threaded = read_cpuid_mpidr() & MPIDR_MT_BITMASK;
+       if (acpi_disabled)
+               return 0;
 
        for_each_possible_cpu(cpu) {
                int i, cache_id;
@@ -358,7 +92,7 @@ static int __init parse_acpi_topology(void)
                if (topology_id < 0)
                        return topology_id;
 
-               if (is_threaded) {
+               if (acpi_cpu_is_threaded(cpu)) {
                        cpu_topology[cpu].thread_id = topology_id;
                        topology_id = find_acpi_cpu_topology(cpu, 1);
                        cpu_topology[cpu].core_id   = topology_id;
@@ -384,24 +118,6 @@ static int __init parse_acpi_topology(void)
 
        return 0;
 }
-
-#else
-static inline int __init parse_acpi_topology(void)
-{
-       return -EINVAL;
-}
 #endif
 
-void __init init_cpu_topology(void)
-{
-       reset_cpu_topology();
 
-       /*
-        * Discard anything that was parsed if we hit an error so we
-        * don't use partial information.
-        */
-       if (!acpi_disabled && parse_acpi_topology())
-               reset_cpu_topology();
-       else if (of_have_populated_dt() && parse_dt_topology())
-               reset_cpu_topology();
-}
index 32893b3..34739e8 100644 (file)
@@ -7,9 +7,11 @@
  */
 
 #include <linux/bug.h>
+#include <linux/context_tracking.h>
 #include <linux/signal.h>
 #include <linux/personality.h>
 #include <linux/kallsyms.h>
+#include <linux/kprobes.h>
 #include <linux/spinlock.h>
 #include <linux/uaccess.h>
 #include <linux/hardirq.h>
@@ -511,7 +513,7 @@ struct sys64_hook {
        void (*handler)(unsigned int esr, struct pt_regs *regs);
 };
 
-static struct sys64_hook sys64_hooks[] = {
+static const struct sys64_hook sys64_hooks[] = {
        {
                .esr_mask = ESR_ELx_SYS64_ISS_EL0_CACHE_OP_MASK,
                .esr_val = ESR_ELx_SYS64_ISS_EL0_CACHE_OP_VAL,
@@ -636,7 +638,7 @@ static void compat_cntfrq_read_handler(unsigned int esr, struct pt_regs *regs)
        arm64_compat_skip_faulting_instruction(regs, 4);
 }
 
-static struct sys64_hook cp15_32_hooks[] = {
+static const struct sys64_hook cp15_32_hooks[] = {
        {
                .esr_mask = ESR_ELx_CP15_32_ISS_SYS_MASK,
                .esr_val = ESR_ELx_CP15_32_ISS_SYS_CNTFRQ,
@@ -656,7 +658,7 @@ static void compat_cntvct_read_handler(unsigned int esr, struct pt_regs *regs)
        arm64_compat_skip_faulting_instruction(regs, 4);
 }
 
-static struct sys64_hook cp15_64_hooks[] = {
+static const struct sys64_hook cp15_64_hooks[] = {
        {
                .esr_mask = ESR_ELx_CP15_64_ISS_SYS_MASK,
                .esr_val = ESR_ELx_CP15_64_ISS_SYS_CNTVCT,
@@ -667,7 +669,7 @@ static struct sys64_hook cp15_64_hooks[] = {
 
 asmlinkage void __exception do_cp15instr(unsigned int esr, struct pt_regs *regs)
 {
-       struct sys64_hook *hook, *hook_base;
+       const struct sys64_hook *hook, *hook_base;
 
        if (!cp15_cond_valid(esr, regs)) {
                /*
@@ -707,7 +709,7 @@ asmlinkage void __exception do_cp15instr(unsigned int esr, struct pt_regs *regs)
 
 asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
 {
-       struct sys64_hook *hook;
+       const struct sys64_hook *hook;
 
        for (hook = sys64_hooks; hook->handler; hook++)
                if ((hook->esr_mask & esr) == hook->esr_val) {
@@ -744,6 +746,7 @@ static const char *esr_class_str[] = {
        [ESR_ELx_EC_SMC64]              = "SMC (AArch64)",
        [ESR_ELx_EC_SYS64]              = "MSR/MRS (AArch64)",
        [ESR_ELx_EC_SVE]                = "SVE",
+       [ESR_ELx_EC_ERET]               = "ERET/ERETAA/ERETAB",
        [ESR_ELx_EC_IMP_DEF]            = "EL3 IMP DEF",
        [ESR_ELx_EC_IABT_LOW]           = "IABT (lower EL)",
        [ESR_ELx_EC_IABT_CUR]           = "IABT (current EL)",
@@ -900,6 +903,13 @@ asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr)
                nmi_exit();
 }
 
+asmlinkage void enter_from_user_mode(void)
+{
+       CT_WARN_ON(ct_state() != CONTEXT_USER);
+       user_exit_irqoff();
+}
+NOKPROBE_SYMBOL(enter_from_user_mode);
+
 void __pte_error(const char *file, int line, unsigned long val)
 {
        pr_err("%s:%d: bad pte %016lx.\n", file, line, val);
index 7fa0083..aa76f72 100644 (file)
@@ -200,6 +200,15 @@ SECTIONS
        __rela_offset   = ABSOLUTE(ADDR(.rela.dyn) - KIMAGE_VADDR);
        __rela_size     = SIZEOF(.rela.dyn);
 
+#ifdef CONFIG_RELR
+       .relr.dyn : ALIGN(8) {
+               *(.relr.dyn)
+       }
+
+       __relr_offset   = ABSOLUTE(ADDR(.relr.dyn) - KIMAGE_VADDR);
+       __relr_size     = SIZEOF(.relr.dyn);
+#endif
+
        . = ALIGN(SEGMENT_ALIGN);
        __initdata_end = .;
        __init_end = .;
@@ -245,6 +254,8 @@ SECTIONS
        HEAD_SYMBOLS
 }
 
+#include "image-vars.h"
+
 /*
  * The HYP init code and ID map text can't be longer than a page each,
  * and should not cross a page boundary.
index adaf266..bd978ad 100644 (file)
@@ -264,7 +264,7 @@ static bool __hyp_text __translate_far_to_hpfar(u64 far, u64 *hpfar)
        tmp = read_sysreg(par_el1);
        write_sysreg(par, par_el1);
 
-       if (unlikely(tmp & 1))
+       if (unlikely(tmp & SYS_PAR_EL1_F))
                return false; /* Translation failed, back to guest */
 
        /* Convert PAR to HPFAR format */
index acd8084..2cf7d4b 100644 (file)
@@ -29,25 +29,25 @@ static void compute_layout(void)
        int kva_msb;
 
        /* Where is my RAM region? */
-       hyp_va_msb  = idmap_addr & BIT(VA_BITS - 1);
-       hyp_va_msb ^= BIT(VA_BITS - 1);
+       hyp_va_msb  = idmap_addr & BIT(vabits_actual - 1);
+       hyp_va_msb ^= BIT(vabits_actual - 1);
 
        kva_msb = fls64((u64)phys_to_virt(memblock_start_of_DRAM()) ^
                        (u64)(high_memory - 1));
 
-       if (kva_msb == (VA_BITS - 1)) {
+       if (kva_msb == (vabits_actual - 1)) {
                /*
                 * No space in the address, let's compute the mask so
-                * that it covers (VA_BITS - 1) bits, and the region
+                * that it covers (vabits_actual - 1) bits, and the region
                 * bit. The tag stays set to zero.
                 */
-               va_mask  = BIT(VA_BITS - 1) - 1;
+               va_mask  = BIT(vabits_actual - 1) - 1;
                va_mask |= hyp_va_msb;
        } else {
                /*
                 * We do have some free bits to insert a random tag.
                 * Hyp VAs are now created from kernel linear map VAs
-                * using the following formula (with V == VA_BITS):
+                * using the following formula (with V == vabits_actual):
                 *
                 *  63 ... V |     V-1    | V-2 .. tag_lsb | tag_lsb - 1 .. 0
                 *  ---------------------------------------------------------
@@ -55,7 +55,7 @@ static void compute_layout(void)
                 */
                tag_lsb = kva_msb;
                va_mask = GENMASK_ULL(tag_lsb - 1, 0);
-               tag_val = get_random_long() & GENMASK_ULL(VA_BITS - 2, tag_lsb);
+               tag_val = get_random_long() & GENMASK_ULL(vabits_actual - 2, tag_lsb);
                tag_val |= hyp_va_msb;
                tag_val >>= tag_lsb;
        }
index 33c2a4a..c21b936 100644 (file)
@@ -11,25 +11,8 @@ CFLAGS_REMOVE_xor-neon.o     += -mgeneral-regs-only
 CFLAGS_xor-neon.o              += -ffreestanding
 endif
 
-# Tell the compiler to treat all general purpose registers (with the
-# exception of the IP registers, which are already handled by the caller
-# in case of a PLT) as callee-saved, which allows for efficient runtime
-# patching of the bl instruction in the caller with an atomic instruction
-# when supported by the CPU. Result and argument registers are handled
-# correctly, based on the function prototype.
-lib-$(CONFIG_ARM64_LSE_ATOMICS) += atomic_ll_sc.o
-CFLAGS_atomic_ll_sc.o  := -ffixed-x1 -ffixed-x2                        \
-                  -ffixed-x3 -ffixed-x4 -ffixed-x5 -ffixed-x6          \
-                  -ffixed-x7 -fcall-saved-x8 -fcall-saved-x9           \
-                  -fcall-saved-x10 -fcall-saved-x11 -fcall-saved-x12   \
-                  -fcall-saved-x13 -fcall-saved-x14 -fcall-saved-x15   \
-                  -fcall-saved-x18 -fomit-frame-pointer
-CFLAGS_REMOVE_atomic_ll_sc.o := $(CC_FLAGS_FTRACE)
-GCOV_PROFILE_atomic_ll_sc.o    := n
-KASAN_SANITIZE_atomic_ll_sc.o  := n
-KCOV_INSTRUMENT_atomic_ll_sc.o := n
-UBSAN_SANITIZE_atomic_ll_sc.o  := n
-
 lib-$(CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE) += uaccess_flushcache.o
 
 obj-$(CONFIG_CRC32) += crc32.o
+
+obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
diff --git a/arch/arm64/lib/atomic_ll_sc.c b/arch/arm64/lib/atomic_ll_sc.c
deleted file mode 100644 (file)
index b0c538b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <asm/atomic.h>
-#define __ARM64_IN_ATOMIC_IMPL
-#include <asm/atomic_ll_sc.h>
diff --git a/arch/arm64/lib/error-inject.c b/arch/arm64/lib/error-inject.c
new file mode 100644 (file)
index 0000000..ed15021
--- /dev/null
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/error-injection.h>
+#include <linux/kprobes.h>
+
+void override_function_with_return(struct pt_regs *regs)
+{
+       /*
+        * 'regs' represents the state on entry of a predefined function in
+        * the kernel/module and which is captured on a kprobe.
+        *
+        * When kprobe returns back from exception it will override the end
+        * of probed function and directly return to the predefined
+        * function's caller.
+        */
+       instruction_pointer_set(regs, procedure_link_pointer(regs));
+}
+NOKPROBE_SYMBOL(override_function_with_return);
index 82b3a7f..93f9f77 100644 (file)
 #include <asm/pgtable-hwdef.h>
 #include <asm/ptdump.h>
 
-static const struct addr_marker address_markers[] = {
+
+enum address_markers_idx {
+       PAGE_OFFSET_NR = 0,
+       PAGE_END_NR,
 #ifdef CONFIG_KASAN
-       { KASAN_SHADOW_START,           "Kasan shadow start" },
+       KASAN_START_NR,
+#endif
+};
+
+static struct addr_marker address_markers[] = {
+       { PAGE_OFFSET,                  "Linear Mapping start" },
+       { 0 /* PAGE_END */,             "Linear Mapping end" },
+#ifdef CONFIG_KASAN
+       { 0 /* KASAN_SHADOW_START */,   "Kasan shadow start" },
        { KASAN_SHADOW_END,             "Kasan shadow end" },
 #endif
        { MODULES_VADDR,                "Modules start" },
@@ -42,7 +53,6 @@ static const struct addr_marker address_markers[] = {
        { VMEMMAP_START,                "vmemmap start" },
        { VMEMMAP_START + VMEMMAP_SIZE, "vmemmap end" },
 #endif
-       { PAGE_OFFSET,                  "Linear mapping" },
        { -1,                           NULL },
 };
 
@@ -376,7 +386,7 @@ static void ptdump_initialize(void)
 static struct ptdump_info kernel_ptdump_info = {
        .mm             = &init_mm,
        .markers        = address_markers,
-       .base_addr      = VA_START,
+       .base_addr      = PAGE_OFFSET,
 };
 
 void ptdump_check_wx(void)
@@ -390,7 +400,7 @@ void ptdump_check_wx(void)
                .check_wx = true,
        };
 
-       walk_pgd(&st, &init_mm, VA_START);
+       walk_pgd(&st, &init_mm, PAGE_OFFSET);
        note_page(&st, 0, 0, 0);
        if (st.wx_pages || st.uxn_pages)
                pr_warn("Checked W+X mappings: FAILED, %lu W+X pages found, %lu non-UXN pages found\n",
@@ -401,6 +411,10 @@ void ptdump_check_wx(void)
 
 static int ptdump_init(void)
 {
+       address_markers[PAGE_END_NR].start_address = PAGE_END;
+#ifdef CONFIG_KASAN
+       address_markers[KASAN_START_NR].start_address = KASAN_SHADOW_START;
+#endif
        ptdump_initialize();
        ptdump_debugfs_register(&kernel_ptdump_info, "kernel_page_tables");
        return 0;
index cfd65b6..115d7a0 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/bitfield.h>
 #include <linux/extable.h>
 #include <linux/signal.h>
 #include <linux/mm.h>
@@ -86,8 +87,8 @@ static void mem_abort_decode(unsigned int esr)
        pr_alert("Mem abort info:\n");
 
        pr_alert("  ESR = 0x%08x\n", esr);
-       pr_alert("  Exception class = %s, IL = %u bits\n",
-                esr_get_class_string(esr),
+       pr_alert("  EC = 0x%02lx: %s, IL = %u bits\n",
+                ESR_ELx_EC(esr), esr_get_class_string(esr),
                 (esr & ESR_ELx_IL) ? 32 : 16);
        pr_alert("  SET = %lu, FnV = %lu\n",
                 (esr & ESR_ELx_SET_MASK) >> ESR_ELx_SET_SHIFT,
@@ -109,7 +110,7 @@ static inline bool is_ttbr0_addr(unsigned long addr)
 static inline bool is_ttbr1_addr(unsigned long addr)
 {
        /* TTBR1 addresses may have a tag if KASAN_SW_TAGS is in use */
-       return arch_kasan_reset_tag(addr) >= VA_START;
+       return arch_kasan_reset_tag(addr) >= PAGE_OFFSET;
 }
 
 /*
@@ -138,10 +139,9 @@ static void show_pte(unsigned long addr)
                return;
        }
 
-       pr_alert("%s pgtable: %luk pages, %u-bit VAs, pgdp=%016lx\n",
+       pr_alert("%s pgtable: %luk pages, %llu-bit VAs, pgdp=%016lx\n",
                 mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
-                mm == &init_mm ? VA_BITS : (int)vabits_user,
-                (unsigned long)virt_to_phys(mm->pgd));
+                vabits_actual, (unsigned long)virt_to_phys(mm->pgd));
        pgdp = pgd_offset(mm, addr);
        pgd = READ_ONCE(*pgdp);
        pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
@@ -242,6 +242,34 @@ static inline bool is_el1_permission_fault(unsigned long addr, unsigned int esr,
        return false;
 }
 
+static bool __kprobes is_spurious_el1_translation_fault(unsigned long addr,
+                                                       unsigned int esr,
+                                                       struct pt_regs *regs)
+{
+       unsigned long flags;
+       u64 par, dfsc;
+
+       if (ESR_ELx_EC(esr) != ESR_ELx_EC_DABT_CUR ||
+           (esr & ESR_ELx_FSC_TYPE) != ESR_ELx_FSC_FAULT)
+               return false;
+
+       local_irq_save(flags);
+       asm volatile("at s1e1r, %0" :: "r" (addr));
+       isb();
+       par = read_sysreg(par_el1);
+       local_irq_restore(flags);
+
+       if (!(par & SYS_PAR_EL1_F))
+               return false;
+
+       /*
+        * If we got a different type of fault from the AT instruction,
+        * treat the translation fault as spurious.
+        */
+       dfsc = FIELD_PREP(SYS_PAR_EL1_FST, par);
+       return (dfsc & ESR_ELx_FSC_TYPE) != ESR_ELx_FSC_FAULT;
+}
+
 static void die_kernel_fault(const char *msg, unsigned long addr,
                             unsigned int esr, struct pt_regs *regs)
 {
@@ -270,6 +298,10 @@ static void __do_kernel_fault(unsigned long addr, unsigned int esr,
        if (!is_el1_instruction_abort(esr) && fixup_exception(regs))
                return;
 
+       if (WARN_RATELIMIT(is_spurious_el1_translation_fault(addr, esr, regs),
+           "Ignoring spurious kernel translation fault at virtual address %016lx\n", addr))
+               return;
+
        if (is_el1_permission_fault(addr, esr, regs)) {
                if (esr & ESR_ELx_WNR)
                        msg = "write to read-only memory";
index f3c7952..45c00a5 100644 (file)
 s64 memstart_addr __ro_after_init = -1;
 EXPORT_SYMBOL(memstart_addr);
 
+s64 physvirt_offset __ro_after_init;
+EXPORT_SYMBOL(physvirt_offset);
+
+struct page *vmemmap __ro_after_init;
+EXPORT_SYMBOL(vmemmap);
+
 phys_addr_t arm64_dma_phys_limit __ro_after_init;
 
 #ifdef CONFIG_KEXEC_CORE
@@ -301,7 +307,7 @@ static void __init fdt_enforce_memory_region(void)
 
 void __init arm64_memblock_init(void)
 {
-       const s64 linear_region_size = -(s64)PAGE_OFFSET;
+       const s64 linear_region_size = BIT(vabits_actual - 1);
 
        /* Handle linux,usable-memory-range property */
        fdt_enforce_memory_region();
@@ -310,18 +316,25 @@ void __init arm64_memblock_init(void)
        memblock_remove(1ULL << PHYS_MASK_SHIFT, ULLONG_MAX);
 
        /*
-        * Ensure that the linear region takes up exactly half of the kernel
-        * virtual address space. This way, we can distinguish a linear address
-        * from a kernel/module/vmalloc address by testing a single bit.
-        */
-       BUILD_BUG_ON(linear_region_size != BIT(VA_BITS - 1));
-
-       /*
         * Select a suitable value for the base of physical memory.
         */
        memstart_addr = round_down(memblock_start_of_DRAM(),
                                   ARM64_MEMSTART_ALIGN);
 
+       physvirt_offset = PHYS_OFFSET - PAGE_OFFSET;
+
+       vmemmap = ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT));
+
+       /*
+        * If we are running with a 52-bit kernel VA config on a system that
+        * does not support it, we have to offset our vmemmap and physvirt_offset
+        * s.t. we avoid the 52-bit portion of the direct linear map
+        */
+       if (IS_ENABLED(CONFIG_ARM64_VA_BITS_52) && (vabits_actual != 52)) {
+               vmemmap += (_PAGE_OFFSET(48) - _PAGE_OFFSET(52)) >> PAGE_SHIFT;
+               physvirt_offset = PHYS_OFFSET - _PAGE_OFFSET(48);
+       }
+
        /*
         * Remove the memory that we will not be able to cover with the
         * linear mapping. Take care not to clip the kernel which may be
@@ -570,8 +583,12 @@ void free_initmem(void)
 #ifdef CONFIG_BLK_DEV_INITRD
 void __init free_initrd_mem(unsigned long start, unsigned long end)
 {
+       unsigned long aligned_start, aligned_end;
+
+       aligned_start = __virt_to_phys(start) & PAGE_MASK;
+       aligned_end = PAGE_ALIGN(__virt_to_phys(end));
+       memblock_free(aligned_start, aligned_end - aligned_start);
        free_reserved_area((void *)start, (void *)end, 0, "initrd");
-       memblock_free(__virt_to_phys(start), end - start);
 }
 #endif
 
index fdb595a..9be71be 100644 (file)
@@ -69,7 +69,7 @@ void __iomem *__ioremap(phys_addr_t phys_addr, size_t size, pgprot_t prot)
 }
 EXPORT_SYMBOL(__ioremap);
 
-void __iounmap(volatile void __iomem *io_addr)
+void iounmap(volatile void __iomem *io_addr)
 {
        unsigned long addr = (unsigned long)io_addr & PAGE_MASK;
 
@@ -80,7 +80,7 @@ void __iounmap(volatile void __iomem *io_addr)
        if (is_vmalloc_addr((void *)addr))
                vunmap((void *)addr);
 }
-EXPORT_SYMBOL(__iounmap);
+EXPORT_SYMBOL(iounmap);
 
 void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size)
 {
index 6cf97b9..f87a324 100644 (file)
@@ -156,7 +156,8 @@ asmlinkage void __init kasan_early_init(void)
 {
        BUILD_BUG_ON(KASAN_SHADOW_OFFSET !=
                KASAN_SHADOW_END - (1UL << (64 - KASAN_SHADOW_SCALE_SHIFT)));
-       BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_START, PGDIR_SIZE));
+       BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS), PGDIR_SIZE));
+       BUILD_BUG_ON(!IS_ALIGNED(_KASAN_SHADOW_START(VA_BITS_MIN), PGDIR_SIZE));
        BUILD_BUG_ON(!IS_ALIGNED(KASAN_SHADOW_END, PGDIR_SIZE));
        kasan_pgd_populate(KASAN_SHADOW_START, KASAN_SHADOW_END, NUMA_NO_NODE,
                           true);
@@ -225,10 +226,10 @@ void __init kasan_init(void)
        kasan_map_populate(kimg_shadow_start, kimg_shadow_end,
                           early_pfn_to_nid(virt_to_pfn(lm_alias(_text))));
 
-       kasan_populate_early_shadow((void *)KASAN_SHADOW_START,
-                                   (void *)mod_shadow_start);
+       kasan_populate_early_shadow(kasan_mem_to_shadow((void *)PAGE_END),
+                                  (void *)mod_shadow_start);
        kasan_populate_early_shadow((void *)kimg_shadow_end,
-                                   kasan_mem_to_shadow((void *)PAGE_OFFSET));
+                                  (void *)KASAN_SHADOW_END);
 
        if (kimg_shadow_start > mod_shadow_end)
                kasan_populate_early_shadow((void *)mod_shadow_end,
index 750a69d..53dc6f2 100644 (file)
@@ -40,8 +40,9 @@
 
 u64 idmap_t0sz = TCR_T0SZ(VA_BITS);
 u64 idmap_ptrs_per_pgd = PTRS_PER_PGD;
-u64 vabits_user __ro_after_init;
-EXPORT_SYMBOL(vabits_user);
+
+u64 __section(".mmuoff.data.write") vabits_actual;
+EXPORT_SYMBOL(vabits_actual);
 
 u64 kimage_voffset __ro_after_init;
 EXPORT_SYMBOL(kimage_voffset);
@@ -398,7 +399,7 @@ static phys_addr_t pgd_pgtable_alloc(int shift)
 static void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt,
                                  phys_addr_t size, pgprot_t prot)
 {
-       if (virt < VMALLOC_START) {
+       if ((virt >= PAGE_END) && (virt < VMALLOC_START)) {
                pr_warn("BUG: not creating mapping for %pa at 0x%016lx - outside kernel range\n",
                        &phys, virt);
                return;
@@ -425,7 +426,7 @@ void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
 static void update_mapping_prot(phys_addr_t phys, unsigned long virt,
                                phys_addr_t size, pgprot_t prot)
 {
-       if (virt < VMALLOC_START) {
+       if ((virt >= PAGE_END) && (virt < VMALLOC_START)) {
                pr_warn("BUG: not updating mapping for %pa at 0x%016lx - outside kernel range\n",
                        &phys, virt);
                return;
@@ -646,6 +647,8 @@ static void __init map_kernel(pgd_t *pgdp)
                set_pgd(pgd_offset_raw(pgdp, FIXADDR_START),
                        READ_ONCE(*pgd_offset_k(FIXADDR_START)));
        } else if (CONFIG_PGTABLE_LEVELS > 3) {
+               pgd_t *bm_pgdp;
+               pud_t *bm_pudp;
                /*
                 * The fixmap shares its top level pgd entry with the kernel
                 * mapping. This can really only occur when we are running
@@ -653,9 +656,9 @@ static void __init map_kernel(pgd_t *pgdp)
                 * entry instead.
                 */
                BUG_ON(!IS_ENABLED(CONFIG_ARM64_16K_PAGES));
-               pud_populate(&init_mm,
-                            pud_set_fixmap_offset(pgdp, FIXADDR_START),
-                            lm_alias(bm_pmd));
+               bm_pgdp = pgd_offset_raw(pgdp, FIXADDR_START);
+               bm_pudp = pud_set_fixmap_offset(bm_pgdp, FIXADDR_START);
+               pud_populate(&init_mm, bm_pudp, lm_alias(bm_pmd));
                pud_clear_fixmap();
        } else {
                BUG();
@@ -876,7 +879,7 @@ void __set_fixmap(enum fixed_addresses idx,
        }
 }
 
-void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
+void *__init fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
 {
        const u64 dt_virt_base = __fix_to_virt(FIX_FDT);
        int offset;
@@ -929,19 +932,6 @@ void *__init __fixmap_remap_fdt(phys_addr_t dt_phys, int *size, pgprot_t prot)
        return dt_virt;
 }
 
-void *__init fixmap_remap_fdt(phys_addr_t dt_phys)
-{
-       void *dt_virt;
-       int size;
-
-       dt_virt = __fixmap_remap_fdt(dt_phys, &size, PAGE_KERNEL_RO);
-       if (!dt_virt)
-               return NULL;
-
-       memblock_reserve(dt_phys, size);
-       return dt_virt;
-}
-
 int __init arch_ioremap_p4d_supported(void)
 {
        return 0;
index 4f241cc..4decf16 100644 (file)
@@ -29,7 +29,7 @@ static __init int numa_parse_early_param(char *opt)
 {
        if (!opt)
                return -EINVAL;
-       if (!strncmp(opt, "off", 3))
+       if (str_has_prefix(opt, "off"))
                numa_off = true;
 
        return 0;
index 03c53f1..9ce7bd9 100644 (file)
@@ -128,7 +128,6 @@ int set_memory_nx(unsigned long addr, int numpages)
                                        __pgprot(PTE_PXN),
                                        __pgprot(0));
 }
-EXPORT_SYMBOL_GPL(set_memory_nx);
 
 int set_memory_x(unsigned long addr, int numpages)
 {
@@ -136,7 +135,6 @@ int set_memory_x(unsigned long addr, int numpages)
                                        __pgprot(0),
                                        __pgprot(PTE_PXN));
 }
-EXPORT_SYMBOL_GPL(set_memory_x);
 
 int set_memory_valid(unsigned long addr, int numpages, int enable)
 {
index 7dbf2be..a1e0592 100644 (file)
@@ -168,7 +168,7 @@ ENDPROC(cpu_do_switch_mm)
 .macro __idmap_cpu_set_reserved_ttbr1, tmp1, tmp2
        adrp    \tmp1, empty_zero_page
        phys_to_ttbr \tmp2, \tmp1
-       offset_ttbr1 \tmp2
+       offset_ttbr1 \tmp2, \tmp1
        msr     ttbr1_el1, \tmp2
        isb
        tlbi    vmalle1
@@ -187,7 +187,7 @@ ENTRY(idmap_cpu_replace_ttbr1)
 
        __idmap_cpu_set_reserved_ttbr1 x1, x3
 
-       offset_ttbr1 x0
+       offset_ttbr1 x0, x3
        msr     ttbr1_el1, x0
        isb
 
@@ -286,6 +286,15 @@ skip_pgd:
        msr     sctlr_el1, x18
        isb
 
+       /*
+        * Invalidate the local I-cache so that any instructions fetched
+        * speculatively from the PoC are discarded, since they may have
+        * been dynamically patched at the PoU.
+        */
+       ic      iallu
+       dsb     nsh
+       isb
+
        /* Set the flag to zero to indicate that we're all done */
        str     wzr, [flag_ptr]
        ret
@@ -362,7 +371,7 @@ __idmap_kpti_secondary:
        cbnz    w18, 1b
 
        /* All done, act like nothing happened */
-       offset_ttbr1 swapper_ttb
+       offset_ttbr1 swapper_ttb, x18
        msr     ttbr1_el1, swapper_ttb
        isb
        ret
@@ -438,10 +447,11 @@ ENTRY(__cpu_setup)
                        TCR_TBI0 | TCR_A1 | TCR_KASAN_FLAGS
        tcr_clear_errata_bits x10, x9, x5
 
-#ifdef CONFIG_ARM64_USER_VA_BITS_52
-       ldr_l           x9, vabits_user
+#ifdef CONFIG_ARM64_VA_BITS_52
+       ldr_l           x9, vabits_actual
        sub             x9, xzr, x9
        add             x9, x9, #64
+       tcr_set_t1sz    x10, x9
 #else
        ldr_l           x9, idmap_t0sz
 #endif
index 7468d8e..13d49c2 100644 (file)
@@ -10,12 +10,14 @@ config IA64
        bool
        select ARCH_MIGHT_HAVE_PC_PARPORT
        select ARCH_MIGHT_HAVE_PC_SERIO
-       select ACPI if (!IA64_HP_SIM)
-       select ARCH_SUPPORTS_ACPI if (!IA64_HP_SIM)
+       select ACPI
+       select ACPI_NUMA if NUMA
+       select ARCH_SUPPORTS_ACPI
        select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI
        select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI
-       select FORCE_PCI if (!IA64_HP_SIM)
+       select FORCE_PCI
        select PCI_DOMAINS if PCI
+       select PCI_MSI
        select PCI_SYSCALL if PCI
        select HAVE_UNSTABLE_SCHED_CLOCK
        select HAVE_EXIT_THREAD
@@ -30,8 +32,8 @@ config IA64
        select HAVE_ARCH_TRACEHOOK
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_VIRT_CPU_ACCOUNTING
-       select ARCH_HAS_DMA_COHERENT_TO_PFN if SWIOTLB
-       select ARCH_HAS_SYNC_DMA_FOR_CPU if SWIOTLB
+       select ARCH_HAS_DMA_COHERENT_TO_PFN
+       select ARCH_HAS_SYNC_DMA_FOR_CPU
        select VIRT_TO_BUS
        select GENERIC_IRQ_PROBE
        select GENERIC_PENDING_IRQ if SMP
@@ -45,6 +47,7 @@ config IA64
        select ARCH_THREAD_STACK_ALLOCATOR
        select ARCH_CLOCKSOURCE_DATA
        select GENERIC_TIME_VSYSCALL
+       select SWIOTLB
        select SYSCTL_ARCH_UNALIGN_NO_WARN
        select HAVE_MOD_ARCH_SPECIFIC
        select MODULES_USE_ELF_RELA
@@ -52,6 +55,7 @@ config IA64
        select HAVE_ARCH_AUDITSYSCALL
        select NEED_DMA_MAP_STATE
        select NEED_SG_DMA_LENGTH
+       select NUMA if !FLATMEM
        default y
        help
          The Itanium Processor Family is Intel's 64-bit successor to
@@ -66,7 +70,6 @@ config 64BIT
 
 config ZONE_DMA32
        def_bool y
-       depends on !IA64_SGI_SN2
 
 config QUICKLIST
        bool
@@ -121,87 +124,6 @@ config AUDIT_ARCH
        default y
 
 choice
-       prompt "System type"
-       default IA64_GENERIC
-
-config IA64_GENERIC
-       bool "generic"
-       select NUMA
-       select ACPI_NUMA
-       select SWIOTLB
-       select PCI_MSI
-       help
-         This selects the system type of your hardware.  A "generic" kernel
-         will run on any supported IA-64 system.  However, if you configure
-         a kernel for your specific system, it will be faster and smaller.
-
-         generic               For any supported IA-64 system
-         DIG-compliant         For DIG ("Developer's Interface Guide") compliant systems
-         DIG+Intel+IOMMU       For DIG systems with Intel IOMMU
-         HP-zx1/sx1000         For HP systems
-         HP-zx1/sx1000+swiotlb For HP systems with (broken) DMA-constrained devices.
-         SGI-SN2               For SGI Altix systems
-         SGI-UV                For SGI UV systems
-         Ski-simulator         For the HP simulator <http://www.hpl.hp.com/research/linux/ski/>
-
-         If you don't know what to do, choose "generic".
-
-config IA64_DIG
-       bool "DIG-compliant"
-       select SWIOTLB
-
-config IA64_DIG_VTD
-       bool "DIG+Intel+IOMMU"
-       select INTEL_IOMMU
-       select PCI_MSI
-
-config IA64_HP_ZX1
-       bool "HP-zx1/sx1000"
-       help
-         Build a kernel that runs on HP zx1 and sx1000 systems.  This adds
-         support for the HP I/O MMU.
-
-config IA64_HP_ZX1_SWIOTLB
-       bool "HP-zx1/sx1000 with software I/O TLB"
-       select SWIOTLB
-       help
-         Build a kernel that runs on HP zx1 and sx1000 systems even when they
-         have broken PCI devices which cannot DMA to full 32 bits.  Apart
-         from support for the HP I/O MMU, this includes support for the software
-         I/O TLB, which allows supporting the broken devices at the expense of
-         wasting some kernel memory (about 2MB by default).
-
-config IA64_SGI_SN2
-       bool "SGI-SN2"
-       select NUMA
-       select ACPI_NUMA
-       help
-         Selecting this option will optimize the kernel for use on sn2 based
-         systems, but the resulting kernel binary will not run on other
-         types of ia64 systems.  If you have an SGI Altix system, it's safe
-         to select this option.  If in doubt, select ia64 generic support
-         instead.
-
-config IA64_SGI_UV
-       bool "SGI-UV"
-       select NUMA
-       select ACPI_NUMA
-       select SWIOTLB
-       help
-         Selecting this option will optimize the kernel for use on UV based
-         systems, but the resulting kernel binary will not run on other
-         types of ia64 systems.  If you have an SGI UV system, it's safe
-         to select this option.  If in doubt, select ia64 generic support
-         instead.
-
-config IA64_HP_SIM
-       bool "Ski-simulator"
-       select SWIOTLB
-       depends on !PM
-
-endchoice
-
-choice
        prompt "Processor type"
        default ITANIUM
 
@@ -252,14 +174,7 @@ config IA64_PAGE_SIZE_64KB
 
 endchoice
 
-if IA64_HP_SIM
-config HZ
-       default 32
-endif
-
-if !IA64_HP_SIM
 source "kernel/Kconfig.hz"
-endif
 
 config IA64_BRL_EMU
        bool
@@ -272,17 +187,26 @@ config IA64_L1_CACHE_SHIFT
        default "7" if MCKINLEY
        default "6" if ITANIUM
 
+config IA64_SGI_UV
+       bool "SGI-UV support"
+       help
+         Selecting this option will add specific support for running on SGI
+         UV based systems.  If you have an SGI UV system or are building a
+         distro kernel, select this option.
+
+config IA64_HP_SBA_IOMMU
+       bool "HP SBA IOMMU support"
+       default y
+       help
+         Say Y here to add support for the SBA IOMMU found on HP zx1 and
+         sx1000 systems.  If you're unsure, answer Y.
+
 config IA64_CYCLONE
        bool "Cyclone (EXA) Time Source support"
        help
          Say Y here to enable support for IBM EXA Cyclone time source.
          If you're unsure, answer N.
 
-config IOSAPIC
-       bool
-       depends on !IA64_HP_SIM
-       default y
-
 config FORCE_MAX_ZONEORDER
        int "MAX_ORDER (11 - 17)"  if !HUGETLB_PAGE
        range 11 17  if !HUGETLB_PAGE
@@ -381,14 +305,12 @@ config ARCH_SPARSEMEM_ENABLE
        select SPARSEMEM_VMEMMAP_ENABLE
 
 config ARCH_DISCONTIGMEM_DEFAULT
-       def_bool y if (IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB)
+       def_bool y
        depends on ARCH_DISCONTIGMEM_ENABLE
 
 config NUMA
        bool "NUMA support"
-       depends on !IA64_HP_SIM && !FLATMEM
-       default y if IA64_SGI_SN2
-       select ACPI_NUMA if ACPI
+       depends on !FLATMEM
        help
          Say Y to compile the kernel to support NUMA (Non-Uniform Memory
          Access).  This option is for configuring high-end multiprocessor
@@ -409,7 +331,7 @@ config NODES_SHIFT
 config VIRTUAL_MEM_MAP
        bool "Virtual mem map"
        depends on !SPARSEMEM
-       default y if !IA64_HP_SIM
+       default y
        help
          Say Y to compile the kernel with support for a virtual mem map.
          This code also only takes effect if a memory hole of greater than
@@ -472,9 +394,6 @@ config IA64_MC_ERR_INJECT
 
          If you're unsure, do not select this option.
 
-config SGI_SN
-       def_bool y if (IA64_SGI_SN2 || IA64_GENERIC)
-
 config IA64_ESI
        bool "ESI (Extensible SAL Interface) support"
        help
@@ -493,11 +412,9 @@ config IA64_HP_AML_NFW
          the "force" module parameter, e.g., with the "aml_nfw.force"
          kernel command line option.
 
-source "drivers/sn/Kconfig"
-
 config KEXEC
        bool "kexec system call"
-       depends on !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
+       depends on !SMP || HOTPLUG_CPU
        select KEXEC_CORE
        help
          kexec is a system call that implements the ability to shutdown your
@@ -515,7 +432,7 @@ config KEXEC
 
 config CRASH_DUMP
          bool "kernel crash dumps"
-         depends on IA64_MCA_RECOVERY && !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
+         depends on IA64_MCA_RECOVERY && (!SMP || HOTPLUG_CPU)
          help
            Generate crash dump after being started by kexec.
 
@@ -537,8 +454,6 @@ endif
 
 endmenu
 
-source "arch/ia64/hp/sim/Kconfig"
-
 config MSPEC
        tristate "Memory special operations driver"
        depends on IA64
index 1371efc..40ca23b 100644 (file)
@@ -14,7 +14,7 @@ config IA64_GRANULE_16MB
 
 config IA64_GRANULE_64MB
        bool "64MB"
-       depends on !(IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_SGI_SN2)
+       depends on BROKEN
 
 endchoice
 
index 171290f..e0bb2b6 100644 (file)
@@ -39,29 +39,23 @@ $(error Sorry, you need a newer version of the assember, one that is built from
                ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz)
 endif
 
+quiet_cmd_gzip = GZIP    $@
+cmd_gzip = cat $(real-prereqs) | gzip -n -f -9 > $@
+
+quiet_cmd_objcopy = OBJCOPY $@
+cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
+
 KBUILD_CFLAGS += $(cflags-y)
 head-y := arch/ia64/kernel/head.o
 
 libs-y                         += arch/ia64/lib/
 core-y                         += arch/ia64/kernel/ arch/ia64/mm/
-core-$(CONFIG_IA64_DIG)        += arch/ia64/dig/
-core-$(CONFIG_IA64_DIG_VTD)    += arch/ia64/dig/
-core-$(CONFIG_IA64_GENERIC)    += arch/ia64/dig/
-core-$(CONFIG_IA64_HP_ZX1)     += arch/ia64/dig/
-core-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/dig/
-core-$(CONFIG_IA64_SGI_SN2)    += arch/ia64/sn/
 core-$(CONFIG_IA64_SGI_UV)     += arch/ia64/uv/
 
-drivers-$(CONFIG_PCI)          += arch/ia64/pci/
-drivers-$(CONFIG_IA64_HP_SIM)  += arch/ia64/hp/sim/
-drivers-$(CONFIG_IA64_HP_ZX1)  += arch/ia64/hp/common/ arch/ia64/hp/zx1/
-drivers-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += arch/ia64/hp/common/ arch/ia64/hp/zx1/
-drivers-$(CONFIG_IA64_GENERIC) += arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/ arch/ia64/sn/ arch/ia64/uv/
+drivers-y                      += arch/ia64/pci/ arch/ia64/hp/common/
 drivers-$(CONFIG_OPROFILE)     += arch/ia64/oprofile/
 
-boot := arch/ia64/hp/sim/boot
-
-PHONY += boot compressed check
+PHONY += compressed check
 
 all: compressed unwcheck
 
@@ -69,22 +63,21 @@ compressed: vmlinux.gz
 
 vmlinuz: vmlinux.gz
 
-vmlinux.gz: vmlinux
-       $(Q)$(MAKE) $(build)=$(boot) $@
+vmlinux.gz: vmlinux.bin FORCE
+       $(call if_changed,gzip)
+
+vmlinux.bin: vmlinux FORCE
+       $(call if_changed,objcopy)
 
 unwcheck: vmlinux
        -$(Q)READELF=$(READELF) $(PYTHON) $(srctree)/arch/ia64/scripts/unwcheck.py $<
 
 archclean:
-       $(Q)$(MAKE) $(clean)=$(boot)
 
 archheaders:
        $(Q)$(MAKE) $(build)=arch/ia64/kernel/syscalls all
 
-CLEAN_FILES += vmlinux.gz bootloader
-
-boot:  lib/lib.a vmlinux
-       $(Q)$(MAKE) $(build)=$(boot) $@
+CLEAN_FILES += vmlinux.gz
 
 install: vmlinux.gz
        sh $(srctree)/arch/ia64/install.sh $(KERNELRELEASE) $< System.map "$(INSTALL_PATH)"
@@ -92,7 +85,6 @@ install: vmlinux.gz
 define archhelp
   echo '* compressed   - Build compressed kernel image'
   echo '  install      - Install compressed kernel image'
-  echo '  boot         - Build vmlinux and bootloader for Ski simulator'
   echo '* unwcheck     - Check vmlinux for invalid unwind info'
 endef
 
index b6bda18..b630bd7 100644 (file)
@@ -7,7 +7,6 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_SGI_PARTITION=y
-CONFIG_IA64_DIG=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
 CONFIG_PREEMPT=y
index 81f686d..661d90b 100644 (file)
@@ -44,14 +44,12 @@ CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
-CONFIG_SGI_IOC4=y
 CONFIG_SGI_XP=m
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_GENERIC=y
 CONFIG_BLK_DEV_CMD64X=y
 CONFIG_BLK_DEV_PIIX=y
-CONFIG_BLK_DEV_SGIIOC4=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
 CONFIG_BLK_DEV_SR=m
@@ -90,16 +88,11 @@ CONFIG_IGB=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_GAMEPORT=m
 CONFIG_SERIAL_NONSTANDARD=y
-CONFIG_SGI_SNSC=y
-CONFIG_SGI_TIOCX=y
-CONFIG_SGI_MBCS=m
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=6
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_SGI_L1_CONSOLE=y
-CONFIG_SERIAL_SGI_IOC4=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_EFI_RTC=y
 CONFIG_RAW_DRIVER=m
@@ -107,7 +100,6 @@ CONFIG_HPET=y
 CONFIG_AGP=m
 CONFIG_AGP_I460=m
 CONFIG_AGP_HP_ZX1=m
-CONFIG_AGP_SGI_TIOCA=m
 CONFIG_DRM=m
 CONFIG_DRM_TDFX=m
 CONFIG_DRM_R128=m
index 5b4fcdd..7844e6a 100644 (file)
@@ -19,7 +19,6 @@ CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_IA64_MCA_RECOVERY=y
 CONFIG_PERFMON=y
 CONFIG_IA64_PALINFO=y
-CONFIG_SGI_IOC3=y
 CONFIG_EFI_VARS=y
 CONFIG_BINFMT_MISC=m
 CONFIG_ACPI_BUTTON=m
@@ -37,14 +36,12 @@ CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
-CONFIG_SGI_IOC4=y
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_IDE_GENERIC=y
 CONFIG_BLK_DEV_GENERIC=y
 CONFIG_BLK_DEV_CMD64X=y
 CONFIG_BLK_DEV_PIIX=y
-CONFIG_BLK_DEV_SGIIOC4=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
@@ -79,17 +76,11 @@ CONFIG_E1000=y
 # CONFIG_SERIO_SERPORT is not set
 CONFIG_GAMEPORT=m
 CONFIG_SERIAL_NONSTANDARD=y
-CONFIG_SGI_SNSC=y
-CONFIG_SGI_TIOCX=y
-CONFIG_SGI_MBCS=m
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=6
 CONFIG_SERIAL_8250_EXTENDED=y
 CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_SERIAL_SGI_L1_CONSOLE=y
-CONFIG_SERIAL_SGI_IOC4=y
-CONFIG_SERIAL_SGI_IOC3=y
 # CONFIG_HW_RANDOM is not set
 CONFIG_EFI_RTC=y
 CONFIG_RAW_DRIVER=m
@@ -97,7 +88,6 @@ CONFIG_HPET=y
 CONFIG_AGP=m
 CONFIG_AGP_I460=m
 CONFIG_AGP_HP_ZX1=m
-CONFIG_AGP_SGI_TIOCA=m
 CONFIG_DRM=m
 CONFIG_DRM_TDFX=m
 CONFIG_DRM_R128=m
diff --git a/arch/ia64/configs/sim_defconfig b/arch/ia64/configs/sim_defconfig
deleted file mode 100644 (file)
index f0f69fd..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_IA64_HP_SIM=y
-CONFIG_MCKINLEY=y
-CONFIG_IA64_PAGE_SIZE_64KB=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=64
-CONFIG_PREEMPT=y
-CONFIG_IA64_PALINFO=m
-CONFIG_EFI_VARS=y
-CONFIG_BINFMT_MISC=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IPV6 is not set
-# CONFIG_STANDALONE is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SPI_ATTRS=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_EFI_RTC=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_HP_SIMETH=y
-CONFIG_HP_SIMSERIAL=y
-CONFIG_HP_SIMSERIAL_CONSOLE=y
-CONFIG_HP_SIMSCSI=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_PROC_KCORE=y
-CONFIG_HUGETLBFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
index 192ed15..1d6e2a0 100644 (file)
@@ -12,7 +12,6 @@ CONFIG_MODULE_SRCVERSION_ALL=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_SGI_PARTITION=y
-CONFIG_IA64_DIG=y
 CONFIG_MCKINLEY=y
 CONFIG_IA64_PAGE_SIZE_64KB=y
 CONFIG_IA64_CYCLONE=y
index b504c8e..8c92e09 100644 (file)
@@ -4,7 +4,6 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_KPROBES=y
 CONFIG_MODULES=y
 CONFIG_PARTITION_ADVANCED=y
-CONFIG_IA64_HP_ZX1=y
 CONFIG_MCKINLEY=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=16
diff --git a/arch/ia64/dig/Makefile b/arch/ia64/dig/Makefile
deleted file mode 100644 (file)
index e7f8308..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# ia64/platform/dig/Makefile
-#
-# Copyright (C) 1999 Silicon Graphics, Inc.
-# Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
-#
-
-obj-y := setup.o
-ifeq ($(CONFIG_INTEL_IOMMU), y)
-obj-$(CONFIG_IA64_GENERIC) += machvec.o machvec_vtd.o
-else
-obj-$(CONFIG_IA64_GENERIC) += machvec.o
-endif
-
diff --git a/arch/ia64/dig/machvec.c b/arch/ia64/dig/machvec.c
deleted file mode 100644 (file)
index 0c55bda..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#define MACHVEC_PLATFORM_NAME          dig
-#define MACHVEC_PLATFORM_HEADER                <asm/machvec_dig.h>
-#include <asm/machvec_init.h>
diff --git a/arch/ia64/dig/machvec_vtd.c b/arch/ia64/dig/machvec_vtd.c
deleted file mode 100644 (file)
index 7cd3eb4..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#define MACHVEC_PLATFORM_NAME          dig_vtd
-#define MACHVEC_PLATFORM_HEADER                <asm/machvec_dig_vtd.h>
-#include <asm/machvec_init.h>
diff --git a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c
deleted file mode 100644 (file)
index cc14fdc..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Platform dependent support for DIG64 platforms.
- *
- * Copyright (C) 1999 Intel Corp.
- * Copyright (C) 1999, 2001 Hewlett-Packard Co
- * Copyright (C) 1999, 2001, 2003 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 VA Linux Systems
- * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/kdev_t.h>
-#include <linux/string.h>
-#include <linux/screen_info.h>
-#include <linux/console.h>
-#include <linux/timex.h>
-#include <linux/sched.h>
-#include <linux/root_dev.h>
-
-#include <asm/io.h>
-#include <asm/machvec.h>
-#include <asm/setup.h>
-
-void __init
-dig_setup (char **cmdline_p)
-{
-       unsigned int orig_x, orig_y, num_cols, num_rows, font_height;
-
-       /*
-        * Default to /dev/sda2.  This assumes that the EFI partition
-        * is physical disk 1 partition 1 and the Linux root disk is
-        * physical disk 1 partition 2.
-        */
-       ROOT_DEV = Root_SDA2;           /* default to second partition on first drive */
-
-#ifdef CONFIG_SMP
-       init_smp_config();
-#endif
-
-       memset(&screen_info, 0, sizeof(screen_info));
-
-       if (!ia64_boot_param->console_info.num_rows
-           || !ia64_boot_param->console_info.num_cols)
-       {
-               printk(KERN_WARNING "dig_setup: warning: invalid screen-info, guessing 80x25\n");
-               orig_x = 0;
-               orig_y = 0;
-               num_cols = 80;
-               num_rows = 25;
-               font_height = 16;
-       } else {
-               orig_x = ia64_boot_param->console_info.orig_x;
-               orig_y = ia64_boot_param->console_info.orig_y;
-               num_cols = ia64_boot_param->console_info.num_cols;
-               num_rows = ia64_boot_param->console_info.num_rows;
-               font_height = 400 / num_rows;
-       }
-
-       screen_info.orig_x = orig_x;
-       screen_info.orig_y = orig_y;
-       screen_info.orig_video_cols  = num_cols;
-       screen_info.orig_video_lines = num_rows;
-       screen_info.orig_video_points = font_height;
-       screen_info.orig_video_mode = 3;        /* XXX fake */
-       screen_info.orig_video_isVGA = 1;       /* XXX fake */
-       screen_info.orig_video_ega_bx = 3;      /* XXX fake */
-}
index 6026308..11a56ed 100644 (file)
@@ -6,7 +6,5 @@
 # Copyright (C) Alex Williamson (alex_williamson@hp.com)
 #
 
-obj-y := sba_iommu.o
-obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += hwsw_iommu.o
-obj-$(CONFIG_IA64_GENERIC) += hwsw_iommu.o
+obj-$(CONFIG_IA64_HP_SBA_IOMMU) += sba_iommu.o
 obj-$(CONFIG_IA64_HP_AML_NFW) += aml_nfw.o
diff --git a/arch/ia64/hp/common/hwsw_iommu.c b/arch/ia64/hp/common/hwsw_iommu.c
deleted file mode 100644 (file)
index 8840ed9..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (c) 2004 Hewlett-Packard Development Company, L.P.
- *   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * This is a pseudo I/O MMU which dispatches to the hardware I/O MMU
- * whenever possible.  We assume that the hardware I/O MMU requires
- * full 32-bit addressability, as is the case, e.g., for HP zx1-based
- * systems (there, the I/O MMU window is mapped at 3-4GB).  If a
- * device doesn't provide full 32-bit addressability, we fall back on
- * the sw I/O TLB.  This is good enough to let us support broken
- * hardware such as soundcards which have a DMA engine that can
- * address only 28 bits.
- */
-
-#include <linux/device.h>
-#include <linux/dma-mapping.h>
-#include <linux/swiotlb.h>
-#include <linux/export.h>
-#include <asm/machvec.h>
-
-extern const struct dma_map_ops sba_dma_ops;
-
-/* swiotlb declarations & definitions: */
-extern int swiotlb_late_init_with_default_size (size_t size);
-
-/*
- * Note: we need to make the determination of whether or not to use
- * the sw I/O TLB based purely on the device structure.  Anything else
- * would be unreliable or would be too intrusive.
- */
-static inline int use_swiotlb(struct device *dev)
-{
-       return dev && dev->dma_mask &&
-               !sba_dma_ops.dma_supported(dev, *dev->dma_mask);
-}
-
-const struct dma_map_ops *hwsw_dma_get_ops(struct device *dev)
-{
-       if (use_swiotlb(dev))
-               return NULL;
-       return &sba_dma_ops;
-}
-EXPORT_SYMBOL(hwsw_dma_get_ops);
-
-void __init
-hwsw_init (void)
-{
-       /* default to a smallish 2MB sw I/O TLB */
-       if (swiotlb_late_init_with_default_size (2 * (1<<20)) != 0) {
-#ifdef CONFIG_IA64_GENERIC
-               /* Better to have normal DMA than panic */
-               printk(KERN_WARNING "%s: Failed to initialize software I/O TLB,"
-                      " reverting to hpzx1 platform vector\n", __func__);
-               machvec_init("hpzx1");
-#else
-               panic("Unable to initialize software I/O TLB services");
-#endif
-       }
-}
index 3d24cc4..a7eff5e 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/iommu-helper.h>
 #include <linux/dma-mapping.h>
 #include <linux/prefetch.h>
+#include <linux/swiotlb.h>
 
 #include <asm/delay.h>         /* ia64_get_itc() */
 #include <asm/io.h>
@@ -43,8 +44,6 @@
 
 #include <asm/acpi-ext.h>
 
-extern int swiotlb_late_init_with_default_size (size_t size);
-
 #define PFX "IOC: "
 
 /*
@@ -251,12 +250,8 @@ static SBA_INLINE void sba_free_range(struct ioc *, dma_addr_t, size_t);
 static u64 prefetch_spill_page;
 #endif
 
-#ifdef CONFIG_PCI
-# define GET_IOC(dev)  ((dev_is_pci(dev))                                              \
+#define GET_IOC(dev)   ((dev_is_pci(dev))                                              \
                         ? ((struct ioc *) PCI_CONTROLLER(to_pci_dev(dev))->iommu) : NULL)
-#else
-# define GET_IOC(dev)  NULL
-#endif
 
 /*
 ** DMA_CHUNK_SIZE is used by the SCSI mid-layer to break up
@@ -1741,9 +1736,7 @@ ioc_sac_init(struct ioc *ioc)
        controller->iommu = ioc;
        sac->sysdata = controller;
        sac->dma_mask = 0xFFFFFFFFUL;
-#ifdef CONFIG_PCI
        sac->dev.bus = &pci_bus_type;
-#endif
        ioc->sac_only_dev = sac;
 }
 
@@ -2062,27 +2055,33 @@ static int __init acpi_sba_ioc_init_acpi(void)
 /* This has to run before acpi_scan_init(). */
 arch_initcall(acpi_sba_ioc_init_acpi);
 
+static int sba_dma_supported (struct device *dev, u64 mask)
+{
+       /* make sure it's at least 32bit capable */
+       return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL);
+}
+
+static const struct dma_map_ops sba_dma_ops = {
+       .alloc                  = sba_alloc_coherent,
+       .free                   = sba_free_coherent,
+       .map_page               = sba_map_page,
+       .unmap_page             = sba_unmap_page,
+       .map_sg                 = sba_map_sg_attrs,
+       .unmap_sg               = sba_unmap_sg_attrs,
+       .dma_supported          = sba_dma_supported,
+};
+
 static int __init
 sba_init(void)
 {
-       if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb"))
-               return 0;
-
-#if defined(CONFIG_IA64_GENERIC)
-       /* If we are booting a kdump kernel, the sba_iommu will
-        * cause devices that were not shutdown properly to MCA
-        * as soon as they are turned back on.  Our only option for
-        * a successful kdump kernel boot is to use the swiotlb.
+       /*
+        * If we are booting a kdump kernel, the sba_iommu will cause devices
+        * that were not shutdown properly to MCA as soon as they are turned
+        * back on.  Our only option for a successful kdump kernel boot is to
+        * use swiotlb.
         */
-       if (is_kdump_kernel()) {
-               dma_ops = NULL;
-               if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
-                       panic("Unable to initialize software I/O TLB:"
-                                 " Try machvec=dig boot option");
-               machvec_init("dig");
+       if (is_kdump_kernel())
                return 0;
-       }
-#endif
 
        /*
         * ioc_found should be populated by the acpi_sba_ioc_handler's .attach()
@@ -2091,43 +2090,18 @@ sba_init(void)
        while (ioc_found)
                acpi_sba_ioc_add(ioc_found);
 
-       if (!ioc_list) {
-#ifdef CONFIG_IA64_GENERIC
-               /*
-                * If we didn't find something sba_iommu can claim, we
-                * need to setup the swiotlb and switch to the dig machvec.
-                */
-               dma_ops = NULL;
-               if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
-                       panic("Unable to find SBA IOMMU or initialize "
-                             "software I/O TLB: Try machvec=dig boot option");
-               machvec_init("dig");
-#else
-               panic("Unable to find SBA IOMMU: Try a generic or DIG kernel");
-#endif
+       if (!ioc_list)
                return 0;
-       }
 
-#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_HP_ZX1_SWIOTLB)
-       /*
-        * hpzx1_swiotlb needs to have a fairly small swiotlb bounce
-        * buffer setup to support devices with smaller DMA masks than
-        * sba_iommu can handle.
-        */
-       if (ia64_platform_is("hpzx1_swiotlb")) {
-               extern void hwsw_init(void);
-
-               hwsw_init();
-       }
-#endif
-
-#ifdef CONFIG_PCI
        {
                struct pci_bus *b = NULL;
                while ((b = pci_find_next_bus(b)) != NULL)
                        sba_connect_bus(b);
        }
-#endif
+
+       /* no need for swiotlb with the iommu */
+       swiotlb_exit();
+       dma_ops = &sba_dma_ops;
 
 #ifdef CONFIG_PROC_FS
        ioc_proc_init();
@@ -2144,12 +2118,6 @@ nosbagart(char *str)
        return 1;
 }
 
-static int sba_dma_supported (struct device *dev, u64 mask)
-{
-       /* make sure it's at least 32bit capable */
-       return ((mask & 0xFFFFFFFFUL) == 0xFFFFFFFFUL);
-}
-
 __setup("nosbagart", nosbagart);
 
 static int __init
@@ -2174,18 +2142,3 @@ sba_page_override(char *str)
 }
 
 __setup("sbapagesize=",sba_page_override);
-
-const struct dma_map_ops sba_dma_ops = {
-       .alloc                  = sba_alloc_coherent,
-       .free                   = sba_free_coherent,
-       .map_page               = sba_map_page,
-       .unmap_page             = sba_unmap_page,
-       .map_sg                 = sba_map_sg_attrs,
-       .unmap_sg               = sba_unmap_sg_attrs,
-       .dma_supported          = sba_dma_supported,
-};
-
-void sba_dma_init(void)
-{
-       dma_ops = &sba_dma_ops;
-}
diff --git a/arch/ia64/hp/sim/Kconfig b/arch/ia64/hp/sim/Kconfig
deleted file mode 100644 (file)
index 56fb4f1..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-
-menu "HP Simulator drivers"
-       depends on IA64_HP_SIM || IA64_GENERIC
-
-config HP_SIMETH
-       bool "Simulated Ethernet "
-       depends on NET
-
-config HP_SIMSERIAL
-       bool "Simulated serial driver support"
-       depends on TTY
-
-config HP_SIMSERIAL_CONSOLE
-       bool "Console for HP simulator"
-       depends on HP_SIMSERIAL
-
-config HP_SIMSCSI
-       bool "Simulated SCSI disk"
-       depends on SCSI=y
-
-endmenu
-
diff --git a/arch/ia64/hp/sim/Makefile b/arch/ia64/hp/sim/Makefile
deleted file mode 100644 (file)
index 0224a13..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# ia64/platform/hp/sim/Makefile
-#
-# Copyright (C) 2002 Hewlett-Packard Co.
-#      David Mosberger-Tang <davidm@hpl.hp.com>
-# Copyright (C) 1999 Silicon Graphics, Inc.
-# Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
-#
-
-obj-y := hpsim_irq.o hpsim_setup.o hpsim.o
-obj-$(CONFIG_IA64_GENERIC) += hpsim_machvec.o
-
-obj-$(CONFIG_HP_SIMETH)        += simeth.o
-obj-$(CONFIG_HP_SIMSERIAL) += simserial.o
-obj-$(CONFIG_HP_SIMSERIAL_CONSOLE) += hpsim_console.o
-obj-$(CONFIG_HP_SIMSCSI) += simscsi.o
diff --git a/arch/ia64/hp/sim/boot/Makefile b/arch/ia64/hp/sim/boot/Makefile
deleted file mode 100644 (file)
index df6e996..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# ia64/boot/Makefile
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1998, 2003 by David Mosberger-Tang <davidm@hpl.hp.com>
-#
-
-targets-$(CONFIG_IA64_HP_SIM)  += bootloader
-targets := vmlinux.bin vmlinux.gz $(targets-y)
-
-quiet_cmd_cptotop = LN      $@
-      cmd_cptotop = ln -f $< $@
-
-vmlinux.gz: $(obj)/vmlinux.gz $(addprefix $(obj)/,$(targets-y))
-       $(call cmd,cptotop)
-       @echo '  Kernel: $@ is ready'
-
-boot: bootloader
-
-bootloader: $(obj)/bootloader
-       $(call cmd,cptotop)
-
-$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE
-       $(call if_changed,gzip)
-
-$(obj)/vmlinux.bin: vmlinux FORCE
-       $(call if_changed,objcopy)
-
-
-LDFLAGS_bootloader = -static -T
-
-$(obj)/bootloader: $(src)/bootloader.lds $(obj)/bootloader.o $(obj)/boot_head.o $(obj)/fw-emu.o \
-                   lib/lib.a arch/ia64/lib/lib.a FORCE
-       $(call if_changed,ld)
diff --git a/arch/ia64/hp/sim/boot/boot_head.S b/arch/ia64/hp/sim/boot/boot_head.S
deleted file mode 100644 (file)
index a7d178f..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- *     David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <asm/asmmacro.h>
-#include <asm/pal.h>
-
-       .bss
-       .align 16
-stack_mem:
-       .skip 16834
-
-       .text
-
-/* This needs to be defined because lib/string.c:strlcat() calls it in case of error... */
-GLOBAL_ENTRY(printk)
-       break 0
-END(printk)
-
-GLOBAL_ENTRY(_start)
-       .prologue
-       .save rp, r0
-       .body
-       movl gp = __gp
-       movl sp = stack_mem+16384-16
-       bsw.1
-       br.call.sptk.many rp=start_bootloader
-0:     nop 0             /* dummy nop to make unwinding work */
-END(_start)
-
-/*
- * Set a break point on this function so that symbols are available to set breakpoints in
- * the kernel being debugged.
- */
-GLOBAL_ENTRY(debug_break)
-       br.ret.sptk.many b0
-END(debug_break)
-
-GLOBAL_ENTRY(ssc)
-       .regstk 5,0,0,0
-       mov r15=in4
-       break 0x80001
-       br.ret.sptk.many b0
-END(ssc)
-
-GLOBAL_ENTRY(jmp_to_kernel)
-       .regstk 2,0,0,0
-       mov r28=in0
-       mov b7=in1
-       br.sptk.few b7
-END(jmp_to_kernel)
-
-/*
- * r28 contains the index of the PAL function
- * r29--31 the args
- * Return values in ret0--3 (r8--11)
- */
-GLOBAL_ENTRY(pal_emulator_static)
-       mov r8=-1
-       mov r9=256
-       ;;
-       cmp.gtu p6,p7=r9,r28            /* r28 <= 255? */
-(p6)   br.cond.sptk.few static
-       ;;
-       mov r9=512
-       ;;
-       cmp.gtu p6,p7=r9,r28
-(p6)   br.cond.sptk.few stacked
-       ;;
-static:        cmp.eq p6,p7=PAL_PTCE_INFO,r28
-(p7)   br.cond.sptk.few 1f
-       ;;
-       mov r8=0                        /* status = 0 */
-       movl r9=0x100000000             /* tc.base */
-       movl r10=0x0000000200000003     /* count[0], count[1] */
-       movl r11=0x1000000000002000     /* stride[0], stride[1] */
-       br.cond.sptk.few rp
-1:     cmp.eq p6,p7=PAL_FREQ_RATIOS,r28
-(p7)   br.cond.sptk.few 1f
-       mov r8=0                        /* status = 0 */
-       movl r9 =0x100000064            /* proc_ratio (1/100) */
-       movl r10=0x100000100            /* bus_ratio<<32 (1/256) */
-       movl r11=0x100000064            /* itc_ratio<<32 (1/100) */
-       ;;
-1:     cmp.eq p6,p7=PAL_RSE_INFO,r28
-(p7)   br.cond.sptk.few 1f
-       mov r8=0                        /* status = 0 */
-       mov r9=96                       /* num phys stacked */
-       mov r10=0                       /* hints */
-       mov r11=0
-       br.cond.sptk.few rp
-1:     cmp.eq p6,p7=PAL_CACHE_FLUSH,r28                /* PAL_CACHE_FLUSH */
-(p7)   br.cond.sptk.few 1f
-       mov r9=ar.lc
-       movl r8=524288                  /* flush 512k million cache lines (16MB) */
-       ;;
-       mov ar.lc=r8
-       movl r8=0xe000000000000000
-       ;;
-.loop: fc r8
-       add r8=32,r8
-       br.cloop.sptk.few .loop
-       sync.i
-       ;;
-       srlz.i
-       ;;
-       mov ar.lc=r9
-       mov r8=r0
-       ;;
-1:     cmp.eq p6,p7=PAL_PERF_MON_INFO,r28
-(p7)   br.cond.sptk.few 1f
-       mov r8=0                        /* status = 0 */
-       movl r9 =0x08122f04             /* generic=4 width=47 retired=8 cycles=18 */
-       mov r10=0                       /* reserved */
-       mov r11=0                       /* reserved */
-       mov r16=0xffff                  /* implemented PMC */
-       mov r17=0x3ffff                 /* implemented PMD */
-       add r18=8,r29                   /* second index */
-       ;;
-       st8 [r29]=r16,16                /* store implemented PMC */
-       st8 [r18]=r0,16                 /* clear remaining bits  */
-       ;;
-       st8 [r29]=r0,16                 /* clear remaining bits  */
-       st8 [r18]=r0,16                 /* clear remaining bits  */
-       ;;
-       st8 [r29]=r17,16                /* store implemented PMD */
-       st8 [r18]=r0,16                 /* clear remaining bits  */
-       mov r16=0xf0                    /* cycles count capable PMC */
-       ;;
-       st8 [r29]=r0,16                 /* clear remaining bits  */
-       st8 [r18]=r0,16                 /* clear remaining bits  */
-       mov r17=0xf0                    /* retired bundles capable PMC */
-       ;;
-       st8 [r29]=r16,16                /* store cycles capable */
-       st8 [r18]=r0,16                 /* clear remaining bits  */
-       ;;
-       st8 [r29]=r0,16                 /* clear remaining bits  */
-       st8 [r18]=r0,16                 /* clear remaining bits  */
-       ;;
-       st8 [r29]=r17,16                /* store retired bundle capable */
-       st8 [r18]=r0,16                 /* clear remaining bits  */
-       ;;
-       st8 [r29]=r0,16                 /* clear remaining bits  */
-       st8 [r18]=r0,16                 /* clear remaining bits  */
-       ;;
-1:     cmp.eq p6,p7=PAL_VM_SUMMARY,r28
-(p7)   br.cond.sptk.few 1f
-       mov     r8=0                    /* status = 0  */
-       movl    r9=0x2044040020F1865    /* num_tc_levels=2, num_unique_tcs=4 */
-                                       /* max_itr_entry=64, max_dtr_entry=64 */
-                                       /* hash_tag_id=2, max_pkr=15 */
-                                       /* key_size=24, phys_add_size=50, vw=1 */
-       movl    r10=0x183C              /* rid_size=24, impl_va_msb=60 */
-       ;;
-1:     cmp.eq p6,p7=PAL_MEM_ATTRIB,r28
-(p7)   br.cond.sptk.few 1f
-       mov     r8=0                    /* status = 0 */
-       mov     r9=0x80|0x01            /* NatPage|WB */
-       ;;
-1:     br.cond.sptk.few rp
-stacked:
-       br.ret.sptk.few rp
-END(pal_emulator_static)
diff --git a/arch/ia64/hp/sim/boot/bootloader.c b/arch/ia64/hp/sim/boot/bootloader.c
deleted file mode 100644 (file)
index 6d80460..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * arch/ia64/hp/sim/boot/bootloader.c
- *
- * Loads an ELF kernel.
- *
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- *     David Mosberger-Tang <davidm@hpl.hp.com>
- *     Stephane Eranian <eranian@hpl.hp.com>
- *
- * 01/07/99 S.Eranian modified to pass command line arguments to kernel
- */
-struct task_struct;    /* forward declaration for elf.h */
-
-#include <linux/elf.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <asm/elf.h>
-#include <asm/intrinsics.h>
-#include <asm/pal.h>
-#include <asm/pgtable.h>
-#include <asm/sal.h>
-
-#include "ssc.h"
-
-struct disk_req {
-       unsigned long addr;
-       unsigned len;
-};
-
-struct disk_stat {
-       int fd;
-       unsigned count;
-};
-
-extern void jmp_to_kernel (unsigned long bp, unsigned long e_entry);
-extern struct ia64_boot_param *sys_fw_init (const char *args, int arglen);
-extern void debug_break (void);
-
-static void
-cons_write (const char *buf)
-{
-       unsigned long ch;
-
-       while ((ch = *buf++) != '\0') {
-               ssc(ch, 0, 0, 0, SSC_PUTCHAR);
-               if (ch == '\n')
-                 ssc('\r', 0, 0, 0, SSC_PUTCHAR);
-       }
-}
-
-#define MAX_ARGS 32
-
-void
-start_bootloader (void)
-{
-       static char mem[4096];
-       static char buffer[1024];
-       unsigned long off;
-       int fd, i;
-       struct disk_req req;
-       struct disk_stat stat;
-       struct elfhdr *elf;
-       struct elf_phdr *elf_phdr;      /* program header */
-       unsigned long e_entry, e_phoff, e_phnum;
-       register struct ia64_boot_param *bp;
-       char *kpath, *args;
-       long arglen = 0;
-
-       ssc(0, 0, 0, 0, SSC_CONSOLE_INIT);
-
-       /*
-        * S.Eranian: extract the commandline argument from the simulator
-        *
-        * The expected format is as follows:
-         *
-        *      kernelname args...
-        *
-        * Both are optional but you can't have the second one without the first.
-        */
-       arglen = ssc((long) buffer, 0, 0, 0, SSC_GET_ARGS);
-
-       kpath = "vmlinux";
-       args = buffer;
-       if (arglen > 0) {
-               kpath = buffer;
-               while (*args != ' ' && *args != '\0')
-                       ++args, --arglen;
-               if (*args == ' ')
-                       *args++ = '\0', --arglen;
-       }
-
-       if (arglen <= 0) {
-               args = "";
-               arglen = 1;
-       }
-
-       fd = ssc((long) kpath, 1, 0, 0, SSC_OPEN);
-
-       if (fd < 0) {
-               cons_write(kpath);
-               cons_write(": file not found, reboot now\n");
-               for(;;);
-       }
-       stat.fd = fd;
-       off = 0;
-
-       req.len = sizeof(mem);
-       req.addr = (long) mem;
-       ssc(fd, 1, (long) &req, off, SSC_READ);
-       ssc((long) &stat, 0, 0, 0, SSC_WAIT_COMPLETION);
-
-       elf = (struct elfhdr *) mem;
-       if (elf->e_ident[0] == 0x7f && strncmp(elf->e_ident + 1, "ELF", 3) != 0) {
-               cons_write("not an ELF file\n");
-               return;
-       }
-       if (elf->e_type != ET_EXEC) {
-               cons_write("not an ELF executable\n");
-               return;
-       }
-       if (!elf_check_arch(elf)) {
-               cons_write("kernel not for this processor\n");
-               return;
-       }
-
-       e_entry = elf->e_entry;
-       e_phnum = elf->e_phnum;
-       e_phoff = elf->e_phoff;
-
-       cons_write("loading ");
-       cons_write(kpath);
-       cons_write("...\n");
-
-       for (i = 0; i < e_phnum; ++i) {
-               req.len = sizeof(*elf_phdr);
-               req.addr = (long) mem;
-               ssc(fd, 1, (long) &req, e_phoff, SSC_READ);
-               ssc((long) &stat, 0, 0, 0, SSC_WAIT_COMPLETION);
-               if (stat.count != sizeof(*elf_phdr)) {
-                       cons_write("failed to read phdr\n");
-                       return;
-               }
-               e_phoff += sizeof(*elf_phdr);
-
-               elf_phdr = (struct elf_phdr *) mem;
-
-               if (elf_phdr->p_type != PT_LOAD)
-                       continue;
-
-               req.len = elf_phdr->p_filesz;
-               req.addr = __pa(elf_phdr->p_paddr);
-               ssc(fd, 1, (long) &req, elf_phdr->p_offset, SSC_READ);
-               ssc((long) &stat, 0, 0, 0, SSC_WAIT_COMPLETION);
-               memset((char *)__pa(elf_phdr->p_paddr) + elf_phdr->p_filesz, 0,
-                      elf_phdr->p_memsz - elf_phdr->p_filesz);
-       }
-       ssc(fd, 0, 0, 0, SSC_CLOSE);
-
-       cons_write("starting kernel...\n");
-
-       /* fake an I/O base address: */
-       ia64_setreg(_IA64_REG_AR_KR0, 0xffffc000000UL);
-
-       bp = sys_fw_init(args, arglen);
-
-       ssc(0, (long) kpath, 0, 0, SSC_LOAD_SYMBOLS);
-
-       debug_break();
-       jmp_to_kernel((unsigned long) bp, e_entry);
-
-       cons_write("kernel returned!\n");
-       ssc(-1, 0, 0, 0, SSC_EXIT);
-}
diff --git a/arch/ia64/hp/sim/boot/bootloader.lds b/arch/ia64/hp/sim/boot/bootloader.lds
deleted file mode 100644 (file)
index f3f284d..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-OUTPUT_FORMAT("elf64-ia64-little")
-OUTPUT_ARCH(ia64)
-ENTRY(_start)
-SECTIONS
-{
-  /* Read-only sections, merged into text segment: */
-  . = 0x100000;
-
-  _text = .;
-  .text : { *(__ivt_section) *(.text) }
-  _etext = .;
-
-  /* Global data */
-  _data = .;
-  .rodata : { *(.rodata) *(.rodata.*) }
-  .data    : { *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
-  __gp = ALIGN (8) + 0x200000;
-  .got           : { *(.got.plt) *(.got) }
-  /* We want the small data sections together, so single-instruction offsets
-     can access them all, and initialized data all before uninitialized, so
-     we can shorten the on-disk segment size.  */
-  .sdata     : { *(.sdata) }
-  _edata  =  .;
-
-  __bss_start = .;
-  .sbss      : { *(.sbss) *(.scommon) }
-  .bss       : { *(.bss) *(COMMON) }
-  . = ALIGN(64 / 8);
-  __bss_stop = .;
-  _end = . ;
-
-  /* Stabs debugging sections.  */
-  .stab 0 : { *(.stab) }
-  .stabstr 0 : { *(.stabstr) }
-  .stab.excl 0 : { *(.stab.excl) }
-  .stab.exclstr 0 : { *(.stab.exclstr) }
-  .stab.index 0 : { *(.stab.index) }
-  .stab.indexstr 0 : { *(.stab.indexstr) }
-  .comment 0 : { *(.comment) }
-  /* DWARF debug sections.
-     Symbols in the DWARF debugging sections are relative to the beginning
-     of the section so we begin them at 0.  */
-  /* DWARF 1 */
-  .debug          0 : { *(.debug) }
-  .line           0 : { *(.line) }
-  /* GNU DWARF 1 extensions */
-  .debug_srcinfo  0 : { *(.debug_srcinfo) }
-  .debug_sfnames  0 : { *(.debug_sfnames) }
-  /* DWARF 1.1 and DWARF 2 */
-  .debug_aranges  0 : { *(.debug_aranges) }
-  .debug_pubnames 0 : { *(.debug_pubnames) }
-  /* DWARF 2 */
-  .debug_info     0 : { *(.debug_info) }
-  .debug_abbrev   0 : { *(.debug_abbrev) }
-  .debug_line     0 : { *(.debug_line) }
-  .debug_frame    0 : { *(.debug_frame) }
-  .debug_str      0 : { *(.debug_str) }
-  .debug_loc      0 : { *(.debug_loc) }
-  .debug_macinfo  0 : { *(.debug_macinfo) }
-  /* SGI/MIPS DWARF 2 extensions */
-  .debug_weaknames 0 : { *(.debug_weaknames) }
-  .debug_funcnames 0 : { *(.debug_funcnames) }
-  .debug_typenames 0 : { *(.debug_typenames) }
-  .debug_varnames  0 : { *(.debug_varnames) }
-  /* These must appear regardless of  .  */
-}
diff --git a/arch/ia64/hp/sim/boot/fw-emu.c b/arch/ia64/hp/sim/boot/fw-emu.c
deleted file mode 100644 (file)
index 517fb28..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * PAL & SAL emulation.
- *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- *     David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#ifdef CONFIG_PCI
-# include <linux/pci.h>
-#endif
-
-#include <linux/efi.h>
-#include <asm/io.h>
-#include <asm/pal.h>
-#include <asm/sal.h>
-#include <asm/setup.h>
-
-#include "ssc.h"
-
-#define MB     (1024*1024UL)
-
-#define SIMPLE_MEMMAP  1
-
-#if SIMPLE_MEMMAP
-# define NUM_MEM_DESCS 4
-#else
-# define NUM_MEM_DESCS 16
-#endif
-
-static char fw_mem[(  sizeof(struct ia64_boot_param)
-                   + sizeof(efi_system_table_t)
-                   + sizeof(efi_runtime_services_t)
-                   + 1*sizeof(efi_config_table_t)
-                   + sizeof(struct ia64_sal_systab)
-                   + sizeof(struct ia64_sal_desc_entry_point)
-                   + NUM_MEM_DESCS*(sizeof(efi_memory_desc_t))
-                   + 1024)] __attribute__ ((aligned (8)));
-
-#define SECS_PER_HOUR   (60 * 60)
-#define SECS_PER_DAY    (SECS_PER_HOUR * 24)
-
-/* Compute the `struct tm' representation of *T,
-   offset OFFSET seconds east of UTC,
-   and store year, yday, mon, mday, wday, hour, min, sec into *TP.
-   Return nonzero if successful.  */
-int
-offtime (unsigned long t, efi_time_t *tp)
-{
-       const unsigned short int __mon_yday[2][13] =
-       {
-               /* Normal years.  */
-               { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
-               /* Leap years.  */
-               { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
-       };
-       long int days, rem, y;
-       const unsigned short int *ip;
-
-       days = t / SECS_PER_DAY;
-       rem = t % SECS_PER_DAY;
-       while (rem < 0) {
-               rem += SECS_PER_DAY;
-               --days;
-       }
-       while (rem >= SECS_PER_DAY) {
-               rem -= SECS_PER_DAY;
-               ++days;
-       }
-       tp->hour = rem / SECS_PER_HOUR;
-       rem %= SECS_PER_HOUR;
-       tp->minute = rem / 60;
-       tp->second = rem % 60;
-       /* January 1, 1970 was a Thursday.  */
-       y = 1970;
-
-#      define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
-#      define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
-#      define __isleap(year) \
-         ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
-
-       while (days < 0 || days >= (__isleap (y) ? 366 : 365)) {
-               /* Guess a corrected year, assuming 365 days per year.  */
-               long int yg = y + days / 365 - (days % 365 < 0);
-
-               /* Adjust DAYS and Y to match the guessed year.  */
-               days -= ((yg - y) * 365 + LEAPS_THRU_END_OF (yg - 1)
-                        - LEAPS_THRU_END_OF (y - 1));
-               y = yg;
-       }
-       tp->year = y;
-       ip = __mon_yday[__isleap(y)];
-       for (y = 11; days < (long int) ip[y]; --y)
-               continue;
-       days -= ip[y];
-       tp->month = y + 1;
-       tp->day = days + 1;
-       return 1;
-}
-
-extern void pal_emulator_static (void);
-
-/* Macro to emulate SAL call using legacy IN and OUT calls to CF8, CFC etc.. */
-
-#define BUILD_CMD(addr)                ((0x80000000 | (addr)) & ~3)
-
-#define REG_OFFSET(addr)       (0x00000000000000FF & (addr))
-#define DEVICE_FUNCTION(addr)  (0x000000000000FF00 & (addr))
-#define BUS_NUMBER(addr)       (0x0000000000FF0000 & (addr))
-
-static efi_status_t
-fw_efi_get_time (efi_time_t *tm, efi_time_cap_t *tc)
-{
-#if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_GENERIC)
-       struct {
-               int tv_sec;     /* must be 32bits to work */
-               int tv_usec;
-       } tv32bits;
-
-       ssc((unsigned long) &tv32bits, 0, 0, 0, SSC_GET_TOD);
-
-       memset(tm, 0, sizeof(*tm));
-       offtime(tv32bits.tv_sec, tm);
-
-       if (tc)
-               memset(tc, 0, sizeof(*tc));
-#else
-#      error Not implemented yet...
-#endif
-       return EFI_SUCCESS;
-}
-
-static void
-efi_reset_system (int reset_type, efi_status_t status, unsigned long data_size, efi_char16_t *data)
-{
-#if defined(CONFIG_IA64_HP_SIM) || defined(CONFIG_IA64_GENERIC)
-       ssc(status, 0, 0, 0, SSC_EXIT);
-#else
-#      error Not implemented yet...
-#endif
-}
-
-static efi_status_t
-efi_unimplemented (void)
-{
-       return EFI_UNSUPPORTED;
-}
-
-static struct sal_ret_values
-sal_emulator (long index, unsigned long in1, unsigned long in2,
-             unsigned long in3, unsigned long in4, unsigned long in5,
-             unsigned long in6, unsigned long in7)
-{
-       long r9  = 0;
-       long r10 = 0;
-       long r11 = 0;
-       long status;
-
-       /*
-        * Don't do a "switch" here since that gives us code that
-        * isn't self-relocatable.
-        */
-       status = 0;
-       if (index == SAL_FREQ_BASE) {
-               if (in1 == SAL_FREQ_BASE_PLATFORM)
-                       r9 = 200000000;
-               else if (in1 == SAL_FREQ_BASE_INTERVAL_TIMER) {
-                       /*
-                        * Is this supposed to be the cr.itc frequency
-                        * or something platform specific?  The SAL
-                        * doc ain't exactly clear on this...
-                        */
-                       r9 = 700000000;
-               } else if (in1 == SAL_FREQ_BASE_REALTIME_CLOCK)
-                       r9 = 1;
-               else
-                       status = -1;
-       } else if (index == SAL_SET_VECTORS) {
-               ;
-       } else if (index == SAL_GET_STATE_INFO) {
-               ;
-       } else if (index == SAL_GET_STATE_INFO_SIZE) {
-               ;
-       } else if (index == SAL_CLEAR_STATE_INFO) {
-               ;
-       } else if (index == SAL_MC_RENDEZ) {
-               ;
-       } else if (index == SAL_MC_SET_PARAMS) {
-               ;
-       } else if (index == SAL_CACHE_FLUSH) {
-               ;
-       } else if (index == SAL_CACHE_INIT) {
-               ;
-#ifdef CONFIG_PCI
-       } else if (index == SAL_PCI_CONFIG_READ) {
-               /*
-                * in1 contains the PCI configuration address and in2
-                * the size of the read.  The value that is read is
-                * returned via the general register r9.
-                */
-                outl(BUILD_CMD(in1), 0xCF8);
-                if (in2 == 1)                           /* Reading byte  */
-                        r9 = inb(0xCFC + ((REG_OFFSET(in1) & 3)));
-                else if (in2 == 2)                      /* Reading word  */
-                        r9 = inw(0xCFC + ((REG_OFFSET(in1) & 2)));
-                else                                    /* Reading dword */
-                        r9 = inl(0xCFC);
-                status = PCIBIOS_SUCCESSFUL;
-       } else if (index == SAL_PCI_CONFIG_WRITE) {
-               /*
-                * in1 contains the PCI configuration address, in2 the
-                * size of the write, and in3 the actual value to be
-                * written out.
-                */
-                outl(BUILD_CMD(in1), 0xCF8);
-                if (in2 == 1)                           /* Writing byte  */
-                        outb(in3, 0xCFC + ((REG_OFFSET(in1) & 3)));
-                else if (in2 == 2)                      /* Writing word  */
-                        outw(in3, 0xCFC + ((REG_OFFSET(in1) & 2)));
-                else                                    /* Writing dword */
-                        outl(in3, 0xCFC);
-                status = PCIBIOS_SUCCESSFUL;
-#endif /* CONFIG_PCI */
-       } else if (index == SAL_UPDATE_PAL) {
-               ;
-       } else {
-               status = -1;
-       }
-       return ((struct sal_ret_values) {status, r9, r10, r11});
-}
-
-struct ia64_boot_param *
-sys_fw_init (const char *args, int arglen)
-{
-       efi_system_table_t *efi_systab;
-       efi_runtime_services_t *efi_runtime;
-       efi_config_table_t *efi_tables;
-       struct ia64_sal_systab *sal_systab;
-       efi_memory_desc_t *efi_memmap, *md;
-       unsigned long *pal_desc, *sal_desc;
-       struct ia64_sal_desc_entry_point *sal_ed;
-       struct ia64_boot_param *bp;
-       unsigned char checksum = 0;
-       char *cp, *cmd_line;
-       int i = 0;
-#      define MAKE_MD(typ, attr, start, end)           \
-       do {                                            \
-               md = efi_memmap + i++;                  \
-               md->type = typ;                         \
-               md->pad = 0;                            \
-               md->phys_addr = start;                  \
-               md->virt_addr = 0;                      \
-               md->num_pages = (end - start) >> 12;    \
-               md->attribute = attr;                   \
-       } while (0)
-
-       memset(fw_mem, 0, sizeof(fw_mem));
-
-       pal_desc = (unsigned long *) &pal_emulator_static;
-       sal_desc = (unsigned long *) &sal_emulator;
-
-       cp = fw_mem;
-       efi_systab  = (void *) cp; cp += sizeof(*efi_systab);
-       efi_runtime = (void *) cp; cp += sizeof(*efi_runtime);
-       efi_tables  = (void *) cp; cp += sizeof(*efi_tables);
-       sal_systab  = (void *) cp; cp += sizeof(*sal_systab);
-       sal_ed      = (void *) cp; cp += sizeof(*sal_ed);
-       efi_memmap  = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap);
-       bp          = (void *) cp; cp += sizeof(*bp);
-       cmd_line    = (void *) cp;
-
-       if (args) {
-               if (arglen >= 1024)
-                       arglen = 1023;
-               memcpy(cmd_line, args, arglen);
-       } else {
-               arglen = 0;
-       }
-       cmd_line[arglen] = '\0';
-
-       memset(efi_systab, 0, sizeof(*efi_systab));
-       efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
-       efi_systab->hdr.revision  = ((1 << 16) | 00);
-       efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
-       efi_systab->fw_vendor = __pa("H\0e\0w\0l\0e\0t\0t\0-\0P\0a\0c\0k\0a\0r\0d\0\0");
-       efi_systab->fw_revision = 1;
-       efi_systab->runtime = (void *) __pa(efi_runtime);
-       efi_systab->nr_tables = 1;
-       efi_systab->tables = __pa(efi_tables);
-
-       efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
-       efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
-       efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
-       efi_runtime->get_time = (void *)__pa(&fw_efi_get_time);
-       efi_runtime->set_time = (void *)__pa(&efi_unimplemented);
-       efi_runtime->get_wakeup_time = (void *)__pa(&efi_unimplemented);
-       efi_runtime->set_wakeup_time = (void *)__pa(&efi_unimplemented);
-       efi_runtime->set_virtual_address_map = (void *)__pa(&efi_unimplemented);
-       efi_runtime->get_variable = (void *)__pa(&efi_unimplemented);
-       efi_runtime->get_next_variable = (void *)__pa(&efi_unimplemented);
-       efi_runtime->set_variable = (void *)__pa(&efi_unimplemented);
-       efi_runtime->get_next_high_mono_count = (void *)__pa(&efi_unimplemented);
-       efi_runtime->reset_system = (void *)__pa(&efi_reset_system);
-
-       efi_tables->guid = SAL_SYSTEM_TABLE_GUID;
-       efi_tables->table = __pa(sal_systab);
-
-       /* fill in the SAL system table: */
-       memcpy(sal_systab->signature, "SST_", 4);
-       sal_systab->size = sizeof(*sal_systab);
-       sal_systab->sal_rev_minor = 1;
-       sal_systab->sal_rev_major = 0;
-       sal_systab->entry_count = 1;
-
-#ifdef CONFIG_IA64_GENERIC
-        strcpy(sal_systab->oem_id, "Generic");
-        strcpy(sal_systab->product_id, "IA-64 system");
-#endif
-
-#ifdef CONFIG_IA64_HP_SIM
-       strcpy(sal_systab->oem_id, "Hewlett-Packard");
-       strcpy(sal_systab->product_id, "HP-simulator");
-#endif
-
-       /* fill in an entry point: */
-       sal_ed->type = SAL_DESC_ENTRY_POINT;
-       sal_ed->pal_proc = __pa(pal_desc[0]);
-       sal_ed->sal_proc = __pa(sal_desc[0]);
-       sal_ed->gp = __pa(sal_desc[1]);
-
-       for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp)
-               checksum += *cp;
-
-       sal_systab->checksum = -checksum;
-
-#if SIMPLE_MEMMAP
-       /* simulate free memory at physical address zero */
-       MAKE_MD(EFI_BOOT_SERVICES_DATA,         EFI_MEMORY_WB,    0*MB,    1*MB);
-       MAKE_MD(EFI_PAL_CODE,                   EFI_MEMORY_WB,    1*MB,    2*MB);
-       MAKE_MD(EFI_CONVENTIONAL_MEMORY,        EFI_MEMORY_WB,    2*MB,  130*MB);
-       MAKE_MD(EFI_CONVENTIONAL_MEMORY,        EFI_MEMORY_WB, 4096*MB, 4128*MB);
-#else
-       MAKE_MD( 4,                0x9, 0x0000000000000000, 0x0000000000001000);
-       MAKE_MD( 7,                0x9, 0x0000000000001000, 0x000000000008a000);
-       MAKE_MD( 4,                0x9, 0x000000000008a000, 0x00000000000a0000);
-       MAKE_MD( 5, 0x8000000000000009, 0x00000000000c0000, 0x0000000000100000);
-       MAKE_MD( 7,                0x9, 0x0000000000100000, 0x0000000004400000);
-       MAKE_MD( 2,                0x9, 0x0000000004400000, 0x0000000004be5000);
-       MAKE_MD( 7,                0x9, 0x0000000004be5000, 0x000000007f77e000);
-       MAKE_MD( 6, 0x8000000000000009, 0x000000007f77e000, 0x000000007fb94000);
-       MAKE_MD( 6, 0x8000000000000009, 0x000000007fb94000, 0x000000007fb95000);
-       MAKE_MD( 6, 0x8000000000000009, 0x000000007fb95000, 0x000000007fc00000);
-       MAKE_MD(13, 0x8000000000000009, 0x000000007fc00000, 0x000000007fc3a000);
-       MAKE_MD( 7,                0x9, 0x000000007fc3a000, 0x000000007fea0000);
-       MAKE_MD( 5, 0x8000000000000009, 0x000000007fea0000, 0x000000007fea8000);
-       MAKE_MD( 7,                0x9, 0x000000007fea8000, 0x000000007feab000);
-       MAKE_MD( 5, 0x8000000000000009, 0x000000007feab000, 0x000000007ffff000);
-       MAKE_MD( 7,                0x9, 0x00000000ff400000, 0x0000000104000000);
-#endif
-
-       bp->efi_systab = __pa(&fw_mem);
-       bp->efi_memmap = __pa(efi_memmap);
-       bp->efi_memmap_size = NUM_MEM_DESCS*sizeof(efi_memory_desc_t);
-       bp->efi_memdesc_size = sizeof(efi_memory_desc_t);
-       bp->efi_memdesc_version = 1;
-       bp->command_line = __pa(cmd_line);
-       bp->console_info.num_cols = 80;
-       bp->console_info.num_rows = 25;
-       bp->console_info.orig_x = 0;
-       bp->console_info.orig_y = 24;
-       bp->fpswa = 0;
-
-       return bp;
-}
diff --git a/arch/ia64/hp/sim/boot/ssc.h b/arch/ia64/hp/sim/boot/ssc.h
deleted file mode 100644 (file)
index 88752c7..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 1998-2003 Hewlett-Packard Co
- *     David Mosberger-Tang <davidm@hpl.hp.com>
- *     Stephane Eranian <eranian@hpl.hp.com>
- */
-#ifndef ssc_h
-#define ssc_h
-
-/* Simulator system calls: */
-
-#define SSC_CONSOLE_INIT               20
-#define SSC_GETCHAR                    21
-#define SSC_PUTCHAR                    31
-#define SSC_OPEN                       50
-#define SSC_CLOSE                      51
-#define SSC_READ                       52
-#define SSC_WRITE                      53
-#define SSC_GET_COMPLETION             54
-#define SSC_WAIT_COMPLETION            55
-#define SSC_CONNECT_INTERRUPT          58
-#define SSC_GENERATE_INTERRUPT         59
-#define SSC_SET_PERIODIC_INTERRUPT     60
-#define SSC_GET_RTC                    65
-#define SSC_EXIT                       66
-#define SSC_LOAD_SYMBOLS               69
-#define SSC_GET_TOD                    74
-
-#define SSC_GET_ARGS                   75
-
-/*
- * Simulator system call.
- */
-extern long ssc (long arg0, long arg1, long arg2, long arg3, int nr);
-
-#endif /* ssc_h */
diff --git a/arch/ia64/hp/sim/hpsim.S b/arch/ia64/hp/sim/hpsim.S
deleted file mode 100644 (file)
index 44b4d53..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/asmmacro.h>
-
-/*
- * Simulator system call.
- */
-GLOBAL_ENTRY(ia64_ssc)
-       mov r15=r36
-       break 0x80001
-       br.ret.sptk.many rp
-END(ia64_ssc)
diff --git a/arch/ia64/hp/sim/hpsim_console.c b/arch/ia64/hp/sim/hpsim_console.c
deleted file mode 100644 (file)
index bffd9f6..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Platform dependent support for HP simulator.
- *
- * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
- *     David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/tty.h>
-#include <linux/kdev_t.h>
-#include <linux/console.h>
-
-#include <asm/delay.h>
-#include <asm/irq.h>
-#include <asm/pal.h>
-#include <asm/machvec.h>
-#include <asm/pgtable.h>
-#include <asm/sal.h>
-#include <asm/hpsim.h>
-
-#include "hpsim_ssc.h"
-
-static int simcons_init (struct console *, char *);
-static void simcons_write (struct console *, const char *, unsigned);
-static struct tty_driver *simcons_console_device (struct console *, int *);
-
-static struct console hpsim_cons = {
-       .name =         "simcons",
-       .write =        simcons_write,
-       .device =       simcons_console_device,
-       .setup =        simcons_init,
-       .flags =        CON_PRINTBUFFER,
-       .index =        -1,
-};
-
-static int
-simcons_init (struct console *cons, char *options)
-{
-       return 0;
-}
-
-static void
-simcons_write (struct console *cons, const char *buf, unsigned count)
-{
-       unsigned long ch;
-
-       while (count-- > 0) {
-               ch = *buf++;
-               ia64_ssc(ch, 0, 0, 0, SSC_PUTCHAR);
-               if (ch == '\n')
-                 ia64_ssc('\r', 0, 0, 0, SSC_PUTCHAR);
-       }
-}
-
-static struct tty_driver *simcons_console_device (struct console *c, int *index)
-{
-       *index = c->index;
-       return hp_simserial_driver;
-}
-
-int simcons_register(void)
-{
-       if (!ia64_platform_is("hpsim"))
-               return 1;
-
-       if (hpsim_cons.flags & CON_ENABLED)
-               return 1;
-
-       register_console(&hpsim_cons);
-       return 0;
-}
diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c
deleted file mode 100644 (file)
index 2f1cc59..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Platform dependent support for HP simulator.
- *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
- * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/irq.h>
-
-#include "hpsim_ssc.h"
-
-static unsigned int
-hpsim_irq_startup(struct irq_data *data)
-{
-       return 0;
-}
-
-static void
-hpsim_irq_noop(struct irq_data *data)
-{
-}
-
-static int
-hpsim_set_affinity_noop(struct irq_data *d, const struct cpumask *b, bool f)
-{
-       return 0;
-}
-
-static struct irq_chip irq_type_hp_sim = {
-       .name =                 "hpsim",
-       .irq_startup =          hpsim_irq_startup,
-       .irq_shutdown =         hpsim_irq_noop,
-       .irq_enable =           hpsim_irq_noop,
-       .irq_disable =          hpsim_irq_noop,
-       .irq_ack =              hpsim_irq_noop,
-       .irq_set_affinity =     hpsim_set_affinity_noop,
-};
-
-static void hpsim_irq_set_chip(int irq)
-{
-       struct irq_chip *chip = irq_get_chip(irq);
-
-       if (chip == &no_irq_chip)
-               irq_set_chip(irq, &irq_type_hp_sim);
-}
-
-static void hpsim_connect_irq(int intr, int irq)
-{
-       ia64_ssc(intr, irq, 0, 0, SSC_CONNECT_INTERRUPT);
-}
-
-int hpsim_get_irq(int intr)
-{
-       int irq = assign_irq_vector(AUTO_ASSIGN);
-
-       if (irq >= 0) {
-               hpsim_irq_set_chip(irq);
-               irq_set_handler(irq, handle_simple_irq);
-               hpsim_connect_irq(intr, irq);
-       }
-
-       return irq;
-}
-
-void __init
-hpsim_irq_init (void)
-{
-       int i;
-
-       for_each_active_irq(i)
-               hpsim_irq_set_chip(i);
-}
diff --git a/arch/ia64/hp/sim/hpsim_machvec.c b/arch/ia64/hp/sim/hpsim_machvec.c
deleted file mode 100644 (file)
index c214193..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#define MACHVEC_PLATFORM_NAME          hpsim
-#define MACHVEC_PLATFORM_HEADER                <asm/machvec_hpsim.h>
-#include <asm/machvec_init.h>
diff --git a/arch/ia64/hp/sim/hpsim_setup.c b/arch/ia64/hp/sim/hpsim_setup.c
deleted file mode 100644 (file)
index 41d21d5..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Platform dependent support for HP simulator.
- *
- * Copyright (C) 1998, 1999, 2002 Hewlett-Packard Co
- *     David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
- */
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/kdev_t.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/param.h>
-#include <linux/root_dev.h>
-#include <linux/string.h>
-#include <linux/types.h>
-
-#include <asm/delay.h>
-#include <asm/irq.h>
-#include <asm/pal.h>
-#include <asm/machvec.h>
-#include <asm/pgtable.h>
-#include <asm/sal.h>
-#include <asm/hpsim.h>
-
-#include "hpsim_ssc.h"
-
-void
-ia64_ctl_trace (long on)
-{
-       ia64_ssc(on, 0, 0, 0, SSC_CTL_TRACE);
-}
-
-void __init
-hpsim_setup (char **cmdline_p)
-{
-       ROOT_DEV = Root_SDA1;           /* default to first SCSI drive */
-
-       simcons_register();
-}
diff --git a/arch/ia64/hp/sim/hpsim_ssc.h b/arch/ia64/hp/sim/hpsim_ssc.h
deleted file mode 100644 (file)
index 6fd97a4..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Platform dependent support for HP simulator.
- *
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
- * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
- */
-#ifndef _IA64_PLATFORM_HPSIM_SSC_H
-#define _IA64_PLATFORM_HPSIM_SSC_H
-
-/* Simulator system calls: */
-
-#define SSC_CONSOLE_INIT               20
-#define SSC_GETCHAR                    21
-#define SSC_PUTCHAR                    31
-#define SSC_CONNECT_INTERRUPT          58
-#define SSC_GENERATE_INTERRUPT         59
-#define SSC_SET_PERIODIC_INTERRUPT     60
-#define SSC_GET_RTC                    65
-#define SSC_EXIT                       66
-#define SSC_LOAD_SYMBOLS               69
-#define SSC_GET_TOD                    74
-#define SSC_CTL_TRACE                  76
-
-#define SSC_NETDEV_PROBE               100
-#define SSC_NETDEV_SEND                        101
-#define SSC_NETDEV_RECV                        102
-#define SSC_NETDEV_ATTACH              103
-#define SSC_NETDEV_DETACH              104
-
-/*
- * Simulator system call.
- */
-extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr);
-
-#endif /* _IA64_PLATFORM_HPSIM_SSC_H */
diff --git a/arch/ia64/hp/sim/simeth.c b/arch/ia64/hp/sim/simeth.c
deleted file mode 100644 (file)
index f39ef2b..0000000
+++ /dev/null
@@ -1,510 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Simulated Ethernet Driver
- *
- * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co
- *     Stephane Eranian <eranian@hpl.hp.com>
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <linux/notifier.h>
-#include <linux/bitops.h>
-#include <asm/irq.h>
-#include <asm/hpsim.h>
-
-#include "hpsim_ssc.h"
-
-#define SIMETH_RECV_MAX        10
-
-/*
- * Maximum possible received frame for Ethernet.
- * We preallocate an sk_buff of that size to avoid costly
- * memcpy for temporary buffer into sk_buff. We do basically
- * what's done in other drivers, like eepro with a ring.
- * The difference is, of course, that we don't have real DMA !!!
- */
-#define SIMETH_FRAME_SIZE      ETH_FRAME_LEN
-
-
-#define NETWORK_INTR                   8
-
-struct simeth_local {
-       struct net_device_stats stats;
-       int                     simfd;   /* descriptor in the simulator */
-};
-
-static int simeth_probe1(void);
-static int simeth_open(struct net_device *dev);
-static int simeth_close(struct net_device *dev);
-static int simeth_tx(struct sk_buff *skb, struct net_device *dev);
-static int simeth_rx(struct net_device *dev);
-static struct net_device_stats *simeth_get_stats(struct net_device *dev);
-static irqreturn_t simeth_interrupt(int irq, void *dev_id);
-static void set_multicast_list(struct net_device *dev);
-static int simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr);
-
-static char *simeth_version="0.3";
-
-/*
- * This variable is used to establish a mapping between the Linux/ia64 kernel
- * and the host linux kernel.
- *
- * As of today, we support only one card, even though most of the code
- * is ready for many more. The mapping is then:
- *     linux/ia64 -> linux/x86
- *        eth0    -> eth1
- *
- * In the future, we some string operations, we could easily support up
- * to 10 cards (0-9).
- *
- * The default mapping can be changed on the kernel command line by
- * specifying simeth=ethX (or whatever string you want).
- */
-static char *simeth_device="eth0";      /* default host interface to use */
-
-
-
-static volatile unsigned int card_count; /* how many cards "found" so far */
-static int simeth_debug;               /* set to 1 to get debug information */
-
-/*
- * Used to catch IFF_UP & IFF_DOWN events
- */
-static struct notifier_block simeth_dev_notifier = {
-       simeth_device_event,
-       NULL
-};
-
-
-/*
- * Function used when using a kernel command line option.
- *
- * Format: simeth=interface_name (like eth0)
- */
-static int __init
-simeth_setup(char *str)
-{
-       simeth_device = str;
-       return 1;
-}
-
-__setup("simeth=", simeth_setup);
-
-/*
- * Function used to probe for simeth devices when not installed
- * as a loadable module
- */
-
-int __init
-simeth_probe (void)
-{
-       int r;
-
-       printk(KERN_INFO "simeth: v%s\n", simeth_version);
-
-       r = simeth_probe1();
-
-       if (r == 0) register_netdevice_notifier(&simeth_dev_notifier);
-
-       return r;
-}
-
-static inline int
-netdev_probe(char *name, unsigned char *ether)
-{
-       return ia64_ssc(__pa(name), __pa(ether), 0,0, SSC_NETDEV_PROBE);
-}
-
-
-static inline int
-netdev_attach(int fd, int irq, unsigned int ipaddr)
-{
-       /* this puts the host interface in the right mode (start interrupting) */
-       return ia64_ssc(fd, ipaddr, 0,0, SSC_NETDEV_ATTACH);
-}
-
-
-static inline int
-netdev_detach(int fd)
-{
-       /*
-        * inactivate the host interface (don't interrupt anymore) */
-       return ia64_ssc(fd, 0,0,0, SSC_NETDEV_DETACH);
-}
-
-static inline int
-netdev_send(int fd, unsigned char *buf, unsigned int len)
-{
-       return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_SEND);
-}
-
-static inline int
-netdev_read(int fd, unsigned char *buf, unsigned int len)
-{
-       return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_RECV);
-}
-
-static const struct net_device_ops simeth_netdev_ops = {
-       .ndo_open               = simeth_open,
-       .ndo_stop               = simeth_close,
-       .ndo_start_xmit         = simeth_tx,
-       .ndo_get_stats          = simeth_get_stats,
-       .ndo_set_rx_mode        = set_multicast_list, /* not yet used */
-
-};
-
-/*
- * Function shared with module code, so cannot be in init section
- *
- * So far this function "detects" only one card (test_&_set) but could
- * be extended easily.
- *
- * Return:
- *     - -ENODEV is no device found
- *     - -ENOMEM is no more memory
- *     - 0 otherwise
- */
-static int
-simeth_probe1(void)
-{
-       unsigned char mac_addr[ETH_ALEN];
-       struct simeth_local *local;
-       struct net_device *dev;
-       int fd, err, rc;
-
-       /*
-        * XXX Fix me
-        * let's support just one card for now
-        */
-       if (test_and_set_bit(0, &card_count))
-               return -ENODEV;
-
-       /*
-        * check with the simulator for the device
-        */
-       fd = netdev_probe(simeth_device, mac_addr);
-       if (fd == -1)
-               return -ENODEV;
-
-       dev = alloc_etherdev(sizeof(struct simeth_local));
-       if (!dev)
-               return -ENOMEM;
-
-       memcpy(dev->dev_addr, mac_addr, sizeof(mac_addr));
-
-       local = netdev_priv(dev);
-       local->simfd = fd; /* keep track of underlying file descriptor */
-
-       dev->netdev_ops = &simeth_netdev_ops;
-
-       err = register_netdev(dev);
-       if (err) {
-               free_netdev(dev);
-               return err;
-       }
-
-       /*
-        * attach the interrupt in the simulator, this does enable interrupts
-        * until a netdev_attach() is called
-        */
-       if ((rc = hpsim_get_irq(NETWORK_INTR)) < 0)
-               panic("%s: out of interrupt vectors!\n", __func__);
-       dev->irq = rc;
-
-       printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr=%pm, IRQ %d\n",
-              dev->name, simeth_device, local->simfd, dev->dev_addr, dev->irq);
-
-       return 0;
-}
-
-/*
- * actually binds the device to an interrupt vector
- */
-static int
-simeth_open(struct net_device *dev)
-{
-       if (request_irq(dev->irq, simeth_interrupt, 0, "simeth", dev)) {
-               printk(KERN_WARNING "simeth: unable to get IRQ %d.\n", dev->irq);
-               return -EAGAIN;
-       }
-
-       netif_start_queue(dev);
-
-       return 0;
-}
-
-/* copied from lapbether.c */
-static __inline__ int dev_is_ethdev(struct net_device *dev)
-{
-       return ( dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5));
-}
-
-
-/*
- * Handler for IFF_UP or IFF_DOWN
- *
- * The reason for that is that we don't want to be interrupted when the
- * interface is down. There is no way to unconnect in the simualtor. Instead
- * we use this function to shutdown packet processing in the frame filter
- * in the simulator. Thus no interrupts are generated
- *
- *
- * That's also the place where we pass the IP address of this device to the
- * simulator so that that we can start filtering packets for it
- *
- * There may be a better way of doing this, but I don't know which yet.
- */
-static int
-simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
-{
-       struct net_device *dev = netdev_notifier_info_to_dev(ptr);
-       struct simeth_local *local;
-       struct in_device *in_dev;
-       struct in_ifaddr **ifap = NULL;
-       struct in_ifaddr *ifa = NULL;
-       int r;
-
-
-       if ( ! dev ) {
-               printk(KERN_WARNING "simeth_device_event dev=0\n");
-               return NOTIFY_DONE;
-       }
-
-       if (dev_net(dev) != &init_net)
-               return NOTIFY_DONE;
-
-       if ( event != NETDEV_UP && event != NETDEV_DOWN ) return NOTIFY_DONE;
-
-       /*
-        * Check whether or not it's for an ethernet device
-        *
-        * XXX Fixme: This works only as long as we support one
-        * type of ethernet device.
-        */
-       if ( !dev_is_ethdev(dev) ) return NOTIFY_DONE;
-
-       if ((in_dev=dev->ip_ptr) != NULL) {
-               for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
-                       if (strcmp(dev->name, ifa->ifa_label) == 0) break;
-       }
-       if ( ifa == NULL ) {
-               printk(KERN_ERR "simeth_open: can't find device %s's ifa\n", dev->name);
-               return NOTIFY_DONE;
-       }
-
-       printk(KERN_INFO "simeth_device_event: %s ipaddr=0x%x\n",
-              dev->name, ntohl(ifa->ifa_local));
-
-       /*
-        * XXX Fix me
-        * if the device was up, and we're simply reconfiguring it, not sure
-        * we get DOWN then UP.
-        */
-
-       local = netdev_priv(dev);
-       /* now do it for real */
-       r = event == NETDEV_UP ?
-               netdev_attach(local->simfd, dev->irq, ntohl(ifa->ifa_local)):
-               netdev_detach(local->simfd);
-
-       printk(KERN_INFO "simeth: netdev_attach/detach: event=%s ->%d\n",
-              event == NETDEV_UP ? "attach":"detach", r);
-
-       return NOTIFY_DONE;
-}
-
-static int
-simeth_close(struct net_device *dev)
-{
-       netif_stop_queue(dev);
-
-       free_irq(dev->irq, dev);
-
-       return 0;
-}
-
-/*
- * Only used for debug
- */
-static void
-frame_print(unsigned char *from, unsigned char *frame, int len)
-{
-       int i;
-
-       printk("%s: (%d) %02x", from, len, frame[0] & 0xff);
-       for(i=1; i < 6; i++ ) {
-               printk(":%02x", frame[i] &0xff);
-       }
-       printk(" %2x", frame[6] &0xff);
-       for(i=7; i < 12; i++ ) {
-               printk(":%02x", frame[i] &0xff);
-       }
-       printk(" [%02x%02x]\n", frame[12], frame[13]);
-
-       for(i=14; i < len; i++ ) {
-               printk("%02x ", frame[i] &0xff);
-               if ( (i%10)==0) printk("\n");
-       }
-       printk("\n");
-}
-
-
-/*
- * Function used to transmit of frame, very last one on the path before
- * going to the simulator.
- */
-static int
-simeth_tx(struct sk_buff *skb, struct net_device *dev)
-{
-       struct simeth_local *local = netdev_priv(dev);
-
-#if 0
-       /* ensure we have at least ETH_ZLEN bytes (min frame size) */
-       unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
-       /* Where do the extra padding bytes comes from inthe skbuff ? */
-#else
-       /* the real driver in the host system is going to take care of that
-        * or maybe it's the NIC itself.
-        */
-       unsigned int length = skb->len;
-#endif
-
-       local->stats.tx_bytes += skb->len;
-       local->stats.tx_packets++;
-
-
-       if (simeth_debug > 5) frame_print("simeth_tx", skb->data, length);
-
-       netdev_send(local->simfd, skb->data, length);
-
-       /*
-        * we are synchronous on write, so we don't simulate a
-        * trasnmit complete interrupt, thus we don't need to arm a tx
-        */
-
-       dev_kfree_skb(skb);
-       return NETDEV_TX_OK;
-}
-
-static inline struct sk_buff *
-make_new_skb(struct net_device *dev)
-{
-       struct sk_buff *nskb;
-
-       /*
-        * The +2 is used to make sure that the IP header is nicely
-        * aligned (on 4byte boundary I assume 14+2=16)
-        */
-       nskb = dev_alloc_skb(SIMETH_FRAME_SIZE + 2);
-       if ( nskb == NULL ) {
-               printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name);
-               return NULL;
-       }
-
-       skb_reserve(nskb, 2);   /* Align IP on 16 byte boundaries */
-
-       skb_put(nskb,SIMETH_FRAME_SIZE);
-
-       return nskb;
-}
-
-/*
- * called from interrupt handler to process a received frame
- */
-static int
-simeth_rx(struct net_device *dev)
-{
-       struct simeth_local     *local;
-       struct sk_buff          *skb;
-       int                     len;
-       int                     rcv_count = SIMETH_RECV_MAX;
-
-       local = netdev_priv(dev);
-       /*
-        * the loop concept has been borrowed from other drivers
-        * looks to me like it's a throttling thing to avoid pushing to many
-        * packets at one time into the stack. Making sure we can process them
-        * upstream and make forward progress overall
-        */
-       do {
-               if ( (skb=make_new_skb(dev)) == NULL ) {
-                       printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name);
-                       local->stats.rx_dropped++;
-                       return 0;
-               }
-               /*
-                * Read only one frame at a time
-                */
-               len = netdev_read(local->simfd, skb->data, SIMETH_FRAME_SIZE);
-               if ( len == 0 ) {
-                       if ( simeth_debug > 0 ) printk(KERN_WARNING "%s: count=%d netdev_read=0\n",
-                                                      dev->name, SIMETH_RECV_MAX-rcv_count);
-                       break;
-               }
-#if 0
-               /*
-                * XXX Fix me
-                * Should really do a csum+copy here
-                */
-               skb_copy_to_linear_data(skb, frame, len);
-#endif
-               skb->protocol = eth_type_trans(skb, dev);
-
-               if ( simeth_debug > 6 ) frame_print("simeth_rx", skb->data, len);
-
-               /*
-                * push the packet up & trigger software interrupt
-                */
-               netif_rx(skb);
-
-               local->stats.rx_packets++;
-               local->stats.rx_bytes += len;
-
-       } while ( --rcv_count );
-
-       return len; /* 0 = nothing left to read, otherwise, we can try again */
-}
-
-/*
- * Interrupt handler (Yes, we can do it too !!!)
- */
-static irqreturn_t
-simeth_interrupt(int irq, void *dev_id)
-{
-       struct net_device *dev = dev_id;
-
-       /*
-        * very simple loop because we get interrupts only when receiving
-        */
-       while (simeth_rx(dev));
-       return IRQ_HANDLED;
-}
-
-static struct net_device_stats *
-simeth_get_stats(struct net_device *dev)
-{
-       struct simeth_local *local = netdev_priv(dev);
-
-       return &local->stats;
-}
-
-/* fake multicast ability */
-static void
-set_multicast_list(struct net_device *dev)
-{
-       printk(KERN_WARNING "%s: set_multicast_list called\n", dev->name);
-}
-
-__initcall(simeth_probe);
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
deleted file mode 100644 (file)
index 0a8a742..0000000
+++ /dev/null
@@ -1,373 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Simulated SCSI driver.
- *
- * Copyright (C) 1999, 2001-2003 Hewlett-Packard Co
- *     David Mosberger-Tang <davidm@hpl.hp.com>
- *     Stephane Eranian <eranian@hpl.hp.com>
- *
- * 02/01/15 David Mosberger    Updated for v2.5.1
- * 99/12/18 David Mosberger    Added support for READ10/WRITE10 needed by linux v2.3.33
- */
-#include <linux/blkdev.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <asm/irq.h>
-#include "hpsim_ssc.h"
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_cmnd.h>
-#include <scsi/scsi_device.h>
-#include <scsi/scsi_host.h>
-
-#define DEBUG_SIMSCSI  0
-
-#define SIMSCSI_REQ_QUEUE_LEN  64
-#define DEFAULT_SIMSCSI_ROOT   "/var/ski-disks/sd"
-
-/* Simulator system calls: */
-
-#define SSC_OPEN                       50
-#define SSC_CLOSE                      51
-#define SSC_READ                       52
-#define SSC_WRITE                      53
-#define SSC_GET_COMPLETION             54
-#define SSC_WAIT_COMPLETION            55
-
-#define SSC_WRITE_ACCESS               2
-#define SSC_READ_ACCESS                        1
-
-#if DEBUG_SIMSCSI
-  int simscsi_debug;
-# define DBG   simscsi_debug
-#else
-# define DBG   0
-#endif
-
-static struct Scsi_Host *host;
-
-static void simscsi_interrupt (unsigned long val);
-static DECLARE_TASKLET(simscsi_tasklet, simscsi_interrupt, 0);
-
-struct disk_req {
-       unsigned long addr;
-       unsigned len;
-};
-
-struct disk_stat {
-       int fd;
-       unsigned count;
-};
-
-static int desc[16] = {
-       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-static struct queue_entry {
-       struct scsi_cmnd *sc;
-} queue[SIMSCSI_REQ_QUEUE_LEN];
-
-static int rd, wr;
-static atomic_t num_reqs = ATOMIC_INIT(0);
-
-/* base name for default disks */
-static char *simscsi_root = DEFAULT_SIMSCSI_ROOT;
-
-#define MAX_ROOT_LEN   128
-
-/*
- * used to setup a new base for disk images
- * to use /foo/bar/disk[a-z] as disk images
- * you have to specify simscsi=/foo/bar/disk on the command line
- */
-static int __init
-simscsi_setup (char *s)
-{
-       /* XXX Fix me we may need to strcpy() ? */
-       if (strlen(s) > MAX_ROOT_LEN) {
-               printk(KERN_ERR "simscsi_setup: prefix too long---using default %s\n",
-                      simscsi_root);
-       } else
-               simscsi_root = s;
-       return 1;
-}
-
-__setup("simscsi=", simscsi_setup);
-
-static void
-simscsi_interrupt (unsigned long val)
-{
-       struct scsi_cmnd *sc;
-
-       while ((sc = queue[rd].sc) != NULL) {
-               atomic_dec(&num_reqs);
-               queue[rd].sc = NULL;
-               if (DBG)
-                       printk("simscsi_interrupt: done with %u\n",
-                              sc->request->tag);
-               (*sc->scsi_done)(sc);
-               rd = (rd + 1) % SIMSCSI_REQ_QUEUE_LEN;
-       }
-}
-
-static int
-simscsi_biosparam (struct scsi_device *sdev, struct block_device *n,
-               sector_t capacity, int ip[])
-{
-       ip[0] = 64;             /* heads */
-       ip[1] = 32;             /* sectors */
-       ip[2] = capacity >> 11; /* cylinders */
-       return 0;
-}
-
-static void
-simscsi_sg_readwrite (struct scsi_cmnd *sc, int mode, unsigned long offset)
-{
-       int i;
-       struct scatterlist *sl;
-       struct disk_stat stat;
-       struct disk_req req;
-
-       stat.fd = desc[sc->device->id];
-
-       scsi_for_each_sg(sc, sl, scsi_sg_count(sc), i) {
-               req.addr = __pa(sg_virt(sl));
-               req.len  = sl->length;
-               if (DBG)
-                       printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
-                              mode == SSC_READ ? "read":"write", req.addr, offset,
-                              scsi_sg_count(sc) - i, sl->length);
-               ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
-               ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
-
-               /* should not happen in our case */
-               if (stat.count != req.len) {
-                       sc->result = DID_ERROR << 16;
-                       return;
-               }
-               offset +=  sl->length;
-       }
-       sc->result = GOOD;
-}
-
-/*
- * function handling both READ_6/WRITE_6 (non-scatter/gather mode)
- * commands.
- * Added 02/26/99 S.Eranian
- */
-static void
-simscsi_readwrite6 (struct scsi_cmnd *sc, int mode)
-{
-       unsigned long offset;
-
-       offset = (((sc->cmnd[1] & 0x1f) << 16) | (sc->cmnd[2] << 8) | sc->cmnd[3])*512;
-       simscsi_sg_readwrite(sc, mode, offset);
-}
-
-static size_t
-simscsi_get_disk_size (int fd)
-{
-       struct disk_stat stat;
-       size_t bit, sectors = 0;
-       struct disk_req req;
-       char buf[512];
-
-       /*
-        * This is a bit kludgey: the simulator doesn't provide a
-        * direct way of determining the disk size, so we do a binary
-        * search, assuming a maximum disk size of 128GB.
-        */
-       for (bit = (128UL << 30)/512; bit != 0; bit >>= 1) {
-               req.addr = __pa(&buf);
-               req.len = sizeof(buf);
-               ia64_ssc(fd, 1, __pa(&req), ((sectors | bit) - 1)*512, SSC_READ);
-               stat.fd = fd;
-               ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
-               if (stat.count == sizeof(buf))
-                       sectors |= bit;
-       }
-       return sectors - 1;     /* return last valid sector number */
-}
-
-static void
-simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
-{
-       unsigned long offset;
-
-       offset = (((unsigned long)sc->cmnd[2] << 24) 
-               | ((unsigned long)sc->cmnd[3] << 16)
-               | ((unsigned long)sc->cmnd[4] <<  8) 
-               | ((unsigned long)sc->cmnd[5] <<  0))*512UL;
-       simscsi_sg_readwrite(sc, mode, offset);
-}
-
-static int
-simscsi_queuecommand_lck (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
-{
-       unsigned int target_id = sc->device->id;
-       char fname[MAX_ROOT_LEN+16];
-       size_t disk_size;
-       char *buf;
-       char localbuf[36];
-#if DEBUG_SIMSCSI
-       register long sp asm ("sp");
-
-       if (DBG)
-               printk("simscsi_queuecommand: target=%d,cmnd=%u,sc=%u,sp=%lx,done=%p\n",
-                      target_id, sc->cmnd[0], sc->request->tag, sp, done);
-#endif
-
-       sc->result = DID_BAD_TARGET << 16;
-       sc->scsi_done = done;
-       if (target_id <= 15 && sc->device->lun == 0) {
-               switch (sc->cmnd[0]) {
-                     case INQUIRY:
-                       if (scsi_bufflen(sc) < 35) {
-                               break;
-                       }
-                       sprintf (fname, "%s%c", simscsi_root, 'a' + target_id);
-                       desc[target_id] = ia64_ssc(__pa(fname), SSC_READ_ACCESS|SSC_WRITE_ACCESS,
-                                                  0, 0, SSC_OPEN);
-                       if (desc[target_id] < 0) {
-                               /* disk doesn't exist... */
-                               break;
-                       }
-                       buf = localbuf;
-                       buf[0] = 0;     /* magnetic disk */
-                       buf[1] = 0;     /* not a removable medium */
-                       buf[2] = 2;     /* SCSI-2 compliant device */
-                       buf[3] = 2;     /* SCSI-2 response data format */
-                       buf[4] = 31;    /* additional length (bytes) */
-                       buf[5] = 0;     /* reserved */
-                       buf[6] = 0;     /* reserved */
-                       buf[7] = 0;     /* various flags */
-                       memcpy(buf + 8, "HP      SIMULATED DISK  0.00",  28);
-                       scsi_sg_copy_from_buffer(sc, buf, 36);
-                       sc->result = GOOD;
-                       break;
-
-                     case TEST_UNIT_READY:
-                       sc->result = GOOD;
-                       break;
-
-                     case READ_6:
-                       if (desc[target_id] < 0 )
-                               break;
-                       simscsi_readwrite6(sc, SSC_READ);
-                       break;
-
-                     case READ_10:
-                       if (desc[target_id] < 0 )
-                               break;
-                       simscsi_readwrite10(sc, SSC_READ);
-                       break;
-
-                     case WRITE_6:
-                       if (desc[target_id] < 0)
-                               break;
-                       simscsi_readwrite6(sc, SSC_WRITE);
-                       break;
-
-                     case WRITE_10:
-                       if (desc[target_id] < 0)
-                               break;
-                       simscsi_readwrite10(sc, SSC_WRITE);
-                       break;
-
-                     case READ_CAPACITY:
-                       if (desc[target_id] < 0 || scsi_bufflen(sc) < 8) {
-                               break;
-                       }
-                       buf = localbuf;
-                       disk_size = simscsi_get_disk_size(desc[target_id]);
-
-                       buf[0] = (disk_size >> 24) & 0xff;
-                       buf[1] = (disk_size >> 16) & 0xff;
-                       buf[2] = (disk_size >>  8) & 0xff;
-                       buf[3] = (disk_size >>  0) & 0xff;
-                       /* set block size of 512 bytes: */
-                       buf[4] = 0;
-                       buf[5] = 0;
-                       buf[6] = 2;
-                       buf[7] = 0;
-                       scsi_sg_copy_from_buffer(sc, buf, 8);
-                       sc->result = GOOD;
-                       break;
-
-                     case MODE_SENSE:
-                     case MODE_SENSE_10:
-                       /* sd.c uses this to determine whether disk does write-caching. */
-                       scsi_sg_copy_from_buffer(sc, (char *)empty_zero_page,
-                                                PAGE_SIZE);
-                       sc->result = GOOD;
-                       break;
-
-                     case START_STOP:
-                       printk(KERN_ERR "START_STOP\n");
-                       break;
-
-                     default:
-                       panic("simscsi: unknown SCSI command %u\n", sc->cmnd[0]);
-               }
-       }
-       if (sc->result == DID_BAD_TARGET) {
-               sc->result |= DRIVER_SENSE << 24;
-               sc->sense_buffer[0] = 0x70;
-               sc->sense_buffer[2] = 0x00;
-       }
-       if (atomic_read(&num_reqs) >= SIMSCSI_REQ_QUEUE_LEN) {
-               panic("Attempt to queue command while command is pending!!");
-       }
-       atomic_inc(&num_reqs);
-       queue[wr].sc = sc;
-       wr = (wr + 1) % SIMSCSI_REQ_QUEUE_LEN;
-
-       tasklet_schedule(&simscsi_tasklet);
-       return 0;
-}
-
-static DEF_SCSI_QCMD(simscsi_queuecommand)
-
-static int
-simscsi_host_reset (struct scsi_cmnd *sc)
-{
-       printk(KERN_ERR "simscsi_host_reset: not implemented\n");
-       return 0;
-}
-
-static struct scsi_host_template driver_template = {
-       .name                   = "simulated SCSI host adapter",
-       .proc_name              = "simscsi",
-       .queuecommand           = simscsi_queuecommand,
-       .eh_host_reset_handler  = simscsi_host_reset,
-       .bios_param             = simscsi_biosparam,
-       .can_queue              = SIMSCSI_REQ_QUEUE_LEN,
-       .this_id                = -1,
-       .sg_tablesize           = SG_ALL,
-       .max_sectors            = 1024,
-       .cmd_per_lun            = SIMSCSI_REQ_QUEUE_LEN,
-       .dma_boundary           = PAGE_SIZE - 1,
-};
-
-static int __init
-simscsi_init(void)
-{
-       int error;
-
-       host = scsi_host_alloc(&driver_template, 0);
-       if (!host)
-               return -ENOMEM;
-
-       error = scsi_add_host(host, NULL);
-       if (error)
-               goto free_host;
-       scsi_scan_host(host);
-       return 0;
-
- free_host:
-       scsi_host_put(host);
-       return error;
-}
-device_initcall(simscsi_init);
diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
deleted file mode 100644 (file)
index 1a338e5..0000000
+++ /dev/null
@@ -1,521 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Simulated Serial Driver (fake serial)
- *
- * This driver is mostly used for bringup purposes and will go away.
- * It has a strong dependency on the system console. All outputs
- * are rerouted to the same facility as the one used by printk which, in our
- * case means sys_sim.c console (goes via the simulator).
- *
- * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co
- *     Stephane Eranian <eranian@hpl.hp.com>
- *     David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/sched/debug.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/major.h>
-#include <linux/fcntl.h>
-#include <linux/mm.h>
-#include <linux/seq_file.h>
-#include <linux/slab.h>
-#include <linux/capability.h>
-#include <linux/circ_buf.h>
-#include <linux/console.h>
-#include <linux/irq.h>
-#include <linux/module.h>
-#include <linux/serial.h>
-#include <linux/sysrq.h>
-#include <linux/uaccess.h>
-
-#include <asm/hpsim.h>
-
-#include "hpsim_ssc.h"
-
-#undef SIMSERIAL_DEBUG /* define this to get some debug information */
-
-#define KEYBOARD_INTR  3       /* must match with simulator! */
-
-#define NR_PORTS       1       /* only one port for now */
-
-struct serial_state {
-       struct tty_port port;
-       struct circ_buf xmit;
-       int irq;
-       int x_char;
-};
-
-static struct serial_state rs_table[NR_PORTS];
-
-struct tty_driver *hp_simserial_driver;
-
-static struct console *console;
-
-static void receive_chars(struct tty_port *port)
-{
-       unsigned char ch;
-       static unsigned char seen_esc = 0;
-
-       while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) {
-               if (ch == 27 && seen_esc == 0) {
-                       seen_esc = 1;
-                       continue;
-               } else if (seen_esc == 1 && ch == 'O') {
-                       seen_esc = 2;
-                       continue;
-               } else if (seen_esc == 2) {
-                       if (ch == 'P') /* F1 */
-                               show_state();
-#ifdef CONFIG_MAGIC_SYSRQ
-                       if (ch == 'S') { /* F4 */
-                               do {
-                                       ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR);
-                               } while (!ch);
-                               handle_sysrq(ch);
-                       }
-#endif
-                       seen_esc = 0;
-                       continue;
-               }
-               seen_esc = 0;
-
-               if (tty_insert_flip_char(port, ch, TTY_NORMAL) == 0)
-                       break;
-       }
-       tty_flip_buffer_push(port);
-}
-
-/*
- * This is the serial driver's interrupt routine for a single port
- */
-static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
-{
-       struct serial_state *info = dev_id;
-
-       receive_chars(&info->port);
-
-       return IRQ_HANDLED;
-}
-
-/*
- * -------------------------------------------------------------------
- * Here ends the serial interrupt routines.
- * -------------------------------------------------------------------
- */
-
-static int rs_put_char(struct tty_struct *tty, unsigned char ch)
-{
-       struct serial_state *info = tty->driver_data;
-       unsigned long flags;
-
-       if (!info->xmit.buf)
-               return 0;
-
-       local_irq_save(flags);
-       if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) == 0) {
-               local_irq_restore(flags);
-               return 0;
-       }
-       info->xmit.buf[info->xmit.head] = ch;
-       info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
-       local_irq_restore(flags);
-       return 1;
-}
-
-static void transmit_chars(struct tty_struct *tty, struct serial_state *info,
-               int *intr_done)
-{
-       int count;
-       unsigned long flags;
-
-       local_irq_save(flags);
-
-       if (info->x_char) {
-               char c = info->x_char;
-
-               console->write(console, &c, 1);
-
-               info->x_char = 0;
-
-               goto out;
-       }
-
-       if (info->xmit.head == info->xmit.tail || tty->stopped) {
-#ifdef SIMSERIAL_DEBUG
-               printk("transmit_chars: head=%d, tail=%d, stopped=%d\n",
-                      info->xmit.head, info->xmit.tail, tty->stopped);
-#endif
-               goto out;
-       }
-       /*
-        * We removed the loop and try to do it in to chunks. We need
-        * 2 operations maximum because it's a ring buffer.
-        *
-        * First from current to tail if possible.
-        * Then from the beginning of the buffer until necessary
-        */
-
-       count = min(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE),
-                   SERIAL_XMIT_SIZE - info->xmit.tail);
-       console->write(console, info->xmit.buf+info->xmit.tail, count);
-
-       info->xmit.tail = (info->xmit.tail+count) & (SERIAL_XMIT_SIZE-1);
-
-       /*
-        * We have more at the beginning of the buffer
-        */
-       count = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-       if (count) {
-               console->write(console, info->xmit.buf, count);
-               info->xmit.tail += count;
-       }
-out:
-       local_irq_restore(flags);
-}
-
-static void rs_flush_chars(struct tty_struct *tty)
-{
-       struct serial_state *info = tty->driver_data;
-
-       if (info->xmit.head == info->xmit.tail || tty->stopped ||
-                       !info->xmit.buf)
-               return;
-
-       transmit_chars(tty, info, NULL);
-}
-
-static int rs_write(struct tty_struct * tty,
-                   const unsigned char *buf, int count)
-{
-       struct serial_state *info = tty->driver_data;
-       int     c, ret = 0;
-       unsigned long flags;
-
-       if (!info->xmit.buf)
-               return 0;
-
-       local_irq_save(flags);
-       while (1) {
-               c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-               if (count < c)
-                       c = count;
-               if (c <= 0) {
-                       break;
-               }
-               memcpy(info->xmit.buf + info->xmit.head, buf, c);
-               info->xmit.head = ((info->xmit.head + c) &
-                                  (SERIAL_XMIT_SIZE-1));
-               buf += c;
-               count -= c;
-               ret += c;
-       }
-       local_irq_restore(flags);
-       /*
-        * Hey, we transmit directly from here in our case
-        */
-       if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) &&
-                       !tty->stopped)
-               transmit_chars(tty, info, NULL);
-
-       return ret;
-}
-
-static int rs_write_room(struct tty_struct *tty)
-{
-       struct serial_state *info = tty->driver_data;
-
-       return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-}
-
-static int rs_chars_in_buffer(struct tty_struct *tty)
-{
-       struct serial_state *info = tty->driver_data;
-
-       return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
-}
-
-static void rs_flush_buffer(struct tty_struct *tty)
-{
-       struct serial_state *info = tty->driver_data;
-       unsigned long flags;
-
-       local_irq_save(flags);
-       info->xmit.head = info->xmit.tail = 0;
-       local_irq_restore(flags);
-
-       tty_wakeup(tty);
-}
-
-/*
- * This function is used to send a high-priority XON/XOFF character to
- * the device
- */
-static void rs_send_xchar(struct tty_struct *tty, char ch)
-{
-       struct serial_state *info = tty->driver_data;
-
-       info->x_char = ch;
-       if (ch) {
-               /*
-                * I guess we could call console->write() directly but
-                * let's do that for now.
-                */
-               transmit_chars(tty, info, NULL);
-       }
-}
-
-/*
- * ------------------------------------------------------------
- * rs_throttle()
- *
- * This routine is called by the upper-layer tty layer to signal that
- * incoming characters should be throttled.
- * ------------------------------------------------------------
- */
-static void rs_throttle(struct tty_struct * tty)
-{
-       if (I_IXOFF(tty))
-               rs_send_xchar(tty, STOP_CHAR(tty));
-
-       printk(KERN_INFO "simrs_throttle called\n");
-}
-
-static void rs_unthrottle(struct tty_struct * tty)
-{
-       struct serial_state *info = tty->driver_data;
-
-       if (I_IXOFF(tty)) {
-               if (info->x_char)
-                       info->x_char = 0;
-               else
-                       rs_send_xchar(tty, START_CHAR(tty));
-       }
-       printk(KERN_INFO "simrs_unthrottle called\n");
-}
-
-static int rs_setserial(struct tty_struct *tty, struct serial_struct *ss)
-{
-       return 0;
-}
-
-static int rs_getserial(struct tty_struct *tty, struct serial_struct *ss)
-{
-       return 0;
-}
-
-static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
-{
-       if ((cmd != TIOCSERCONFIG) && (cmd != TIOCMIWAIT)) {
-               if (tty_io_error(tty))
-                   return -EIO;
-       }
-
-       switch (cmd) {
-       case TIOCMIWAIT:
-               return 0;
-       case TIOCSERCONFIG:
-       case TIOCSERGETLSR: /* Get line status register */
-               return -EINVAL;
-       }
-       return -ENOIOCTLCMD;
-}
-
-/*
- * This routine will shutdown a serial port; interrupts are disabled, and
- * DTR is dropped if the hangup on close termio flag is on.
- */
-static void shutdown(struct tty_port *port)
-{
-       struct serial_state *info = container_of(port, struct serial_state,
-                       port);
-       unsigned long flags;
-
-       local_irq_save(flags);
-       if (info->irq)
-               free_irq(info->irq, info);
-
-       if (info->xmit.buf) {
-               free_page((unsigned long) info->xmit.buf);
-               info->xmit.buf = NULL;
-       }
-       local_irq_restore(flags);
-}
-
-static void rs_close(struct tty_struct *tty, struct file * filp)
-{
-       struct serial_state *info = tty->driver_data;
-
-       tty_port_close(&info->port, tty, filp);
-}
-
-static void rs_hangup(struct tty_struct *tty)
-{
-       struct serial_state *info = tty->driver_data;
-
-       rs_flush_buffer(tty);
-       tty_port_hangup(&info->port);
-}
-
-static int activate(struct tty_port *port, struct tty_struct *tty)
-{
-       struct serial_state *state = container_of(port, struct serial_state,
-                       port);
-       unsigned long flags, page;
-       int retval = 0;
-
-       page = get_zeroed_page(GFP_KERNEL);
-       if (!page)
-               return -ENOMEM;
-
-       local_irq_save(flags);
-
-       if (state->xmit.buf)
-               free_page(page);
-       else
-               state->xmit.buf = (unsigned char *) page;
-
-       if (state->irq) {
-               retval = request_irq(state->irq, rs_interrupt_single, 0,
-                               "simserial", state);
-               if (retval)
-                       goto errout;
-       }
-
-       state->xmit.head = state->xmit.tail = 0;
-errout:
-       local_irq_restore(flags);
-       return retval;
-}
-
-
-/*
- * This routine is called whenever a serial port is opened.  It
- * enables interrupts for a serial port, linking in its async structure into
- * the IRQ chain.   It also performs the serial-specific
- * initialization for the tty structure.
- */
-static int rs_open(struct tty_struct *tty, struct file * filp)
-{
-       struct serial_state *info = rs_table + tty->index;
-       struct tty_port *port = &info->port;
-
-       tty->driver_data = info;
-       port->low_latency = (port->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
-
-       /*
-        * figure out which console to use (should be one already)
-        */
-       console = console_drivers;
-       while (console) {
-               if ((console->flags & CON_ENABLED) && console->write) break;
-               console = console->next;
-       }
-
-       return tty_port_open(port, tty, filp);
-}
-
-/*
- * /proc fs routines....
- */
-
-static int rs_proc_show(struct seq_file *m, void *v)
-{
-       int i;
-
-       seq_printf(m, "simserinfo:1.0\n");
-       for (i = 0; i < NR_PORTS; i++)
-               seq_printf(m, "%d: uart:16550 port:3F8 irq:%d\n",
-                      i, rs_table[i].irq);
-       return 0;
-}
-
-static const struct tty_operations hp_ops = {
-       .open = rs_open,
-       .close = rs_close,
-       .write = rs_write,
-       .put_char = rs_put_char,
-       .flush_chars = rs_flush_chars,
-       .write_room = rs_write_room,
-       .chars_in_buffer = rs_chars_in_buffer,
-       .flush_buffer = rs_flush_buffer,
-       .ioctl = rs_ioctl,
-       .throttle = rs_throttle,
-       .unthrottle = rs_unthrottle,
-       .send_xchar = rs_send_xchar,
-       .set_serial = rs_setserial,
-       .get_serial = rs_getserial,
-       .hangup = rs_hangup,
-       .proc_show = rs_proc_show,
-};
-
-static const struct tty_port_operations hp_port_ops = {
-       .activate = activate,
-       .shutdown = shutdown,
-};
-
-static int __init simrs_init(void)
-{
-       struct serial_state *state;
-       int retval;
-
-       if (!ia64_platform_is("hpsim"))
-               return -ENODEV;
-
-       hp_simserial_driver = alloc_tty_driver(NR_PORTS);
-       if (!hp_simserial_driver)
-               return -ENOMEM;
-
-       printk(KERN_INFO "SimSerial driver with no serial options enabled\n");
-
-       /* Initialize the tty_driver structure */
-
-       hp_simserial_driver->driver_name = "simserial";
-       hp_simserial_driver->name = "ttyS";
-       hp_simserial_driver->major = TTY_MAJOR;
-       hp_simserial_driver->minor_start = 64;
-       hp_simserial_driver->type = TTY_DRIVER_TYPE_SERIAL;
-       hp_simserial_driver->subtype = SERIAL_TYPE_NORMAL;
-       hp_simserial_driver->init_termios = tty_std_termios;
-       hp_simserial_driver->init_termios.c_cflag =
-               B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-       hp_simserial_driver->flags = TTY_DRIVER_REAL_RAW;
-       tty_set_operations(hp_simserial_driver, &hp_ops);
-
-       state = rs_table;
-       tty_port_init(&state->port);
-       state->port.ops = &hp_port_ops;
-       state->port.close_delay = 0; /* XXX really 0? */
-
-       retval = hpsim_get_irq(KEYBOARD_INTR);
-       if (retval < 0) {
-               printk(KERN_ERR "%s: out of interrupt vectors!\n",
-                               __func__);
-               goto err_free_tty;
-       }
-
-       state->irq = retval;
-
-       /* the port is imaginary */
-       printk(KERN_INFO "ttyS0 at 0x03f8 (irq = %d) is a 16550\n", state->irq);
-
-       tty_port_link_device(&state->port, hp_simserial_driver, 0);
-       retval = tty_register_driver(hp_simserial_driver);
-       if (retval) {
-               printk(KERN_ERR "Couldn't register simserial driver\n");
-               goto err_free_tty;
-       }
-
-       return 0;
-err_free_tty:
-       put_tty_driver(hp_simserial_driver);
-       tty_port_destroy(&state->port);
-       return retval;
-}
-
-#ifndef MODULE
-__initcall(simrs_init);
-#endif
diff --git a/arch/ia64/hp/zx1/Makefile b/arch/ia64/hp/zx1/Makefile
deleted file mode 100644 (file)
index 46b37d8..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# ia64/hp/zx1/Makefile
-#
-# Copyright (C) 2002 Hewlett Packard
-# Copyright (C) Alex Williamson (alex_williamson@hp.com)
-#
-
-obj-$(CONFIG_IA64_GENERIC) += hpzx1_machvec.o hpzx1_swiotlb_machvec.o
diff --git a/arch/ia64/hp/zx1/hpzx1_machvec.c b/arch/ia64/hp/zx1/hpzx1_machvec.c
deleted file mode 100644 (file)
index 32518b0..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#define MACHVEC_PLATFORM_NAME          hpzx1
-#define MACHVEC_PLATFORM_HEADER                <asm/machvec_hpzx1.h>
-#include <asm/machvec_init.h>
diff --git a/arch/ia64/hp/zx1/hpzx1_swiotlb_machvec.c b/arch/ia64/hp/zx1/hpzx1_swiotlb_machvec.c
deleted file mode 100644 (file)
index 4392a96..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#define MACHVEC_PLATFORM_NAME          hpzx1_swiotlb
-#define MACHVEC_PLATFORM_HEADER                <asm/machvec_hpzx1_swiotlb.h>
-#include <asm/machvec_init.h>
index 0ea5690..f886d4d 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/numa.h>
 #include <asm/numa.h>
 
-#ifdef CONFIG_ACPI
+
 extern int acpi_lapic;
 #define acpi_disabled 0        /* ACPI always enabled on IA64 */
 #define acpi_noirq 0   /* ACPI always enabled on IA64 */
@@ -28,34 +28,10 @@ static inline bool acpi_has_cpu_in_madt(void)
 {
        return !!acpi_lapic;
 }
-#endif
+
 #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */
 static inline void disable_acpi(void) { }
 
-#ifdef CONFIG_IA64_GENERIC
-const char *acpi_get_sysname (void);
-#else
-static inline const char *acpi_get_sysname (void)
-{
-# if defined (CONFIG_IA64_HP_SIM)
-       return "hpsim";
-# elif defined (CONFIG_IA64_HP_ZX1)
-       return "hpzx1";
-# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
-       return "hpzx1_swiotlb";
-# elif defined (CONFIG_IA64_SGI_SN2)
-       return "sn2";
-# elif defined (CONFIG_IA64_SGI_UV)
-       return "uv";
-# elif defined (CONFIG_IA64_DIG)
-       return "dig";
-# elif defined(CONFIG_IA64_DIG_VTD)
-       return "dig_vtd";
-# else
-#      error Unknown platform.  Fix acpi.c.
-# endif
-}
-#endif
 int acpi_request_vector (u32 int_type);
 int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
 
index f7ec71e..a5d9d78 100644 (file)
@@ -6,17 +6,11 @@
  * Copyright (C) 2003-2004 Hewlett-Packard Co
  *     David Mosberger-Tang <davidm@hpl.hp.com>
  */
-#include <asm/machvec.h>
-#include <linux/scatterlist.h>
-#include <linux/dma-debug.h>
-
 extern const struct dma_map_ops *dma_ops;
-extern struct ia64_machine_vector ia64_mv;
-extern void set_iommu_machvec(void);
 
 static inline const struct dma_map_ops *get_arch_dma_ops(struct bus_type *bus)
 {
-       return platform_dma_get_ops(NULL);
+       return dma_ops;
 }
 
 #endif /* _ASM_IA64_DMA_MAPPING_H */
index 23604d6..59625e9 100644 (file)
 
 extern unsigned long MAX_DMA_ADDRESS;
 
-#ifdef CONFIG_PCI
-  extern int isa_dma_bridge_buggy;
-#else
-# define isa_dma_bridge_buggy  (0)
-#endif
+extern int isa_dma_bridge_buggy;
 
 #define free_dma(x)
 
diff --git a/arch/ia64/include/asm/hpsim.h b/arch/ia64/include/asm/hpsim.h
deleted file mode 100644 (file)
index 00fbd5c..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASMIA64_HPSIM_H
-#define _ASMIA64_HPSIM_H
-
-#ifndef CONFIG_HP_SIMSERIAL_CONSOLE
-static inline int simcons_register(void) { return 1; }
-#else
-int simcons_register(void);
-#endif
-
-struct tty_driver;
-extern struct tty_driver *hp_simserial_driver;
-
-extern int hpsim_get_irq(int intr);
-void ia64_ctl_trace(long on);
-
-#endif
index 5dd3c64..e6385c7 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/types.h>
 #include <linux/profile.h>
 
-#include <asm/machvec.h>
 #include <asm/ptrace.h>
 #include <asm/smp.h>
 
@@ -56,7 +55,7 @@ typedef u8 ia64_vector;
 extern int ia64_first_device_vector;
 extern int ia64_last_device_vector;
 
-#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined (CONFIG_IA64_DIG))
+#ifdef CONFIG_SMP
 /* Reserve the lower priority vector than device vectors for "move IRQ" IPI */
 #define IA64_IRQ_MOVE_VECTOR           0x30    /* "move IRQ" IPI */
 #define IA64_DEF_FIRST_DEVICE_VECTOR   0x31
@@ -127,7 +126,7 @@ extern void ia64_send_ipi (int cpu, int vector, int delivery_mode, int redirect)
 extern void ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action);
 extern void destroy_and_reserve_irq (unsigned int irq);
 
-#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG))
+#ifdef CONFIG_SMP
 extern int irq_prepare_move(int irq, int cpu);
 extern void irq_complete_move(unsigned int irq);
 #else
@@ -137,26 +136,10 @@ static inline void irq_complete_move(unsigned int irq) {}
 
 static inline void ia64_native_resend_irq(unsigned int vector)
 {
-       platform_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
+       ia64_send_ipi(smp_processor_id(), vector, IA64_IPI_DM_INT, 0);
 }
 
 /*
- * Default implementations for the irq-descriptor API:
- */
-#ifndef CONFIG_IA64_GENERIC
-static inline ia64_vector __ia64_irq_to_vector(int irq)
-{
-       return irq_cfg[irq].vector;
-}
-
-static inline unsigned int
-__ia64_local_vector_to_irq (ia64_vector vec)
-{
-       return __this_cpu_read(vector_irq[vec]);
-}
-#endif
-
-/*
  * Next follows the irq descriptor interface.  On IA-64, each CPU supports 256 interrupt
  * vectors.  On smaller systems, there is a one-to-one correspondence between interrupt
  * vectors and the Linux irq numbers.  However, larger systems may have multiple interrupt
@@ -170,7 +153,7 @@ __ia64_local_vector_to_irq (ia64_vector vec)
 static inline ia64_vector
 irq_to_vector (int irq)
 {
-       return platform_irq_to_vector(irq);
+       return irq_cfg[irq].vector;
 }
 
 /*
@@ -181,7 +164,7 @@ irq_to_vector (int irq)
 static inline unsigned int
 local_vector_to_irq (ia64_vector vec)
 {
-       return platform_local_vector_to_irq(vec);
+       return __this_cpu_read(vector_irq[vec]);
 }
 
 #endif /* _ASM_IA64_HW_IRQ_H */
index a511d62..54e70c2 100644 (file)
@@ -71,7 +71,6 @@ extern unsigned int num_io_spaces;
 #define HAVE_ARCH_PIO_SIZE
 
 #include <asm/intrinsics.h>
-#include <asm/machvec.h>
 #include <asm/page.h>
 #include <asm-generic/iomap.h>
 
@@ -129,25 +128,6 @@ __ia64_mk_io_addr (unsigned long port)
        return (void *) (space->mmio_base | offset);
 }
 
-#define __ia64_inb     ___ia64_inb
-#define __ia64_inw     ___ia64_inw
-#define __ia64_inl     ___ia64_inl
-#define __ia64_outb    ___ia64_outb
-#define __ia64_outw    ___ia64_outw
-#define __ia64_outl    ___ia64_outl
-#define __ia64_readb   ___ia64_readb
-#define __ia64_readw   ___ia64_readw
-#define __ia64_readl   ___ia64_readl
-#define __ia64_readq   ___ia64_readq
-#define __ia64_readb_relaxed   ___ia64_readb
-#define __ia64_readw_relaxed   ___ia64_readw
-#define __ia64_readl_relaxed   ___ia64_readl
-#define __ia64_readq_relaxed   ___ia64_readq
-#define __ia64_writeb  ___ia64_writeb
-#define __ia64_writew  ___ia64_writew
-#define __ia64_writel  ___ia64_writel
-#define __ia64_writeq  ___ia64_writeq
-
 /*
  * For the in/out routines, we need to do "mf.a" _after_ doing the I/O access to ensure
  * that the access has completed before executing other I/O accesses.  Since we're doing
@@ -156,8 +136,8 @@ __ia64_mk_io_addr (unsigned long port)
  * during optimization, which is why we use "volatile" pointers.
  */
 
-static inline unsigned int
-___ia64_inb (unsigned long port)
+#define inb inb
+static inline unsigned int inb(unsigned long port)
 {
        volatile unsigned char *addr = __ia64_mk_io_addr(port);
        unsigned char ret;
@@ -167,8 +147,8 @@ ___ia64_inb (unsigned long port)
        return ret;
 }
 
-static inline unsigned int
-___ia64_inw (unsigned long port)
+#define inw inw
+static inline unsigned int inw(unsigned long port)
 {
        volatile unsigned short *addr = __ia64_mk_io_addr(port);
        unsigned short ret;
@@ -178,8 +158,8 @@ ___ia64_inw (unsigned long port)
        return ret;
 }
 
-static inline unsigned int
-___ia64_inl (unsigned long port)
+#define inl inl
+static inline unsigned int inl(unsigned long port)
 {
        volatile unsigned int *addr = __ia64_mk_io_addr(port);
        unsigned int ret;
@@ -189,8 +169,8 @@ ___ia64_inl (unsigned long port)
        return ret;
 }
 
-static inline void
-___ia64_outb (unsigned char val, unsigned long port)
+#define outb outb
+static inline void outb(unsigned char val, unsigned long port)
 {
        volatile unsigned char *addr = __ia64_mk_io_addr(port);
 
@@ -198,8 +178,8 @@ ___ia64_outb (unsigned char val, unsigned long port)
        __ia64_mf_a();
 }
 
-static inline void
-___ia64_outw (unsigned short val, unsigned long port)
+#define outw outw
+static inline void outw(unsigned short val, unsigned long port)
 {
        volatile unsigned short *addr = __ia64_mk_io_addr(port);
 
@@ -207,8 +187,8 @@ ___ia64_outw (unsigned short val, unsigned long port)
        __ia64_mf_a();
 }
 
-static inline void
-___ia64_outl (unsigned int val, unsigned long port)
+#define outl outl
+static inline void outl(unsigned int val, unsigned long port)
 {
        volatile unsigned int *addr = __ia64_mk_io_addr(port);
 
@@ -216,199 +196,63 @@ ___ia64_outl (unsigned int val, unsigned long port)
        __ia64_mf_a();
 }
 
-static inline void
-__insb (unsigned long port, void *dst, unsigned long count)
+#define insb insb
+static inline void insb(unsigned long port, void *dst, unsigned long count)
 {
        unsigned char *dp = dst;
 
        while (count--)
-               *dp++ = platform_inb(port);
+               *dp++ = inb(port);
 }
 
-static inline void
-__insw (unsigned long port, void *dst, unsigned long count)
+#define insw insw
+static inline void insw(unsigned long port, void *dst, unsigned long count)
 {
        unsigned short *dp = dst;
 
        while (count--)
-               put_unaligned(platform_inw(port), dp++);
+               put_unaligned(inw(port), dp++);
 }
 
-static inline void
-__insl (unsigned long port, void *dst, unsigned long count)
+#define insl insl
+static inline void insl(unsigned long port, void *dst, unsigned long count)
 {
        unsigned int *dp = dst;
 
        while (count--)
-               put_unaligned(platform_inl(port), dp++);
+               put_unaligned(inl(port), dp++);
 }
 
-static inline void
-__outsb (unsigned long port, const void *src, unsigned long count)
+#define outsb outsb
+static inline void outsb(unsigned long port, const void *src,
+               unsigned long count)
 {
        const unsigned char *sp = src;
 
        while (count--)
-               platform_outb(*sp++, port);
+               outb(*sp++, port);
 }
 
-static inline void
-__outsw (unsigned long port, const void *src, unsigned long count)
+#define outsw outsw
+static inline void outsw(unsigned long port, const void *src,
+               unsigned long count)
 {
        const unsigned short *sp = src;
 
        while (count--)
-               platform_outw(get_unaligned(sp++), port);
+               outw(get_unaligned(sp++), port);
 }
 
-static inline void
-__outsl (unsigned long port, const void *src, unsigned long count)
+#define outsl outsl
+static inline void outsl(unsigned long port, const void *src,
+               unsigned long count)
 {
        const unsigned int *sp = src;
 
        while (count--)
-               platform_outl(get_unaligned(sp++), port);
+               outl(get_unaligned(sp++), port);
 }
 
-/*
- * Unfortunately, some platforms are broken and do not follow the IA-64 architecture
- * specification regarding legacy I/O support.  Thus, we have to make these operations
- * platform dependent...
- */
-#define __inb          platform_inb
-#define __inw          platform_inw
-#define __inl          platform_inl
-#define __outb         platform_outb
-#define __outw         platform_outw
-#define __outl         platform_outl
-
-#define inb(p)         __inb(p)
-#define inw(p)         __inw(p)
-#define inl(p)         __inl(p)
-#define insb(p,d,c)    __insb(p,d,c)
-#define insw(p,d,c)    __insw(p,d,c)
-#define insl(p,d,c)    __insl(p,d,c)
-#define outb(v,p)      __outb(v,p)
-#define outw(v,p)      __outw(v,p)
-#define outl(v,p)      __outl(v,p)
-#define outsb(p,s,c)   __outsb(p,s,c)
-#define outsw(p,s,c)   __outsw(p,s,c)
-#define outsl(p,s,c)   __outsl(p,s,c)
-
-/*
- * The address passed to these functions are ioremap()ped already.
- *
- * We need these to be machine vectors since some platforms don't provide
- * DMA coherence via PIO reads (PCI drivers and the spec imply that this is
- * a good idea).  Writes are ok though for all existing ia64 platforms (and
- * hopefully it'll stay that way).
- */
-static inline unsigned char
-___ia64_readb (const volatile void __iomem *addr)
-{
-       return *(volatile unsigned char __force *)addr;
-}
-
-static inline unsigned short
-___ia64_readw (const volatile void __iomem *addr)
-{
-       return *(volatile unsigned short __force *)addr;
-}
-
-static inline unsigned int
-___ia64_readl (const volatile void __iomem *addr)
-{
-       return *(volatile unsigned int __force *) addr;
-}
-
-static inline unsigned long
-___ia64_readq (const volatile void __iomem *addr)
-{
-       return *(volatile unsigned long __force *) addr;
-}
-
-static inline void
-__writeb (unsigned char val, volatile void __iomem *addr)
-{
-       *(volatile unsigned char __force *) addr = val;
-}
-
-static inline void
-__writew (unsigned short val, volatile void __iomem *addr)
-{
-       *(volatile unsigned short __force *) addr = val;
-}
-
-static inline void
-__writel (unsigned int val, volatile void __iomem *addr)
-{
-       *(volatile unsigned int __force *) addr = val;
-}
-
-static inline void
-__writeq (unsigned long val, volatile void __iomem *addr)
-{
-       *(volatile unsigned long __force *) addr = val;
-}
-
-#define __readb                platform_readb
-#define __readw                platform_readw
-#define __readl                platform_readl
-#define __readq                platform_readq
-#define __readb_relaxed        platform_readb_relaxed
-#define __readw_relaxed        platform_readw_relaxed
-#define __readl_relaxed        platform_readl_relaxed
-#define __readq_relaxed        platform_readq_relaxed
-
-#define readb(a)       __readb((a))
-#define readw(a)       __readw((a))
-#define readl(a)       __readl((a))
-#define readq(a)       __readq((a))
-#define readb_relaxed(a)       __readb_relaxed((a))
-#define readw_relaxed(a)       __readw_relaxed((a))
-#define readl_relaxed(a)       __readl_relaxed((a))
-#define readq_relaxed(a)       __readq_relaxed((a))
-#define __raw_readb    readb
-#define __raw_readw    readw
-#define __raw_readl    readl
-#define __raw_readq    readq
-#define __raw_readb_relaxed    readb_relaxed
-#define __raw_readw_relaxed    readw_relaxed
-#define __raw_readl_relaxed    readl_relaxed
-#define __raw_readq_relaxed    readq_relaxed
-#define writeb(v,a)    __writeb((v), (a))
-#define writew(v,a)    __writew((v), (a))
-#define writel(v,a)    __writel((v), (a))
-#define writeq(v,a)    __writeq((v), (a))
-#define writeb_relaxed(v,a)    __writeb((v), (a))
-#define writew_relaxed(v,a)    __writew((v), (a))
-#define writel_relaxed(v,a)    __writel((v), (a))
-#define writeq_relaxed(v,a)    __writeq((v), (a))
-#define __raw_writeb   writeb
-#define __raw_writew   writew
-#define __raw_writel   writel
-#define __raw_writeq   writeq
-
-#ifndef inb_p
-# define inb_p         inb
-#endif
-#ifndef inw_p
-# define inw_p         inw
-#endif
-#ifndef inl_p
-# define inl_p         inl
-#endif
-
-#ifndef outb_p
-# define outb_p                outb
-#endif
-#ifndef outw_p
-# define outw_p                outw
-#endif
-#ifndef outl_p
-# define outl_p                outl
-#endif
-
 # ifdef __KERNEL__
 
 extern void __iomem * ioremap(unsigned long offset, unsigned long size);
index 7429a72..7904f59 100644 (file)
@@ -8,13 +8,10 @@
 extern void no_iommu_init(void);
 #ifdef CONFIG_INTEL_IOMMU
 extern int force_iommu, no_iommu;
-extern int iommu_pass_through;
 extern int iommu_detected;
 #else
-#define iommu_pass_through     (0)
 #define no_iommu               (1)
 #define iommu_detected         (0)
 #endif
-extern void machvec_init(const char *name);
 
 #endif
index f48556c..a91aeb4 100644 (file)
@@ -52,8 +52,6 @@
 
 #ifndef __ASSEMBLY__
 
-#ifdef CONFIG_IOSAPIC
-
 #define NR_IOSAPICS                    256
 
 #define iosapic_pcat_compat_init       ia64_native_iosapic_pcat_compat_init
@@ -103,16 +101,6 @@ extern int __init iosapic_register_platform_intr (u32 int_type,
 #ifdef CONFIG_NUMA
 extern void map_iosapic_to_node (unsigned int, int);
 #endif
-#else
-#define iosapic_system_init(pcat_compat)                       do { } while (0)
-#define iosapic_init(address,gsi_base)                         (-EINVAL)
-#define iosapic_remove(gsi_base)                               (-ENODEV)
-#define iosapic_register_intr(gsi,polarity,trigger)            (gsi)
-#define iosapic_unregister_intr(irq)                           do { } while (0)
-#define iosapic_override_isa_irq(isa_irq,gsi,polarity,trigger) do { } while (0)
-#define iosapic_register_platform_intr(type,gsi,pmi,eid,id, \
-       polarity,trigger)                                       (gsi)
-#endif
 
 # endif /* !__ASSEMBLY__ */
 #endif /* __ASM_IA64_IOSAPIC_H */
index 8b84a55..5acf52e 100644 (file)
@@ -28,9 +28,6 @@ irq_canonicalize (int irq)
 }
 
 extern void set_irq_affinity_info (unsigned int irq, int dest, int redir);
-bool is_affinity_mask_valid(const struct cpumask *cpumask);
-
-#define is_affinity_mask_valid is_affinity_mask_valid
 
 int create_irq(void);
 void destroy_irq(unsigned int irq);
diff --git a/arch/ia64/include/asm/machvec.h b/arch/ia64/include/asm/machvec.h
deleted file mode 100644 (file)
index beae261..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Machine vector for IA-64.
- *
- * Copyright (C) 1999 Silicon Graphics, Inc.
- * Copyright (C) Srinivasa Thirumalachar <sprasad@engr.sgi.com>
- * Copyright (C) Vijay Chander <vijay@engr.sgi.com>
- * Copyright (C) 1999-2001, 2003-2004 Hewlett-Packard Co.
- *     David Mosberger-Tang <davidm@hpl.hp.com>
- */
-#ifndef _ASM_IA64_MACHVEC_H
-#define _ASM_IA64_MACHVEC_H
-
-#include <linux/types.h>
-
-/* forward declarations: */
-struct device;
-struct pt_regs;
-struct scatterlist;
-struct page;
-struct mm_struct;
-struct pci_bus;
-struct task_struct;
-struct pci_dev;
-struct msi_desc;
-
-typedef void ia64_mv_setup_t (char **);
-typedef void ia64_mv_cpu_init_t (void);
-typedef void ia64_mv_irq_init_t (void);
-typedef void ia64_mv_send_ipi_t (int, int, int, int);
-typedef void ia64_mv_timer_interrupt_t (int, void *);
-typedef void ia64_mv_global_tlb_purge_t (struct mm_struct *, unsigned long, unsigned long, unsigned long);
-typedef u8 ia64_mv_irq_to_vector (int);
-typedef unsigned int ia64_mv_local_vector_to_irq (u8);
-typedef char *ia64_mv_pci_get_legacy_mem_t (struct pci_bus *);
-typedef int ia64_mv_pci_legacy_read_t (struct pci_bus *, u16 port, u32 *val,
-                                      u8 size);
-typedef int ia64_mv_pci_legacy_write_t (struct pci_bus *, u16 port, u32 val,
-                                       u8 size);
-typedef void ia64_mv_migrate_t(struct task_struct * task);
-typedef void ia64_mv_pci_fixup_bus_t (struct pci_bus *);
-typedef void ia64_mv_kernel_launch_event_t(void);
-
-/* DMA-mapping interface: */
-typedef void ia64_mv_dma_init (void);
-typedef const struct dma_map_ops *ia64_mv_dma_get_ops(struct device *);
-
-/*
- * WARNING: The legacy I/O space is _architected_.  Platforms are
- * expected to follow this architected model (see Section 10.7 in the
- * IA-64 Architecture Software Developer's Manual).  Unfortunately,
- * some broken machines do not follow that model, which is why we have
- * to make the inX/outX operations part of the machine vector.
- * Platform designers should follow the architected model whenever
- * possible.
- */
-typedef unsigned int ia64_mv_inb_t (unsigned long);
-typedef unsigned int ia64_mv_inw_t (unsigned long);
-typedef unsigned int ia64_mv_inl_t (unsigned long);
-typedef void ia64_mv_outb_t (unsigned char, unsigned long);
-typedef void ia64_mv_outw_t (unsigned short, unsigned long);
-typedef void ia64_mv_outl_t (unsigned int, unsigned long);
-typedef void ia64_mv_mmiowb_t (void);
-typedef unsigned char ia64_mv_readb_t (const volatile void __iomem *);
-typedef unsigned short ia64_mv_readw_t (const volatile void __iomem *);
-typedef unsigned int ia64_mv_readl_t (const volatile void __iomem *);
-typedef unsigned long ia64_mv_readq_t (const volatile void __iomem *);
-typedef unsigned char ia64_mv_readb_relaxed_t (const volatile void __iomem *);
-typedef unsigned short ia64_mv_readw_relaxed_t (const volatile void __iomem *);
-typedef unsigned int ia64_mv_readl_relaxed_t (const volatile void __iomem *);
-typedef unsigned long ia64_mv_readq_relaxed_t (const volatile void __iomem *);
-
-typedef int ia64_mv_setup_msi_irq_t (struct pci_dev *pdev, struct msi_desc *);
-typedef void ia64_mv_teardown_msi_irq_t (unsigned int irq);
-
-static inline void
-machvec_noop (void)
-{
-}
-
-static inline void
-machvec_noop_task (struct task_struct *task)
-{
-}
-
-static inline void
-machvec_noop_bus (struct pci_bus *bus)
-{
-}
-
-extern void machvec_setup (char **);
-extern void machvec_timer_interrupt (int, void *);
-
-# if defined (CONFIG_IA64_HP_SIM)
-#  include <asm/machvec_hpsim.h>
-# elif defined (CONFIG_IA64_DIG)
-#  include <asm/machvec_dig.h>
-# elif defined(CONFIG_IA64_DIG_VTD)
-#  include <asm/machvec_dig_vtd.h>
-# elif defined (CONFIG_IA64_HP_ZX1)
-#  include <asm/machvec_hpzx1.h>
-# elif defined (CONFIG_IA64_HP_ZX1_SWIOTLB)
-#  include <asm/machvec_hpzx1_swiotlb.h>
-# elif defined (CONFIG_IA64_SGI_SN2)
-#  include <asm/machvec_sn2.h>
-# elif defined (CONFIG_IA64_SGI_UV)
-#  include <asm/machvec_uv.h>
-# elif defined (CONFIG_IA64_GENERIC)
-
-# ifdef MACHVEC_PLATFORM_HEADER
-#  include MACHVEC_PLATFORM_HEADER
-# else
-#  define ia64_platform_name   ia64_mv.name
-#  define platform_setup       ia64_mv.setup
-#  define platform_cpu_init    ia64_mv.cpu_init
-#  define platform_irq_init    ia64_mv.irq_init
-#  define platform_send_ipi    ia64_mv.send_ipi
-#  define platform_timer_interrupt     ia64_mv.timer_interrupt
-#  define platform_global_tlb_purge    ia64_mv.global_tlb_purge
-#  define platform_dma_init            ia64_mv.dma_init
-#  define platform_dma_get_ops         ia64_mv.dma_get_ops
-#  define platform_irq_to_vector       ia64_mv.irq_to_vector
-#  define platform_local_vector_to_irq ia64_mv.local_vector_to_irq
-#  define platform_pci_get_legacy_mem  ia64_mv.pci_get_legacy_mem
-#  define platform_pci_legacy_read     ia64_mv.pci_legacy_read
-#  define platform_pci_legacy_write    ia64_mv.pci_legacy_write
-#  define platform_inb         ia64_mv.inb
-#  define platform_inw         ia64_mv.inw
-#  define platform_inl         ia64_mv.inl
-#  define platform_outb                ia64_mv.outb
-#  define platform_outw                ia64_mv.outw
-#  define platform_outl                ia64_mv.outl
-#  define platform_mmiowb      ia64_mv.mmiowb
-#  define platform_readb        ia64_mv.readb
-#  define platform_readw        ia64_mv.readw
-#  define platform_readl        ia64_mv.readl
-#  define platform_readq        ia64_mv.readq
-#  define platform_readb_relaxed        ia64_mv.readb_relaxed
-#  define platform_readw_relaxed        ia64_mv.readw_relaxed
-#  define platform_readl_relaxed        ia64_mv.readl_relaxed
-#  define platform_readq_relaxed        ia64_mv.readq_relaxed
-#  define platform_migrate             ia64_mv.migrate
-#  define platform_setup_msi_irq       ia64_mv.setup_msi_irq
-#  define platform_teardown_msi_irq    ia64_mv.teardown_msi_irq
-#  define platform_pci_fixup_bus       ia64_mv.pci_fixup_bus
-#  define platform_kernel_launch_event ia64_mv.kernel_launch_event
-# endif
-
-/* __attribute__((__aligned__(16))) is required to make size of the
- * structure multiple of 16 bytes.
- * This will fillup the holes created because of section 3.3.1 in
- * Software Conventions guide.
- */
-struct ia64_machine_vector {
-       const char *name;
-       ia64_mv_setup_t *setup;
-       ia64_mv_cpu_init_t *cpu_init;
-       ia64_mv_irq_init_t *irq_init;
-       ia64_mv_send_ipi_t *send_ipi;
-       ia64_mv_timer_interrupt_t *timer_interrupt;
-       ia64_mv_global_tlb_purge_t *global_tlb_purge;
-       ia64_mv_dma_init *dma_init;
-       ia64_mv_dma_get_ops *dma_get_ops;
-       ia64_mv_irq_to_vector *irq_to_vector;
-       ia64_mv_local_vector_to_irq *local_vector_to_irq;
-       ia64_mv_pci_get_legacy_mem_t *pci_get_legacy_mem;
-       ia64_mv_pci_legacy_read_t *pci_legacy_read;
-       ia64_mv_pci_legacy_write_t *pci_legacy_write;
-       ia64_mv_inb_t *inb;
-       ia64_mv_inw_t *inw;
-       ia64_mv_inl_t *inl;
-       ia64_mv_outb_t *outb;
-       ia64_mv_outw_t *outw;
-       ia64_mv_outl_t *outl;
-       ia64_mv_mmiowb_t *mmiowb;
-       ia64_mv_readb_t *readb;
-       ia64_mv_readw_t *readw;
-       ia64_mv_readl_t *readl;
-       ia64_mv_readq_t *readq;
-       ia64_mv_readb_relaxed_t *readb_relaxed;
-       ia64_mv_readw_relaxed_t *readw_relaxed;
-       ia64_mv_readl_relaxed_t *readl_relaxed;
-       ia64_mv_readq_relaxed_t *readq_relaxed;
-       ia64_mv_migrate_t *migrate;
-       ia64_mv_setup_msi_irq_t *setup_msi_irq;
-       ia64_mv_teardown_msi_irq_t *teardown_msi_irq;
-       ia64_mv_pci_fixup_bus_t *pci_fixup_bus;
-       ia64_mv_kernel_launch_event_t *kernel_launch_event;
-} __attribute__((__aligned__(16))); /* align attrib? see above comment */
-
-#define MACHVEC_INIT(name)                     \
-{                                              \
-       #name,                                  \
-       platform_setup,                         \
-       platform_cpu_init,                      \
-       platform_irq_init,                      \
-       platform_send_ipi,                      \
-       platform_timer_interrupt,               \
-       platform_global_tlb_purge,              \
-       platform_dma_init,                      \
-       platform_dma_get_ops,                   \
-       platform_irq_to_vector,                 \
-       platform_local_vector_to_irq,           \
-       platform_pci_get_legacy_mem,            \
-       platform_pci_legacy_read,               \
-       platform_pci_legacy_write,              \
-       platform_inb,                           \
-       platform_inw,                           \
-       platform_inl,                           \
-       platform_outb,                          \
-       platform_outw,                          \
-       platform_outl,                          \
-       platform_mmiowb,                        \
-       platform_readb,                         \
-       platform_readw,                         \
-       platform_readl,                         \
-       platform_readq,                         \
-       platform_readb_relaxed,                 \
-       platform_readw_relaxed,                 \
-       platform_readl_relaxed,                 \
-       platform_readq_relaxed,                 \
-       platform_migrate,                       \
-       platform_setup_msi_irq,                 \
-       platform_teardown_msi_irq,              \
-       platform_pci_fixup_bus,                 \
-       platform_kernel_launch_event            \
-}
-
-extern struct ia64_machine_vector ia64_mv;
-extern void machvec_init (const char *name);
-extern void machvec_init_from_cmdline(const char *cmdline);
-
-# else
-#  error Unknown configuration.  Update arch/ia64/include/asm/machvec.h.
-# endif /* CONFIG_IA64_GENERIC */
-
-extern void swiotlb_dma_init(void);
-extern const struct dma_map_ops *dma_get_ops(struct device *);
-
-/*
- * Define default versions so we can extend machvec for new platforms without having
- * to update the machvec files for all existing platforms.
- */
-#ifndef platform_setup
-# define platform_setup                        machvec_setup
-#endif
-#ifndef platform_cpu_init
-# define platform_cpu_init             machvec_noop
-#endif
-#ifndef platform_irq_init
-# define platform_irq_init             machvec_noop
-#endif
-
-#ifndef platform_send_ipi
-# define platform_send_ipi             ia64_send_ipi   /* default to architected version */
-#endif
-#ifndef platform_timer_interrupt
-# define platform_timer_interrupt      machvec_timer_interrupt
-#endif
-#ifndef platform_global_tlb_purge
-# define platform_global_tlb_purge     ia64_global_tlb_purge /* default to architected version */
-#endif
-#ifndef platform_kernel_launch_event
-# define platform_kernel_launch_event  machvec_noop
-#endif
-#ifndef platform_dma_init
-# define platform_dma_init             swiotlb_dma_init
-#endif
-#ifndef platform_dma_get_ops
-# define platform_dma_get_ops          dma_get_ops
-#endif
-#ifndef platform_irq_to_vector
-# define platform_irq_to_vector                __ia64_irq_to_vector
-#endif
-#ifndef platform_local_vector_to_irq
-# define platform_local_vector_to_irq  __ia64_local_vector_to_irq
-#endif
-#ifndef platform_pci_get_legacy_mem
-# define platform_pci_get_legacy_mem   ia64_pci_get_legacy_mem
-#endif
-#ifndef platform_pci_legacy_read
-# define platform_pci_legacy_read      ia64_pci_legacy_read
-extern int ia64_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size);
-#endif
-#ifndef platform_pci_legacy_write
-# define platform_pci_legacy_write     ia64_pci_legacy_write
-extern int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size);
-#endif
-#ifndef platform_inb
-# define platform_inb          __ia64_inb
-#endif
-#ifndef platform_inw
-# define platform_inw          __ia64_inw
-#endif
-#ifndef platform_inl
-# define platform_inl          __ia64_inl
-#endif
-#ifndef platform_outb
-# define platform_outb         __ia64_outb
-#endif
-#ifndef platform_outw
-# define platform_outw         __ia64_outw
-#endif
-#ifndef platform_outl
-# define platform_outl         __ia64_outl
-#endif
-#ifndef platform_mmiowb
-# define platform_mmiowb       __ia64_mmiowb
-#endif
-#ifndef platform_readb
-# define platform_readb                __ia64_readb
-#endif
-#ifndef platform_readw
-# define platform_readw                __ia64_readw
-#endif
-#ifndef platform_readl
-# define platform_readl                __ia64_readl
-#endif
-#ifndef platform_readq
-# define platform_readq                __ia64_readq
-#endif
-#ifndef platform_readb_relaxed
-# define platform_readb_relaxed        __ia64_readb_relaxed
-#endif
-#ifndef platform_readw_relaxed
-# define platform_readw_relaxed        __ia64_readw_relaxed
-#endif
-#ifndef platform_readl_relaxed
-# define platform_readl_relaxed        __ia64_readl_relaxed
-#endif
-#ifndef platform_readq_relaxed
-# define platform_readq_relaxed        __ia64_readq_relaxed
-#endif
-#ifndef platform_migrate
-# define platform_migrate machvec_noop_task
-#endif
-#ifndef platform_setup_msi_irq
-# define platform_setup_msi_irq                ((ia64_mv_setup_msi_irq_t*)NULL)
-#endif
-#ifndef platform_teardown_msi_irq
-# define platform_teardown_msi_irq     ((ia64_mv_teardown_msi_irq_t*)NULL)
-#endif
-#ifndef platform_pci_fixup_bus
-# define platform_pci_fixup_bus        machvec_noop_bus
-#endif
-
-#endif /* _ASM_IA64_MACHVEC_H */
diff --git a/arch/ia64/include/asm/machvec_dig.h b/arch/ia64/include/asm/machvec_dig.h
deleted file mode 100644 (file)
index bc230f6..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_MACHVEC_DIG_h
-#define _ASM_IA64_MACHVEC_DIG_h
-
-extern ia64_mv_setup_t dig_setup;
-
-/*
- * This stuff has dual use!
- *
- * For a generic kernel, the macros are used to initialize the
- * platform's machvec structure.  When compiling a non-generic kernel,
- * the macros are used directly.
- */
-#define ia64_platform_name     "dig"
-#define platform_setup         dig_setup
-
-#endif /* _ASM_IA64_MACHVEC_DIG_h */
diff --git a/arch/ia64/include/asm/machvec_dig_vtd.h b/arch/ia64/include/asm/machvec_dig_vtd.h
deleted file mode 100644 (file)
index bb44eb9..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_MACHVEC_DIG_VTD_h
-#define _ASM_IA64_MACHVEC_DIG_VTD_h
-
-extern ia64_mv_setup_t                 dig_setup;
-extern ia64_mv_dma_init                        pci_iommu_alloc;
-
-/*
- * This stuff has dual use!
- *
- * For a generic kernel, the macros are used to initialize the
- * platform's machvec structure.  When compiling a non-generic kernel,
- * the macros are used directly.
- */
-#define ia64_platform_name                     "dig_vtd"
-#define platform_setup                         dig_setup
-#define platform_dma_init                      pci_iommu_alloc
-
-#endif /* _ASM_IA64_MACHVEC_DIG_VTD_h */
diff --git a/arch/ia64/include/asm/machvec_hpsim.h b/arch/ia64/include/asm/machvec_hpsim.h
deleted file mode 100644 (file)
index 056f840..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_MACHVEC_HPSIM_h
-#define _ASM_IA64_MACHVEC_HPSIM_h
-
-extern ia64_mv_setup_t hpsim_setup;
-extern ia64_mv_irq_init_t hpsim_irq_init;
-
-/*
- * This stuff has dual use!
- *
- * For a generic kernel, the macros are used to initialize the
- * platform's machvec structure.  When compiling a non-generic kernel,
- * the macros are used directly.
- */
-#define ia64_platform_name     "hpsim"
-#define platform_setup         hpsim_setup
-#define platform_irq_init      hpsim_irq_init
-
-#endif /* _ASM_IA64_MACHVEC_HPSIM_h */
diff --git a/arch/ia64/include/asm/machvec_hpzx1.h b/arch/ia64/include/asm/machvec_hpzx1.h
deleted file mode 100644 (file)
index 5299ac3..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_MACHVEC_HPZX1_h
-#define _ASM_IA64_MACHVEC_HPZX1_h
-
-extern ia64_mv_setup_t                 dig_setup;
-extern ia64_mv_dma_init                        sba_dma_init;
-
-/*
- * This stuff has dual use!
- *
- * For a generic kernel, the macros are used to initialize the
- * platform's machvec structure.  When compiling a non-generic kernel,
- * the macros are used directly.
- */
-#define ia64_platform_name                     "hpzx1"
-#define platform_setup                         dig_setup
-#define platform_dma_init                      sba_dma_init
-
-#endif /* _ASM_IA64_MACHVEC_HPZX1_h */
diff --git a/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h b/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h
deleted file mode 100644 (file)
index 5aec6a0..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h
-#define _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h
-
-extern ia64_mv_setup_t                         dig_setup;
-extern ia64_mv_dma_get_ops                     hwsw_dma_get_ops;
-
-/*
- * This stuff has dual use!
- *
- * For a generic kernel, the macros are used to initialize the
- * platform's machvec structure.  When compiling a non-generic kernel,
- * the macros are used directly.
- */
-#define ia64_platform_name                     "hpzx1_swiotlb"
-#define platform_setup                         dig_setup
-#define platform_dma_init                      machvec_noop
-#define platform_dma_get_ops                   hwsw_dma_get_ops
-
-#endif /* _ASM_IA64_MACHVEC_HPZX1_SWIOTLB_h */
diff --git a/arch/ia64/include/asm/machvec_init.h b/arch/ia64/include/asm/machvec_init.h
deleted file mode 100644 (file)
index 2aafb69..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <asm/iommu.h>
-#include <asm/machvec.h>
-
-extern ia64_mv_send_ipi_t ia64_send_ipi;
-extern ia64_mv_global_tlb_purge_t ia64_global_tlb_purge;
-extern ia64_mv_irq_to_vector __ia64_irq_to_vector;
-extern ia64_mv_local_vector_to_irq __ia64_local_vector_to_irq;
-extern ia64_mv_pci_get_legacy_mem_t ia64_pci_get_legacy_mem;
-extern ia64_mv_pci_legacy_read_t ia64_pci_legacy_read;
-extern ia64_mv_pci_legacy_write_t ia64_pci_legacy_write;
-
-extern ia64_mv_inb_t __ia64_inb;
-extern ia64_mv_inw_t __ia64_inw;
-extern ia64_mv_inl_t __ia64_inl;
-extern ia64_mv_outb_t __ia64_outb;
-extern ia64_mv_outw_t __ia64_outw;
-extern ia64_mv_outl_t __ia64_outl;
-extern ia64_mv_mmiowb_t __ia64_mmiowb;
-extern ia64_mv_readb_t __ia64_readb;
-extern ia64_mv_readw_t __ia64_readw;
-extern ia64_mv_readl_t __ia64_readl;
-extern ia64_mv_readq_t __ia64_readq;
-extern ia64_mv_readb_t __ia64_readb_relaxed;
-extern ia64_mv_readw_t __ia64_readw_relaxed;
-extern ia64_mv_readl_t __ia64_readl_relaxed;
-extern ia64_mv_readq_t __ia64_readq_relaxed;
-
-#define MACHVEC_HELPER(name)                                                                   \
- struct ia64_machine_vector machvec_##name __attribute__ ((unused, __section__ (".machvec")))  \
-       = MACHVEC_INIT(name);
-
-#define MACHVEC_DEFINE(name)   MACHVEC_HELPER(name)
-
-MACHVEC_DEFINE(MACHVEC_PLATFORM_NAME)
diff --git a/arch/ia64/include/asm/machvec_sn2.h b/arch/ia64/include/asm/machvec_sn2.h
deleted file mode 100644 (file)
index a243e4f..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2002-2003,2006 Silicon Graphics, Inc.  All Rights Reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#ifndef _ASM_IA64_MACHVEC_SN2_H
-#define _ASM_IA64_MACHVEC_SN2_H
-
-extern ia64_mv_setup_t sn_setup;
-extern ia64_mv_cpu_init_t sn_cpu_init;
-extern ia64_mv_irq_init_t sn_irq_init;
-extern ia64_mv_send_ipi_t sn2_send_IPI;
-extern ia64_mv_timer_interrupt_t sn_timer_interrupt;
-extern ia64_mv_global_tlb_purge_t sn2_global_tlb_purge;
-extern ia64_mv_irq_to_vector sn_irq_to_vector;
-extern ia64_mv_local_vector_to_irq sn_local_vector_to_irq;
-extern ia64_mv_pci_get_legacy_mem_t sn_pci_get_legacy_mem;
-extern ia64_mv_pci_legacy_read_t sn_pci_legacy_read;
-extern ia64_mv_pci_legacy_write_t sn_pci_legacy_write;
-extern ia64_mv_inb_t __sn_inb;
-extern ia64_mv_inw_t __sn_inw;
-extern ia64_mv_inl_t __sn_inl;
-extern ia64_mv_outb_t __sn_outb;
-extern ia64_mv_outw_t __sn_outw;
-extern ia64_mv_outl_t __sn_outl;
-extern ia64_mv_mmiowb_t __sn_mmiowb;
-extern ia64_mv_readb_t __sn_readb;
-extern ia64_mv_readw_t __sn_readw;
-extern ia64_mv_readl_t __sn_readl;
-extern ia64_mv_readq_t __sn_readq;
-extern ia64_mv_readb_t __sn_readb_relaxed;
-extern ia64_mv_readw_t __sn_readw_relaxed;
-extern ia64_mv_readl_t __sn_readl_relaxed;
-extern ia64_mv_readq_t __sn_readq_relaxed;
-extern ia64_mv_dma_init                        sn_dma_init;
-extern ia64_mv_migrate_t               sn_migrate;
-extern ia64_mv_kernel_launch_event_t   sn_kernel_launch_event;
-extern ia64_mv_setup_msi_irq_t         sn_setup_msi_irq;
-extern ia64_mv_teardown_msi_irq_t      sn_teardown_msi_irq;
-extern ia64_mv_pci_fixup_bus_t         sn_pci_fixup_bus;
-
-
-/*
- * This stuff has dual use!
- *
- * For a generic kernel, the macros are used to initialize the
- * platform's machvec structure.  When compiling a non-generic kernel,
- * the macros are used directly.
- */
-#define ia64_platform_name             "sn2"
-#define platform_setup                 sn_setup
-#define platform_cpu_init              sn_cpu_init
-#define platform_irq_init              sn_irq_init
-#define platform_send_ipi              sn2_send_IPI
-#define platform_timer_interrupt       sn_timer_interrupt
-#define platform_global_tlb_purge       sn2_global_tlb_purge
-#define platform_pci_fixup             sn_pci_fixup
-#define platform_inb                   __sn_inb
-#define platform_inw                   __sn_inw
-#define platform_inl                   __sn_inl
-#define platform_outb                  __sn_outb
-#define platform_outw                  __sn_outw
-#define platform_outl                  __sn_outl
-#define platform_mmiowb                        __sn_mmiowb
-#define platform_readb                 __sn_readb
-#define platform_readw                 __sn_readw
-#define platform_readl                 __sn_readl
-#define platform_readq                 __sn_readq
-#define platform_readb_relaxed         __sn_readb_relaxed
-#define platform_readw_relaxed         __sn_readw_relaxed
-#define platform_readl_relaxed         __sn_readl_relaxed
-#define platform_readq_relaxed         __sn_readq_relaxed
-#define platform_irq_to_vector         sn_irq_to_vector
-#define platform_local_vector_to_irq   sn_local_vector_to_irq
-#define platform_pci_get_legacy_mem    sn_pci_get_legacy_mem
-#define platform_pci_legacy_read       sn_pci_legacy_read
-#define platform_pci_legacy_write      sn_pci_legacy_write
-#define platform_dma_init              sn_dma_init
-#define platform_migrate               sn_migrate
-#define platform_kernel_launch_event    sn_kernel_launch_event
-#ifdef CONFIG_PCI_MSI
-#define platform_setup_msi_irq         sn_setup_msi_irq
-#define platform_teardown_msi_irq      sn_teardown_msi_irq
-#else
-#define platform_setup_msi_irq         ((ia64_mv_setup_msi_irq_t*)NULL)
-#define platform_teardown_msi_irq      ((ia64_mv_teardown_msi_irq_t*)NULL)
-#endif
-#define platform_pci_fixup_bus         sn_pci_fixup_bus
-
-#include <asm/sn/io.h>
-
-#endif /* _ASM_IA64_MACHVEC_SN2_H */
diff --git a/arch/ia64/include/asm/machvec_uv.h b/arch/ia64/include/asm/machvec_uv.h
deleted file mode 100644 (file)
index 2c50853..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * SGI UV Core Functions
- *
- * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_MACHVEC_UV_H
-#define _ASM_IA64_MACHVEC_UV_H
-
-extern ia64_mv_setup_t uv_setup;
-
-/*
- * This stuff has dual use!
- *
- * For a generic kernel, the macros are used to initialize the
- * platform's machvec structure.  When compiling a non-generic kernel,
- * the macros are used directly.
- */
-#define ia64_platform_name             "uv"
-#define platform_setup                 uv_setup
-
-#endif /* _ASM_IA64_MACHVEC_UV_H */
index 297b85a..d67aab4 100644 (file)
@@ -3,22 +3,14 @@
 #ifndef _ASM_IA64_MMIOWB_H
 #define _ASM_IA64_MMIOWB_H
 
-#include <asm/machvec.h>
-
 /**
- * ___ia64_mmiowb - I/O write barrier
+ * mmiowb - I/O write barrier
  *
  * Ensure ordering of I/O space writes.  This will make sure that writes
  * following the barrier will arrive after all previous writes.  For most
  * ia64 platforms, this is a simple 'mf.a' instruction.
  */
-static inline void ___ia64_mmiowb(void)
-{
-       ia64_mfa();
-}
-
-#define __ia64_mmiowb  ___ia64_mmiowb
-#define mmiowb()       platform_mmiowb()
+#define mmiowb()       ia64_mfa()
 
 #include <asm-generic/mmiowb.h>
 
index e0de617..767201f 100644 (file)
@@ -27,16 +27,9 @@ static inline int pfn_to_nid(unsigned long pfn)
                return nid;
 }
 
-#ifdef CONFIG_IA64_DIG /* DIG systems are small */
-# define MAX_PHYSNODE_ID       8
-# define NR_NODE_MEMBLKS       (MAX_NUMNODES * 8)
-#else /* sn2 is the biggest case, so we use that if !DIG */
-# define MAX_PHYSNODE_ID       2048
-# define NR_NODE_MEMBLKS       (MAX_NUMNODES * 4)
-#endif
-
-#else /* CONFIG_NUMA */
-# define NR_NODE_MEMBLKS       (MAX_NUMNODES * 4)
+#define MAX_PHYSNODE_ID                2048
 #endif /* CONFIG_NUMA */
 
+#define NR_NODE_MEMBLKS                (MAX_NUMNODES * 4)
+
 #endif /* _ASM_IA64_MMZONE_H */
index 780e874..8c163d1 100644 (file)
@@ -39,9 +39,9 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
                                      struct vm_area_struct *vma,
                                      enum pci_mmap_state mmap_state);
 
-#define pci_get_legacy_mem platform_pci_get_legacy_mem
-#define pci_legacy_read platform_pci_legacy_read
-#define pci_legacy_write platform_pci_legacy_write
+char *pci_get_legacy_mem(struct pci_bus *bus);
+int pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size);
+int pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size);
 
 struct pci_controller {
        struct acpi_device *companion;
@@ -69,7 +69,4 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
        return channel ? isa_irq_to_vector(15) : isa_irq_to_vector(14);
 }
 
-#ifdef CONFIG_INTEL_IOMMU
-extern void pci_iommu_alloc(void);
-#endif
 #endif /* _ASM_IA64_PCI_H */
index c91ef98..95a2ec3 100644 (file)
@@ -679,8 +679,6 @@ enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_FORCE_MWAIT,
 
 void default_idle(void);
 
-#define ia64_platform_is(x) (strcmp(x, ia64_platform_name) == 0)
-
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_IA64_PROCESSOR_H */
diff --git a/arch/ia64/include/asm/sn/acpi.h b/arch/ia64/include/asm/sn/acpi.h
deleted file mode 100644 (file)
index fd480db..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_ACPI_H
-#define _ASM_IA64_SN_ACPI_H
-
-extern int sn_acpi_rev;
-#define SN_ACPI_BASE_SUPPORT()   (sn_acpi_rev >= 0x20101)
-
-#endif /* _ASM_IA64_SN_ACPI_H */
diff --git a/arch/ia64/include/asm/sn/addrs.h b/arch/ia64/include/asm/sn/addrs.h
deleted file mode 100644 (file)
index e715c79..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 1992-1999,2001-2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_ADDRS_H
-#define _ASM_IA64_SN_ADDRS_H
-
-#include <asm/percpu.h>
-#include <asm/sn/types.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/pda.h>
-
-/*
- *  Memory/SHUB Address Format:
- *  +-+---------+--+--------------+
- *  |0|  NASID  |AS| NodeOffset   |
- *  +-+---------+--+--------------+
- *
- *  NASID: (low NASID bit is 0) Memory and SHUB MMRs
- *   AS: 2-bit Address Space Identifier. Used only if low NASID bit is 0
- *     00: Local Resources and MMR space
- *           Top bit of NodeOffset
- *               0: Local resources space
- *                  node id:
- *                        0: IA64/NT compatibility space
- *                        2: Local MMR Space
- *                        4: Local memory, regardless of local node id
- *               1: Global MMR space
- *     01: GET space.
- *     10: AMO space.
- *     11: Cacheable memory space.
- *
- *   NodeOffset: byte offset
- *
- *
- *  TIO address format:
- *  +-+----------+--+--------------+
- *  |0|  NASID   |AS| Nodeoffset   |
- *  +-+----------+--+--------------+
- *
- *  NASID: (low NASID bit is 1) TIO
- *   AS: 2-bit Chiplet Identifier
- *     00: TIO LB (Indicates TIO MMR access.)
- *     01: TIO ICE (indicates coretalk space access.)
- * 
- *   NodeOffset: top bit must be set.
- *
- *
- * Note that in both of the above address formats, the low
- * NASID bit indicates if the reference is to the SHUB or TIO MMRs.
- */
-
-
-/*
- * Define basic shift & mask constants for manipulating NASIDs and AS values.
- */
-#define NASID_BITMASK          (sn_hub_info->nasid_bitmask)
-#define NASID_SHIFT            (sn_hub_info->nasid_shift)
-#define AS_SHIFT               (sn_hub_info->as_shift)
-#define AS_BITMASK             0x3UL
-
-#define NASID_MASK              ((u64)NASID_BITMASK << NASID_SHIFT)
-#define AS_MASK                        ((u64)AS_BITMASK << AS_SHIFT)
-
-
-/*
- * AS values. These are the same on both SHUB1 & SHUB2.
- */
-#define AS_GET_VAL             1UL
-#define AS_AMO_VAL             2UL
-#define AS_CAC_VAL             3UL
-#define AS_GET_SPACE           (AS_GET_VAL << AS_SHIFT)
-#define AS_AMO_SPACE           (AS_AMO_VAL << AS_SHIFT)
-#define AS_CAC_SPACE           (AS_CAC_VAL << AS_SHIFT)
-
-
-/* 
- * Virtual Mode Local & Global MMR space.  
- */
-#define SH1_LOCAL_MMR_OFFSET   0x8000000000UL
-#define SH2_LOCAL_MMR_OFFSET   0x0200000000UL
-#define LOCAL_MMR_OFFSET       (is_shub2() ? SH2_LOCAL_MMR_OFFSET : SH1_LOCAL_MMR_OFFSET)
-#define LOCAL_MMR_SPACE                (__IA64_UNCACHED_OFFSET | LOCAL_MMR_OFFSET)
-#define LOCAL_PHYS_MMR_SPACE   (RGN_BASE(RGN_HPAGE) | LOCAL_MMR_OFFSET)
-
-#define SH1_GLOBAL_MMR_OFFSET  0x0800000000UL
-#define SH2_GLOBAL_MMR_OFFSET  0x0300000000UL
-#define GLOBAL_MMR_OFFSET      (is_shub2() ? SH2_GLOBAL_MMR_OFFSET : SH1_GLOBAL_MMR_OFFSET)
-#define GLOBAL_MMR_SPACE       (__IA64_UNCACHED_OFFSET | GLOBAL_MMR_OFFSET)
-
-/*
- * Physical mode addresses
- */
-#define GLOBAL_PHYS_MMR_SPACE  (RGN_BASE(RGN_HPAGE) | GLOBAL_MMR_OFFSET)
-
-
-/*
- * Clear region & AS bits.
- */
-#define TO_PHYS_MASK           (~(RGN_BITS | AS_MASK))
-
-
-/*
- * Misc NASID manipulation.
- */
-#define NASID_SPACE(n)         ((u64)(n) << NASID_SHIFT)
-#define REMOTE_ADDR(n,a)       (NASID_SPACE(n) | (a))
-#define NODE_OFFSET(x)         ((x) & (NODE_ADDRSPACE_SIZE - 1))
-#define NODE_ADDRSPACE_SIZE     (1UL << AS_SHIFT)
-#define NASID_GET(x)           (int) (((u64) (x) >> NASID_SHIFT) & NASID_BITMASK)
-#define LOCAL_MMR_ADDR(a)      (LOCAL_MMR_SPACE | (a))
-#define GLOBAL_MMR_ADDR(n,a)   (GLOBAL_MMR_SPACE | REMOTE_ADDR(n,a))
-#define GLOBAL_MMR_PHYS_ADDR(n,a) (GLOBAL_PHYS_MMR_SPACE | REMOTE_ADDR(n,a))
-#define GLOBAL_CAC_ADDR(n,a)   (CAC_BASE | REMOTE_ADDR(n,a))
-#define CHANGE_NASID(n,x)      ((void *)(((u64)(x) & ~NASID_MASK) | NASID_SPACE(n)))
-#define IS_TIO_NASID(n)                ((n) & 1)
-
-
-/* non-II mmr's start at top of big window space (4G) */
-#define BWIN_TOP               0x0000000100000000UL
-
-/*
- * general address defines
- */
-#define CAC_BASE               (PAGE_OFFSET | AS_CAC_SPACE)
-#define AMO_BASE               (__IA64_UNCACHED_OFFSET | AS_AMO_SPACE)
-#define AMO_PHYS_BASE          (RGN_BASE(RGN_HPAGE) | AS_AMO_SPACE)
-#define GET_BASE               (PAGE_OFFSET | AS_GET_SPACE)
-
-/*
- * Convert Memory addresses between various addressing modes.
- */
-#define TO_PHYS(x)             (TO_PHYS_MASK & (x))
-#define TO_CAC(x)              (CAC_BASE     | TO_PHYS(x))
-#ifdef CONFIG_SGI_SN
-#define TO_AMO(x)              (AMO_BASE     | TO_PHYS(x))
-#define TO_GET(x)              (GET_BASE     | TO_PHYS(x))
-#else
-#define TO_AMO(x)              ({ BUG(); x; })
-#define TO_GET(x)              ({ BUG(); x; })
-#endif
-
-/*
- * Covert from processor physical address to II/TIO physical address:
- *     II - squeeze out the AS bits
- *     TIO- requires a chiplet id in bits 38-39.  For DMA to memory,
- *           the chiplet id is zero.  If we implement TIO-TIO dma, we might need
- *           to insert a chiplet id into this macro.  However, it is our belief
- *           right now that this chiplet id will be ICE, which is also zero.
- */
-#define SH1_TIO_PHYS_TO_DMA(x)                                                 \
-       ((((u64)(NASID_GET(x))) << 40) | NODE_OFFSET(x))
-
-#define SH2_NETWORK_BANK_OFFSET(x)                                     \
-        ((u64)(x) & ((1UL << (sn_hub_info->nasid_shift - 4)) -1))
-
-#define SH2_NETWORK_BANK_SELECT(x)                                     \
-        ((((u64)(x) & (0x3UL << (sn_hub_info->nasid_shift - 4)))       \
-               >> (sn_hub_info->nasid_shift - 4)) << 36)
-
-#define SH2_NETWORK_ADDRESS(x)                                                 \
-       (SH2_NETWORK_BANK_OFFSET(x) | SH2_NETWORK_BANK_SELECT(x))
-
-#define SH2_TIO_PHYS_TO_DMA(x)                                                 \
-        (((u64)(NASID_GET(x)) << 40) |         SH2_NETWORK_ADDRESS(x))
-
-#define PHYS_TO_TIODMA(x)                                              \
-       (is_shub1() ? SH1_TIO_PHYS_TO_DMA(x) : SH2_TIO_PHYS_TO_DMA(x))
-
-#define PHYS_TO_DMA(x)                                                 \
-       ((((u64)(x) & NASID_MASK) >> 2) | NODE_OFFSET(x))
-
-
-/*
- * Macros to test for address type.
- */
-#define IS_AMO_ADDRESS(x)      (((u64)(x) & (RGN_BITS | AS_MASK)) == AMO_BASE)
-#define IS_AMO_PHYS_ADDRESS(x) (((u64)(x) & (RGN_BITS | AS_MASK)) == AMO_PHYS_BASE)
-
-
-/*
- * The following definitions pertain to the IO special address
- * space.  They define the location of the big and little windows
- * of any given node.
- */
-#define BWIN_SIZE_BITS                 29      /* big window size: 512M */
-#define TIO_BWIN_SIZE_BITS             30      /* big window size: 1G */
-#define NODE_SWIN_BASE(n, w)           ((w == 0) ? NODE_BWIN_BASE((n), SWIN0_BIGWIN) \
-               : RAW_NODE_SWIN_BASE(n, w))
-#define TIO_SWIN_BASE(n, w)            (TIO_IO_BASE(n) + \
-                                           ((u64) (w) << TIO_SWIN_SIZE_BITS))
-#define NODE_IO_BASE(n)                        (GLOBAL_MMR_SPACE | NASID_SPACE(n))
-#define TIO_IO_BASE(n)                  (__IA64_UNCACHED_OFFSET | NASID_SPACE(n))
-#define BWIN_SIZE                      (1UL << BWIN_SIZE_BITS)
-#define NODE_BWIN_BASE0(n)             (NODE_IO_BASE(n) + BWIN_SIZE)
-#define NODE_BWIN_BASE(n, w)           (NODE_BWIN_BASE0(n) + ((u64) (w) << BWIN_SIZE_BITS))
-#define RAW_NODE_SWIN_BASE(n, w)       (NODE_IO_BASE(n) + ((u64) (w) << SWIN_SIZE_BITS))
-#define BWIN_WIDGET_MASK               0x7
-#define BWIN_WINDOWNUM(x)              (((x) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK)
-#define SH1_IS_BIG_WINDOW_ADDR(x)      ((x) & BWIN_TOP)
-
-#define TIO_BWIN_WINDOW_SELECT_MASK    0x7
-#define TIO_BWIN_WINDOWNUM(x)          (((x) >> TIO_BWIN_SIZE_BITS) & TIO_BWIN_WINDOW_SELECT_MASK)
-
-#define TIO_HWIN_SHIFT_BITS            33
-#define TIO_HWIN(x)                    (NODE_OFFSET(x) >> TIO_HWIN_SHIFT_BITS)
-
-/*
- * The following definitions pertain to the IO special address
- * space.  They define the location of the big and little windows
- * of any given node.
- */
-
-#define SWIN_SIZE_BITS                 24
-#define        SWIN_WIDGET_MASK                0xF
-
-#define TIO_SWIN_SIZE_BITS             28
-#define TIO_SWIN_SIZE                  (1UL << TIO_SWIN_SIZE_BITS)
-#define TIO_SWIN_WIDGET_MASK           0x3
-
-/*
- * Convert smallwindow address to xtalk address.
- *
- * 'addr' can be physical or virtual address, but will be converted
- * to Xtalk address in the range 0 -> SWINZ_SIZEMASK
- */
-#define        SWIN_WIDGETNUM(x)               (((x)  >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK)
-#define TIO_SWIN_WIDGETNUM(x)          (((x)  >> TIO_SWIN_SIZE_BITS) & TIO_SWIN_WIDGET_MASK)
-
-
-/*
- * The following macros produce the correct base virtual address for
- * the hub registers. The REMOTE_HUB_* macro produce
- * the address for the specified hub's registers.  The intent is
- * that the appropriate PI, MD, NI, or II register would be substituted
- * for x.
- *
- *   WARNING:
- *     When certain Hub chip workaround are defined, it's not sufficient
- *     to dereference the *_HUB_ADDR() macros.  You should instead use
- *     HUB_L() and HUB_S() if you must deal with pointers to hub registers.
- *     Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
- *     They're always safe.
- */
-/* Shub1 TIO & MMR addressing macros */
-#define SH1_TIO_IOSPACE_ADDR(n,x)                                      \
-       GLOBAL_MMR_ADDR(n,x)
-
-#define SH1_REMOTE_BWIN_MMR(n,x)                                       \
-       GLOBAL_MMR_ADDR(n,x)
-
-#define SH1_REMOTE_SWIN_MMR(n,x)                                       \
-       (NODE_SWIN_BASE(n,1) + 0x800000UL + (x))
-
-#define SH1_REMOTE_MMR(n,x)                                            \
-       (SH1_IS_BIG_WINDOW_ADDR(x) ? SH1_REMOTE_BWIN_MMR(n,x) :         \
-               SH1_REMOTE_SWIN_MMR(n,x))
-
-/* Shub1 TIO & MMR addressing macros */
-#define SH2_TIO_IOSPACE_ADDR(n,x)                                      \
-       ((__IA64_UNCACHED_OFFSET | REMOTE_ADDR(n,x) | 1UL << (NASID_SHIFT - 2)))
-
-#define SH2_REMOTE_MMR(n,x)                                            \
-       GLOBAL_MMR_ADDR(n,x)
-
-
-/* TIO & MMR addressing macros that work on both shub1 & shub2 */
-#define TIO_IOSPACE_ADDR(n,x)                                          \
-       ((u64 *)(is_shub1() ? SH1_TIO_IOSPACE_ADDR(n,x) :               \
-                SH2_TIO_IOSPACE_ADDR(n,x)))
-
-#define SH_REMOTE_MMR(n,x)                                             \
-       (is_shub1() ? SH1_REMOTE_MMR(n,x) : SH2_REMOTE_MMR(n,x))
-
-#define REMOTE_HUB_ADDR(n,x)                                           \
-       (IS_TIO_NASID(n) ?  ((volatile u64*)TIO_IOSPACE_ADDR(n,x)) :    \
-        ((volatile u64*)SH_REMOTE_MMR(n,x)))
-
-
-#define HUB_L(x)                       (*((volatile typeof(*x) *)x))
-#define        HUB_S(x,d)                      (*((volatile typeof(*x) *)x) = (d))
-
-#define REMOTE_HUB_L(n, a)             HUB_L(REMOTE_HUB_ADDR((n), (a)))
-#define REMOTE_HUB_S(n, a, d)          HUB_S(REMOTE_HUB_ADDR((n), (a)), (d))
-
-/*
- * Coretalk address breakdown
- */
-#define CTALK_NASID_SHFT               40
-#define CTALK_NASID_MASK               (0x3FFFULL << CTALK_NASID_SHFT)
-#define CTALK_CID_SHFT                 38
-#define CTALK_CID_MASK                 (0x3ULL << CTALK_CID_SHFT)
-#define CTALK_NODE_OFFSET              0x3FFFFFFFFF
-
-#endif /* _ASM_IA64_SN_ADDRS_H */
diff --git a/arch/ia64/include/asm/sn/arch.h b/arch/ia64/include/asm/sn/arch.h
deleted file mode 100644 (file)
index 31eb784..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * SGI specific setup.
- *
- * Copyright (C) 1995-1997,1999,2001-2005 Silicon Graphics, Inc.  All rights reserved.
- * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
- */
-#ifndef _ASM_IA64_SN_ARCH_H
-#define _ASM_IA64_SN_ARCH_H
-
-#include <linux/numa.h>
-#include <asm/types.h>
-#include <asm/percpu.h>
-#include <asm/sn/types.h>
-#include <asm/sn/sn_cpuid.h>
-
-/*
- * This is the maximum number of NUMALINK nodes that can be part of a single
- * SSI kernel. This number includes C-brick, M-bricks, and TIOs. Nodes in
- * remote partitions are NOT included in this number.
- * The number of compact nodes cannot exceed size of a coherency domain.
- * The purpose of this define is to specify a node count that includes
- * all C/M/TIO nodes in an SSI system.
- *
- * SGI system can currently support up to 256 C/M nodes plus additional TIO nodes.
- *
- *     Note: ACPI20 has an architectural limit of 256 nodes. When we upgrade
- *     to ACPI3.0, this limit will be removed. The notion of "compact nodes"
- *     should be deleted and TIOs should be included in MAX_NUMNODES.
- */
-#define MAX_TIO_NODES          MAX_NUMNODES
-#define MAX_COMPACT_NODES      (MAX_NUMNODES + MAX_TIO_NODES)
-
-/*
- * Maximum number of nodes in all partitions and in all coherency domains.
- * This is the total number of nodes accessible in the numalink fabric. It
- * includes all C & M bricks, plus all TIOs.
- *
- * This value is also the value of the maximum number of NASIDs in the numalink
- * fabric.
- */
-#define MAX_NUMALINK_NODES     16384
-
-/*
- * The following defines attributes of the HUB chip. These attributes are
- * frequently referenced. They are kept in the per-cpu data areas of each cpu.
- * They are kept together in a struct to minimize cache misses.
- */
-struct sn_hub_info_s {
-       u8 shub2;
-       u8 nasid_shift;
-       u8 as_shift;
-       u8 shub_1_1_found;
-       u16 nasid_bitmask;
-};
-DECLARE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
-#define sn_hub_info    this_cpu_ptr(&__sn_hub_info)
-#define is_shub2()     (sn_hub_info->shub2)
-#define is_shub1()     (sn_hub_info->shub2 == 0)
-
-/*
- * Use this macro to test if shub 1.1 wars should be enabled
- */
-#define enable_shub_wars_1_1() (sn_hub_info->shub_1_1_found)
-
-
-/*
- * Compact node ID to nasid mappings kept in the per-cpu data areas of each
- * cpu.
- */
-DECLARE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]);
-#define sn_cnodeid_to_nasid    this_cpu_ptr(&__sn_cnodeid_to_nasid[0])
-
-
-extern u8 sn_partition_id;
-extern u8 sn_system_size;
-extern u8 sn_sharing_domain_size;
-extern u8 sn_region_size;
-
-extern void sn_flush_all_caches(long addr, long bytes);
-extern bool sn_cpu_disable_allowed(int cpu);
-
-#endif /* _ASM_IA64_SN_ARCH_H */
diff --git a/arch/ia64/include/asm/sn/bte.h b/arch/ia64/include/asm/sn/bte.h
deleted file mode 100644 (file)
index cd71ab5..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2000-2007 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-
-#ifndef _ASM_IA64_SN_BTE_H
-#define _ASM_IA64_SN_BTE_H
-
-#include <linux/timer.h>
-#include <linux/spinlock.h>
-#include <linux/cache.h>
-#include <asm/sn/pda.h>
-#include <asm/sn/types.h>
-#include <asm/sn/shub_mmr.h>
-
-struct nodepda_s;
-
-#define IBCT_NOTIFY             (0x1UL << 4)
-#define IBCT_ZFIL_MODE          (0x1UL << 0)
-
-/* #define BTE_DEBUG */
-/* #define BTE_DEBUG_VERBOSE */
-
-#ifdef BTE_DEBUG
-#  define BTE_PRINTK(x) printk x       /* Terse */
-#  ifdef BTE_DEBUG_VERBOSE
-#    define BTE_PRINTKV(x) printk x    /* Verbose */
-#  else
-#    define BTE_PRINTKV(x)
-#  endif /* BTE_DEBUG_VERBOSE */
-#else
-#  define BTE_PRINTK(x)
-#  define BTE_PRINTKV(x)
-#endif /* BTE_DEBUG */
-
-
-/* BTE status register only supports 16 bits for length field */
-#define BTE_LEN_BITS (16)
-#define BTE_LEN_MASK ((1 << BTE_LEN_BITS) - 1)
-#define BTE_MAX_XFER (BTE_LEN_MASK << L1_CACHE_SHIFT)
-
-
-/* Define hardware */
-#define BTES_PER_NODE (is_shub2() ? 4 : 2)
-#define MAX_BTES_PER_NODE 4
-
-#define BTE2OFF_CTRL   0
-#define BTE2OFF_SRC    (SH2_BT_ENG_SRC_ADDR_0 - SH2_BT_ENG_CSR_0)
-#define BTE2OFF_DEST   (SH2_BT_ENG_DEST_ADDR_0 - SH2_BT_ENG_CSR_0)
-#define BTE2OFF_NOTIFY (SH2_BT_ENG_NOTIF_ADDR_0 - SH2_BT_ENG_CSR_0)
-
-#define BTE_BASE_ADDR(interface)                               \
-    (is_shub2() ? (interface == 0) ? SH2_BT_ENG_CSR_0 :                \
-                 (interface == 1) ? SH2_BT_ENG_CSR_1 :         \
-                 (interface == 2) ? SH2_BT_ENG_CSR_2 :         \
-                                    SH2_BT_ENG_CSR_3           \
-               : (interface == 0) ? IIO_IBLS0 : IIO_IBLS1)
-
-#define BTE_SOURCE_ADDR(base)                                  \
-    (is_shub2() ? base + (BTE2OFF_SRC/8)                       \
-               : base + (BTEOFF_SRC/8))
-
-#define BTE_DEST_ADDR(base)                                    \
-    (is_shub2() ? base + (BTE2OFF_DEST/8)                      \
-               : base + (BTEOFF_DEST/8))
-
-#define BTE_CTRL_ADDR(base)                                    \
-    (is_shub2() ? base + (BTE2OFF_CTRL/8)                      \
-               : base + (BTEOFF_CTRL/8))
-
-#define BTE_NOTIF_ADDR(base)                                   \
-    (is_shub2() ? base + (BTE2OFF_NOTIFY/8)                    \
-               : base + (BTEOFF_NOTIFY/8))
-
-/* Define hardware modes */
-#define BTE_NOTIFY IBCT_NOTIFY
-#define BTE_NORMAL BTE_NOTIFY
-#define BTE_ZERO_FILL (BTE_NOTIFY | IBCT_ZFIL_MODE)
-/* Use a reserved bit to let the caller specify a wait for any BTE */
-#define BTE_WACQUIRE 0x4000
-/* Use the BTE on the node with the destination memory */
-#define BTE_USE_DEST (BTE_WACQUIRE << 1)
-/* Use any available BTE interface on any node for the transfer */
-#define BTE_USE_ANY (BTE_USE_DEST << 1)
-/* macro to force the IBCT0 value valid */
-#define BTE_VALID_MODE(x) ((x) & (IBCT_NOTIFY | IBCT_ZFIL_MODE))
-
-#define BTE_ACTIVE             (IBLS_BUSY | IBLS_ERROR)
-#define BTE_WORD_AVAILABLE     (IBLS_BUSY << 1)
-#define BTE_WORD_BUSY          (~BTE_WORD_AVAILABLE)
-
-/*
- * Some macros to simplify reading.
- * Start with macros to locate the BTE control registers.
- */
-#define BTE_LNSTAT_LOAD(_bte)                                          \
-                       HUB_L(_bte->bte_base_addr)
-#define BTE_LNSTAT_STORE(_bte, _x)                                     \
-                       HUB_S(_bte->bte_base_addr, (_x))
-#define BTE_SRC_STORE(_bte, _x)                                                \
-({                                                                     \
-               u64 __addr = ((_x) & ~AS_MASK);                         \
-               if (is_shub2())                                         \
-                       __addr = SH2_TIO_PHYS_TO_DMA(__addr);           \
-               HUB_S(_bte->bte_source_addr, __addr);                   \
-})
-#define BTE_DEST_STORE(_bte, _x)                                       \
-({                                                                     \
-               u64 __addr = ((_x) & ~AS_MASK);                         \
-               if (is_shub2())                                         \
-                       __addr = SH2_TIO_PHYS_TO_DMA(__addr);           \
-               HUB_S(_bte->bte_destination_addr, __addr);              \
-})
-#define BTE_CTRL_STORE(_bte, _x)                                       \
-                       HUB_S(_bte->bte_control_addr, (_x))
-#define BTE_NOTIF_STORE(_bte, _x)                                      \
-({                                                                     \
-               u64 __addr = ia64_tpa((_x) & ~AS_MASK);                 \
-               if (is_shub2())                                         \
-                       __addr = SH2_TIO_PHYS_TO_DMA(__addr);           \
-               HUB_S(_bte->bte_notify_addr, __addr);                   \
-})
-
-#define BTE_START_TRANSFER(_bte, _len, _mode)                          \
-       is_shub2() ? BTE_CTRL_STORE(_bte, IBLS_BUSY | (_mode << 24) | _len) \
-               : BTE_LNSTAT_STORE(_bte, _len);                         \
-                 BTE_CTRL_STORE(_bte, _mode)
-
-/* Possible results from bte_copy and bte_unaligned_copy */
-/* The following error codes map into the BTE hardware codes
- * IIO_ICRB_ECODE_* (in shubio.h). The hardware uses
- * an error code of 0 (IIO_ICRB_ECODE_DERR), but we want zero
- * to mean BTE_SUCCESS, so add one (BTEFAIL_OFFSET) to the error
- * codes to give the following error codes.
- */
-#define BTEFAIL_OFFSET 1
-
-typedef enum {
-       BTE_SUCCESS,            /* 0 is success */
-       BTEFAIL_DIR,            /* Directory error due to IIO access*/
-       BTEFAIL_POISON,         /* poison error on IO access (write to poison page) */
-       BTEFAIL_WERR,           /* Write error (ie WINV to a Read only line) */
-       BTEFAIL_ACCESS,         /* access error (protection violation) */
-       BTEFAIL_PWERR,          /* Partial Write Error */
-       BTEFAIL_PRERR,          /* Partial Read Error */
-       BTEFAIL_TOUT,           /* CRB Time out */
-       BTEFAIL_XTERR,          /* Incoming xtalk pkt had error bit */
-       BTEFAIL_NOTAVAIL,       /* BTE not available */
-} bte_result_t;
-
-#define BTEFAIL_SH2_RESP_SHORT 0x1     /* bit 000001 */
-#define BTEFAIL_SH2_RESP_LONG  0x2     /* bit 000010 */
-#define BTEFAIL_SH2_RESP_DSP   0x4     /* bit 000100 */
-#define BTEFAIL_SH2_RESP_ACCESS        0x8     /* bit 001000 */
-#define BTEFAIL_SH2_CRB_TO     0x10    /* bit 010000 */
-#define BTEFAIL_SH2_NACK_LIMIT 0x20    /* bit 100000 */
-#define BTEFAIL_SH2_ALL                0x3F    /* bit 111111 */
-
-#define        BTE_ERR_BITS    0x3FUL
-#define        BTE_ERR_SHIFT   36
-#define BTE_ERR_MASK   (BTE_ERR_BITS << BTE_ERR_SHIFT)
-
-#define BTE_ERROR_RETRY(value)                                         \
-       (is_shub2() ? (value != BTEFAIL_SH2_CRB_TO)                     \
-               : (value != BTEFAIL_TOUT))
-
-/*
- * On shub1 BTE_ERR_MASK will always be false, so no need for is_shub2()
- */
-#define BTE_SHUB2_ERROR(_status)                                       \
-       ((_status & BTE_ERR_MASK)                                       \
-          ? (((_status >> BTE_ERR_SHIFT) & BTE_ERR_BITS) | IBLS_ERROR) \
-          : _status)
-
-#define BTE_GET_ERROR_STATUS(_status)                                  \
-       (BTE_SHUB2_ERROR(_status) & ~IBLS_ERROR)
-
-#define BTE_VALID_SH2_ERROR(value)                                     \
-       ((value >= BTEFAIL_SH2_RESP_SHORT) && (value <= BTEFAIL_SH2_ALL))
-
-/*
- * Structure defining a bte.  An instance of this
- * structure is created in the nodepda for each
- * bte on that node (as defined by BTES_PER_NODE)
- * This structure contains everything necessary
- * to work with a BTE.
- */
-struct bteinfo_s {
-       volatile u64 notify ____cacheline_aligned;
-       u64 *bte_base_addr ____cacheline_aligned;
-       u64 *bte_source_addr;
-       u64 *bte_destination_addr;
-       u64 *bte_control_addr;
-       u64 *bte_notify_addr;
-       spinlock_t spinlock;
-       cnodeid_t bte_cnode;    /* cnode                            */
-       int bte_error_count;    /* Number of errors encountered     */
-       int bte_num;            /* 0 --> BTE0, 1 --> BTE1           */
-       int cleanup_active;     /* Interface is locked for cleanup  */
-       volatile bte_result_t bh_error; /* error while processing   */
-       volatile u64 *most_rcnt_na;
-       struct bteinfo_s *btes_to_try[MAX_BTES_PER_NODE];
-};
-
-
-/*
- * Function prototypes (functions defined in bte.c, used elsewhere)
- */
-extern bte_result_t bte_copy(u64, u64, u64, u64, void *);
-extern bte_result_t bte_unaligned_copy(u64, u64, u64, u64);
-extern void bte_error_handler(struct nodepda_s *);
-
-#define bte_zero(dest, len, mode, notification) \
-       bte_copy(0, dest, len, ((mode) | BTE_ZERO_FILL), notification)
-
-/*
- * The following is the preferred way of calling bte_unaligned_copy
- * If the copy is fully cache line aligned, then bte_copy is
- * used instead.  Since bte_copy is inlined, this saves a call
- * stack.  NOTE: bte_copy is called synchronously and does block
- * until the transfer is complete.  In order to get the asynch
- * version of bte_copy, you must perform this check yourself.
- */
-#define BTE_UNALIGNED_COPY(src, dest, len, mode)                       \
-       (((len & (L1_CACHE_BYTES - 1)) ||                               \
-         (src & (L1_CACHE_BYTES - 1)) ||                               \
-         (dest & (L1_CACHE_BYTES - 1))) ?                              \
-        bte_unaligned_copy(src, dest, len, mode) :                     \
-        bte_copy(src, dest, len, mode, NULL))
-
-
-#endif /* _ASM_IA64_SN_BTE_H */
diff --git a/arch/ia64/include/asm/sn/clksupport.h b/arch/ia64/include/asm/sn/clksupport.h
deleted file mode 100644 (file)
index d340c36..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * This file contains definitions for accessing a platform supported high resolution
- * clock. The clock is monitonically increasing and can be accessed from any node
- * in the system. The clock is synchronized across nodes - all nodes see the
- * same value.
- * 
- *     RTC_COUNTER_ADDR - contains the address of the counter 
- *
- */
-
-#ifndef _ASM_IA64_SN_CLKSUPPORT_H
-#define _ASM_IA64_SN_CLKSUPPORT_H
-
-extern unsigned long sn_rtc_cycles_per_second;
-
-#define RTC_COUNTER_ADDR       ((long *)LOCAL_MMR_ADDR(SH_RTC))
-
-#define rtc_time()             (*RTC_COUNTER_ADDR)
-
-#endif /* _ASM_IA64_SN_CLKSUPPORT_H */
diff --git a/arch/ia64/include/asm/sn/geo.h b/arch/ia64/include/asm/sn/geo.h
deleted file mode 100644 (file)
index f083c94..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_GEO_H
-#define _ASM_IA64_SN_GEO_H
-
-/* The geoid_t implementation below is based loosely on the pcfg_t
-   implementation in sys/SN/promcfg.h. */
-
-/* Type declaractions */
-
-/* Size of a geoid_t structure (must be before decl. of geoid_u) */
-#define GEOID_SIZE     8       /* Would 16 be better?  The size can
-                                  be different on different platforms. */
-
-#define MAX_SLOTS      0xf     /* slots per module */
-#define MAX_SLABS      0xf     /* slabs per slot */
-
-typedef unsigned char  geo_type_t;
-
-/* Fields common to all substructures */
-typedef struct geo_common_s {
-    moduleid_t module;         /* The module (box) this h/w lives in */
-    geo_type_t type;           /* What type of h/w is named by this geoid_t */
-    slabid_t   slab:4;         /* slab (ASIC), 0 .. 15 within slot */
-    slotid_t   slot:4;         /* slot (Blade), 0 .. 15 within module */
-} geo_common_t;
-
-/* Additional fields for particular types of hardware */
-typedef struct geo_node_s {
-    geo_common_t       common;         /* No additional fields needed */
-} geo_node_t;
-
-typedef struct geo_rtr_s {
-    geo_common_t       common;         /* No additional fields needed */
-} geo_rtr_t;
-
-typedef struct geo_iocntl_s {
-    geo_common_t       common;         /* No additional fields needed */
-} geo_iocntl_t;
-
-typedef struct geo_pcicard_s {
-    geo_iocntl_t       common;
-    char               bus;    /* Bus/widget number */
-    char               slot;   /* PCI slot number */
-} geo_pcicard_t;
-
-/* Subcomponents of a node */
-typedef struct geo_cpu_s {
-    geo_node_t node;
-    char       slice;          /* Which CPU on the node */
-} geo_cpu_t;
-
-typedef struct geo_mem_s {
-    geo_node_t node;
-    char       membus;         /* The memory bus on the node */
-    char       memslot;        /* The memory slot on the bus */
-} geo_mem_t;
-
-
-typedef union geoid_u {
-    geo_common_t       common;
-    geo_node_t         node;
-    geo_iocntl_t       iocntl;
-    geo_pcicard_t      pcicard;
-    geo_rtr_t          rtr;
-    geo_cpu_t          cpu;
-    geo_mem_t          mem;
-    char               padsize[GEOID_SIZE];
-} geoid_t;
-
-
-/* Preprocessor macros */
-
-#define GEO_MAX_LEN    48      /* max. formatted length, plus some pad:
-                                  module/001c07/slab/5/node/memory/2/slot/4 */
-
-/* Values for geo_type_t */
-#define GEO_TYPE_INVALID       0
-#define GEO_TYPE_MODULE                1
-#define GEO_TYPE_NODE          2
-#define GEO_TYPE_RTR           3
-#define GEO_TYPE_IOCNTL                4
-#define GEO_TYPE_IOCARD                5
-#define GEO_TYPE_CPU           6
-#define GEO_TYPE_MEM           7
-#define GEO_TYPE_MAX           (GEO_TYPE_MEM+1)
-
-/* Parameter for hwcfg_format_geoid_compt() */
-#define GEO_COMPT_MODULE       1
-#define GEO_COMPT_SLAB         2
-#define GEO_COMPT_IOBUS                3
-#define GEO_COMPT_IOSLOT       4
-#define GEO_COMPT_CPU          5
-#define GEO_COMPT_MEMBUS       6
-#define GEO_COMPT_MEMSLOT      7
-
-#define GEO_INVALID_STR                "<invalid>"
-
-#define INVALID_NASID           ((nasid_t)-1)
-#define INVALID_CNODEID         ((cnodeid_t)-1)
-#define INVALID_PNODEID         ((pnodeid_t)-1)
-#define INVALID_SLAB            (slabid_t)-1
-#define INVALID_SLOT            (slotid_t)-1
-#define INVALID_MODULE          ((moduleid_t)-1)
-
-static inline slabid_t geo_slab(geoid_t g)
-{
-       return (g.common.type == GEO_TYPE_INVALID) ?
-               INVALID_SLAB : g.common.slab;
-}
-
-static inline slotid_t geo_slot(geoid_t g)
-{
-       return (g.common.type == GEO_TYPE_INVALID) ?
-               INVALID_SLOT : g.common.slot;
-}
-
-static inline moduleid_t geo_module(geoid_t g)
-{
-       return (g.common.type == GEO_TYPE_INVALID) ?
-               INVALID_MODULE : g.common.module;
-}
-
-extern geoid_t cnodeid_get_geoid(cnodeid_t cnode);
-
-#endif /* _ASM_IA64_SN_GEO_H */
index e0487aa..3885a77 100644 (file)
@@ -9,60 +9,7 @@
 #ifndef _ASM_IA64_SN_INTR_H
 #define _ASM_IA64_SN_INTR_H
 
-#include <linux/rcupdate.h>
-#include <asm/sn/types.h>
-
-#define SGI_UART_VECTOR                0xe9
-
-/* Reserved IRQs : Note, not to exceed IA64_SN2_FIRST_DEVICE_VECTOR */
 #define SGI_XPC_ACTIVATE       0x30
-#define SGI_II_ERROR           0x31
-#define SGI_XBOW_ERROR         0x32
-#define SGI_PCIASIC_ERROR      0x33
-#define SGI_ACPI_SCI_INT       0x34
-#define SGI_TIOCA_ERROR                0x35
-#define SGI_TIO_ERROR          0x36
-#define SGI_TIOCX_ERROR                0x37
-#define SGI_MMTIMER_VECTOR     0x38
 #define SGI_XPC_NOTIFY         0xe7
 
-#define IA64_SN2_FIRST_DEVICE_VECTOR   0x3c
-#define IA64_SN2_LAST_DEVICE_VECTOR    0xe6
-
-#define SN2_IRQ_RESERVED       0x1
-#define SN2_IRQ_CONNECTED      0x2
-#define SN2_IRQ_SHARED         0x4
-
-// The SN PROM irq struct
-struct sn_irq_info {
-       struct sn_irq_info *irq_next;   /* deprecated DO NOT USE     */
-       short           irq_nasid;      /* Nasid IRQ is assigned to  */
-       int             irq_slice;      /* slice IRQ is assigned to  */
-       int             irq_cpuid;      /* kernel logical cpuid      */
-       int             irq_irq;        /* the IRQ number */
-       int             irq_int_bit;    /* Bridge interrupt pin */
-                                       /* <0 means MSI */
-       u64     irq_xtalkaddr;  /* xtalkaddr IRQ is sent to  */
-       int             irq_bridge_type;/* pciio asic type (pciio.h) */
-       void           *irq_bridge;     /* bridge generating irq     */
-       void           *irq_pciioinfo;  /* associated pciio_info_t   */
-       int             irq_last_intr;  /* For Shub lb lost intr WAR */
-       int             irq_cookie;     /* unique cookie             */
-       int             irq_flags;      /* flags */
-       int             irq_share_cnt;  /* num devices sharing IRQ   */
-       struct list_head        list;   /* list of sn_irq_info structs */
-       struct rcu_head         rcu;    /* rcu callback list */
-};
-
-extern void sn_send_IPI_phys(int, long, int, int);
-extern u64 sn_intr_alloc(nasid_t, int,
-                             struct sn_irq_info *,
-                             int, nasid_t, int);
-extern void sn_intr_free(nasid_t, int, struct sn_irq_info *);
-extern struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *, nasid_t, int);
-extern void sn_set_err_irq_affinity(unsigned int);
-extern struct list_head **sn_irq_lh;
-
-#define CPU_VECTOR_TO_IRQ(cpuid,vector) (vector)
-
 #endif /* _ASM_IA64_SN_INTR_H */
diff --git a/arch/ia64/include/asm/sn/io.h b/arch/ia64/include/asm/sn/io.h
deleted file mode 100644 (file)
index 41c73a7..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_SN_IO_H
-#define _ASM_SN_IO_H
-#include <linux/compiler.h>
-#include <asm/intrinsics.h>
-
-extern void * sn_io_addr(unsigned long port) __attribute_const__; /* Forward definition */
-extern void __sn_mmiowb(void); /* Forward definition */
-
-extern int num_cnodes;
-
-#define __sn_mf_a()   ia64_mfa()
-
-extern void sn_dma_flush(unsigned long);
-
-#define __sn_inb ___sn_inb
-#define __sn_inw ___sn_inw
-#define __sn_inl ___sn_inl
-#define __sn_outb ___sn_outb
-#define __sn_outw ___sn_outw
-#define __sn_outl ___sn_outl
-#define __sn_readb ___sn_readb
-#define __sn_readw ___sn_readw
-#define __sn_readl ___sn_readl
-#define __sn_readq ___sn_readq
-#define __sn_readb_relaxed ___sn_readb_relaxed
-#define __sn_readw_relaxed ___sn_readw_relaxed
-#define __sn_readl_relaxed ___sn_readl_relaxed
-#define __sn_readq_relaxed ___sn_readq_relaxed
-
-/*
- * Convenience macros for setting/clearing bits using the above accessors
- */
-
-#define __sn_setq_relaxed(addr, val) \
-       writeq((__sn_readq_relaxed(addr) | (val)), (addr))
-#define __sn_clrq_relaxed(addr, val) \
-       writeq((__sn_readq_relaxed(addr) & ~(val)), (addr))
-
-/*
- * The following routines are SN Platform specific, called when
- * a reference is made to inX/outX set macros.  SN Platform
- * inX set of macros ensures that Posted DMA writes on the
- * Bridge is flushed.
- *
- * The routines should be self explainatory.
- */
-
-static inline unsigned int
-___sn_inb (unsigned long port)
-{
-       volatile unsigned char *addr;
-       unsigned char ret = -1;
-
-       if ((addr = sn_io_addr(port))) {
-               ret = *addr;
-               __sn_mf_a();
-               sn_dma_flush((unsigned long)addr);
-       }
-       return ret;
-}
-
-static inline unsigned int
-___sn_inw (unsigned long port)
-{
-       volatile unsigned short *addr;
-       unsigned short ret = -1;
-
-       if ((addr = sn_io_addr(port))) {
-               ret = *addr;
-               __sn_mf_a();
-               sn_dma_flush((unsigned long)addr);
-       }
-       return ret;
-}
-
-static inline unsigned int
-___sn_inl (unsigned long port)
-{
-       volatile unsigned int *addr;
-       unsigned int ret = -1;
-
-       if ((addr = sn_io_addr(port))) {
-               ret = *addr;
-               __sn_mf_a();
-               sn_dma_flush((unsigned long)addr);
-       }
-       return ret;
-}
-
-static inline void
-___sn_outb (unsigned char val, unsigned long port)
-{
-       volatile unsigned char *addr;
-
-       if ((addr = sn_io_addr(port))) {
-               *addr = val;
-               __sn_mmiowb();
-       }
-}
-
-static inline void
-___sn_outw (unsigned short val, unsigned long port)
-{
-       volatile unsigned short *addr;
-
-       if ((addr = sn_io_addr(port))) {
-               *addr = val;
-               __sn_mmiowb();
-       }
-}
-
-static inline void
-___sn_outl (unsigned int val, unsigned long port)
-{
-       volatile unsigned int *addr;
-
-       if ((addr = sn_io_addr(port))) {
-               *addr = val;
-               __sn_mmiowb();
-       }
-}
-
-/*
- * The following routines are SN Platform specific, called when 
- * a reference is made to readX/writeX set macros.  SN Platform 
- * readX set of macros ensures that Posted DMA writes on the 
- * Bridge is flushed.
- * 
- * The routines should be self explainatory.
- */
-
-static inline unsigned char
-___sn_readb (const volatile void __iomem *addr)
-{
-       unsigned char val;
-
-       val = *(volatile unsigned char __force *)addr;
-       __sn_mf_a();
-       sn_dma_flush((unsigned long)addr);
-        return val;
-}
-
-static inline unsigned short
-___sn_readw (const volatile void __iomem *addr)
-{
-       unsigned short val;
-
-       val = *(volatile unsigned short __force *)addr;
-       __sn_mf_a();
-       sn_dma_flush((unsigned long)addr);
-        return val;
-}
-
-static inline unsigned int
-___sn_readl (const volatile void __iomem *addr)
-{
-       unsigned int val;
-
-       val = *(volatile unsigned int __force *)addr;
-       __sn_mf_a();
-       sn_dma_flush((unsigned long)addr);
-        return val;
-}
-
-static inline unsigned long
-___sn_readq (const volatile void __iomem *addr)
-{
-       unsigned long val;
-
-       val = *(volatile unsigned long __force *)addr;
-       __sn_mf_a();
-       sn_dma_flush((unsigned long)addr);
-        return val;
-}
-
-/*
- * For generic and SN2 kernels, we have a set of fast access
- * PIO macros. These macros are provided on SN Platform
- * because the normal inX and readX macros perform an
- * additional task of flushing Post DMA request on the Bridge.
- *
- * These routines should be self explainatory.
- */
-
-static inline unsigned int
-sn_inb_fast (unsigned long port)
-{
-       volatile unsigned char *addr = (unsigned char *)port;
-       unsigned char ret;
-
-       ret = *addr;
-       __sn_mf_a();
-       return ret;
-}
-
-static inline unsigned int
-sn_inw_fast (unsigned long port)
-{
-       volatile unsigned short *addr = (unsigned short *)port;
-       unsigned short ret;
-
-       ret = *addr;
-       __sn_mf_a();
-       return ret;
-}
-
-static inline unsigned int
-sn_inl_fast (unsigned long port)
-{
-       volatile unsigned int *addr = (unsigned int *)port;
-       unsigned int ret;
-
-       ret = *addr;
-       __sn_mf_a();
-       return ret;
-}
-
-static inline unsigned char
-___sn_readb_relaxed (const volatile void __iomem *addr)
-{
-       return *(volatile unsigned char __force *)addr;
-}
-
-static inline unsigned short
-___sn_readw_relaxed (const volatile void __iomem *addr)
-{
-       return *(volatile unsigned short __force *)addr;
-}
-
-static inline unsigned int
-___sn_readl_relaxed (const volatile void __iomem *addr)
-{
-       return *(volatile unsigned int __force *) addr;
-}
-
-static inline unsigned long
-___sn_readq_relaxed (const volatile void __iomem *addr)
-{
-       return *(volatile unsigned long __force *) addr;
-}
-
-struct pci_dev;
-
-static inline int
-sn_pci_set_vchan(struct pci_dev *pci_dev, unsigned long *addr, int vchan)
-{
-
-       if (vchan > 1) {
-               return -1;
-       }
-
-       if (!(*addr >> 32))     /* Using a mask here would be cleaner */
-               return 0;       /* but this generates better code */
-
-       if (vchan == 1) {
-               /* Set Bit 57 */
-               *addr |= (1UL << 57);
-       } else {
-               /* Clear Bit 57 */
-               *addr &= ~(1UL << 57);
-       }
-
-       return 0;
-}
-
-#endif /* _ASM_SN_IO_H */
diff --git a/arch/ia64/include/asm/sn/ioc3.h b/arch/ia64/include/asm/sn/ioc3.h
deleted file mode 100644 (file)
index d4a5249..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2005 Silicon Graphics, Inc.
- */
-#ifndef IA64_SN_IOC3_H
-#define IA64_SN_IOC3_H
-
-/* serial port register map */
-struct ioc3_serialregs {
-       uint32_t sscr;
-       uint32_t stpir;
-       uint32_t stcir;
-       uint32_t srpir;
-       uint32_t srcir;
-       uint32_t srtr;
-       uint32_t shadow;
-};
-
-/* SUPERIO uart register map */
-struct ioc3_uartregs {
-       char iu_lcr;
-       union {
-               char iir;       /* read only */
-               char fcr;       /* write only */
-       } u3;
-       union {
-               char ier;       /* DLAB == 0 */
-               char dlm;       /* DLAB == 1 */
-       } u2;
-       union {
-               char rbr;       /* read only, DLAB == 0 */
-               char thr;       /* write only, DLAB == 0 */
-               char dll;       /* DLAB == 1 */
-       } u1;
-       char iu_scr;
-       char iu_msr;
-       char iu_lsr;
-       char iu_mcr;
-};
-
-#define iu_rbr u1.rbr
-#define iu_thr u1.thr
-#define iu_dll u1.dll
-#define iu_ier u2.ier
-#define iu_dlm u2.dlm
-#define iu_iir u3.iir
-#define iu_fcr u3.fcr
-
-struct ioc3_sioregs {
-       char fill[0x170];
-       struct ioc3_uartregs uartb;
-       struct ioc3_uartregs uarta;
-};
-
-/* PCI IO/mem space register map */
-struct ioc3 {
-       uint32_t pci_id;
-       uint32_t pci_scr;
-       uint32_t pci_rev;
-       uint32_t pci_lat;
-       uint32_t pci_addr;
-       uint32_t pci_err_addr_l;
-       uint32_t pci_err_addr_h;
-
-       uint32_t sio_ir;
-       /* these registers are read-only for general kernel code. To
-        * modify them use the functions in ioc3.c
-        */
-       uint32_t sio_ies;
-       uint32_t sio_iec;
-       uint32_t sio_cr;
-       uint32_t int_out;
-       uint32_t mcr;
-       uint32_t gpcr_s;
-       uint32_t gpcr_c;
-       uint32_t gpdr;
-       uint32_t gppr[9];
-       char fill[0x4c];
-
-       /* serial port registers */
-       uint32_t sbbr_h;
-       uint32_t sbbr_l;
-
-       struct ioc3_serialregs port_a;
-       struct ioc3_serialregs port_b;
-       char fill1[0x1ff10];
-       /* superio registers */
-       struct ioc3_sioregs sregs;
-};
-
-/* These don't exist on the ioc3 serial card... */
-#define eier   fill1[8]
-#define eisr   fill1[4]
-
-#define PCI_LAT                        0xc     /* Latency Timer */
-#define PCI_SCR_DROP_MODE_EN   0x00008000 /* drop pios on parity err */
-#define UARTA_BASE             0x178
-#define UARTB_BASE             0x170
-
-
-/* bitmasks for serial RX status byte */
-#define RXSB_OVERRUN           0x01    /* char(s) lost */
-#define RXSB_PAR_ERR           0x02    /* parity error */
-#define RXSB_FRAME_ERR         0x04    /* framing error */
-#define RXSB_BREAK             0x08    /* break character */
-#define RXSB_CTS               0x10    /* state of CTS */
-#define RXSB_DCD               0x20    /* state of DCD */
-#define RXSB_MODEM_VALID       0x40    /* DCD, CTS and OVERRUN are valid */
-#define RXSB_DATA_VALID                0x80    /* FRAME_ERR PAR_ERR & BREAK valid */
-
-/* bitmasks for serial TX control byte */
-#define TXCB_INT_WHEN_DONE     0x20    /* interrupt after this byte is sent */
-#define TXCB_INVALID           0x00    /* byte is invalid */
-#define TXCB_VALID             0x40    /* byte is valid */
-#define TXCB_MCR               0x80    /* data<7:0> to modem cntrl register */
-#define TXCB_DELAY             0xc0    /* delay data<7:0> mSec */
-
-/* bitmasks for SBBR_L */
-#define SBBR_L_SIZE            0x00000001      /* 0 1KB rings, 1 4KB rings */
-
-/* bitmasks for SSCR_<A:B> */
-#define SSCR_RX_THRESHOLD      0x000001ff      /* hiwater mark */
-#define SSCR_TX_TIMER_BUSY     0x00010000      /* TX timer in progress */
-#define SSCR_HFC_EN            0x00020000      /* h/w flow cntrl enabled */
-#define SSCR_RX_RING_DCD       0x00040000      /* postRX record on delta-DCD */
-#define SSCR_RX_RING_CTS       0x00080000      /* postRX record on delta-CTS */
-#define SSCR_HIGH_SPD          0x00100000      /* 4X speed */
-#define SSCR_DIAG              0x00200000      /* bypass clock divider */
-#define SSCR_RX_DRAIN          0x08000000      /* drain RX buffer to memory */
-#define SSCR_DMA_EN            0x10000000      /* enable ring buffer DMA */
-#define SSCR_DMA_PAUSE         0x20000000      /* pause DMA */
-#define SSCR_PAUSE_STATE       0x40000000      /* set when PAUSE takes effect*/
-#define SSCR_RESET             0x80000000      /* reset DMA channels */
-
-/* all producer/consumer pointers are the same bitfield */
-#define PROD_CONS_PTR_4K       0x00000ff8      /* for 4K buffers */
-#define PROD_CONS_PTR_1K       0x000003f8      /* for 1K buffers */
-#define PROD_CONS_PTR_OFF      3
-
-/* bitmasks for SRCIR_<A:B> */
-#define SRCIR_ARM              0x80000000      /* arm RX timer */
-
-/* bitmasks for SHADOW_<A:B> */
-#define SHADOW_DR              0x00000001      /* data ready */
-#define SHADOW_OE              0x00000002      /* overrun error */
-#define SHADOW_PE              0x00000004      /* parity error */
-#define SHADOW_FE              0x00000008      /* framing error */
-#define SHADOW_BI              0x00000010      /* break interrupt */
-#define SHADOW_THRE            0x00000020      /* transmit holding reg empty */
-#define SHADOW_TEMT            0x00000040      /* transmit shift reg empty */
-#define SHADOW_RFCE            0x00000080      /* char in RX fifo has error */
-#define SHADOW_DCTS            0x00010000      /* delta clear to send */
-#define SHADOW_DDCD            0x00080000      /* delta data carrier detect */
-#define SHADOW_CTS             0x00100000      /* clear to send */
-#define SHADOW_DCD             0x00800000      /* data carrier detect */
-#define SHADOW_DTR             0x01000000      /* data terminal ready */
-#define SHADOW_RTS             0x02000000      /* request to send */
-#define SHADOW_OUT1            0x04000000      /* 16550 OUT1 bit */
-#define SHADOW_OUT2            0x08000000      /* 16550 OUT2 bit */
-#define SHADOW_LOOP            0x10000000      /* loopback enabled */
-
-/* bitmasks for SRTR_<A:B> */
-#define SRTR_CNT               0x00000fff      /* reload value for RX timer */
-#define SRTR_CNT_VAL           0x0fff0000      /* current value of RX timer */
-#define SRTR_CNT_VAL_SHIFT     16
-#define SRTR_HZ                        16000           /* SRTR clock frequency */
-
-/* bitmasks for SIO_IR, SIO_IEC and SIO_IES  */
-#define SIO_IR_SA_TX_MT                0x00000001      /* Serial port A TX empty */
-#define SIO_IR_SA_RX_FULL      0x00000002      /* port A RX buf full */
-#define SIO_IR_SA_RX_HIGH      0x00000004      /* port A RX hiwat */
-#define SIO_IR_SA_RX_TIMER     0x00000008      /* port A RX timeout */
-#define SIO_IR_SA_DELTA_DCD    0x00000010      /* port A delta DCD */
-#define SIO_IR_SA_DELTA_CTS    0x00000020      /* port A delta CTS */
-#define SIO_IR_SA_INT          0x00000040      /* port A pass-thru intr */
-#define SIO_IR_SA_TX_EXPLICIT  0x00000080      /* port A explicit TX thru */
-#define SIO_IR_SA_MEMERR       0x00000100      /* port A PCI error */
-#define SIO_IR_SB_TX_MT                0x00000200
-#define SIO_IR_SB_RX_FULL      0x00000400
-#define SIO_IR_SB_RX_HIGH      0x00000800
-#define SIO_IR_SB_RX_TIMER     0x00001000
-#define SIO_IR_SB_DELTA_DCD    0x00002000
-#define SIO_IR_SB_DELTA_CTS    0x00004000
-#define SIO_IR_SB_INT          0x00008000
-#define SIO_IR_SB_TX_EXPLICIT  0x00010000
-#define SIO_IR_SB_MEMERR       0x00020000
-#define SIO_IR_PP_INT          0x00040000      /* P port pass-thru intr */
-#define SIO_IR_PP_INTA         0x00080000      /* PP context A thru */
-#define SIO_IR_PP_INTB         0x00100000      /* PP context B thru */
-#define SIO_IR_PP_MEMERR       0x00200000      /* PP PCI error */
-#define SIO_IR_KBD_INT         0x00400000      /* kbd/mouse intr */
-#define SIO_IR_RT_INT          0x08000000      /* RT output pulse */
-#define SIO_IR_GEN_INT1                0x10000000      /* RT input pulse */
-#define SIO_IR_GEN_INT_SHIFT   28
-
-/* per device interrupt masks */
-#define SIO_IR_SA              (SIO_IR_SA_TX_MT | \
-                                SIO_IR_SA_RX_FULL | \
-                                SIO_IR_SA_RX_HIGH | \
-                                SIO_IR_SA_RX_TIMER | \
-                                SIO_IR_SA_DELTA_DCD | \
-                                SIO_IR_SA_DELTA_CTS | \
-                                SIO_IR_SA_INT | \
-                                SIO_IR_SA_TX_EXPLICIT | \
-                                SIO_IR_SA_MEMERR)
-
-#define SIO_IR_SB              (SIO_IR_SB_TX_MT | \
-                                SIO_IR_SB_RX_FULL | \
-                                SIO_IR_SB_RX_HIGH | \
-                                SIO_IR_SB_RX_TIMER | \
-                                SIO_IR_SB_DELTA_DCD | \
-                                SIO_IR_SB_DELTA_CTS | \
-                                SIO_IR_SB_INT | \
-                                SIO_IR_SB_TX_EXPLICIT | \
-                                SIO_IR_SB_MEMERR)
-
-#define SIO_IR_PP              (SIO_IR_PP_INT | SIO_IR_PP_INTA | \
-                                SIO_IR_PP_INTB | SIO_IR_PP_MEMERR)
-#define SIO_IR_RT              (SIO_IR_RT_INT | SIO_IR_GEN_INT1)
-
-/* bitmasks for SIO_CR */
-#define SIO_CR_CMD_PULSE_SHIFT 15
-#define SIO_CR_SER_A_BASE_SHIFT 1
-#define SIO_CR_SER_B_BASE_SHIFT 8
-#define SIO_CR_ARB_DIAG                0x00380000      /* cur !enet PCI requet (ro) */
-#define SIO_CR_ARB_DIAG_TXA    0x00000000
-#define SIO_CR_ARB_DIAG_RXA    0x00080000
-#define SIO_CR_ARB_DIAG_TXB    0x00100000
-#define SIO_CR_ARB_DIAG_RXB    0x00180000
-#define SIO_CR_ARB_DIAG_PP     0x00200000
-#define SIO_CR_ARB_DIAG_IDLE   0x00400000      /* 0 -> active request (ro) */
-
-/* defs for some of the generic I/O pins */
-#define GPCR_PHY_RESET         0x20    /* pin is output to PHY reset */
-#define GPCR_UARTB_MODESEL     0x40    /* pin is output to port B mode sel */
-#define GPCR_UARTA_MODESEL     0x80    /* pin is output to port A mode sel */
-
-#define GPPR_PHY_RESET_PIN     5       /* GIO pin controlling phy reset */
-#define GPPR_UARTB_MODESEL_PIN 6       /* GIO pin cntrling uartb modeselect */
-#define GPPR_UARTA_MODESEL_PIN 7       /* GIO pin cntrling uarta modeselect */
-
-#endif /* IA64_SN_IOC3_H */
diff --git a/arch/ia64/include/asm/sn/klconfig.h b/arch/ia64/include/asm/sn/klconfig.h
deleted file mode 100644 (file)
index bcbf209..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Derived from IRIX <sys/SN/klconfig.h>.
- *
- * Copyright (C) 1992-1997,1999,2001-2004 Silicon Graphics, Inc.  All Rights Reserved.
- * Copyright (C) 1999 by Ralf Baechle
- */
-#ifndef _ASM_IA64_SN_KLCONFIG_H
-#define _ASM_IA64_SN_KLCONFIG_H
-
-/*
- * The KLCONFIG structures store info about the various BOARDs found
- * during Hardware Discovery. In addition, it stores info about the
- * components found on the BOARDs.
- */
-
-typedef s32 klconf_off_t;
-
-
-/* Functions/macros needed to use this structure */
-
-typedef struct kl_config_hdr {
-       char            pad[20];
-       klconf_off_t    ch_board_info;  /* the link list of boards */
-       char            pad0[88];
-} kl_config_hdr_t;
-
-
-#define NODE_OFFSET_TO_LBOARD(nasid,off)        (lboard_t*)(GLOBAL_CAC_ADDR((nasid), (off)))
-
-/*
- * The KLCONFIG area is organized as a LINKED LIST of BOARDs. A BOARD
- * can be either 'LOCAL' or 'REMOTE'. LOCAL means it is attached to 
- * the LOCAL/current NODE. REMOTE means it is attached to a different
- * node.(TBD - Need a way to treat ROUTER boards.)
- *
- * There are 2 different structures to represent these boards -
- * lboard - Local board, rboard - remote board. These 2 structures
- * can be arbitrarily mixed in the LINKED LIST of BOARDs. (Refer
- * Figure below). The first byte of the rboard or lboard structure
- * is used to find out its type - no unions are used.
- * If it is a lboard, then the config info of this board will be found
- * on the local node. (LOCAL NODE BASE + offset value gives pointer to 
- * the structure.
- * If it is a rboard, the local structure contains the node number
- * and the offset of the beginning of the LINKED LIST on the remote node.
- * The details of the hardware on a remote node can be built locally,
- * if required, by reading the LINKED LIST on the remote node and 
- * ignoring all the rboards on that node.
- *
- * The local node uses the REMOTE NODE NUMBER + OFFSET to point to the 
- * First board info on the remote node. The remote node list is 
- * traversed as the local list, using the REMOTE BASE ADDRESS and not
- * the local base address and ignoring all rboard values.
- *
- * 
- KLCONFIG
-
- +------------+      +------------+      +------------+      +------------+
- |  lboard    |  +-->|   lboard   |  +-->|   rboard   |  +-->|   lboard   |
- +------------+  |   +------------+  |   +------------+  |   +------------+
- | board info |  |   | board info |  |   |errinfo,bptr|  |   | board info |
- +------------+  |   +------------+  |   +------------+  |   +------------+
- | offset     |--+   |  offset    |--+   |  offset    |--+   |offset=NULL |
- +------------+      +------------+      +------------+      +------------+
-
-
- +------------+
- | board info |
- +------------+       +--------------------------------+
- | compt 1    |------>| type, rev, diaginfo, size ...  |  (CPU)
- +------------+       +--------------------------------+
- | compt 2    |--+
- +------------+  |    +--------------------------------+
- |  ...       |  +--->| type, rev, diaginfo, size ...  |  (MEM_BANK)
- +------------+       +--------------------------------+
- | errinfo    |--+
- +------------+  |    +--------------------------------+
-                 +--->|r/l brd errinfo,compt err flags |
-                      +--------------------------------+
-
- *
- * Each BOARD consists of COMPONENTs and the BOARD structure has 
- * pointers (offsets) to its COMPONENT structure.
- * The COMPONENT structure has version info, size and speed info, revision,
- * error info and the NIC info. This structure can accommodate any
- * BOARD with arbitrary COMPONENT composition.
- *
- * The ERRORINFO part of each BOARD has error information
- * that describes errors about the BOARD itself. It also has flags to
- * indicate the COMPONENT(s) on the board that have errors. The error 
- * information specific to the COMPONENT is present in the respective 
- * COMPONENT structure.
- *
- * The ERRORINFO structure is also treated like a COMPONENT, ie. the 
- * BOARD has pointers(offset) to the ERRORINFO structure. The rboard
- * structure also has a pointer to the ERRORINFO structure. This is 
- * the place to store ERRORINFO about a REMOTE NODE, if the HUB on
- * that NODE is not working or if the REMOTE MEMORY is BAD. In cases where 
- * only the CPU of the REMOTE NODE is disabled, the ERRORINFO pointer can
- * be a NODE NUMBER, REMOTE OFFSET combination, pointing to error info 
- * which is present on the REMOTE NODE.(TBD)
- * REMOTE ERRINFO can be stored on any of the nearest nodes 
- * or on all the nearest nodes.(TBD)
- * Like BOARD structures, REMOTE ERRINFO structures can be built locally
- * using the rboard errinfo pointer.
- *
- * In order to get useful information from this Data organization, a set of
- * interface routines are provided (TBD). The important thing to remember while
- * manipulating the structures, is that, the NODE number information should
- * be used. If the NODE is non-zero (remote) then each offset should
- * be added to the REMOTE BASE ADDR else it should be added to the LOCAL BASE ADDR. 
- * This includes offsets for BOARDS, COMPONENTS and ERRORINFO.
- * 
- * Note that these structures do not provide much info about connectivity.
- * That info will be part of HWGRAPH, which is an extension of the cfg_t
- * data structure. (ref IP27prom/cfg.h) It has to be extended to include
- * the IO part of the Network(TBD).
- *
- * The data structures below define the above concepts.
- */
-
-
-/*
- * BOARD classes
- */
-
-#define KLCLASS_MASK   0xf0   
-#define KLCLASS_NONE   0x00
-#define KLCLASS_NODE   0x10             /* CPU, Memory and HUB board */
-#define KLCLASS_CPU    KLCLASS_NODE    
-#define KLCLASS_IO     0x20             /* BaseIO, 4 ch SCSI, ethernet, FDDI 
-                                           and the non-graphics widget boards */
-#define KLCLASS_ROUTER 0x30             /* Router board */
-#define KLCLASS_MIDPLANE 0x40            /* We need to treat this as a board
-                                            so that we can record error info */
-#define KLCLASS_IOBRICK        0x70            /* IP35 iobrick */
-#define KLCLASS_MAX    8               /* Bump this if a new CLASS is added */
-
-#define KLCLASS(_x) ((_x) & KLCLASS_MASK)
-
-
-/*
- * board types
- */
-
-#define KLTYPE_MASK    0x0f
-#define KLTYPE(_x)      ((_x) & KLTYPE_MASK)
-
-#define KLTYPE_SNIA    (KLCLASS_CPU | 0x1)
-#define KLTYPE_TIO     (KLCLASS_CPU | 0x2)
-
-#define KLTYPE_ROUTER     (KLCLASS_ROUTER | 0x1)
-#define KLTYPE_META_ROUTER (KLCLASS_ROUTER | 0x3)
-#define KLTYPE_REPEATER_ROUTER (KLCLASS_ROUTER | 0x4)
-
-#define KLTYPE_IOBRICK_XBOW    (KLCLASS_MIDPLANE | 0x2)
-
-#define KLTYPE_IOBRICK         (KLCLASS_IOBRICK | 0x0)
-#define KLTYPE_NBRICK          (KLCLASS_IOBRICK | 0x4)
-#define KLTYPE_PXBRICK         (KLCLASS_IOBRICK | 0x6)
-#define KLTYPE_IXBRICK         (KLCLASS_IOBRICK | 0x7)
-#define KLTYPE_CGBRICK         (KLCLASS_IOBRICK | 0x8)
-#define KLTYPE_OPUSBRICK       (KLCLASS_IOBRICK | 0x9)
-#define KLTYPE_SABRICK          (KLCLASS_IOBRICK | 0xa)
-#define KLTYPE_IABRICK         (KLCLASS_IOBRICK | 0xb)
-#define KLTYPE_PABRICK          (KLCLASS_IOBRICK | 0xc)
-#define KLTYPE_GABRICK         (KLCLASS_IOBRICK | 0xd)
-
-
-/* 
- * board structures
- */
-
-#define MAX_COMPTS_PER_BRD 24
-
-typedef struct lboard_s {
-       klconf_off_t    brd_next_any;     /* Next BOARD */
-       unsigned char   struct_type;      /* type of structure, local or remote */
-       unsigned char   brd_type;         /* type+class */
-       unsigned char   brd_sversion;     /* version of this structure */
-        unsigned char  brd_brevision;    /* board revision */
-        unsigned char  brd_promver;      /* board prom version, if any */
-       unsigned char   brd_flags;        /* Enabled, Disabled etc */
-       unsigned char   brd_slot;         /* slot number */
-       unsigned short  brd_debugsw;      /* Debug switches */
-       geoid_t         brd_geoid;        /* geo id */
-       partid_t        brd_partition;    /* Partition number */
-        unsigned short         brd_diagval;      /* diagnostic value */
-        unsigned short         brd_diagparm;     /* diagnostic parameter */
-        unsigned char  brd_inventory;    /* inventory history */
-        unsigned char  brd_numcompts;    /* Number of components */
-        nic_t          brd_nic;          /* Number in CAN */
-       nasid_t         brd_nasid;        /* passed parameter */
-       klconf_off_t    brd_compts[MAX_COMPTS_PER_BRD]; /* pointers to COMPONENTS */
-       klconf_off_t    brd_errinfo;      /* Board's error information */
-       struct lboard_s *brd_parent;      /* Logical parent for this brd */
-       char            pad0[4];
-       unsigned char   brd_confidence;   /* confidence that the board is bad */
-       nasid_t         brd_owner;        /* who owns this board */
-       unsigned char   brd_nic_flags;    /* To handle 8 more NICs */
-       char            pad1[24];         /* future expansion */
-       char            brd_name[32];
-       nasid_t         brd_next_same_host; /* host of next brd w/same nasid */
-       klconf_off_t    brd_next_same;    /* Next BOARD with same nasid */
-} lboard_t;
-
-/*
- * Generic info structure. This stores common info about a 
- * component.
- */
-typedef struct klinfo_s {                  /* Generic info */
-        unsigned char   struct_type;       /* type of this structure */
-        unsigned char   struct_version;    /* version of this structure */
-        unsigned char   flags;            /* Enabled, disabled etc */
-        unsigned char   revision;         /* component revision */
-        unsigned short  diagval;          /* result of diagnostics */
-        unsigned short  diagparm;         /* diagnostic parameter */
-        unsigned char   inventory;        /* previous inventory status */
-        unsigned short  partid;                   /* widget part number */
-       nic_t           nic;              /* MUst be aligned properly */
-        unsigned char   physid;           /* physical id of component */
-        unsigned int    virtid;           /* virtual id as seen by system */
-       unsigned char   widid;            /* Widget id - if applicable */
-       nasid_t         nasid;            /* node number - from parent */
-       char            pad1;             /* pad out structure. */
-       char            pad2;             /* pad out structure. */
-       void            *data;
-        klconf_off_t   errinfo;          /* component specific errors */
-        unsigned short  pad3;             /* pci fields have moved over to */
-        unsigned short  pad4;             /* klbri_t */
-} klinfo_t ;
-
-
-static inline lboard_t *find_lboard_next(lboard_t * brd)
-{
-       if (brd && brd->brd_next_any)
-               return NODE_OFFSET_TO_LBOARD(NASID_GET(brd), brd->brd_next_any);
-        return NULL;
-}
-
-#endif /* _ASM_IA64_SN_KLCONFIG_H */
diff --git a/arch/ia64/include/asm/sn/l1.h b/arch/ia64/include/asm/sn/l1.h
deleted file mode 100644 (file)
index 344bf44..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#ifndef _ASM_IA64_SN_L1_H
-#define _ASM_IA64_SN_L1_H
-
-/* brick type response codes */
-#define L1_BRICKTYPE_PX         0x23            /* # */
-#define L1_BRICKTYPE_PE         0x25            /* % */
-#define L1_BRICKTYPE_N_p0       0x26            /* & */
-#define L1_BRICKTYPE_IP45       0x34            /* 4 */
-#define L1_BRICKTYPE_IP41       0x35            /* 5 */
-#define L1_BRICKTYPE_TWISTER    0x36            /* 6 */ /* IP53 & ROUTER */
-#define L1_BRICKTYPE_IX         0x3d            /* = */
-#define L1_BRICKTYPE_IP34       0x61            /* a */
-#define L1_BRICKTYPE_GA                0x62            /* b */
-#define L1_BRICKTYPE_C          0x63            /* c */
-#define L1_BRICKTYPE_OPUS_TIO  0x66            /* f */
-#define L1_BRICKTYPE_I          0x69            /* i */
-#define L1_BRICKTYPE_N          0x6e            /* n */
-#define L1_BRICKTYPE_OPUS       0x6f           /* o */
-#define L1_BRICKTYPE_P          0x70            /* p */
-#define L1_BRICKTYPE_R          0x72            /* r */
-#define L1_BRICKTYPE_CHI_CG     0x76            /* v */
-#define L1_BRICKTYPE_X          0x78            /* x */
-#define L1_BRICKTYPE_X2         0x79            /* y */
-#define L1_BRICKTYPE_SA                0x5e            /* ^ */
-#define L1_BRICKTYPE_PA                0x6a            /* j */
-#define L1_BRICKTYPE_IA                0x6b            /* k */
-#define L1_BRICKTYPE_ATHENA    0x2b            /* + */
-#define L1_BRICKTYPE_DAYTONA   0x7a            /* z */
-#define L1_BRICKTYPE_1932      0x2c            /* . */
-#define L1_BRICKTYPE_191010    0x2e            /* , */
-
-/* board type response codes */
-#define L1_BOARDTYPE_IP69       0x0100          /* CA */
-#define L1_BOARDTYPE_IP63       0x0200          /* CB */
-#define L1_BOARDTYPE_BASEIO     0x0300          /* IB */
-#define L1_BOARDTYPE_PCIE2SLOT  0x0400          /* IC */
-#define L1_BOARDTYPE_PCIX3SLOT  0x0500          /* ID */
-#define L1_BOARDTYPE_PCIXPCIE4SLOT 0x0600       /* IE */
-#define L1_BOARDTYPE_ABACUS     0x0700          /* AB */
-#define L1_BOARDTYPE_DAYTONA    0x0800          /* AD */
-#define L1_BOARDTYPE_INVAL      (-1)            /* invalid brick type */
-
-#endif /* _ASM_IA64_SN_L1_H */
diff --git a/arch/ia64/include/asm/sn/leds.h b/arch/ia64/include/asm/sn/leds.h
deleted file mode 100644 (file)
index 66cf8c4..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_LEDS_H
-#define _ASM_IA64_SN_LEDS_H
-
-#include <asm/sn/addrs.h>
-#include <asm/sn/pda.h>
-#include <asm/sn/shub_mmr.h>
-
-#define LED0           (LOCAL_MMR_ADDR(SH_REAL_JUNK_BUS_LED0))
-#define LED_CPU_SHIFT  16
-
-#define LED_CPU_HEARTBEAT      0x01
-#define LED_CPU_ACTIVITY       0x02
-#define LED_ALWAYS_SET         0x00
-
-/*
- * Basic macros for flashing the LEDS on an SGI SN.
- */
-
-static __inline__ void
-set_led_bits(u8 value, u8 mask)
-{
-       pda->led_state = (pda->led_state & ~mask) | (value & mask);
-       *pda->led_address = (short) pda->led_state;
-}
-
-#endif /* _ASM_IA64_SN_LEDS_H */
-
diff --git a/arch/ia64/include/asm/sn/module.h b/arch/ia64/include/asm/sn/module.h
deleted file mode 100644 (file)
index 734e980..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2004 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_MODULE_H
-#define _ASM_IA64_SN_MODULE_H
-
-/* parameter for format_module_id() */
-#define MODULE_FORMAT_BRIEF    1
-#define MODULE_FORMAT_LONG     2
-#define MODULE_FORMAT_LCD      3
-
-/*
- *     Module id format
- *
- *     31-16   Rack ID (encoded class, group, number - 16-bit unsigned int)
- *      15-8   Brick type (8-bit ascii character)
- *       7-0   Bay (brick position in rack (0-63) - 8-bit unsigned int)
- *
- */
-
-/*
- * Macros for getting the brick type
- */
-#define MODULE_BTYPE_MASK      0xff00
-#define MODULE_BTYPE_SHFT      8
-#define MODULE_GET_BTYPE(_m)   (((_m) & MODULE_BTYPE_MASK) >> MODULE_BTYPE_SHFT)
-#define MODULE_BT_TO_CHAR(_b)  ((char)(_b))
-#define MODULE_GET_BTCHAR(_m)  (MODULE_BT_TO_CHAR(MODULE_GET_BTYPE(_m)))
-
-/*
- * Macros for getting the rack ID.
- */
-#define MODULE_RACK_MASK       0xffff0000
-#define MODULE_RACK_SHFT       16
-#define MODULE_GET_RACK(_m)    (((_m) & MODULE_RACK_MASK) >> MODULE_RACK_SHFT)
-
-/*
- * Macros for getting the brick position
- */
-#define MODULE_BPOS_MASK       0x00ff
-#define MODULE_BPOS_SHFT       0
-#define MODULE_GET_BPOS(_m)    (((_m) & MODULE_BPOS_MASK) >> MODULE_BPOS_SHFT)
-
-/*
- * Macros for encoding and decoding rack IDs
- * A rack number consists of three parts:
- *   class (0==CPU/mixed, 1==I/O), group, number
- *
- * Rack number is stored just as it is displayed on the screen:
- * a 3-decimal-digit number.
- */
-#define RACK_CLASS_DVDR         100
-#define RACK_GROUP_DVDR         10
-#define RACK_NUM_DVDR           1
-
-#define RACK_CREATE_RACKID(_c, _g, _n)  ((_c) * RACK_CLASS_DVDR +       \
-        (_g) * RACK_GROUP_DVDR + (_n) * RACK_NUM_DVDR)
-
-#define RACK_GET_CLASS(_r)              ((_r) / RACK_CLASS_DVDR)
-#define RACK_GET_GROUP(_r)              (((_r) - RACK_GET_CLASS(_r) *   \
-            RACK_CLASS_DVDR) / RACK_GROUP_DVDR)
-#define RACK_GET_NUM(_r)                (((_r) - RACK_GET_CLASS(_r) *   \
-            RACK_CLASS_DVDR - RACK_GET_GROUP(_r) *      \
-            RACK_GROUP_DVDR) / RACK_NUM_DVDR)
-
-/*
- * Macros for encoding and decoding rack IDs
- * A rack number consists of three parts:
- *   class      1 bit, 0==CPU/mixed, 1==I/O
- *   group      2 bits for CPU/mixed, 3 bits for I/O
- *   number     3 bits for CPU/mixed, 2 bits for I/O (1 based)
- */
-#define RACK_GROUP_BITS(_r)     (RACK_GET_CLASS(_r) ? 3 : 2)
-#define RACK_NUM_BITS(_r)       (RACK_GET_CLASS(_r) ? 2 : 3)
-
-#define RACK_CLASS_MASK(_r)     0x20
-#define RACK_CLASS_SHFT(_r)     5
-#define RACK_ADD_CLASS(_r, _c)  \
-        ((_r) |= (_c) << RACK_CLASS_SHFT(_r) & RACK_CLASS_MASK(_r))
-
-#define RACK_GROUP_SHFT(_r)     RACK_NUM_BITS(_r)
-#define RACK_GROUP_MASK(_r)     \
-        ( (((unsigned)1<<RACK_GROUP_BITS(_r)) - 1) << RACK_GROUP_SHFT(_r) )
-#define RACK_ADD_GROUP(_r, _g)  \
-        ((_r) |= (_g) << RACK_GROUP_SHFT(_r) & RACK_GROUP_MASK(_r))
-
-#define RACK_NUM_SHFT(_r)       0
-#define RACK_NUM_MASK(_r)       \
-        ( (((unsigned)1<<RACK_NUM_BITS(_r)) - 1) << RACK_NUM_SHFT(_r) )
-#define RACK_ADD_NUM(_r, _n)    \
-        ((_r) |= ((_n) - 1) << RACK_NUM_SHFT(_r) & RACK_NUM_MASK(_r))
-
-
-/*
- * Brick type definitions
- */
-#define MAX_BRICK_TYPES         256 /* brick type is stored as uchar */
-
-extern char brick_types[];
-
-#define MODULE_CBRICK           0
-#define MODULE_RBRICK           1
-#define MODULE_IBRICK           2
-#define MODULE_KBRICK           3
-#define MODULE_XBRICK           4
-#define MODULE_DBRICK           5
-#define MODULE_PBRICK           6
-#define MODULE_NBRICK           7
-#define MODULE_PEBRICK          8
-#define MODULE_PXBRICK          9
-#define MODULE_IXBRICK          10
-#define MODULE_CGBRICK         11
-#define MODULE_OPUSBRICK        12
-#define MODULE_SABRICK         13      /* TIO BringUp Brick */
-#define MODULE_IABRICK         14
-#define MODULE_PABRICK         15
-#define MODULE_GABRICK         16
-#define MODULE_OPUS_TIO                17      /* OPUS TIO Riser */
-
-extern char brick_types[];
-extern void format_module_id(char *, moduleid_t, int);
-
-#endif /* _ASM_IA64_SN_MODULE_H */
diff --git a/arch/ia64/include/asm/sn/mspec.h b/arch/ia64/include/asm/sn/mspec.h
deleted file mode 100644 (file)
index c1d3c50..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2001-2008 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_MSPEC_H
-#define _ASM_IA64_SN_MSPEC_H
-
-#define FETCHOP_VAR_SIZE 64 /* 64 byte per fetchop variable */
-
-#define FETCHOP_LOAD           0
-#define FETCHOP_INCREMENT      8
-#define FETCHOP_DECREMENT      16
-#define FETCHOP_CLEAR          24
-
-#define FETCHOP_STORE          0
-#define FETCHOP_AND            24
-#define FETCHOP_OR             32
-
-#define FETCHOP_CLEAR_CACHE    56
-
-#define FETCHOP_LOAD_OP(addr, op) ( \
-         *(volatile long *)((char*) (addr) + (op)))
-
-#define FETCHOP_STORE_OP(addr, op, x) ( \
-         *(volatile long *)((char*) (addr) + (op)) = (long) (x))
-
-#ifdef __KERNEL__
-
-/*
- * Each Atomic Memory Operation (amo, formerly known as fetchop)
- * variable is 64 bytes long.  The first 8 bytes are used.  The
- * remaining 56 bytes are unaddressable due to the operation taking
- * that portion of the address.
- *
- * NOTE: The amo structure _MUST_ be placed in either the first or second
- * half of the cache line.  The cache line _MUST NOT_ be used for anything
- * other than additional amo entries.  This is because there are two
- * addresses which reference the same physical cache line.  One will
- * be a cached entry with the memory type bits all set.  This address
- * may be loaded into processor cache.  The amo will be referenced
- * uncached via the memory special memory type.  If any portion of the
- * cached cache-line is modified, when that line is flushed, it will
- * overwrite the uncached value in physical memory and lead to
- * inconsistency.
- */
-struct amo {
-        u64 variable;
-        u64 unused[7];
-};
-
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_IA64_SN_MSPEC_H */
diff --git a/arch/ia64/include/asm/sn/nodepda.h b/arch/ia64/include/asm/sn/nodepda.h
deleted file mode 100644 (file)
index 7c8b471..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_NODEPDA_H
-#define _ASM_IA64_SN_NODEPDA_H
-
-
-#include <asm/irq.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/bte.h>
-
-/*
- * NUMA Node-Specific Data structures are defined in this file.
- * In particular, this is the location of the node PDA.
- * A pointer to the right node PDA is saved in each CPU PDA.
- */
-
-/*
- * Node-specific data structure.
- *
- * One of these structures is allocated on each node of a NUMA system.
- *
- * This structure provides a convenient way of keeping together 
- * all per-node data structures. 
- */
-struct phys_cpuid {
-       short                   nasid;
-       char                    subnode;
-       char                    slice;
-};
-
-struct nodepda_s {
-       void            *pdinfo;        /* Platform-dependent per-node info */
-
-       /*
-        * The BTEs on this node are shared by the local cpus
-        */
-       struct bteinfo_s        bte_if[MAX_BTES_PER_NODE];      /* Virtual Interface */
-       struct timer_list       bte_recovery_timer;
-       spinlock_t              bte_recovery_lock;
-
-       /* 
-        * Array of pointers to the nodepdas for each node.
-        */
-       struct nodepda_s        *pernode_pdaindr[MAX_COMPACT_NODES]; 
-
-       /*
-        * Array of physical cpu identifiers. Indexed by cpuid.
-        */
-       struct phys_cpuid       phys_cpuid[NR_CPUS];
-       spinlock_t              ptc_lock ____cacheline_aligned_in_smp;
-};
-
-typedef struct nodepda_s nodepda_t;
-
-/*
- * Access Functions for node PDA.
- * Since there is one nodepda for each node, we need a convenient mechanism
- * to access these nodepdas without cluttering code with #ifdefs.
- * The next set of definitions provides this.
- * Routines are expected to use 
- *
- *     sn_nodepda   - to access node PDA for the node on which code is running
- *     NODEPDA(cnodeid)   - to access node PDA for cnodeid
- */
-
-DECLARE_PER_CPU(struct nodepda_s *, __sn_nodepda);
-#define sn_nodepda             __this_cpu_read(__sn_nodepda)
-#define        NODEPDA(cnodeid)        (sn_nodepda->pernode_pdaindr[cnodeid])
-
-/*
- * Check if given a compact node id the corresponding node has all the
- * cpus disabled. 
- */
-#define is_headless_node(cnodeid)      (nr_cpus_node(cnodeid) == 0)
-
-#endif /* _ASM_IA64_SN_NODEPDA_H */
diff --git a/arch/ia64/include/asm/sn/pcibr_provider.h b/arch/ia64/include/asm/sn/pcibr_provider.h
deleted file mode 100644 (file)
index da205b7..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2006 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H
-#define _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H
-
-#include <asm/sn/intr.h>
-#include <asm/sn/pcibus_provider_defs.h>
-
-/* Workarounds */
-#define PV907516 (1 << 1) /* TIOCP: Don't write the write buffer flush reg */
-
-#define BUSTYPE_MASK                    0x1
-
-/* Macros given a pcibus structure */
-#define IS_PCIX(ps)     ((ps)->pbi_bridge_mode & BUSTYPE_MASK)
-#define IS_PCI_BRIDGE_ASIC(asic) (asic == PCIIO_ASIC_TYPE_PIC || \
-                asic == PCIIO_ASIC_TYPE_TIOCP)
-#define IS_PIC_SOFT(ps)     (ps->pbi_bridge_type == PCIBR_BRIDGETYPE_PIC)
-#define IS_TIOCP_SOFT(ps)   (ps->pbi_bridge_type == PCIBR_BRIDGETYPE_TIOCP)
-
-
-/*
- * The different PCI Bridge types supported on the SGI Altix platforms
- */
-#define PCIBR_BRIDGETYPE_UNKNOWN       -1
-#define PCIBR_BRIDGETYPE_PIC            2
-#define PCIBR_BRIDGETYPE_TIOCP          3
-
-/*
- * Bridge 64bit Direct Map Attributes
- */
-#define PCI64_ATTR_PREF                 (1ull << 59)
-#define PCI64_ATTR_PREC                 (1ull << 58)
-#define PCI64_ATTR_VIRTUAL              (1ull << 57)
-#define PCI64_ATTR_BAR                  (1ull << 56)
-#define PCI64_ATTR_SWAP                 (1ull << 55)
-#define PCI64_ATTR_VIRTUAL1             (1ull << 54)
-
-#define PCI32_LOCAL_BASE                0
-#define PCI32_MAPPED_BASE               0x40000000
-#define PCI32_DIRECT_BASE               0x80000000
-
-#define IS_PCI32_MAPPED(x)              ((u64)(x) < PCI32_DIRECT_BASE && \
-                                         (u64)(x) >= PCI32_MAPPED_BASE)
-#define IS_PCI32_DIRECT(x)              ((u64)(x) >= PCI32_MAPPED_BASE)
-
-
-/*
- * Bridge PMU Address Transaltion Entry Attibutes
- */
-#define PCI32_ATE_V                     (0x1 << 0)
-#define PCI32_ATE_CO                    (0x1 << 1)     /* PIC ASIC ONLY */
-#define PCI32_ATE_PIO                   (0x1 << 1)     /* TIOCP ASIC ONLY */
-#define PCI32_ATE_MSI                   (0x1 << 2)
-#define PCI32_ATE_PREF                  (0x1 << 3)
-#define PCI32_ATE_BAR                   (0x1 << 4)
-#define PCI32_ATE_ADDR_SHFT             12
-
-#define MINIMAL_ATES_REQUIRED(addr, size) \
-       (IOPG(IOPGOFF(addr) + (size) - 1) == IOPG((size) - 1))
-
-#define MINIMAL_ATE_FLAG(addr, size) \
-       (MINIMAL_ATES_REQUIRED((u64)addr, size) ? 1 : 0)
-
-/* bit 29 of the pci address is the SWAP bit */
-#define ATE_SWAPSHIFT                   29
-#define ATE_SWAP_ON(x)                  ((x) |= (1 << ATE_SWAPSHIFT))
-#define ATE_SWAP_OFF(x)                 ((x) &= ~(1 << ATE_SWAPSHIFT))
-
-/*
- * I/O page size
- */
-#if PAGE_SIZE < 16384
-#define IOPFNSHIFT                      12      /* 4K per mapped page */
-#else
-#define IOPFNSHIFT                      14      /* 16K per mapped page */
-#endif
-
-#define IOPGSIZE                        (1 << IOPFNSHIFT)
-#define IOPG(x)                         ((x) >> IOPFNSHIFT)
-#define IOPGOFF(x)                      ((x) & (IOPGSIZE-1))
-
-#define PCIBR_DEV_SWAP_DIR              (1ull << 19)
-#define PCIBR_CTRL_PAGE_SIZE            (0x1 << 21)
-
-/*
- * PMU resources.
- */
-struct ate_resource{
-       u64 *ate;
-       u64 num_ate;
-       u64 lowest_free_index;
-};
-
-struct pcibus_info {
-       struct pcibus_bussoft   pbi_buscommon;   /* common header */
-       u32                pbi_moduleid;
-       short                   pbi_bridge_type;
-       short                   pbi_bridge_mode;
-
-       struct ate_resource     pbi_int_ate_resource;
-       u64                pbi_int_ate_size;
-
-       u64                pbi_dir_xbase;
-       char                    pbi_hub_xid;
-
-       u64                pbi_devreg[8];
-
-       u32             pbi_valid_devices;
-       u32             pbi_enabled_devices;
-
-       spinlock_t              pbi_lock;
-};
-
-extern int  pcibr_init_provider(void);
-extern void *pcibr_bus_fixup(struct pcibus_bussoft *, struct pci_controller *);
-extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t, int type);
-extern dma_addr_t pcibr_dma_map_consistent(struct pci_dev *, unsigned long, size_t, int type);
-extern void pcibr_dma_unmap(struct pci_dev *, dma_addr_t, int);
-
-/*
- * prototypes for the bridge asic register access routines in pcibr_reg.c
- */
-extern void             pcireg_control_bit_clr(struct pcibus_info *, u64);
-extern void             pcireg_control_bit_set(struct pcibus_info *, u64);
-extern u64         pcireg_tflush_get(struct pcibus_info *);
-extern u64         pcireg_intr_status_get(struct pcibus_info *);
-extern void             pcireg_intr_enable_bit_clr(struct pcibus_info *, u64);
-extern void             pcireg_intr_enable_bit_set(struct pcibus_info *, u64);
-extern void             pcireg_intr_addr_addr_set(struct pcibus_info *, int, u64);
-extern void             pcireg_force_intr_set(struct pcibus_info *, int);
-extern u64         pcireg_wrb_flush_get(struct pcibus_info *, int);
-extern void             pcireg_int_ate_set(struct pcibus_info *, int, u64);
-extern u64 __iomem *   pcireg_int_ate_addr(struct pcibus_info *, int);
-extern void            pcibr_force_interrupt(struct sn_irq_info *sn_irq_info);
-extern void            pcibr_change_devices_irq(struct sn_irq_info *sn_irq_info);
-extern int             pcibr_ate_alloc(struct pcibus_info *, int);
-extern void            pcibr_ate_free(struct pcibus_info *, int);
-extern void            ate_write(struct pcibus_info *, int, int, u64);
-extern int sal_pcibr_slot_enable(struct pcibus_info *soft, int device,
-                                void *resp, char **ssdt);
-extern int sal_pcibr_slot_disable(struct pcibus_info *soft, int device,
-                                 int action, void *resp);
-extern u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus);
-#endif
diff --git a/arch/ia64/include/asm/sn/pcibus_provider_defs.h b/arch/ia64/include/asm/sn/pcibus_provider_defs.h
deleted file mode 100644 (file)
index 8f7c83d..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_PCI_PCIBUS_PROVIDER_H
-#define _ASM_IA64_SN_PCI_PCIBUS_PROVIDER_H
-
-/*
- * SN pci asic types.  Do not ever renumber these or reuse values.  The
- * values must agree with what prom thinks they are.
- */
-
-#define PCIIO_ASIC_TYPE_UNKNOWN        0
-#define PCIIO_ASIC_TYPE_PPB    1
-#define PCIIO_ASIC_TYPE_PIC    2
-#define PCIIO_ASIC_TYPE_TIOCP  3
-#define PCIIO_ASIC_TYPE_TIOCA  4
-#define PCIIO_ASIC_TYPE_TIOCE  5
-
-#define PCIIO_ASIC_MAX_TYPES   6
-
-/*
- * Common pciio bus provider data.  There should be one of these as the
- * first field in any pciio based provider soft structure (e.g. pcibr_soft
- * tioca_soft, etc).
- */
-
-struct pcibus_bussoft {
-       u32             bs_asic_type;   /* chipset type */
-       u32             bs_xid;         /* xwidget id */
-       u32             bs_persist_busnum; /* Persistent Bus Number */
-       u32             bs_persist_segment; /* Segment Number */
-       u64             bs_legacy_io;   /* legacy io pio addr */
-       u64             bs_legacy_mem;  /* legacy mem pio addr */
-       u64             bs_base;        /* widget base */
-       struct xwidget_info     *bs_xwidget_info;
-};
-
-struct pci_controller;
-/*
- * SN pci bus indirection
- */
-
-struct sn_pcibus_provider {
-       dma_addr_t      (*dma_map)(struct pci_dev *, unsigned long, size_t, int flags);
-       dma_addr_t      (*dma_map_consistent)(struct pci_dev *, unsigned long, size_t, int flags);
-       void            (*dma_unmap)(struct pci_dev *, dma_addr_t, int);
-       void *          (*bus_fixup)(struct pcibus_bussoft *, struct pci_controller *);
-       void            (*force_interrupt)(struct sn_irq_info *);
-       void            (*target_interrupt)(struct sn_irq_info *);
-};
-
-/*
- * Flags used by the map interfaces
- * bits 3:0 specifies format of passed in address
- * bit  4   specifies that address is to be used for MSI
- */
-
-#define SN_DMA_ADDRTYPE(x)     ((x) & 0xf)
-#define     SN_DMA_ADDR_PHYS   1       /* address is an xio address. */
-#define     SN_DMA_ADDR_XIO    2       /* address is phys memory */
-#define SN_DMA_MSI             0x10    /* Bus address is to be used for MSI */
-
-extern struct sn_pcibus_provider *sn_pci_provider[];
-#endif                         /* _ASM_IA64_SN_PCI_PCIBUS_PROVIDER_H */
diff --git a/arch/ia64/include/asm/sn/pcidev.h b/arch/ia64/include/asm/sn/pcidev.h
deleted file mode 100644 (file)
index 1c2382c..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_PCI_PCIDEV_H
-#define _ASM_IA64_SN_PCI_PCIDEV_H
-
-#include <linux/pci.h>
-
-/*
- * In ia64, pci_dev->sysdata must be a *pci_controller. To provide access to
- * the pcidev_info structs for all devices under a controller, we keep a
- * list of pcidev_info under pci_controller->platform_data.
- */
-struct sn_platform_data {
-       void *provider_soft;
-       struct list_head pcidev_info;
-};
-
-#define SN_PLATFORM_DATA(busdev) \
-       ((struct sn_platform_data *)(PCI_CONTROLLER(busdev)->platform_data))
-
-#define SN_PCIDEV_INFO(dev)    sn_pcidev_info_get(dev)
-
-/*
- * Given a pci_bus, return the sn pcibus_bussoft struct.  Note that
- * this only works for root busses, not for busses represented by PPB's.
- */
-
-#define SN_PCIBUS_BUSSOFT(pci_bus) \
-       ((struct pcibus_bussoft *)(SN_PLATFORM_DATA(pci_bus)->provider_soft))
-
-#define SN_PCIBUS_BUSSOFT_INFO(pci_bus) \
-       ((struct pcibus_info *)(SN_PLATFORM_DATA(pci_bus)->provider_soft))
-/*
- * Given a struct pci_dev, return the sn pcibus_bussoft struct.  Note
- * that this is not equivalent to SN_PCIBUS_BUSSOFT(pci_dev->bus) due
- * due to possible PPB's in the path.
- */
-
-#define SN_PCIDEV_BUSSOFT(pci_dev) \
-       (SN_PCIDEV_INFO(pci_dev)->pdi_host_pcidev_info->pdi_pcibus_info)
-
-#define SN_PCIDEV_BUSPROVIDER(pci_dev) \
-       (SN_PCIDEV_INFO(pci_dev)->pdi_provider)
-
-#define PCIIO_BUS_NONE 255      /* bus 255 reserved */
-#define PCIIO_SLOT_NONE 255
-#define PCIIO_FUNC_NONE 255
-#define PCIIO_VENDOR_ID_NONE   (-1)
-
-struct pcidev_info {
-       u64             pdi_pio_mapped_addr[7]; /* 6 BARs PLUS 1 ROM */
-       u64             pdi_slot_host_handle;   /* Bus and devfn Host pci_dev */
-
-       struct pcibus_bussoft   *pdi_pcibus_info;       /* Kernel common bus soft */
-       struct pcidev_info      *pdi_host_pcidev_info;  /* Kernel Host pci_dev */
-       struct pci_dev          *pdi_linux_pcidev;      /* Kernel pci_dev */
-
-       struct sn_irq_info      *pdi_sn_irq_info;
-       struct sn_pcibus_provider *pdi_provider;        /* sn pci ops */
-       struct pci_dev          *host_pci_dev;          /* host bus link */
-       struct list_head        pdi_list;               /* List of pcidev_info */
-};
-
-extern void sn_irq_fixup(struct pci_dev *pci_dev,
-                        struct sn_irq_info *sn_irq_info);
-extern void sn_irq_unfixup(struct pci_dev *pci_dev);
-extern struct pcidev_info * sn_pcidev_info_get(struct pci_dev *);
-extern void sn_bus_fixup(struct pci_bus *);
-extern void sn_acpi_bus_fixup(struct pci_bus *);
-extern void sn_common_bus_fixup(struct pci_bus *, struct pcibus_bussoft *);
-extern void sn_bus_store_sysdata(struct pci_dev *dev);
-extern void sn_bus_free_sysdata(void);
-extern void sn_generate_path(struct pci_bus *pci_bus, char *address);
-extern void sn_io_slot_fixup(struct pci_dev *);
-extern void sn_acpi_slot_fixup(struct pci_dev *);
-extern void sn_pci_fixup_slot(struct pci_dev *dev, struct pcidev_info *,
-                             struct sn_irq_info *);
-extern void sn_pci_unfixup_slot(struct pci_dev *dev);
-extern void sn_irq_lh_init(void);
-#endif                         /* _ASM_IA64_SN_PCI_PCIDEV_H */
diff --git a/arch/ia64/include/asm/sn/pda.h b/arch/ia64/include/asm/sn/pda.h
deleted file mode 100644 (file)
index 22ae358..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_PDA_H
-#define _ASM_IA64_SN_PDA_H
-
-#include <linux/cache.h>
-#include <asm/percpu.h>
-
-
-/*
- * CPU-specific data structure.
- *
- * One of these structures is allocated for each cpu of a NUMA system.
- *
- * This structure provides a convenient way of keeping together 
- * all SN per-cpu data structures. 
- */
-
-typedef struct pda_s {
-
-       /*
-        * Support for SN LEDs
-        */
-       volatile short  *led_address;
-       u8              led_state;
-       u8              hb_state;       /* supports blinking heartbeat leds */
-       unsigned int    hb_count;
-
-       unsigned int    idle_flag;
-       
-       volatile unsigned long *bedrock_rev_id;
-       volatile unsigned long *pio_write_status_addr;
-       unsigned long pio_write_status_val;
-       volatile unsigned long *pio_shub_war_cam_addr;
-
-       unsigned long   sn_in_service_ivecs[4];
-       int             sn_lb_int_war_ticks;
-       int             sn_last_irq;
-       int             sn_first_irq;
-} pda_t;
-
-
-#define CACHE_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
-
-/*
- * PDA
- * Per-cpu private data area for each cpu. The PDA is located immediately after
- * the IA64 cpu_data area. A full page is allocated for the cp_data area for each
- * cpu but only a small amout of the page is actually used. We put the SNIA PDA
- * in the same page as the cpu_data area. Note that there is a check in the setup
- * code to verify that we don't overflow the page.
- *
- * Seems like we should should cache-line align the pda so that any changes in the
- * size of the cpu_data area don't change cache layout. Should we align to 32, 64, 128
- * or 512 boundary. Each has merits. For now, pick 128 but should be revisited later.
- */
-DECLARE_PER_CPU(struct pda_s, pda_percpu);
-
-#define pda            (&__ia64_per_cpu_var(pda_percpu))
-
-#define pdacpu(cpu)    (&per_cpu(pda_percpu, cpu))
-
-#endif /* _ASM_IA64_SN_PDA_H */
diff --git a/arch/ia64/include/asm/sn/pic.h b/arch/ia64/include/asm/sn/pic.h
deleted file mode 100644 (file)
index 5f9da5f..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_PCI_PIC_H
-#define _ASM_IA64_SN_PCI_PIC_H
-
-/*
- * PIC AS DEVICE ZERO
- * ------------------
- *
- * PIC handles PCI/X busses.  PCI/X requires that the 'bridge' (i.e. PIC)
- * be designated as 'device 0'.   That is a departure from earlier SGI
- * PCI bridges.  Because of that we use config space 1 to access the
- * config space of the first actual PCI device on the bus.
- * Here's what the PIC manual says:
- *
- *     The current PCI-X bus specification now defines that the parent
- *     hosts bus bridge (PIC for example) must be device 0 on bus 0. PIC
- *     reduced the total number of devices from 8 to 4 and removed the
- *     device registers and windows, now only supporting devices 0,1,2, and
- *     3. PIC did leave all 8 configuration space windows. The reason was
- *     there was nothing to gain by removing them. Here in lies the problem.
- *     The device numbering we do using 0 through 3 is unrelated to the device
- *     numbering which PCI-X requires in configuration space. In the past we
- *     correlated Configs pace and our device space 0 <-> 0, 1 <-> 1, etc.
- *     PCI-X requires we start a 1, not 0 and currently the PX brick
- *     does associate our:
- *
- *         device 0 with configuration space window 1,
- *         device 1 with configuration space window 2,
- *         device 2 with configuration space window 3,
- *         device 3 with configuration space window 4.
- *
- * The net effect is that all config space access are off-by-one with
- * relation to other per-slot accesses on the PIC.
- * Here is a table that shows some of that:
- *
- *                               Internal Slot#
- *           |
- *           |     0         1        2         3
- * ----------|---------------------------------------
- * config    |  0x21000   0x22000  0x23000   0x24000
- *           |
- * even rrb  |  0[0]      n/a      1[0]      n/a       [] == implied even/odd
- *           |
- * odd rrb   |  n/a       0[1]     n/a       1[1]
- *           |
- * int dev   |  00       01        10        11
- *           |
- * ext slot# |  1        2         3         4
- * ----------|---------------------------------------
- */
-
-#define PIC_ATE_TARGETID_SHFT           8
-#define PIC_HOST_INTR_ADDR              0x0000FFFFFFFFFFFFUL
-#define PIC_PCI64_ATTR_TARG_SHFT        60
-
-
-/*****************************************************************************
- *********************** PIC MMR structure mapping ***************************
- *****************************************************************************/
-
-/* NOTE: PIC WAR. PV#854697.  PIC does not allow writes just to [31:0]
- * of a 64-bit register.  When writing PIC registers, always write the
- * entire 64 bits.
- */
-
-struct pic {
-
-    /* 0x000000-0x00FFFF -- Local Registers */
-
-    /* 0x000000-0x000057 -- Standard Widget Configuration */
-    u64                p_wid_id;                       /* 0x000000 */
-    u64                p_wid_stat;                     /* 0x000008 */
-    u64                p_wid_err_upper;                /* 0x000010 */
-    u64                p_wid_err_lower;                /* 0x000018 */
-    #define p_wid_err p_wid_err_lower
-    u64                p_wid_control;                  /* 0x000020 */
-    u64                p_wid_req_timeout;              /* 0x000028 */
-    u64                p_wid_int_upper;                /* 0x000030 */
-    u64                p_wid_int_lower;                /* 0x000038 */
-    #define p_wid_int p_wid_int_lower
-    u64                p_wid_err_cmdword;              /* 0x000040 */
-    u64                p_wid_llp;                      /* 0x000048 */
-    u64                p_wid_tflush;                   /* 0x000050 */
-
-    /* 0x000058-0x00007F -- Bridge-specific Widget Configuration */
-    u64                p_wid_aux_err;                  /* 0x000058 */
-    u64                p_wid_resp_upper;               /* 0x000060 */
-    u64                p_wid_resp_lower;               /* 0x000068 */
-    #define p_wid_resp p_wid_resp_lower
-    u64                p_wid_tst_pin_ctrl;             /* 0x000070 */
-    u64                p_wid_addr_lkerr;               /* 0x000078 */
-
-    /* 0x000080-0x00008F -- PMU & MAP */
-    u64                p_dir_map;                      /* 0x000080 */
-    u64                _pad_000088;                    /* 0x000088 */
-
-    /* 0x000090-0x00009F -- SSRAM */
-    u64                p_map_fault;                    /* 0x000090 */
-    u64                _pad_000098;                    /* 0x000098 */
-
-    /* 0x0000A0-0x0000AF -- Arbitration */
-    u64                p_arb;                          /* 0x0000A0 */
-    u64                _pad_0000A8;                    /* 0x0000A8 */
-
-    /* 0x0000B0-0x0000BF -- Number In A Can or ATE Parity Error */
-    u64                p_ate_parity_err;               /* 0x0000B0 */
-    u64                _pad_0000B8;                    /* 0x0000B8 */
-
-    /* 0x0000C0-0x0000FF -- PCI/GIO */
-    u64                p_bus_timeout;                  /* 0x0000C0 */
-    u64                p_pci_cfg;                      /* 0x0000C8 */
-    u64                p_pci_err_upper;                /* 0x0000D0 */
-    u64                p_pci_err_lower;                /* 0x0000D8 */
-    #define p_pci_err p_pci_err_lower
-    u64                _pad_0000E0[4];                 /* 0x0000{E0..F8} */
-
-    /* 0x000100-0x0001FF -- Interrupt */
-    u64                p_int_status;                   /* 0x000100 */
-    u64                p_int_enable;                   /* 0x000108 */
-    u64                p_int_rst_stat;                 /* 0x000110 */
-    u64                p_int_mode;                     /* 0x000118 */
-    u64                p_int_device;                   /* 0x000120 */
-    u64                p_int_host_err;                 /* 0x000128 */
-    u64                p_int_addr[8];                  /* 0x0001{30,,,68} */
-    u64                p_err_int_view;                 /* 0x000170 */
-    u64                p_mult_int;                     /* 0x000178 */
-    u64                p_force_always[8];              /* 0x0001{80,,,B8} */
-    u64                p_force_pin[8];                 /* 0x0001{C0,,,F8} */
-
-    /* 0x000200-0x000298 -- Device */
-    u64                p_device[4];                    /* 0x0002{00,,,18} */
-    u64                _pad_000220[4];                 /* 0x0002{20,,,38} */
-    u64                p_wr_req_buf[4];                /* 0x0002{40,,,58} */
-    u64                _pad_000260[4];                 /* 0x0002{60,,,78} */
-    u64                p_rrb_map[2];                   /* 0x0002{80,,,88} */
-    #define p_even_resp p_rrb_map[0]                   /* 0x000280 */
-    #define p_odd_resp  p_rrb_map[1]                   /* 0x000288 */
-    u64                p_resp_status;                  /* 0x000290 */
-    u64                p_resp_clear;                   /* 0x000298 */
-
-    u64                _pad_0002A0[12];                /* 0x0002{A0..F8} */
-
-    /* 0x000300-0x0003F8 -- Buffer Address Match Registers */
-    struct {
-       u64     upper;                          /* 0x0003{00,,,F0} */
-       u64     lower;                          /* 0x0003{08,,,F8} */
-    } p_buf_addr_match[16];
-
-    /* 0x000400-0x0005FF -- Performance Monitor Registers (even only) */
-    struct {
-       u64     flush_w_touch;                  /* 0x000{400,,,5C0} */
-       u64     flush_wo_touch;                 /* 0x000{408,,,5C8} */
-       u64     inflight;                       /* 0x000{410,,,5D0} */
-       u64     prefetch;                       /* 0x000{418,,,5D8} */
-       u64     total_pci_retry;                /* 0x000{420,,,5E0} */
-       u64     max_pci_retry;                  /* 0x000{428,,,5E8} */
-       u64     max_latency;                    /* 0x000{430,,,5F0} */
-       u64     clear_all;                      /* 0x000{438,,,5F8} */
-    } p_buf_count[8];
-
-
-    /* 0x000600-0x0009FF -- PCI/X registers */
-    u64                p_pcix_bus_err_addr;            /* 0x000600 */
-    u64                p_pcix_bus_err_attr;            /* 0x000608 */
-    u64                p_pcix_bus_err_data;            /* 0x000610 */
-    u64                p_pcix_pio_split_addr;          /* 0x000618 */
-    u64                p_pcix_pio_split_attr;          /* 0x000620 */
-    u64                p_pcix_dma_req_err_attr;        /* 0x000628 */
-    u64                p_pcix_dma_req_err_addr;        /* 0x000630 */
-    u64                p_pcix_timeout;                 /* 0x000638 */
-
-    u64                _pad_000640[120];               /* 0x000{640,,,9F8} */
-
-    /* 0x000A00-0x000BFF -- PCI/X Read&Write Buffer */
-    struct {
-       u64     p_buf_addr;                     /* 0x000{A00,,,AF0} */
-       u64     p_buf_attr;                     /* 0X000{A08,,,AF8} */
-    } p_pcix_read_buf_64[16];
-
-    struct {
-       u64     p_buf_addr;                     /* 0x000{B00,,,BE0} */
-       u64     p_buf_attr;                     /* 0x000{B08,,,BE8} */
-       u64     p_buf_valid;                    /* 0x000{B10,,,BF0} */
-       u64     __pad1;                         /* 0x000{B18,,,BF8} */
-    } p_pcix_write_buf_64[8];
-
-    /* End of Local Registers -- Start of Address Map space */
-
-    char               _pad_000c00[0x010000 - 0x000c00];
-
-    /* 0x010000-0x011fff -- Internal ATE RAM (Auto Parity Generation) */
-    u64                p_int_ate_ram[1024];            /* 0x010000-0x011fff */
-
-    /* 0x012000-0x013fff -- Internal ATE RAM (Manual Parity Generation) */
-    u64                p_int_ate_ram_mp[1024];         /* 0x012000-0x013fff */
-
-    char               _pad_014000[0x18000 - 0x014000];
-
-    /* 0x18000-0x197F8 -- PIC Write Request Ram */
-    u64                p_wr_req_lower[256];            /* 0x18000 - 0x187F8 */
-    u64                p_wr_req_upper[256];            /* 0x18800 - 0x18FF8 */
-    u64                p_wr_req_parity[256];           /* 0x19000 - 0x197F8 */
-
-    char               _pad_019800[0x20000 - 0x019800];
-
-    /* 0x020000-0x027FFF -- PCI Device Configuration Spaces */
-    union {
-       u8              c[0x1000 / 1];                  /* 0x02{0000,,,7FFF} */
-       u16     s[0x1000 / 2];                  /* 0x02{0000,,,7FFF} */
-       u32     l[0x1000 / 4];                  /* 0x02{0000,,,7FFF} */
-       u64     d[0x1000 / 8];                  /* 0x02{0000,,,7FFF} */
-       union {
-           u8  c[0x100 / 1];
-           u16 s[0x100 / 2];
-           u32 l[0x100 / 4];
-           u64 d[0x100 / 8];
-       } f[8];
-    } p_type0_cfg_dev[8];                              /* 0x02{0000,,,7FFF} */
-
-    /* 0x028000-0x028FFF -- PCI Type 1 Configuration Space */
-    union {
-       u8              c[0x1000 / 1];                  /* 0x028000-0x029000 */
-       u16     s[0x1000 / 2];                  /* 0x028000-0x029000 */
-       u32     l[0x1000 / 4];                  /* 0x028000-0x029000 */
-       u64     d[0x1000 / 8];                  /* 0x028000-0x029000 */
-       union {
-           u8  c[0x100 / 1];
-           u16 s[0x100 / 2];
-           u32 l[0x100 / 4];
-           u64 d[0x100 / 8];
-       } f[8];
-    } p_type1_cfg;                                     /* 0x028000-0x029000 */
-
-    char               _pad_029000[0x030000-0x029000];
-
-    /* 0x030000-0x030007 -- PCI Interrupt Acknowledge Cycle */
-    union {
-       u8              c[8 / 1];
-       u16     s[8 / 2];
-       u32     l[8 / 4];
-       u64     d[8 / 8];
-    } p_pci_iack;                                      /* 0x030000-0x030007 */
-
-    char               _pad_030007[0x040000-0x030008];
-
-    /* 0x040000-0x030007 -- PCIX Special Cycle */
-    union {
-       u8              c[8 / 1];
-       u16     s[8 / 2];
-       u32     l[8 / 4];
-       u64     d[8 / 8];
-    } p_pcix_cycle;                                    /* 0x040000-0x040007 */
-};
-
-#endif                          /* _ASM_IA64_SN_PCI_PIC_H */
diff --git a/arch/ia64/include/asm/sn/rw_mmr.h b/arch/ia64/include/asm/sn/rw_mmr.h
deleted file mode 100644 (file)
index 2d78f4c..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2002-2006 Silicon Graphics, Inc.  All Rights Reserved.
- */
-#ifndef _ASM_IA64_SN_RW_MMR_H
-#define _ASM_IA64_SN_RW_MMR_H
-
-
-/*
- * This file that access MMRs via uncached physical addresses.
- *     pio_phys_read_mmr  - read an MMR
- *     pio_phys_write_mmr - write an MMR
- *     pio_atomic_phys_write_mmrs - atomically write 1 or 2 MMRs with psr.ic=0
- *             Second MMR will be skipped if address is NULL
- *
- * Addresses passed to these routines should be uncached physical addresses
- * ie., 0x80000....
- */
-
-
-extern long pio_phys_read_mmr(volatile long *mmr); 
-extern void pio_phys_write_mmr(volatile long *mmr, long val);
-extern void pio_atomic_phys_write_mmrs(volatile long *mmr1, long val1, volatile long *mmr2, long val2); 
-
-#endif /* _ASM_IA64_SN_RW_MMR_H */
diff --git a/arch/ia64/include/asm/sn/shub_mmr.h b/arch/ia64/include/asm/sn/shub_mmr.h
deleted file mode 100644 (file)
index a84d870..0000000
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2001-2005 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SHUB_MMR_H
-#define _ASM_IA64_SN_SHUB_MMR_H
-
-/* ==================================================================== */
-/*                        Register "SH_IPI_INT"                         */
-/*               SHub Inter-Processor Interrupt Registers               */
-/* ==================================================================== */
-#define SH1_IPI_INT                    __IA64_UL_CONST(0x0000000110000380)
-#define SH2_IPI_INT                    __IA64_UL_CONST(0x0000000010000380)
-
-/*   SH_IPI_INT_TYPE                                                    */
-/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
-#define SH_IPI_INT_TYPE_SHFT                           0
-#define SH_IPI_INT_TYPE_MASK           __IA64_UL_CONST(0x0000000000000007)
-
-/*   SH_IPI_INT_AGT                                                     */
-/*   Description:  Agent, must be 0 for SHub                            */
-#define SH_IPI_INT_AGT_SHFT                            3
-#define SH_IPI_INT_AGT_MASK            __IA64_UL_CONST(0x0000000000000008)
-
-/*   SH_IPI_INT_PID                                                     */
-/*   Description:  Processor ID, same setting as on targeted McKinley  */
-#define SH_IPI_INT_PID_SHFT                            4
-#define SH_IPI_INT_PID_MASK            __IA64_UL_CONST(0x00000000000ffff0)
-
-/*   SH_IPI_INT_BASE                                                    */
-/*   Description:  Optional interrupt vector area, 2MB aligned          */
-#define SH_IPI_INT_BASE_SHFT                           21
-#define SH_IPI_INT_BASE_MASK           __IA64_UL_CONST(0x0003ffffffe00000)
-
-/*   SH_IPI_INT_IDX                                                     */
-/*   Description:  Targeted McKinley interrupt vector                   */
-#define SH_IPI_INT_IDX_SHFT                            52
-#define SH_IPI_INT_IDX_MASK            __IA64_UL_CONST(0x0ff0000000000000)
-
-/*   SH_IPI_INT_SEND                                                    */
-/*   Description:  Send Interrupt Message to PI, This generates a puls  */
-#define SH_IPI_INT_SEND_SHFT                           63
-#define SH_IPI_INT_SEND_MASK           __IA64_UL_CONST(0x8000000000000000)
-
-/* ==================================================================== */
-/*                     Register "SH_EVENT_OCCURRED"                     */
-/*                    SHub Interrupt Event Occurred                     */
-/* ==================================================================== */
-#define SH1_EVENT_OCCURRED             __IA64_UL_CONST(0x0000000110010000)
-#define SH1_EVENT_OCCURRED_ALIAS       __IA64_UL_CONST(0x0000000110010008)
-#define SH2_EVENT_OCCURRED             __IA64_UL_CONST(0x0000000010010000)
-#define SH2_EVENT_OCCURRED_ALIAS       __IA64_UL_CONST(0x0000000010010008)
-
-/* ==================================================================== */
-/*                     Register "SH_PI_CAM_CONTROL"                     */
-/*                      CRB CAM MMR Access Control                      */
-/* ==================================================================== */
-#define SH1_PI_CAM_CONTROL             __IA64_UL_CONST(0x0000000120050300)
-
-/* ==================================================================== */
-/*                        Register "SH_SHUB_ID"                         */
-/*                            SHub ID Number                            */
-/* ==================================================================== */
-#define SH1_SHUB_ID                    __IA64_UL_CONST(0x0000000110060580)
-#define SH1_SHUB_ID_REVISION_SHFT                      28
-#define SH1_SHUB_ID_REVISION_MASK      __IA64_UL_CONST(0x00000000f0000000)
-
-/* ==================================================================== */
-/*                          Register "SH_RTC"                           */
-/*                           Real-time Clock                            */
-/* ==================================================================== */
-#define SH1_RTC                                __IA64_UL_CONST(0x00000001101c0000)
-#define SH2_RTC                                __IA64_UL_CONST(0x00000002101c0000)
-#define SH_RTC_MASK                    __IA64_UL_CONST(0x007fffffffffffff)
-
-/* ==================================================================== */
-/*                   Register "SH_PIO_WRITE_STATUS_0|1"                 */
-/*                      PIO Write Status for CPU 0 & 1                  */
-/* ==================================================================== */
-#define SH1_PIO_WRITE_STATUS_0         __IA64_UL_CONST(0x0000000120070200)
-#define SH1_PIO_WRITE_STATUS_1         __IA64_UL_CONST(0x0000000120070280)
-#define SH2_PIO_WRITE_STATUS_0         __IA64_UL_CONST(0x0000000020070200)
-#define SH2_PIO_WRITE_STATUS_1         __IA64_UL_CONST(0x0000000020070280)
-#define SH2_PIO_WRITE_STATUS_2         __IA64_UL_CONST(0x0000000020070300)
-#define SH2_PIO_WRITE_STATUS_3         __IA64_UL_CONST(0x0000000020070380)
-
-/*   SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK                               */
-/*   Description:  Deadlock response detected                           */
-#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT                1
-#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK \
-                                       __IA64_UL_CONST(0x0000000000000002)
-
-/*   SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT                          */
-/*   Description:  Count of currently pending PIO writes                */
-#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_SHFT   56
-#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK \
-                                       __IA64_UL_CONST(0x3f00000000000000)
-
-/* ==================================================================== */
-/*                Register "SH_PIO_WRITE_STATUS_0_ALIAS"                */
-/* ==================================================================== */
-#define SH1_PIO_WRITE_STATUS_0_ALIAS   __IA64_UL_CONST(0x0000000120070208)
-#define SH2_PIO_WRITE_STATUS_0_ALIAS   __IA64_UL_CONST(0x0000000020070208)
-
-/* ==================================================================== */
-/*                     Register "SH_EVENT_OCCURRED"                     */
-/*                    SHub Interrupt Event Occurred                     */
-/* ==================================================================== */
-/*   SH_EVENT_OCCURRED_UART_INT                                         */
-/*   Description:  Pending Junk Bus UART Interrupt                      */
-#define SH_EVENT_OCCURRED_UART_INT_SHFT                        20
-#define SH_EVENT_OCCURRED_UART_INT_MASK        __IA64_UL_CONST(0x0000000000100000)
-
-/*   SH_EVENT_OCCURRED_IPI_INT                                          */
-/*   Description:  Pending IPI Interrupt                                */
-#define SH_EVENT_OCCURRED_IPI_INT_SHFT                 28
-#define SH_EVENT_OCCURRED_IPI_INT_MASK __IA64_UL_CONST(0x0000000010000000)
-
-/*   SH_EVENT_OCCURRED_II_INT0                                          */
-/*   Description:  Pending II 0 Interrupt                               */
-#define SH_EVENT_OCCURRED_II_INT0_SHFT                 29
-#define SH_EVENT_OCCURRED_II_INT0_MASK __IA64_UL_CONST(0x0000000020000000)
-
-/*   SH_EVENT_OCCURRED_II_INT1                                          */
-/*   Description:  Pending II 1 Interrupt                               */
-#define SH_EVENT_OCCURRED_II_INT1_SHFT                 30
-#define SH_EVENT_OCCURRED_II_INT1_MASK __IA64_UL_CONST(0x0000000040000000)
-
-/*   SH2_EVENT_OCCURRED_EXTIO_INT2                                      */
-/*   Description:  Pending SHUB 2 EXT IO INT2                           */
-#define SH2_EVENT_OCCURRED_EXTIO_INT2_SHFT             33
-#define SH2_EVENT_OCCURRED_EXTIO_INT2_MASK __IA64_UL_CONST(0x0000000200000000)
-
-/*   SH2_EVENT_OCCURRED_EXTIO_INT3                                      */
-/*   Description:  Pending SHUB 2 EXT IO INT3                           */
-#define SH2_EVENT_OCCURRED_EXTIO_INT3_SHFT             34
-#define SH2_EVENT_OCCURRED_EXTIO_INT3_MASK __IA64_UL_CONST(0x0000000400000000)
-
-#define SH_ALL_INT_MASK \
-       (SH_EVENT_OCCURRED_UART_INT_MASK | SH_EVENT_OCCURRED_IPI_INT_MASK | \
-        SH_EVENT_OCCURRED_II_INT0_MASK | SH_EVENT_OCCURRED_II_INT1_MASK | \
-        SH_EVENT_OCCURRED_II_INT1_MASK | SH2_EVENT_OCCURRED_EXTIO_INT2_MASK | \
-        SH2_EVENT_OCCURRED_EXTIO_INT3_MASK)
-
-
-/* ==================================================================== */
-/*                         LEDS                                         */
-/* ==================================================================== */
-#define SH1_REAL_JUNK_BUS_LED0                 0x7fed00000UL
-#define SH1_REAL_JUNK_BUS_LED1                 0x7fed10000UL
-#define SH1_REAL_JUNK_BUS_LED2                 0x7fed20000UL
-#define SH1_REAL_JUNK_BUS_LED3                 0x7fed30000UL
-
-#define SH2_REAL_JUNK_BUS_LED0                 0xf0000000UL
-#define SH2_REAL_JUNK_BUS_LED1                 0xf0010000UL
-#define SH2_REAL_JUNK_BUS_LED2                 0xf0020000UL
-#define SH2_REAL_JUNK_BUS_LED3                 0xf0030000UL
-
-/* ==================================================================== */
-/*                         Register "SH1_PTC_0"                         */
-/*       Puge Translation Cache Message Configuration Information       */
-/* ==================================================================== */
-#define SH1_PTC_0                      __IA64_UL_CONST(0x00000001101a0000)
-
-/*   SH1_PTC_0_A                                                        */
-/*   Description:  Type                                                 */
-#define SH1_PTC_0_A_SHFT                               0
-
-/*   SH1_PTC_0_PS                                                       */
-/*   Description:  Page Size                                            */
-#define SH1_PTC_0_PS_SHFT                              2
-
-/*   SH1_PTC_0_RID                                                      */
-/*   Description:  Region ID                                            */
-#define SH1_PTC_0_RID_SHFT                             8
-
-/*   SH1_PTC_0_START                                                    */
-/*   Description:  Start                                                */
-#define SH1_PTC_0_START_SHFT                           63
-
-/* ==================================================================== */
-/*                         Register "SH1_PTC_1"                         */
-/*       Puge Translation Cache Message Configuration Information       */
-/* ==================================================================== */
-#define SH1_PTC_1                      __IA64_UL_CONST(0x00000001101a0080)
-
-/*   SH1_PTC_1_START                                                    */
-/*   Description:  PTC_1 Start                                          */
-#define SH1_PTC_1_START_SHFT                           63
-
-/* ==================================================================== */
-/*                         Register "SH2_PTC"                           */
-/*       Puge Translation Cache Message Configuration Information       */
-/* ==================================================================== */
-#define SH2_PTC                                __IA64_UL_CONST(0x0000000170000000)
-
-/*   SH2_PTC_A                                                          */
-/*   Description:  Type                                                 */
-#define SH2_PTC_A_SHFT                                 0
-
-/*   SH2_PTC_PS                                                         */
-/*   Description:  Page Size                                            */
-#define SH2_PTC_PS_SHFT                                        2
-
-/*   SH2_PTC_RID                                                      */
-/*   Description:  Region ID                                            */
-#define SH2_PTC_RID_SHFT                               4
-
-/*   SH2_PTC_START                                                      */
-/*   Description:  Start                                                */
-#define SH2_PTC_START_SHFT                             63
-
-/*   SH2_PTC_ADDR_RID                                                   */
-/*   Description:  Region ID                                            */
-#define SH2_PTC_ADDR_SHFT                              4
-#define SH2_PTC_ADDR_MASK              __IA64_UL_CONST(0x1ffffffffffff000)
-
-/* ==================================================================== */
-/*                    Register "SH_RTC1_INT_CONFIG"                     */
-/*                SHub RTC 1 Interrupt Config Registers                 */
-/* ==================================================================== */
-
-#define SH1_RTC1_INT_CONFIG            __IA64_UL_CONST(0x0000000110001480)
-#define SH2_RTC1_INT_CONFIG            __IA64_UL_CONST(0x0000000010001480)
-#define SH_RTC1_INT_CONFIG_MASK                __IA64_UL_CONST(0x0ff3ffffffefffff)
-#define SH_RTC1_INT_CONFIG_INIT                __IA64_UL_CONST(0x0000000000000000)
-
-/*   SH_RTC1_INT_CONFIG_TYPE                                            */
-/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
-#define SH_RTC1_INT_CONFIG_TYPE_SHFT                   0
-#define SH_RTC1_INT_CONFIG_TYPE_MASK   __IA64_UL_CONST(0x0000000000000007)
-
-/*   SH_RTC1_INT_CONFIG_AGT                                             */
-/*   Description:  Agent, must be 0 for SHub                            */
-#define SH_RTC1_INT_CONFIG_AGT_SHFT                    3
-#define SH_RTC1_INT_CONFIG_AGT_MASK    __IA64_UL_CONST(0x0000000000000008)
-
-/*   SH_RTC1_INT_CONFIG_PID                                             */
-/*   Description:  Processor ID, same setting as on targeted McKinley  */
-#define SH_RTC1_INT_CONFIG_PID_SHFT                    4
-#define SH_RTC1_INT_CONFIG_PID_MASK    __IA64_UL_CONST(0x00000000000ffff0)
-
-/*   SH_RTC1_INT_CONFIG_BASE                                            */
-/*   Description:  Optional interrupt vector area, 2MB aligned          */
-#define SH_RTC1_INT_CONFIG_BASE_SHFT                   21
-#define SH_RTC1_INT_CONFIG_BASE_MASK   __IA64_UL_CONST(0x0003ffffffe00000)
-
-/*   SH_RTC1_INT_CONFIG_IDX                                             */
-/*   Description:  Targeted McKinley interrupt vector                   */
-#define SH_RTC1_INT_CONFIG_IDX_SHFT                    52
-#define SH_RTC1_INT_CONFIG_IDX_MASK    __IA64_UL_CONST(0x0ff0000000000000)
-
-/* ==================================================================== */
-/*                    Register "SH_RTC1_INT_ENABLE"                     */
-/*                SHub RTC 1 Interrupt Enable Registers                 */
-/* ==================================================================== */
-
-#define SH1_RTC1_INT_ENABLE            __IA64_UL_CONST(0x0000000110001500)
-#define SH2_RTC1_INT_ENABLE            __IA64_UL_CONST(0x0000000010001500)
-#define SH_RTC1_INT_ENABLE_MASK                __IA64_UL_CONST(0x0000000000000001)
-#define SH_RTC1_INT_ENABLE_INIT                __IA64_UL_CONST(0x0000000000000000)
-
-/*   SH_RTC1_INT_ENABLE_RTC1_ENABLE                                     */
-/*   Description:  Enable RTC 1 Interrupt                               */
-#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_SHFT            0
-#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_MASK \
-                                       __IA64_UL_CONST(0x0000000000000001)
-
-/* ==================================================================== */
-/*                    Register "SH_RTC2_INT_CONFIG"                     */
-/*                SHub RTC 2 Interrupt Config Registers                 */
-/* ==================================================================== */
-
-#define SH1_RTC2_INT_CONFIG            __IA64_UL_CONST(0x0000000110001580)
-#define SH2_RTC2_INT_CONFIG            __IA64_UL_CONST(0x0000000010001580)
-#define SH_RTC2_INT_CONFIG_MASK                __IA64_UL_CONST(0x0ff3ffffffefffff)
-#define SH_RTC2_INT_CONFIG_INIT                __IA64_UL_CONST(0x0000000000000000)
-
-/*   SH_RTC2_INT_CONFIG_TYPE                                            */
-/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
-#define SH_RTC2_INT_CONFIG_TYPE_SHFT                   0
-#define SH_RTC2_INT_CONFIG_TYPE_MASK   __IA64_UL_CONST(0x0000000000000007)
-
-/*   SH_RTC2_INT_CONFIG_AGT                                             */
-/*   Description:  Agent, must be 0 for SHub                            */
-#define SH_RTC2_INT_CONFIG_AGT_SHFT                    3
-#define SH_RTC2_INT_CONFIG_AGT_MASK    __IA64_UL_CONST(0x0000000000000008)
-
-/*   SH_RTC2_INT_CONFIG_PID                                             */
-/*   Description:  Processor ID, same setting as on targeted McKinley  */
-#define SH_RTC2_INT_CONFIG_PID_SHFT                    4
-#define SH_RTC2_INT_CONFIG_PID_MASK    __IA64_UL_CONST(0x00000000000ffff0)
-
-/*   SH_RTC2_INT_CONFIG_BASE                                            */
-/*   Description:  Optional interrupt vector area, 2MB aligned          */
-#define SH_RTC2_INT_CONFIG_BASE_SHFT                   21
-#define SH_RTC2_INT_CONFIG_BASE_MASK   __IA64_UL_CONST(0x0003ffffffe00000)
-
-/*   SH_RTC2_INT_CONFIG_IDX                                             */
-/*   Description:  Targeted McKinley interrupt vector                   */
-#define SH_RTC2_INT_CONFIG_IDX_SHFT                    52
-#define SH_RTC2_INT_CONFIG_IDX_MASK    __IA64_UL_CONST(0x0ff0000000000000)
-
-/* ==================================================================== */
-/*                    Register "SH_RTC2_INT_ENABLE"                     */
-/*                SHub RTC 2 Interrupt Enable Registers                 */
-/* ==================================================================== */
-
-#define SH1_RTC2_INT_ENABLE            __IA64_UL_CONST(0x0000000110001600)
-#define SH2_RTC2_INT_ENABLE            __IA64_UL_CONST(0x0000000010001600)
-#define SH_RTC2_INT_ENABLE_MASK                __IA64_UL_CONST(0x0000000000000001)
-#define SH_RTC2_INT_ENABLE_INIT                __IA64_UL_CONST(0x0000000000000000)
-
-/*   SH_RTC2_INT_ENABLE_RTC2_ENABLE                                     */
-/*   Description:  Enable RTC 2 Interrupt                               */
-#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_SHFT            0
-#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_MASK \
-                                       __IA64_UL_CONST(0x0000000000000001)
-
-/* ==================================================================== */
-/*                    Register "SH_RTC3_INT_CONFIG"                     */
-/*                SHub RTC 3 Interrupt Config Registers                 */
-/* ==================================================================== */
-
-#define SH1_RTC3_INT_CONFIG            __IA64_UL_CONST(0x0000000110001680)
-#define SH2_RTC3_INT_CONFIG            __IA64_UL_CONST(0x0000000010001680)
-#define SH_RTC3_INT_CONFIG_MASK                __IA64_UL_CONST(0x0ff3ffffffefffff)
-#define SH_RTC3_INT_CONFIG_INIT                __IA64_UL_CONST(0x0000000000000000)
-
-/*   SH_RTC3_INT_CONFIG_TYPE                                            */
-/*   Description:  Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT       */
-#define SH_RTC3_INT_CONFIG_TYPE_SHFT                   0
-#define SH_RTC3_INT_CONFIG_TYPE_MASK   __IA64_UL_CONST(0x0000000000000007)
-
-/*   SH_RTC3_INT_CONFIG_AGT                                             */
-/*   Description:  Agent, must be 0 for SHub                            */
-#define SH_RTC3_INT_CONFIG_AGT_SHFT                    3
-#define SH_RTC3_INT_CONFIG_AGT_MASK    __IA64_UL_CONST(0x0000000000000008)
-
-/*   SH_RTC3_INT_CONFIG_PID                                             */
-/*   Description:  Processor ID, same setting as on targeted McKinley  */
-#define SH_RTC3_INT_CONFIG_PID_SHFT                    4
-#define SH_RTC3_INT_CONFIG_PID_MASK    __IA64_UL_CONST(0x00000000000ffff0)
-
-/*   SH_RTC3_INT_CONFIG_BASE                                            */
-/*   Description:  Optional interrupt vector area, 2MB aligned          */
-#define SH_RTC3_INT_CONFIG_BASE_SHFT                   21
-#define SH_RTC3_INT_CONFIG_BASE_MASK   __IA64_UL_CONST(0x0003ffffffe00000)
-
-/*   SH_RTC3_INT_CONFIG_IDX                                             */
-/*   Description:  Targeted McKinley interrupt vector                   */
-#define SH_RTC3_INT_CONFIG_IDX_SHFT                    52
-#define SH_RTC3_INT_CONFIG_IDX_MASK    __IA64_UL_CONST(0x0ff0000000000000)
-
-/* ==================================================================== */
-/*                    Register "SH_RTC3_INT_ENABLE"                     */
-/*                SHub RTC 3 Interrupt Enable Registers                 */
-/* ==================================================================== */
-
-#define SH1_RTC3_INT_ENABLE            __IA64_UL_CONST(0x0000000110001700)
-#define SH2_RTC3_INT_ENABLE            __IA64_UL_CONST(0x0000000010001700)
-#define SH_RTC3_INT_ENABLE_MASK                __IA64_UL_CONST(0x0000000000000001)
-#define SH_RTC3_INT_ENABLE_INIT                __IA64_UL_CONST(0x0000000000000000)
-
-/*   SH_RTC3_INT_ENABLE_RTC3_ENABLE                                     */
-/*   Description:  Enable RTC 3 Interrupt                               */
-#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_SHFT            0
-#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_MASK \
-                                       __IA64_UL_CONST(0x0000000000000001)
-
-/*   SH_EVENT_OCCURRED_RTC1_INT                                         */
-/*   Description:  Pending RTC 1 Interrupt                              */
-#define SH_EVENT_OCCURRED_RTC1_INT_SHFT                        24
-#define SH_EVENT_OCCURRED_RTC1_INT_MASK        __IA64_UL_CONST(0x0000000001000000)
-
-/*   SH_EVENT_OCCURRED_RTC2_INT                                         */
-/*   Description:  Pending RTC 2 Interrupt                              */
-#define SH_EVENT_OCCURRED_RTC2_INT_SHFT                        25
-#define SH_EVENT_OCCURRED_RTC2_INT_MASK        __IA64_UL_CONST(0x0000000002000000)
-
-/*   SH_EVENT_OCCURRED_RTC3_INT                                         */
-/*   Description:  Pending RTC 3 Interrupt                              */
-#define SH_EVENT_OCCURRED_RTC3_INT_SHFT                        26
-#define SH_EVENT_OCCURRED_RTC3_INT_MASK        __IA64_UL_CONST(0x0000000004000000)
-
-/* ==================================================================== */
-/*                       Register "SH_IPI_ACCESS"                       */
-/*                 CPU interrupt Access Permission Bits                 */
-/* ==================================================================== */
-
-#define SH1_IPI_ACCESS                 __IA64_UL_CONST(0x0000000110060480)
-#define SH2_IPI_ACCESS0                        __IA64_UL_CONST(0x0000000010060c00)
-#define SH2_IPI_ACCESS1                        __IA64_UL_CONST(0x0000000010060c80)
-#define SH2_IPI_ACCESS2                        __IA64_UL_CONST(0x0000000010060d00)
-#define SH2_IPI_ACCESS3                        __IA64_UL_CONST(0x0000000010060d80)
-
-/* ==================================================================== */
-/*                        Register "SH_INT_CMPB"                        */
-/*                  RTC Compare Value for Processor B                   */
-/* ==================================================================== */
-
-#define SH1_INT_CMPB                   __IA64_UL_CONST(0x00000001101b0080)
-#define SH2_INT_CMPB                   __IA64_UL_CONST(0x00000000101b0080)
-#define SH_INT_CMPB_MASK               __IA64_UL_CONST(0x007fffffffffffff)
-#define SH_INT_CMPB_INIT               __IA64_UL_CONST(0x0000000000000000)
-
-/*   SH_INT_CMPB_REAL_TIME_CMPB                                         */
-/*   Description:  Real Time Clock Compare                              */
-#define SH_INT_CMPB_REAL_TIME_CMPB_SHFT                        0
-#define SH_INT_CMPB_REAL_TIME_CMPB_MASK        __IA64_UL_CONST(0x007fffffffffffff)
-
-/* ==================================================================== */
-/*                        Register "SH_INT_CMPC"                        */
-/*                  RTC Compare Value for Processor C                   */
-/* ==================================================================== */
-
-#define SH1_INT_CMPC                   __IA64_UL_CONST(0x00000001101b0100)
-#define SH2_INT_CMPC                   __IA64_UL_CONST(0x00000000101b0100)
-#define SH_INT_CMPC_MASK               __IA64_UL_CONST(0x007fffffffffffff)
-#define SH_INT_CMPC_INIT               __IA64_UL_CONST(0x0000000000000000)
-
-/*   SH_INT_CMPC_REAL_TIME_CMPC                                         */
-/*   Description:  Real Time Clock Compare                              */
-#define SH_INT_CMPC_REAL_TIME_CMPC_SHFT                        0
-#define SH_INT_CMPC_REAL_TIME_CMPC_MASK        __IA64_UL_CONST(0x007fffffffffffff)
-
-/* ==================================================================== */
-/*                        Register "SH_INT_CMPD"                        */
-/*                  RTC Compare Value for Processor D                   */
-/* ==================================================================== */
-
-#define SH1_INT_CMPD                   __IA64_UL_CONST(0x00000001101b0180)
-#define SH2_INT_CMPD                   __IA64_UL_CONST(0x00000000101b0180)
-#define SH_INT_CMPD_MASK               __IA64_UL_CONST(0x007fffffffffffff)
-#define SH_INT_CMPD_INIT               __IA64_UL_CONST(0x0000000000000000)
-
-/*   SH_INT_CMPD_REAL_TIME_CMPD                                         */
-/*   Description:  Real Time Clock Compare                              */
-#define SH_INT_CMPD_REAL_TIME_CMPD_SHFT                        0
-#define SH_INT_CMPD_REAL_TIME_CMPD_MASK        __IA64_UL_CONST(0x007fffffffffffff)
-
-/* ==================================================================== */
-/*                Register "SH_MD_DQLP_MMR_DIR_PRIVEC0"                 */
-/*                      privilege vector for acc=0                      */
-/* ==================================================================== */
-#define SH1_MD_DQLP_MMR_DIR_PRIVEC0    __IA64_UL_CONST(0x0000000100030300)
-
-/* ==================================================================== */
-/*                Register "SH_MD_DQRP_MMR_DIR_PRIVEC0"                 */
-/*                      privilege vector for acc=0                      */
-/* ==================================================================== */
-#define SH1_MD_DQRP_MMR_DIR_PRIVEC0    __IA64_UL_CONST(0x0000000100050300)
-
-/* ==================================================================== */
-/* Some MMRs are functionally identical (or close enough) on both SHUB1 */
-/* and SHUB2 that it makes sense to define a geberic name for the MMR.  */
-/* It is acceptable to use (for example) SH_IPI_INT to reference the    */
-/* the IPI MMR. The value of SH_IPI_INT is determined at runtime based  */
-/* on the type of the SHUB. Do not use these #defines in performance    */
-/* critical code  or loops - there is a small performance penalty.      */
-/* ==================================================================== */
-#define shubmmr(a,b)           (is_shub2() ? a##2_##b : a##1_##b)
-
-#define SH_REAL_JUNK_BUS_LED0  shubmmr(SH, REAL_JUNK_BUS_LED0)
-#define SH_IPI_INT             shubmmr(SH, IPI_INT)
-#define SH_EVENT_OCCURRED      shubmmr(SH, EVENT_OCCURRED)
-#define SH_EVENT_OCCURRED_ALIAS        shubmmr(SH, EVENT_OCCURRED_ALIAS)
-#define SH_RTC                 shubmmr(SH, RTC)
-#define SH_RTC1_INT_CONFIG     shubmmr(SH, RTC1_INT_CONFIG)
-#define SH_RTC1_INT_ENABLE     shubmmr(SH, RTC1_INT_ENABLE)
-#define SH_RTC2_INT_CONFIG     shubmmr(SH, RTC2_INT_CONFIG)
-#define SH_RTC2_INT_ENABLE     shubmmr(SH, RTC2_INT_ENABLE)
-#define SH_RTC3_INT_CONFIG     shubmmr(SH, RTC3_INT_CONFIG)
-#define SH_RTC3_INT_ENABLE     shubmmr(SH, RTC3_INT_ENABLE)
-#define SH_INT_CMPB            shubmmr(SH, INT_CMPB)
-#define SH_INT_CMPC            shubmmr(SH, INT_CMPC)
-#define SH_INT_CMPD            shubmmr(SH, INT_CMPD)
-
-/* ========================================================================== */
-/*                        Register "SH2_BT_ENG_CSR_0"                         */
-/*                    Engine 0 Control and Status Register                    */
-/* ========================================================================== */
-
-#define SH2_BT_ENG_CSR_0               __IA64_UL_CONST(0x0000000030040000)
-#define SH2_BT_ENG_SRC_ADDR_0          __IA64_UL_CONST(0x0000000030040080)
-#define SH2_BT_ENG_DEST_ADDR_0         __IA64_UL_CONST(0x0000000030040100)
-#define SH2_BT_ENG_NOTIF_ADDR_0                __IA64_UL_CONST(0x0000000030040180)
-
-/* ========================================================================== */
-/*                       BTE interfaces 1-3                                   */
-/* ========================================================================== */
-
-#define SH2_BT_ENG_CSR_1               __IA64_UL_CONST(0x0000000030050000)
-#define SH2_BT_ENG_CSR_2               __IA64_UL_CONST(0x0000000030060000)
-#define SH2_BT_ENG_CSR_3               __IA64_UL_CONST(0x0000000030070000)
-
-#endif /* _ASM_IA64_SN_SHUB_MMR_H */
diff --git a/arch/ia64/include/asm/sn/shubio.h b/arch/ia64/include/asm/sn/shubio.h
deleted file mode 100644 (file)
index 8a1ec13..0000000
+++ /dev/null
@@ -1,3358 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SHUBIO_H
-#define _ASM_IA64_SN_SHUBIO_H
-
-#define HUB_WIDGET_ID_MAX      0xf
-#define IIO_NUM_ITTES          7
-#define HUB_NUM_BIG_WINDOW     (IIO_NUM_ITTES - 1)
-
-#define                IIO_WID                 0x00400000      /* Crosstalk Widget Identification */
-                                                       /* This register is also accessible from
-                                                        * Crosstalk at address 0x0.  */
-#define                IIO_WSTAT               0x00400008      /* Crosstalk Widget Status */
-#define                IIO_WCR                 0x00400020      /* Crosstalk Widget Control Register */
-#define                IIO_ILAPR               0x00400100      /* IO Local Access Protection Register */
-#define                IIO_ILAPO               0x00400108      /* IO Local Access Protection Override */
-#define                IIO_IOWA                0x00400110      /* IO Outbound Widget Access */
-#define                IIO_IIWA                0x00400118      /* IO Inbound Widget Access */
-#define                IIO_IIDEM               0x00400120      /* IO Inbound Device Error Mask */
-#define                IIO_ILCSR               0x00400128      /* IO LLP Control and Status Register */
-#define                IIO_ILLR                0x00400130      /* IO LLP Log Register    */
-#define                IIO_IIDSR               0x00400138      /* IO Interrupt Destination */
-
-#define                IIO_IGFX0               0x00400140      /* IO Graphics Node-Widget Map 0 */
-#define                IIO_IGFX1               0x00400148      /* IO Graphics Node-Widget Map 1 */
-
-#define                IIO_ISCR0               0x00400150      /* IO Scratch Register 0 */
-#define                IIO_ISCR1               0x00400158      /* IO Scratch Register 1 */
-
-#define                IIO_ITTE1               0x00400160      /* IO Translation Table Entry 1 */
-#define                IIO_ITTE2               0x00400168      /* IO Translation Table Entry 2 */
-#define                IIO_ITTE3               0x00400170      /* IO Translation Table Entry 3 */
-#define                IIO_ITTE4               0x00400178      /* IO Translation Table Entry 4 */
-#define                IIO_ITTE5               0x00400180      /* IO Translation Table Entry 5 */
-#define                IIO_ITTE6               0x00400188      /* IO Translation Table Entry 6 */
-#define                IIO_ITTE7               0x00400190      /* IO Translation Table Entry 7 */
-
-#define                IIO_IPRB0               0x00400198      /* IO PRB Entry 0   */
-#define                IIO_IPRB8               0x004001A0      /* IO PRB Entry 8   */
-#define                IIO_IPRB9               0x004001A8      /* IO PRB Entry 9   */
-#define                IIO_IPRBA               0x004001B0      /* IO PRB Entry A   */
-#define                IIO_IPRBB               0x004001B8      /* IO PRB Entry B   */
-#define                IIO_IPRBC               0x004001C0      /* IO PRB Entry C   */
-#define                IIO_IPRBD               0x004001C8      /* IO PRB Entry D   */
-#define                IIO_IPRBE               0x004001D0      /* IO PRB Entry E   */
-#define                IIO_IPRBF               0x004001D8      /* IO PRB Entry F   */
-
-#define                IIO_IXCC                0x004001E0      /* IO Crosstalk Credit Count Timeout */
-#define                IIO_IMEM                0x004001E8      /* IO Miscellaneous Error Mask */
-#define                IIO_IXTT                0x004001F0      /* IO Crosstalk Timeout Threshold */
-#define                IIO_IECLR               0x004001F8      /* IO Error Clear Register */
-#define                IIO_IBCR                0x00400200      /* IO BTE Control Register */
-
-#define                IIO_IXSM                0x00400208      /* IO Crosstalk Spurious Message */
-#define                IIO_IXSS                0x00400210      /* IO Crosstalk Spurious Sideband */
-
-#define                IIO_ILCT                0x00400218      /* IO LLP Channel Test    */
-
-#define                IIO_IIEPH1              0x00400220      /* IO Incoming Error Packet Header, Part 1 */
-#define                IIO_IIEPH2              0x00400228      /* IO Incoming Error Packet Header, Part 2 */
-
-#define                IIO_ISLAPR              0x00400230      /* IO SXB Local Access Protection Regster */
-#define                IIO_ISLAPO              0x00400238      /* IO SXB Local Access Protection Override */
-
-#define                IIO_IWI                 0x00400240      /* IO Wrapper Interrupt Register */
-#define                IIO_IWEL                0x00400248      /* IO Wrapper Error Log Register */
-#define                IIO_IWC                 0x00400250      /* IO Wrapper Control Register */
-#define                IIO_IWS                 0x00400258      /* IO Wrapper Status Register */
-#define                IIO_IWEIM               0x00400260      /* IO Wrapper Error Interrupt Masking Register */
-
-#define                IIO_IPCA                0x00400300      /* IO PRB Counter Adjust */
-
-#define                IIO_IPRTE0_A            0x00400308      /* IO PIO Read Address Table Entry 0, Part A */
-#define                IIO_IPRTE1_A            0x00400310      /* IO PIO Read Address Table Entry 1, Part A */
-#define                IIO_IPRTE2_A            0x00400318      /* IO PIO Read Address Table Entry 2, Part A */
-#define                IIO_IPRTE3_A            0x00400320      /* IO PIO Read Address Table Entry 3, Part A */
-#define                IIO_IPRTE4_A            0x00400328      /* IO PIO Read Address Table Entry 4, Part A */
-#define                IIO_IPRTE5_A            0x00400330      /* IO PIO Read Address Table Entry 5, Part A */
-#define                IIO_IPRTE6_A            0x00400338      /* IO PIO Read Address Table Entry 6, Part A */
-#define                IIO_IPRTE7_A            0x00400340      /* IO PIO Read Address Table Entry 7, Part A */
-
-#define                IIO_IPRTE0_B            0x00400348      /* IO PIO Read Address Table Entry 0, Part B */
-#define                IIO_IPRTE1_B            0x00400350      /* IO PIO Read Address Table Entry 1, Part B */
-#define                IIO_IPRTE2_B            0x00400358      /* IO PIO Read Address Table Entry 2, Part B */
-#define                IIO_IPRTE3_B            0x00400360      /* IO PIO Read Address Table Entry 3, Part B */
-#define                IIO_IPRTE4_B            0x00400368      /* IO PIO Read Address Table Entry 4, Part B */
-#define                IIO_IPRTE5_B            0x00400370      /* IO PIO Read Address Table Entry 5, Part B */
-#define                IIO_IPRTE6_B            0x00400378      /* IO PIO Read Address Table Entry 6, Part B */
-#define                IIO_IPRTE7_B            0x00400380      /* IO PIO Read Address Table Entry 7, Part B */
-
-#define                IIO_IPDR                0x00400388      /* IO PIO Deallocation Register */
-#define                IIO_ICDR                0x00400390      /* IO CRB Entry Deallocation Register */
-#define                IIO_IFDR                0x00400398      /* IO IOQ FIFO Depth Register */
-#define                IIO_IIAP                0x004003A0      /* IO IIQ Arbitration Parameters */
-#define                IIO_ICMR                0x004003A8      /* IO CRB Management Register */
-#define                IIO_ICCR                0x004003B0      /* IO CRB Control Register */
-#define                IIO_ICTO                0x004003B8      /* IO CRB Timeout   */
-#define                IIO_ICTP                0x004003C0      /* IO CRB Timeout Prescalar */
-
-#define                IIO_ICRB0_A             0x00400400      /* IO CRB Entry 0_A */
-#define                IIO_ICRB0_B             0x00400408      /* IO CRB Entry 0_B */
-#define                IIO_ICRB0_C             0x00400410      /* IO CRB Entry 0_C */
-#define                IIO_ICRB0_D             0x00400418      /* IO CRB Entry 0_D */
-#define                IIO_ICRB0_E             0x00400420      /* IO CRB Entry 0_E */
-
-#define                IIO_ICRB1_A             0x00400430      /* IO CRB Entry 1_A */
-#define                IIO_ICRB1_B             0x00400438      /* IO CRB Entry 1_B */
-#define                IIO_ICRB1_C             0x00400440      /* IO CRB Entry 1_C */
-#define                IIO_ICRB1_D             0x00400448      /* IO CRB Entry 1_D */
-#define                IIO_ICRB1_E             0x00400450      /* IO CRB Entry 1_E */
-
-#define                IIO_ICRB2_A             0x00400460      /* IO CRB Entry 2_A */
-#define                IIO_ICRB2_B             0x00400468      /* IO CRB Entry 2_B */
-#define                IIO_ICRB2_C             0x00400470      /* IO CRB Entry 2_C */
-#define                IIO_ICRB2_D             0x00400478      /* IO CRB Entry 2_D */
-#define                IIO_ICRB2_E             0x00400480      /* IO CRB Entry 2_E */
-
-#define                IIO_ICRB3_A             0x00400490      /* IO CRB Entry 3_A */
-#define                IIO_ICRB3_B             0x00400498      /* IO CRB Entry 3_B */
-#define                IIO_ICRB3_C             0x004004a0      /* IO CRB Entry 3_C */
-#define                IIO_ICRB3_D             0x004004a8      /* IO CRB Entry 3_D */
-#define                IIO_ICRB3_E             0x004004b0      /* IO CRB Entry 3_E */
-
-#define                IIO_ICRB4_A             0x004004c0      /* IO CRB Entry 4_A */
-#define                IIO_ICRB4_B             0x004004c8      /* IO CRB Entry 4_B */
-#define                IIO_ICRB4_C             0x004004d0      /* IO CRB Entry 4_C */
-#define                IIO_ICRB4_D             0x004004d8      /* IO CRB Entry 4_D */
-#define                IIO_ICRB4_E             0x004004e0      /* IO CRB Entry 4_E */
-
-#define                IIO_ICRB5_A             0x004004f0      /* IO CRB Entry 5_A */
-#define                IIO_ICRB5_B             0x004004f8      /* IO CRB Entry 5_B */
-#define                IIO_ICRB5_C             0x00400500      /* IO CRB Entry 5_C */
-#define                IIO_ICRB5_D             0x00400508      /* IO CRB Entry 5_D */
-#define                IIO_ICRB5_E             0x00400510      /* IO CRB Entry 5_E */
-
-#define                IIO_ICRB6_A             0x00400520      /* IO CRB Entry 6_A */
-#define                IIO_ICRB6_B             0x00400528      /* IO CRB Entry 6_B */
-#define                IIO_ICRB6_C             0x00400530      /* IO CRB Entry 6_C */
-#define                IIO_ICRB6_D             0x00400538      /* IO CRB Entry 6_D */
-#define                IIO_ICRB6_E             0x00400540      /* IO CRB Entry 6_E */
-
-#define                IIO_ICRB7_A             0x00400550      /* IO CRB Entry 7_A */
-#define                IIO_ICRB7_B             0x00400558      /* IO CRB Entry 7_B */
-#define                IIO_ICRB7_C             0x00400560      /* IO CRB Entry 7_C */
-#define                IIO_ICRB7_D             0x00400568      /* IO CRB Entry 7_D */
-#define                IIO_ICRB7_E             0x00400570      /* IO CRB Entry 7_E */
-
-#define                IIO_ICRB8_A             0x00400580      /* IO CRB Entry 8_A */
-#define                IIO_ICRB8_B             0x00400588      /* IO CRB Entry 8_B */
-#define                IIO_ICRB8_C             0x00400590      /* IO CRB Entry 8_C */
-#define                IIO_ICRB8_D             0x00400598      /* IO CRB Entry 8_D */
-#define                IIO_ICRB8_E             0x004005a0      /* IO CRB Entry 8_E */
-
-#define                IIO_ICRB9_A             0x004005b0      /* IO CRB Entry 9_A */
-#define                IIO_ICRB9_B             0x004005b8      /* IO CRB Entry 9_B */
-#define                IIO_ICRB9_C             0x004005c0      /* IO CRB Entry 9_C */
-#define                IIO_ICRB9_D             0x004005c8      /* IO CRB Entry 9_D */
-#define                IIO_ICRB9_E             0x004005d0      /* IO CRB Entry 9_E */
-
-#define                IIO_ICRBA_A             0x004005e0      /* IO CRB Entry A_A */
-#define                IIO_ICRBA_B             0x004005e8      /* IO CRB Entry A_B */
-#define                IIO_ICRBA_C             0x004005f0      /* IO CRB Entry A_C */
-#define                IIO_ICRBA_D             0x004005f8      /* IO CRB Entry A_D */
-#define                IIO_ICRBA_E             0x00400600      /* IO CRB Entry A_E */
-
-#define                IIO_ICRBB_A             0x00400610      /* IO CRB Entry B_A */
-#define                IIO_ICRBB_B             0x00400618      /* IO CRB Entry B_B */
-#define                IIO_ICRBB_C             0x00400620      /* IO CRB Entry B_C */
-#define                IIO_ICRBB_D             0x00400628      /* IO CRB Entry B_D */
-#define                IIO_ICRBB_E             0x00400630      /* IO CRB Entry B_E */
-
-#define                IIO_ICRBC_A             0x00400640      /* IO CRB Entry C_A */
-#define                IIO_ICRBC_B             0x00400648      /* IO CRB Entry C_B */
-#define                IIO_ICRBC_C             0x00400650      /* IO CRB Entry C_C */
-#define                IIO_ICRBC_D             0x00400658      /* IO CRB Entry C_D */
-#define                IIO_ICRBC_E             0x00400660      /* IO CRB Entry C_E */
-
-#define                IIO_ICRBD_A             0x00400670      /* IO CRB Entry D_A */
-#define                IIO_ICRBD_B             0x00400678      /* IO CRB Entry D_B */
-#define                IIO_ICRBD_C             0x00400680      /* IO CRB Entry D_C */
-#define                IIO_ICRBD_D             0x00400688      /* IO CRB Entry D_D */
-#define                IIO_ICRBD_E             0x00400690      /* IO CRB Entry D_E */
-
-#define                IIO_ICRBE_A             0x004006a0      /* IO CRB Entry E_A */
-#define                IIO_ICRBE_B             0x004006a8      /* IO CRB Entry E_B */
-#define                IIO_ICRBE_C             0x004006b0      /* IO CRB Entry E_C */
-#define                IIO_ICRBE_D             0x004006b8      /* IO CRB Entry E_D */
-#define                IIO_ICRBE_E             0x004006c0      /* IO CRB Entry E_E */
-
-#define                IIO_ICSML               0x00400700      /* IO CRB Spurious Message Low */
-#define                IIO_ICSMM               0x00400708      /* IO CRB Spurious Message Middle */
-#define                IIO_ICSMH               0x00400710      /* IO CRB Spurious Message High */
-
-#define                IIO_IDBSS               0x00400718      /* IO Debug Submenu Select */
-
-#define                IIO_IBLS0               0x00410000      /* IO BTE Length Status 0 */
-#define                IIO_IBSA0               0x00410008      /* IO BTE Source Address 0 */
-#define                IIO_IBDA0               0x00410010      /* IO BTE Destination Address 0 */
-#define                IIO_IBCT0               0x00410018      /* IO BTE Control Terminate 0 */
-#define                IIO_IBNA0               0x00410020      /* IO BTE Notification Address 0 */
-#define                IIO_IBIA0               0x00410028      /* IO BTE Interrupt Address 0 */
-#define                IIO_IBLS1               0x00420000      /* IO BTE Length Status 1 */
-#define                IIO_IBSA1               0x00420008      /* IO BTE Source Address 1 */
-#define                IIO_IBDA1               0x00420010      /* IO BTE Destination Address 1 */
-#define                IIO_IBCT1               0x00420018      /* IO BTE Control Terminate 1 */
-#define                IIO_IBNA1               0x00420020      /* IO BTE Notification Address 1 */
-#define                IIO_IBIA1               0x00420028      /* IO BTE Interrupt Address 1 */
-
-#define                IIO_IPCR                0x00430000      /* IO Performance Control */
-#define                IIO_IPPR                0x00430008      /* IO Performance Profiling */
-
-/************************************************************************
- *                                                                     *
- * Description:  This register echoes some information from the         *
- * LB_REV_ID register. It is available through Crosstalk as described   *
- * above. The REV_NUM and MFG_NUM fields receive their values from      *
- * the REVISION and MANUFACTURER fields in the LB_REV_ID register.      *
- * The PART_NUM field's value is the Crosstalk device ID number that    *
- * Steve Miller assigned to the SHub chip.                              *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_wid_u {
-       u64 ii_wid_regval;
-       struct {
-               u64 w_rsvd_1:1;
-               u64 w_mfg_num:11;
-               u64 w_part_num:16;
-               u64 w_rev_num:4;
-               u64 w_rsvd:32;
-       } ii_wid_fld_s;
-} ii_wid_u_t;
-
-/************************************************************************
- *                                                                     *
- *  The fields in this register are set upon detection of an error      *
- * and cleared by various mechanisms, as explained in the               *
- * description.                                                         *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_wstat_u {
-       u64 ii_wstat_regval;
-       struct {
-               u64 w_pending:4;
-               u64 w_xt_crd_to:1;
-               u64 w_xt_tail_to:1;
-               u64 w_rsvd_3:3;
-               u64 w_tx_mx_rty:1;
-               u64 w_rsvd_2:6;
-               u64 w_llp_tx_cnt:8;
-               u64 w_rsvd_1:8;
-               u64 w_crazy:1;
-               u64 w_rsvd:31;
-       } ii_wstat_fld_s;
-} ii_wstat_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  This is a read-write enabled register. It controls     *
- * various aspects of the Crosstalk flow control.                       *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_wcr_u {
-       u64 ii_wcr_regval;
-       struct {
-               u64 w_wid:4;
-               u64 w_tag:1;
-               u64 w_rsvd_1:8;
-               u64 w_dst_crd:3;
-               u64 w_f_bad_pkt:1;
-               u64 w_dir_con:1;
-               u64 w_e_thresh:5;
-               u64 w_rsvd:41;
-       } ii_wcr_fld_s;
-} ii_wcr_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  This register's value is a bit vector that guards      *
- * access to local registers within the II as well as to external       *
- * Crosstalk widgets. Each bit in the register corresponds to a         *
- * particular region in the system; a region consists of one, two or    *
- * four nodes (depending on the value of the REGION_SIZE field in the   *
- * LB_REV_ID register, which is documented in Section 8.3.1.1). The     *
- * protection provided by this register applies to PIO read             *
- * operations as well as PIO write operations. The II will perform a    *
- * PIO read or write request only if the bit for the requestor's        *
- * region is set; otherwise, the II will not perform the requested      *
- * operation and will return an error response. When a PIO read or      *
- * write request targets an external Crosstalk widget, then not only    *
- * must the bit for the requestor's region be set in the ILAPR, but     *
- * also the target widget's bit in the IOWA register must be set in     *
- * order for the II to perform the requested operation; otherwise,      *
- * the II will return an error response. Hence, the protection          *
- * provided by the IOWA register supplements the protection provided    *
- * by the ILAPR for requests that target external Crosstalk widgets.    *
- * This register itself can be accessed only by the nodes whose         *
- * region ID bits are enabled in this same register. It can also be     *
- * accessed through the IAlias space by the local processors.           *
- * The reset value of this register allows access by all nodes.         *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ilapr_u {
-       u64 ii_ilapr_regval;
-       struct {
-               u64 i_region:64;
-       } ii_ilapr_fld_s;
-} ii_ilapr_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  A write to this register of the 64-bit value           *
- * "SGIrules" in ASCII, will cause the bit in the ILAPR register        *
- * corresponding to the region of the requestor to be set (allow        *
- * access). A write of any other value will be ignored. Access          *
- * protection for this register is "SGIrules".                          *
- * This register can also be accessed through the IAlias space.         *
- * However, this access will not change the access permissions in the   *
- * ILAPR.                                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ilapo_u {
-       u64 ii_ilapo_regval;
-       struct {
-               u64 i_io_ovrride:64;
-       } ii_ilapo_fld_s;
-} ii_ilapo_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register qualifies all the PIO and Graphics writes launched    *
- * from the SHUB towards a widget.                                      *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iowa_u {
-       u64 ii_iowa_regval;
-       struct {
-               u64 i_w0_oac:1;
-               u64 i_rsvd_1:7;
-               u64 i_wx_oac:8;
-               u64 i_rsvd:48;
-       } ii_iowa_fld_s;
-} ii_iowa_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  This register qualifies all the requests launched      *
- * from a widget towards the Shub. This register is intended to be      *
- * used by software in case of misbehaving widgets.                     *
- *                                                                     *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iiwa_u {
-       u64 ii_iiwa_regval;
-       struct {
-               u64 i_w0_iac:1;
-               u64 i_rsvd_1:7;
-               u64 i_wx_iac:8;
-               u64 i_rsvd:48;
-       } ii_iiwa_fld_s;
-} ii_iiwa_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  This register qualifies all the operations launched    *
- * from a widget towards the SHub. It allows individual access          *
- * control for up to 8 devices per widget. A device refers to           *
- * individual DMA master hosted by a widget.                            *
- * The bits in each field of this register are cleared by the Shub      *
- * upon detection of an error which requires the device to be           *
- * disabled. These fields assume that 0=TNUM=7 (i.e., Bridge-centric    *
- * Crosstalk). Whether or not a device has access rights to this        *
- * Shub is determined by an AND of the device enable bit in the         *
- * appropriate field of this register and the corresponding bit in      *
- * the Wx_IAC field (for the widget which this device belongs to).      *
- * The bits in this field are set by writing a 1 to them. Incoming      *
- * replies from Crosstalk are not subject to this access control        *
- * mechanism.                                                           *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iidem_u {
-       u64 ii_iidem_regval;
-       struct {
-               u64 i_w8_dxs:8;
-               u64 i_w9_dxs:8;
-               u64 i_wa_dxs:8;
-               u64 i_wb_dxs:8;
-               u64 i_wc_dxs:8;
-               u64 i_wd_dxs:8;
-               u64 i_we_dxs:8;
-               u64 i_wf_dxs:8;
-       } ii_iidem_fld_s;
-} ii_iidem_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register contains the various programmable fields necessary    *
- * for controlling and observing the LLP signals.                       *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ilcsr_u {
-       u64 ii_ilcsr_regval;
-       struct {
-               u64 i_nullto:6;
-               u64 i_rsvd_4:2;
-               u64 i_wrmrst:1;
-               u64 i_rsvd_3:1;
-               u64 i_llp_en:1;
-               u64 i_bm8:1;
-               u64 i_llp_stat:2;
-               u64 i_remote_power:1;
-               u64 i_rsvd_2:1;
-               u64 i_maxrtry:10;
-               u64 i_d_avail_sel:2;
-               u64 i_rsvd_1:4;
-               u64 i_maxbrst:10;
-               u64 i_rsvd:22;
-
-       } ii_ilcsr_fld_s;
-} ii_ilcsr_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This is simply a status registers that monitors the LLP error       *
- * rate.                                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_illr_u {
-       u64 ii_illr_regval;
-       struct {
-               u64 i_sn_cnt:16;
-               u64 i_cb_cnt:16;
-               u64 i_rsvd:32;
-       } ii_illr_fld_s;
-} ii_illr_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  All II-detected non-BTE error interrupts are           *
- * specified via this register.                                         *
- * NOTE: The PI interrupt register address is hardcoded in the II. If   *
- * PI_ID==0, then the II sends an interrupt request (Duplonet PWRI      *
- * packet) to address offset 0x0180_0090 within the local register      *
- * address space of PI0 on the node specified by the NODE field. If     *
- * PI_ID==1, then the II sends the interrupt request to address         *
- * offset 0x01A0_0090 within the local register address space of PI1    *
- * on the node specified by the NODE field.                             *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iidsr_u {
-       u64 ii_iidsr_regval;
-       struct {
-               u64 i_level:8;
-               u64 i_pi_id:1;
-               u64 i_node:11;
-               u64 i_rsvd_3:4;
-               u64 i_enable:1;
-               u64 i_rsvd_2:3;
-               u64 i_int_sent:2;
-               u64 i_rsvd_1:2;
-               u64 i_pi0_forward_int:1;
-               u64 i_pi1_forward_int:1;
-               u64 i_rsvd:30;
-       } ii_iidsr_fld_s;
-} ii_iidsr_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are two instances of this register. This register is used     *
- * for matching up the incoming responses from the graphics widget to   *
- * the processor that initiated the graphics operation. The             *
- * write-responses are converted to graphics credits and returned to    *
- * the processor so that the processor interface can manage the flow    *
- * control.                                                             *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_igfx0_u {
-       u64 ii_igfx0_regval;
-       struct {
-               u64 i_w_num:4;
-               u64 i_pi_id:1;
-               u64 i_n_num:12;
-               u64 i_p_num:1;
-               u64 i_rsvd:46;
-       } ii_igfx0_fld_s;
-} ii_igfx0_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are two instances of this register. This register is used     *
- * for matching up the incoming responses from the graphics widget to   *
- * the processor that initiated the graphics operation. The             *
- * write-responses are converted to graphics credits and returned to    *
- * the processor so that the processor interface can manage the flow    *
- * control.                                                             *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_igfx1_u {
-       u64 ii_igfx1_regval;
-       struct {
-               u64 i_w_num:4;
-               u64 i_pi_id:1;
-               u64 i_n_num:12;
-               u64 i_p_num:1;
-               u64 i_rsvd:46;
-       } ii_igfx1_fld_s;
-} ii_igfx1_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are two instances of this registers. These registers are      *
- * used as scratch registers for software use.                          *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iscr0_u {
-       u64 ii_iscr0_regval;
-       struct {
-               u64 i_scratch:64;
-       } ii_iscr0_fld_s;
-} ii_iscr0_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are two instances of this registers. These registers are      *
- * used as scratch registers for software use.                          *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iscr1_u {
-       u64 ii_iscr1_regval;
-       struct {
-               u64 i_scratch:64;
-       } ii_iscr1_fld_s;
-} ii_iscr1_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Shub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the SHub is thus the lower 16 GBytes per widget       * 
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Shub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_itte1_u {
-       u64 ii_itte1_regval;
-       struct {
-               u64 i_offset:5;
-               u64 i_rsvd_1:3;
-               u64 i_w_num:4;
-               u64 i_iosp:1;
-               u64 i_rsvd:51;
-       } ii_itte1_fld_s;
-} ii_itte1_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Shub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Shub is thus the lower 16 GBytes per widget       *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Shub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_itte2_u {
-       u64 ii_itte2_regval;
-       struct {
-               u64 i_offset:5;
-               u64 i_rsvd_1:3;
-               u64 i_w_num:4;
-               u64 i_iosp:1;
-               u64 i_rsvd:51;
-       } ii_itte2_fld_s;
-} ii_itte2_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Shub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Shub is thus the lower 16 GBytes per widget       *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the SHub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_itte3_u {
-       u64 ii_itte3_regval;
-       struct {
-               u64 i_offset:5;
-               u64 i_rsvd_1:3;
-               u64 i_w_num:4;
-               u64 i_iosp:1;
-               u64 i_rsvd:51;
-       } ii_itte3_fld_s;
-} ii_itte3_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a SHub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the SHub is thus the lower 16 GBytes per widget       *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the SHub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_itte4_u {
-       u64 ii_itte4_regval;
-       struct {
-               u64 i_offset:5;
-               u64 i_rsvd_1:3;
-               u64 i_w_num:4;
-               u64 i_iosp:1;
-               u64 i_rsvd:51;
-       } ii_itte4_fld_s;
-} ii_itte4_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a SHub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Shub is thus the lower 16 GBytes per widget       *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Shub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_itte5_u {
-       u64 ii_itte5_regval;
-       struct {
-               u64 i_offset:5;
-               u64 i_rsvd_1:3;
-               u64 i_w_num:4;
-               u64 i_iosp:1;
-               u64 i_rsvd:51;
-       } ii_itte5_fld_s;
-} ii_itte5_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Shub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Shub is thus the lower 16 GBytes per widget       *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Shub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_itte6_u {
-       u64 ii_itte6_regval;
-       struct {
-               u64 i_offset:5;
-               u64 i_rsvd_1:3;
-               u64 i_w_num:4;
-               u64 i_iosp:1;
-               u64 i_rsvd:51;
-       } ii_itte6_fld_s;
-} ii_itte6_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Shub Big Window to a 48-bit          *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Shub is thus the lower 16 GBytes per widget       *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the SHub is thus the lower            *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_itte7_u {
-       u64 ii_itte7_regval;
-       struct {
-               u64 i_offset:5;
-               u64 i_rsvd_1:3;
-               u64 i_w_num:4;
-               u64 i_iosp:1;
-               u64 i_rsvd:51;
-       } ii_itte7_fld_s;
-} ii_itte7_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                   *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprb0_u {
-       u64 ii_iprb0_regval;
-       struct {
-               u64 i_c:8;
-               u64 i_na:14;
-               u64 i_rsvd_2:2;
-               u64 i_nb:14;
-               u64 i_rsvd_1:2;
-               u64 i_m:2;
-               u64 i_f:1;
-               u64 i_of_cnt:5;
-               u64 i_error:1;
-               u64 i_rd_to:1;
-               u64 i_spur_wr:1;
-               u64 i_spur_rd:1;
-               u64 i_rsvd:11;
-               u64 i_mult_err:1;
-       } ii_iprb0_fld_s;
-} ii_iprb0_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                   *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprb8_u {
-       u64 ii_iprb8_regval;
-       struct {
-               u64 i_c:8;
-               u64 i_na:14;
-               u64 i_rsvd_2:2;
-               u64 i_nb:14;
-               u64 i_rsvd_1:2;
-               u64 i_m:2;
-               u64 i_f:1;
-               u64 i_of_cnt:5;
-               u64 i_error:1;
-               u64 i_rd_to:1;
-               u64 i_spur_wr:1;
-               u64 i_spur_rd:1;
-               u64 i_rsvd:11;
-               u64 i_mult_err:1;
-       } ii_iprb8_fld_s;
-} ii_iprb8_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                   *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprb9_u {
-       u64 ii_iprb9_regval;
-       struct {
-               u64 i_c:8;
-               u64 i_na:14;
-               u64 i_rsvd_2:2;
-               u64 i_nb:14;
-               u64 i_rsvd_1:2;
-               u64 i_m:2;
-               u64 i_f:1;
-               u64 i_of_cnt:5;
-               u64 i_error:1;
-               u64 i_rd_to:1;
-               u64 i_spur_wr:1;
-               u64 i_spur_rd:1;
-               u64 i_rsvd:11;
-               u64 i_mult_err:1;
-       } ii_iprb9_fld_s;
-} ii_iprb9_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- *                                                                     *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprba_u {
-       u64 ii_iprba_regval;
-       struct {
-               u64 i_c:8;
-               u64 i_na:14;
-               u64 i_rsvd_2:2;
-               u64 i_nb:14;
-               u64 i_rsvd_1:2;
-               u64 i_m:2;
-               u64 i_f:1;
-               u64 i_of_cnt:5;
-               u64 i_error:1;
-               u64 i_rd_to:1;
-               u64 i_spur_wr:1;
-               u64 i_spur_rd:1;
-               u64 i_rsvd:11;
-               u64 i_mult_err:1;
-       } ii_iprba_fld_s;
-} ii_iprba_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                   *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprbb_u {
-       u64 ii_iprbb_regval;
-       struct {
-               u64 i_c:8;
-               u64 i_na:14;
-               u64 i_rsvd_2:2;
-               u64 i_nb:14;
-               u64 i_rsvd_1:2;
-               u64 i_m:2;
-               u64 i_f:1;
-               u64 i_of_cnt:5;
-               u64 i_error:1;
-               u64 i_rd_to:1;
-               u64 i_spur_wr:1;
-               u64 i_spur_rd:1;
-               u64 i_rsvd:11;
-               u64 i_mult_err:1;
-       } ii_iprbb_fld_s;
-} ii_iprbb_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                   *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprbc_u {
-       u64 ii_iprbc_regval;
-       struct {
-               u64 i_c:8;
-               u64 i_na:14;
-               u64 i_rsvd_2:2;
-               u64 i_nb:14;
-               u64 i_rsvd_1:2;
-               u64 i_m:2;
-               u64 i_f:1;
-               u64 i_of_cnt:5;
-               u64 i_error:1;
-               u64 i_rd_to:1;
-               u64 i_spur_wr:1;
-               u64 i_spur_rd:1;
-               u64 i_rsvd:11;
-               u64 i_mult_err:1;
-       } ii_iprbc_fld_s;
-} ii_iprbc_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                   *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprbd_u {
-       u64 ii_iprbd_regval;
-       struct {
-               u64 i_c:8;
-               u64 i_na:14;
-               u64 i_rsvd_2:2;
-               u64 i_nb:14;
-               u64 i_rsvd_1:2;
-               u64 i_m:2;
-               u64 i_f:1;
-               u64 i_of_cnt:5;
-               u64 i_error:1;
-               u64 i_rd_to:1;
-               u64 i_spur_wr:1;
-               u64 i_spur_rd:1;
-               u64 i_rsvd:11;
-               u64 i_mult_err:1;
-       } ii_iprbd_fld_s;
-} ii_iprbd_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of SHub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                   *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprbe_u {
-       u64 ii_iprbe_regval;
-       struct {
-               u64 i_c:8;
-               u64 i_na:14;
-               u64 i_rsvd_2:2;
-               u64 i_nb:14;
-               u64 i_rsvd_1:2;
-               u64 i_m:2;
-               u64 i_f:1;
-               u64 i_of_cnt:5;
-               u64 i_error:1;
-               u64 i_rd_to:1;
-               u64 i_spur_wr:1;
-               u64 i_spur_rd:1;
-               u64 i_rsvd:11;
-               u64 i_mult_err:1;
-       } ii_iprbe_fld_s;
-} ii_iprbe_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Shub and Crossbow.           *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                   *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprbf_u {
-       u64 ii_iprbf_regval;
-       struct {
-               u64 i_c:8;
-               u64 i_na:14;
-               u64 i_rsvd_2:2;
-               u64 i_nb:14;
-               u64 i_rsvd_1:2;
-               u64 i_m:2;
-               u64 i_f:1;
-               u64 i_of_cnt:5;
-               u64 i_error:1;
-               u64 i_rd_to:1;
-               u64 i_spur_wr:1;
-               u64 i_spur_rd:1;
-               u64 i_rsvd:11;
-               u64 i_mult_err:1;
-       } ii_iprbe_fld_s;
-} ii_iprbf_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register specifies the timeout value to use for monitoring     *
- * Crosstalk credits which are used outbound to Crosstalk. An           *
- * internal counter called the Crosstalk Credit Timeout Counter         *
- * increments every 128 II clocks. The counter starts counting          *
- * anytime the credit count drops below a threshold, and resets to      *
- * zero (stops counting) anytime the credit count is at or above the    *
- * threshold. The threshold is 1 credit in direct connect mode and 2    *
- * in Crossbow connect mode. When the internal Crosstalk Credit         *
- * Timeout Counter reaches the value programmed in this register, a     *
- * Crosstalk Credit Timeout has occurred. The internal counter is not   *
- * readable from software, and stops counting at its maximum value,     *
- * so it cannot cause more than one interrupt.                          *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ixcc_u {
-       u64 ii_ixcc_regval;
-       struct {
-               u64 i_time_out:26;
-               u64 i_rsvd:38;
-       } ii_ixcc_fld_s;
-} ii_ixcc_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  This register qualifies all the PIO and DMA            *
- * operations launched from widget 0 towards the SHub. In               *
- * addition, it also qualifies accesses by the BTE streams.             *
- * The bits in each field of this register are cleared by the SHub      *
- * upon detection of an error which requires widget 0 or the BTE        *
- * streams to be terminated. Whether or not widget x has access         *
- * rights to this SHub is determined by an AND of the device            *
- * enable bit in the appropriate field of this register and bit 0 in    *
- * the Wx_IAC field. The bits in this field are set by writing a 1 to   *
- * them. Incoming replies from Crosstalk are not subject to this        *
- * access control mechanism.                                            *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_imem_u {
-       u64 ii_imem_regval;
-       struct {
-               u64 i_w0_esd:1;
-               u64 i_rsvd_3:3;
-               u64 i_b0_esd:1;
-               u64 i_rsvd_2:3;
-               u64 i_b1_esd:1;
-               u64 i_rsvd_1:3;
-               u64 i_clr_precise:1;
-               u64 i_rsvd:51;
-       } ii_imem_fld_s;
-} ii_imem_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  This register specifies the timeout value to use for   *
- * monitoring Crosstalk tail flits coming into the Shub in the          *
- * TAIL_TO field. An internal counter associated with this register     *
- * is incremented every 128 II internal clocks (7 bits). The counter    *
- * starts counting anytime a header micropacket is received and stops   *
- * counting (and resets to zero) any time a micropacket with a Tail     *
- * bit is received. Once the counter reaches the threshold value        *
- * programmed in this register, it generates an interrupt to the        *
- * processor that is programmed into the IIDSR. The counter saturates   *
- * (does not roll over) at its maximum value, so it cannot cause        *
- * another interrupt until after it is cleared.                         *
- * The register also contains the Read Response Timeout values. The     *
- * Prescalar is 23 bits, and counts II clocks. An internal counter      *
- * increments on every II clock and when it reaches the value in the    *
- * Prescalar field, all IPRTE registers with their valid bits set       *
- * have their Read Response timers bumped. Whenever any of them match   *
- * the value in the RRSP_TO field, a Read Response Timeout has          *
- * occurred, and error handling occurs as described in the Error        *
- * Handling section of this document.                                   *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ixtt_u {
-       u64 ii_ixtt_regval;
-       struct {
-               u64 i_tail_to:26;
-               u64 i_rsvd_1:6;
-               u64 i_rrsp_ps:23;
-               u64 i_rrsp_to:5;
-               u64 i_rsvd:4;
-       } ii_ixtt_fld_s;
-} ii_ixtt_u_t;
-
-/************************************************************************
- *                                                                     *
- *  Writing a 1 to the fields of this register clears the appropriate   *
- * error bits in other areas of SHub. Note that when the                *
- * E_PRB_x bits are used to clear error bits in PRB registers,          *
- * SPUR_RD and SPUR_WR may persist, because they require additional     *
- * action to clear them. See the IPRBx and IXSS Register                *
- * specifications.                                                      *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ieclr_u {
-       u64 ii_ieclr_regval;
-       struct {
-               u64 i_e_prb_0:1;
-               u64 i_rsvd:7;
-               u64 i_e_prb_8:1;
-               u64 i_e_prb_9:1;
-               u64 i_e_prb_a:1;
-               u64 i_e_prb_b:1;
-               u64 i_e_prb_c:1;
-               u64 i_e_prb_d:1;
-               u64 i_e_prb_e:1;
-               u64 i_e_prb_f:1;
-               u64 i_e_crazy:1;
-               u64 i_e_bte_0:1;
-               u64 i_e_bte_1:1;
-               u64 i_reserved_1:10;
-               u64 i_spur_rd_hdr:1;
-               u64 i_cam_intr_to:1;
-               u64 i_cam_overflow:1;
-               u64 i_cam_read_miss:1;
-               u64 i_ioq_rep_underflow:1;
-               u64 i_ioq_req_underflow:1;
-               u64 i_ioq_rep_overflow:1;
-               u64 i_ioq_req_overflow:1;
-               u64 i_iiq_rep_overflow:1;
-               u64 i_iiq_req_overflow:1;
-               u64 i_ii_xn_rep_cred_overflow:1;
-               u64 i_ii_xn_req_cred_overflow:1;
-               u64 i_ii_xn_invalid_cmd:1;
-               u64 i_xn_ii_invalid_cmd:1;
-               u64 i_reserved_2:21;
-       } ii_ieclr_fld_s;
-} ii_ieclr_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register controls both BTEs. SOFT_RESET is intended for        *
- * recovery after an error. COUNT controls the total number of CRBs     *
- * that both BTEs (combined) can use, which affects total BTE           *
- * bandwidth.                                                           *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibcr_u {
-       u64 ii_ibcr_regval;
-       struct {
-               u64 i_count:4;
-               u64 i_rsvd_1:4;
-               u64 i_soft_reset:1;
-               u64 i_rsvd:55;
-       } ii_ibcr_fld_s;
-} ii_ibcr_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register contains the header of a spurious read response       *
- * received from Crosstalk. A spurious read response is defined as a    *
- * read response received by II from a widget for which (1) the SIDN    *
- * has a value between 1 and 7, inclusive (II never sends requests to   *
- * these widgets (2) there is no valid IPRTE register which             *
- * corresponds to the TNUM, or (3) the widget indicated in SIDN is      *
- * not the same as the widget recorded in the IPRTE register            *
- * referenced by the TNUM. If this condition is true, and if the        *
- * IXSS[VALID] bit is clear, then the header of the spurious read       *
- * response is capture in IXSM and IXSS, and IXSS[VALID] is set. The    *
- * errant header is thereby captured, and no further spurious read      *
- * respones are captured until IXSS[VALID] is cleared by setting the    *
- * appropriate bit in IECLR. Every time a spurious read response is     *
- * detected, the SPUR_RD bit of the PRB corresponding to the incoming   *
- * message's SIDN field is set. This always happens, regardless of       *
- * whether a header is captured. The programmer should check            *
- * IXSM[SIDN] to determine which widget sent the spurious response,     *
- * because there may be more than one SPUR_RD bit set in the PRB        *
- * registers. The widget indicated by IXSM[SIDN] was the first          *
- * spurious read response to be received since the last time            *
- * IXSS[VALID] was clear. The SPUR_RD bit of the corresponding PRB      *
- * will be set. Any SPUR_RD bits in any other PRB registers indicate    *
- * spurious messages from other widets which were detected after the    *
- * header was captured..                                                *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ixsm_u {
-       u64 ii_ixsm_regval;
-       struct {
-               u64 i_byte_en:32;
-               u64 i_reserved:1;
-               u64 i_tag:3;
-               u64 i_alt_pactyp:4;
-               u64 i_bo:1;
-               u64 i_error:1;
-               u64 i_vbpm:1;
-               u64 i_gbr:1;
-               u64 i_ds:2;
-               u64 i_ct:1;
-               u64 i_tnum:5;
-               u64 i_pactyp:4;
-               u64 i_sidn:4;
-               u64 i_didn:4;
-       } ii_ixsm_fld_s;
-} ii_ixsm_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register contains the sideband bits of a spurious read         *
- * response received from Crosstalk.                                    *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ixss_u {
-       u64 ii_ixss_regval;
-       struct {
-               u64 i_sideband:8;
-               u64 i_rsvd:55;
-               u64 i_valid:1;
-       } ii_ixss_fld_s;
-} ii_ixss_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register enables software to access the II LLP's test port.    *
- * Refer to the LLP 2.5 documentation for an explanation of the test    *
- * port. Software can write to this register to program the values      *
- * for the control fields (TestErrCapture, TestClear, TestFlit,         *
- * TestMask and TestSeed). Similarly, software can read from this       *
- * register to obtain the values of the test port's status outputs      *
- * (TestCBerr, TestValid and TestData).                                 *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ilct_u {
-       u64 ii_ilct_regval;
-       struct {
-               u64 i_test_seed:20;
-               u64 i_test_mask:8;
-               u64 i_test_data:20;
-               u64 i_test_valid:1;
-               u64 i_test_cberr:1;
-               u64 i_test_flit:3;
-               u64 i_test_clear:1;
-               u64 i_test_err_capture:1;
-               u64 i_rsvd:9;
-       } ii_ilct_fld_s;
-} ii_ilct_u_t;
-
-/************************************************************************
- *                                                                     *
- *  If the II detects an illegal incoming Duplonet packet (request or   *
- * reply) when VALID==0 in the IIEPH1 register, then it saves the       *
- * contents of the packet's header flit in the IIEPH1 and IIEPH2        *
- * registers, sets the VALID bit in IIEPH1, clears the OVERRUN bit,     *
- * and assigns a value to the ERR_TYPE field which indicates the        *
- * specific nature of the error. The II recognizes four different       *
- * types of errors: short request packets (ERR_TYPE==2), short reply    *
- * packets (ERR_TYPE==3), long request packets (ERR_TYPE==4) and long   *
- * reply packets (ERR_TYPE==5). The encodings for these types of        *
- * errors were chosen to be consistent with the same types of errors    *
- * indicated by the ERR_TYPE field in the LB_ERROR_HDR1 register (in    *
- * the LB unit). If the II detects an illegal incoming Duplonet         *
- * packet when VALID==1 in the IIEPH1 register, then it merely sets     *
- * the OVERRUN bit to indicate that a subsequent error has happened,    *
- * and does nothing further.                                            *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iieph1_u {
-       u64 ii_iieph1_regval;
-       struct {
-               u64 i_command:7;
-               u64 i_rsvd_5:1;
-               u64 i_suppl:14;
-               u64 i_rsvd_4:1;
-               u64 i_source:14;
-               u64 i_rsvd_3:1;
-               u64 i_err_type:4;
-               u64 i_rsvd_2:4;
-               u64 i_overrun:1;
-               u64 i_rsvd_1:3;
-               u64 i_valid:1;
-               u64 i_rsvd:13;
-       } ii_iieph1_fld_s;
-} ii_iieph1_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register holds the Address field from the header flit of an    *
- * incoming erroneous Duplonet packet, along with the tail bit which    *
- * accompanied this header flit. This register is essentially an        *
- * extension of IIEPH1. Two registers were necessary because the 64     *
- * bits available in only a single register were insufficient to        *
- * capture the entire header flit of an erroneous packet.               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iieph2_u {
-       u64 ii_iieph2_regval;
-       struct {
-               u64 i_rsvd_0:3;
-               u64 i_address:47;
-               u64 i_rsvd_1:10;
-               u64 i_tail:1;
-               u64 i_rsvd:3;
-       } ii_iieph2_fld_s;
-} ii_iieph2_u_t;
-
-/******************************/
-
-/************************************************************************
- *                                                                     *
- *  This register's value is a bit vector that guards access from SXBs  *
- * to local registers within the II as well as to external Crosstalk    *
- * widgets                                                             *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_islapr_u {
-       u64 ii_islapr_regval;
-       struct {
-               u64 i_region:64;
-       } ii_islapr_fld_s;
-} ii_islapr_u_t;
-
-/************************************************************************
- *                                                                     *
- *  A write to this register of the 56-bit value "Pup+Bun" will cause  *
- * the bit in the ISLAPR register corresponding to the region of the   *
- * requestor to be set (access allowed).                               (
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_islapo_u {
-       u64 ii_islapo_regval;
-       struct {
-               u64 i_io_sbx_ovrride:56;
-               u64 i_rsvd:8;
-       } ii_islapo_fld_s;
-} ii_islapo_u_t;
-
-/************************************************************************
- *                                                                     *
- *  Determines how long the wrapper will wait aftr an interrupt is     *
- * initially issued from the II before it times out the outstanding    *
- * interrupt and drops it from the interrupt queue.                    * 
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iwi_u {
-       u64 ii_iwi_regval;
-       struct {
-               u64 i_prescale:24;
-               u64 i_rsvd:8;
-               u64 i_timeout:8;
-               u64 i_rsvd1:8;
-               u64 i_intrpt_retry_period:8;
-               u64 i_rsvd2:8;
-       } ii_iwi_fld_s;
-} ii_iwi_u_t;
-
-/************************************************************************
- *                                                                     *
- *  Log errors which have occurred in the II wrapper. The errors are   *
- * cleared by writing to the IECLR register.                           * 
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iwel_u {
-       u64 ii_iwel_regval;
-       struct {
-               u64 i_intr_timed_out:1;
-               u64 i_rsvd:7;
-               u64 i_cam_overflow:1;
-               u64 i_cam_read_miss:1;
-               u64 i_rsvd1:2;
-               u64 i_ioq_rep_underflow:1;
-               u64 i_ioq_req_underflow:1;
-               u64 i_ioq_rep_overflow:1;
-               u64 i_ioq_req_overflow:1;
-               u64 i_iiq_rep_overflow:1;
-               u64 i_iiq_req_overflow:1;
-               u64 i_rsvd2:6;
-               u64 i_ii_xn_rep_cred_over_under:1;
-               u64 i_ii_xn_req_cred_over_under:1;
-               u64 i_rsvd3:6;
-               u64 i_ii_xn_invalid_cmd:1;
-               u64 i_xn_ii_invalid_cmd:1;
-               u64 i_rsvd4:30;
-       } ii_iwel_fld_s;
-} ii_iwel_u_t;
-
-/************************************************************************
- *                                                                     *
- *  Controls the II wrapper.                                           * 
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iwc_u {
-       u64 ii_iwc_regval;
-       struct {
-               u64 i_dma_byte_swap:1;
-               u64 i_rsvd:3;
-               u64 i_cam_read_lines_reset:1;
-               u64 i_rsvd1:3;
-               u64 i_ii_xn_cred_over_under_log:1;
-               u64 i_rsvd2:19;
-               u64 i_xn_rep_iq_depth:5;
-               u64 i_rsvd3:3;
-               u64 i_xn_req_iq_depth:5;
-               u64 i_rsvd4:3;
-               u64 i_iiq_depth:6;
-               u64 i_rsvd5:12;
-               u64 i_force_rep_cred:1;
-               u64 i_force_req_cred:1;
-       } ii_iwc_fld_s;
-} ii_iwc_u_t;
-
-/************************************************************************
- *                                                                     *
- *  Status in the II wrapper.                                          * 
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iws_u {
-       u64 ii_iws_regval;
-       struct {
-               u64 i_xn_rep_iq_credits:5;
-               u64 i_rsvd:3;
-               u64 i_xn_req_iq_credits:5;
-               u64 i_rsvd1:51;
-       } ii_iws_fld_s;
-} ii_iws_u_t;
-
-/************************************************************************
- *                                                                     *
- *  Masks errors in the IWEL register.                                 *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iweim_u {
-       u64 ii_iweim_regval;
-       struct {
-               u64 i_intr_timed_out:1;
-               u64 i_rsvd:7;
-               u64 i_cam_overflow:1;
-               u64 i_cam_read_miss:1;
-               u64 i_rsvd1:2;
-               u64 i_ioq_rep_underflow:1;
-               u64 i_ioq_req_underflow:1;
-               u64 i_ioq_rep_overflow:1;
-               u64 i_ioq_req_overflow:1;
-               u64 i_iiq_rep_overflow:1;
-               u64 i_iiq_req_overflow:1;
-               u64 i_rsvd2:6;
-               u64 i_ii_xn_rep_cred_overflow:1;
-               u64 i_ii_xn_req_cred_overflow:1;
-               u64 i_rsvd3:6;
-               u64 i_ii_xn_invalid_cmd:1;
-               u64 i_xn_ii_invalid_cmd:1;
-               u64 i_rsvd4:30;
-       } ii_iweim_fld_s;
-} ii_iweim_u_t;
-
-/************************************************************************
- *                                                                     *
- *  A write to this register causes a particular field in the           *
- * corresponding widget's PRB entry to be adjusted up or down by 1.     *
- * This counter should be used when recovering from error and reset     *
- * conditions. Note that software would be capable of causing           *
- * inadvertent overflow or underflow of these counters.                 *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ipca_u {
-       u64 ii_ipca_regval;
-       struct {
-               u64 i_wid:4;
-               u64 i_adjust:1;
-               u64 i_rsvd_1:3;
-               u64 i_field:2;
-               u64 i_rsvd:54;
-       } ii_ipca_fld_s;
-} ii_ipca_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte0a_u {
-       u64 ii_iprte0a_regval;
-       struct {
-               u64 i_rsvd_1:54;
-               u64 i_widget:4;
-               u64 i_to_cnt:5;
-               u64 i_vld:1;
-       } ii_iprte0a_fld_s;
-} ii_iprte0a_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte1a_u {
-       u64 ii_iprte1a_regval;
-       struct {
-               u64 i_rsvd_1:54;
-               u64 i_widget:4;
-               u64 i_to_cnt:5;
-               u64 i_vld:1;
-       } ii_iprte1a_fld_s;
-} ii_iprte1a_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte2a_u {
-       u64 ii_iprte2a_regval;
-       struct {
-               u64 i_rsvd_1:54;
-               u64 i_widget:4;
-               u64 i_to_cnt:5;
-               u64 i_vld:1;
-       } ii_iprte2a_fld_s;
-} ii_iprte2a_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte3a_u {
-       u64 ii_iprte3a_regval;
-       struct {
-               u64 i_rsvd_1:54;
-               u64 i_widget:4;
-               u64 i_to_cnt:5;
-               u64 i_vld:1;
-       } ii_iprte3a_fld_s;
-} ii_iprte3a_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte4a_u {
-       u64 ii_iprte4a_regval;
-       struct {
-               u64 i_rsvd_1:54;
-               u64 i_widget:4;
-               u64 i_to_cnt:5;
-               u64 i_vld:1;
-       } ii_iprte4a_fld_s;
-} ii_iprte4a_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte5a_u {
-       u64 ii_iprte5a_regval;
-       struct {
-               u64 i_rsvd_1:54;
-               u64 i_widget:4;
-               u64 i_to_cnt:5;
-               u64 i_vld:1;
-       } ii_iprte5a_fld_s;
-} ii_iprte5a_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte6a_u {
-       u64 ii_iprte6a_regval;
-       struct {
-               u64 i_rsvd_1:54;
-               u64 i_widget:4;
-               u64 i_to_cnt:5;
-               u64 i_vld:1;
-       } ii_iprte6a_fld_s;
-} ii_iprte6a_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte7a_u {
-       u64 ii_iprte7a_regval;
-       struct {
-               u64 i_rsvd_1:54;
-               u64 i_widget:4;
-               u64 i_to_cnt:5;
-               u64 i_vld:1;
-       } ii_iprtea7_fld_s;
-} ii_iprte7a_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte0b_u {
-       u64 ii_iprte0b_regval;
-       struct {
-               u64 i_rsvd_1:3;
-               u64 i_address:47;
-               u64 i_init:3;
-               u64 i_source:11;
-       } ii_iprte0b_fld_s;
-} ii_iprte0b_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte1b_u {
-       u64 ii_iprte1b_regval;
-       struct {
-               u64 i_rsvd_1:3;
-               u64 i_address:47;
-               u64 i_init:3;
-               u64 i_source:11;
-       } ii_iprte1b_fld_s;
-} ii_iprte1b_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte2b_u {
-       u64 ii_iprte2b_regval;
-       struct {
-               u64 i_rsvd_1:3;
-               u64 i_address:47;
-               u64 i_init:3;
-               u64 i_source:11;
-       } ii_iprte2b_fld_s;
-} ii_iprte2b_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte3b_u {
-       u64 ii_iprte3b_regval;
-       struct {
-               u64 i_rsvd_1:3;
-               u64 i_address:47;
-               u64 i_init:3;
-               u64 i_source:11;
-       } ii_iprte3b_fld_s;
-} ii_iprte3b_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte4b_u {
-       u64 ii_iprte4b_regval;
-       struct {
-               u64 i_rsvd_1:3;
-               u64 i_address:47;
-               u64 i_init:3;
-               u64 i_source:11;
-       } ii_iprte4b_fld_s;
-} ii_iprte4b_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte5b_u {
-       u64 ii_iprte5b_regval;
-       struct {
-               u64 i_rsvd_1:3;
-               u64 i_address:47;
-               u64 i_init:3;
-               u64 i_source:11;
-       } ii_iprte5b_fld_s;
-} ii_iprte5b_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte6b_u {
-       u64 ii_iprte6b_regval;
-       struct {
-               u64 i_rsvd_1:3;
-               u64 i_address:47;
-               u64 i_init:3;
-               u64 i_source:11;
-
-       } ii_iprte6b_fld_s;
-} ii_iprte6b_u_t;
-
-/************************************************************************
- *                                                                     *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iprte7b_u {
-       u64 ii_iprte7b_regval;
-       struct {
-               u64 i_rsvd_1:3;
-               u64 i_address:47;
-               u64 i_init:3;
-               u64 i_source:11;
-       } ii_iprte7b_fld_s;
-} ii_iprte7b_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  SHub II contains a feature which did not exist in      *
- * the Hub which automatically cleans up after a Read Response          *
- * timeout, including deallocation of the IPRTE and recovery of IBuf    *
- * space. The inclusion of this register in SHub is for backward        *
- * compatibility                                                        *
- * A write to this register causes an entry from the table of           *
- * outstanding PIO Read Requests to be freed and returned to the        *
- * stack of free entries. This register is used in handling the         *
- * timeout errors that result in a PIO Reply never returning from       *
- * Crosstalk.                                                           *
- * Note that this register does not affect the contents of the IPRTE    *
- * registers. The Valid bits in those registers have to be              *
- * specifically turned off by software.                                 *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ipdr_u {
-       u64 ii_ipdr_regval;
-       struct {
-               u64 i_te:3;
-               u64 i_rsvd_1:1;
-               u64 i_pnd:1;
-               u64 i_init_rpcnt:1;
-               u64 i_rsvd:58;
-       } ii_ipdr_fld_s;
-} ii_ipdr_u_t;
-
-/************************************************************************
- *                                                                     *
- *  A write to this register causes a CRB entry to be returned to the   *
- * queue of free CRBs. The entry should have previously been cleared    *
- * (mark bit) via backdoor access to the pertinent CRB entry. This      *
- * register is used in the last step of handling the errors that are    *
- * captured and marked in CRB entries.  Briefly: 1) first error for     *
- * DMA write from a particular device, and first error for a            *
- * particular BTE stream, lead to a marked CRB entry, and processor     *
- * interrupt, 2) software reads the error information captured in the   *
- * CRB entry, and presumably takes some corrective action, 3)           *
- * software clears the mark bit, and finally 4) software writes to      *
- * the ICDR register to return the CRB entry to the list of free CRB    *
- * entries.                                                             *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_icdr_u {
-       u64 ii_icdr_regval;
-       struct {
-               u64 i_crb_num:4;
-               u64 i_pnd:1;
-               u64 i_rsvd:59;
-       } ii_icdr_fld_s;
-} ii_icdr_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register provides debug access to two FIFOs inside of II.      *
- * Both IOQ_MAX* fields of this register contain the instantaneous      *
- * depth (in units of the number of available entries) of the           *
- * associated IOQ FIFO.  A read of this register will return the        *
- * number of free entries on each FIFO at the time of the read.  So     *
- * when a FIFO is idle, the associated field contains the maximum       *
- * depth of the FIFO.  This register is writable for debug reasons      *
- * and is intended to be written with the maximum desired FIFO depth    *
- * while the FIFO is idle. Software must assure that II is idle when    *
- * this register is written. If there are any active entries in any     *
- * of these FIFOs when this register is written, the results are        *
- * undefined.                                                           *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ifdr_u {
-       u64 ii_ifdr_regval;
-       struct {
-               u64 i_ioq_max_rq:7;
-               u64 i_set_ioq_rq:1;
-               u64 i_ioq_max_rp:7;
-               u64 i_set_ioq_rp:1;
-               u64 i_rsvd:48;
-       } ii_ifdr_fld_s;
-} ii_ifdr_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register allows the II to become sluggish in removing          *
- * messages from its inbound queue (IIQ). This will cause messages to   *
- * back up in either virtual channel. Disabling the "molasses" mode     *
- * subsequently allows the II to be tested under stress. In the         *
- * sluggish ("Molasses") mode, the localized effects of congestion      *
- * can be observed.                                                     *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iiap_u {
-       u64 ii_iiap_regval;
-       struct {
-               u64 i_rq_mls:6;
-               u64 i_rsvd_1:2;
-               u64 i_rp_mls:6;
-               u64 i_rsvd:50;
-       } ii_iiap_fld_s;
-} ii_iiap_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register allows several parameters of CRB operation to be      *
- * set. Note that writing to this register can have catastrophic side   *
- * effects, if the CRB is not quiescent, i.e. if the CRB is             *
- * processing protocol messages when the write occurs.                  *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_icmr_u {
-       u64 ii_icmr_regval;
-       struct {
-               u64 i_sp_msg:1;
-               u64 i_rd_hdr:1;
-               u64 i_rsvd_4:2;
-               u64 i_c_cnt:4;
-               u64 i_rsvd_3:4;
-               u64 i_clr_rqpd:1;
-               u64 i_clr_rppd:1;
-               u64 i_rsvd_2:2;
-               u64 i_fc_cnt:4;
-               u64 i_crb_vld:15;
-               u64 i_crb_mark:15;
-               u64 i_rsvd_1:2;
-               u64 i_precise:1;
-               u64 i_rsvd:11;
-       } ii_icmr_fld_s;
-} ii_icmr_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register allows control of the table portion of the CRB        *
- * logic via software. Control operations from this register have       *
- * priority over all incoming Crosstalk or BTE requests.                *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_iccr_u {
-       u64 ii_iccr_regval;
-       struct {
-               u64 i_crb_num:4;
-               u64 i_rsvd_1:4;
-               u64 i_cmd:8;
-               u64 i_pending:1;
-               u64 i_rsvd:47;
-       } ii_iccr_fld_s;
-} ii_iccr_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register allows the maximum timeout value to be programmed.    *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_icto_u {
-       u64 ii_icto_regval;
-       struct {
-               u64 i_timeout:8;
-               u64 i_rsvd:56;
-       } ii_icto_fld_s;
-} ii_icto_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register allows the timeout prescalar to be programmed. An     *
- * internal counter is associated with this register. When the          *
- * internal counter reaches the value of the PRESCALE field, the        *
- * timer registers in all valid CRBs are incremented (CRBx_D[TIMEOUT]   *
- * field). The internal counter resets to zero, and then continues      *
- * counting.                                                            *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ictp_u {
-       u64 ii_ictp_regval;
-       struct {
-               u64 i_prescale:24;
-               u64 i_rsvd:40;
-       } ii_ictp_fld_s;
-} ii_ictp_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, five   *
- * registers (_A to _E) are required to read and write each entry.      *
- * The CRB Entry registers can be conceptualized as rows and columns    *
- * (illustrated in the table above). Each row contains the 4            *
- * registers required for a single CRB Entry. The first doubleword      *
- * (column) for each entry is labeled A, and the second doubleword      *
- * (higher address) is labeled B, the third doubleword is labeled C,    *
- * the fourth doubleword is labeled D and the fifth doubleword is       *
- * labeled E. All CRB entries have their addresses on a quarter         *
- * cacheline aligned boundary.                   *
- * Upon reset, only the following fields are initialized: valid         *
- * (VLD), priority count, timeout, timeout valid, and context valid.    *
- * All other bits should be cleared by software before use (after       *
- * recovering any potential error state from before the reset).         *
- * The following four tables summarize the format for the four          *
- * registers that are used for each ICRB# Entry.                        *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_icrb0_a_u {
-       u64 ii_icrb0_a_regval;
-       struct {
-               u64 ia_iow:1;
-               u64 ia_vld:1;
-               u64 ia_addr:47;
-               u64 ia_tnum:5;
-               u64 ia_sidn:4;
-               u64 ia_rsvd:6;
-       } ii_icrb0_a_fld_s;
-} ii_icrb0_a_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, five   *
- * registers (_A to _E) are required to read and write each entry.      *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_icrb0_b_u {
-       u64 ii_icrb0_b_regval;
-       struct {
-               u64 ib_xt_err:1;
-               u64 ib_mark:1;
-               u64 ib_ln_uce:1;
-               u64 ib_errcode:3;
-               u64 ib_error:1;
-               u64 ib_stall__bte_1:1;
-               u64 ib_stall__bte_0:1;
-               u64 ib_stall__intr:1;
-               u64 ib_stall_ib:1;
-               u64 ib_intvn:1;
-               u64 ib_wb:1;
-               u64 ib_hold:1;
-               u64 ib_ack:1;
-               u64 ib_resp:1;
-               u64 ib_ack_cnt:11;
-               u64 ib_rsvd:7;
-               u64 ib_exc:5;
-               u64 ib_init:3;
-               u64 ib_imsg:8;
-               u64 ib_imsgtype:2;
-               u64 ib_use_old:1;
-               u64 ib_rsvd_1:11;
-       } ii_icrb0_b_fld_s;
-} ii_icrb0_b_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, five   *
- * registers (_A to _E) are required to read and write each entry.      *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_icrb0_c_u {
-       u64 ii_icrb0_c_regval;
-       struct {
-               u64 ic_source:15;
-               u64 ic_size:2;
-               u64 ic_ct:1;
-               u64 ic_bte_num:1;
-               u64 ic_gbr:1;
-               u64 ic_resprqd:1;
-               u64 ic_bo:1;
-               u64 ic_suppl:15;
-               u64 ic_rsvd:27;
-       } ii_icrb0_c_fld_s;
-} ii_icrb0_c_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, five   *
- * registers (_A to _E) are required to read and write each entry.      *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_icrb0_d_u {
-       u64 ii_icrb0_d_regval;
-       struct {
-               u64 id_pa_be:43;
-               u64 id_bte_op:1;
-               u64 id_pr_psc:4;
-               u64 id_pr_cnt:4;
-               u64 id_sleep:1;
-               u64 id_rsvd:11;
-       } ii_icrb0_d_fld_s;
-} ii_icrb0_d_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, five   *
- * registers (_A to _E) are required to read and write each entry.      *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_icrb0_e_u {
-       u64 ii_icrb0_e_regval;
-       struct {
-               u64 ie_timeout:8;
-               u64 ie_context:15;
-               u64 ie_rsvd:1;
-               u64 ie_tvld:1;
-               u64 ie_cvld:1;
-               u64 ie_rsvd_0:38;
-       } ii_icrb0_e_fld_s;
-} ii_icrb0_e_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register contains the lower 64 bits of the header of the       *
- * spurious message captured by II. Valid when the SP_MSG bit in ICMR   *
- * register is set.                                                     *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_icsml_u {
-       u64 ii_icsml_regval;
-       struct {
-               u64 i_tt_addr:47;
-               u64 i_newsuppl_ex:14;
-               u64 i_reserved:2;
-               u64 i_overflow:1;
-       } ii_icsml_fld_s;
-} ii_icsml_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register contains the middle 64 bits of the header of the      *
- * spurious message captured by II. Valid when the SP_MSG bit in ICMR   *
- * register is set.                                                     *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_icsmm_u {
-       u64 ii_icsmm_regval;
-       struct {
-               u64 i_tt_ack_cnt:11;
-               u64 i_reserved:53;
-       } ii_icsmm_fld_s;
-} ii_icsmm_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register contains the microscopic state, all the inputs to     *
- * the protocol table, captured with the spurious message. Valid when   *
- * the SP_MSG bit in the ICMR register is set.                          *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_icsmh_u {
-       u64 ii_icsmh_regval;
-       struct {
-               u64 i_tt_vld:1;
-               u64 i_xerr:1;
-               u64 i_ft_cwact_o:1;
-               u64 i_ft_wact_o:1;
-               u64 i_ft_active_o:1;
-               u64 i_sync:1;
-               u64 i_mnusg:1;
-               u64 i_mnusz:1;
-               u64 i_plusz:1;
-               u64 i_plusg:1;
-               u64 i_tt_exc:5;
-               u64 i_tt_wb:1;
-               u64 i_tt_hold:1;
-               u64 i_tt_ack:1;
-               u64 i_tt_resp:1;
-               u64 i_tt_intvn:1;
-               u64 i_g_stall_bte1:1;
-               u64 i_g_stall_bte0:1;
-               u64 i_g_stall_il:1;
-               u64 i_g_stall_ib:1;
-               u64 i_tt_imsg:8;
-               u64 i_tt_imsgtype:2;
-               u64 i_tt_use_old:1;
-               u64 i_tt_respreqd:1;
-               u64 i_tt_bte_num:1;
-               u64 i_cbn:1;
-               u64 i_match:1;
-               u64 i_rpcnt_lt_34:1;
-               u64 i_rpcnt_ge_34:1;
-               u64 i_rpcnt_lt_18:1;
-               u64 i_rpcnt_ge_18:1;
-               u64 i_rpcnt_lt_2:1;
-               u64 i_rpcnt_ge_2:1;
-               u64 i_rqcnt_lt_18:1;
-               u64 i_rqcnt_ge_18:1;
-               u64 i_rqcnt_lt_2:1;
-               u64 i_rqcnt_ge_2:1;
-               u64 i_tt_device:7;
-               u64 i_tt_init:3;
-               u64 i_reserved:5;
-       } ii_icsmh_fld_s;
-} ii_icsmh_u_t;
-
-/************************************************************************
- *                                                                     *
- *  The Shub DEBUG unit provides a 3-bit selection signal to the        *
- * II core and a 3-bit selection signal to the fsbclk domain in the II  *
- * wrapper.                                                             *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_idbss_u {
-       u64 ii_idbss_regval;
-       struct {
-               u64 i_iioclk_core_submenu:3;
-               u64 i_rsvd:5;
-               u64 i_fsbclk_wrapper_submenu:3;
-               u64 i_rsvd_1:5;
-               u64 i_iioclk_menu:5;
-               u64 i_rsvd_2:43;
-       } ii_idbss_fld_s;
-} ii_idbss_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  This register is used to set up the length for a       *
- * transfer and then to monitor the progress of that transfer. This     *
- * register needs to be initialized before a transfer is started. A     *
- * legitimate write to this register will set the Busy bit, clear the   *
- * Error bit, and initialize the length to the value desired.           *
- * While the transfer is in progress, hardware will decrement the       *
- * length field with each successful block that is copied. Once the     *
- * transfer completes, hardware will clear the Busy bit. The length     *
- * field will also contain the number of cache lines left to be         *
- * transferred.                                                         *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibls0_u {
-       u64 ii_ibls0_regval;
-       struct {
-               u64 i_length:16;
-               u64 i_error:1;
-               u64 i_rsvd_1:3;
-               u64 i_busy:1;
-               u64 i_rsvd:43;
-       } ii_ibls0_fld_s;
-} ii_ibls0_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibsa0_u {
-       u64 ii_ibsa0_regval;
-       struct {
-               u64 i_rsvd_1:7;
-               u64 i_addr:42;
-               u64 i_rsvd:15;
-       } ii_ibsa0_fld_s;
-} ii_ibsa0_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibda0_u {
-       u64 ii_ibda0_regval;
-       struct {
-               u64 i_rsvd_1:7;
-               u64 i_addr:42;
-               u64 i_rsvd:15;
-       } ii_ibda0_fld_s;
-} ii_ibda0_u_t;
-
-/************************************************************************
- *                                                                     *
- *  Writing to this register sets up the attributes of the transfer     *
- * and initiates the transfer operation. Reading this register has      *
- * the side effect of terminating any transfer in progress. Note:       *
- * stopping a transfer midstream could have an adverse impact on the    *
- * other BTE. If a BTE stream has to be stopped (due to error           *
- * handling for example), both BTE streams should be stopped and        *
- * their transfers discarded.                                           *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibct0_u {
-       u64 ii_ibct0_regval;
-       struct {
-               u64 i_zerofill:1;
-               u64 i_rsvd_2:3;
-               u64 i_notify:1;
-               u64 i_rsvd_1:3;
-               u64 i_poison:1;
-               u64 i_rsvd:55;
-       } ii_ibct0_fld_s;
-} ii_ibct0_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register contains the address to which the WINV is sent.       *
- * This address has to be cache line aligned.                           *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibna0_u {
-       u64 ii_ibna0_regval;
-       struct {
-               u64 i_rsvd_1:7;
-               u64 i_addr:42;
-               u64 i_rsvd:15;
-       } ii_ibna0_fld_s;
-} ii_ibna0_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register contains the programmable level as well as the node   *
- * ID and PI unit of the processor to which the interrupt will be       *
- * sent.                                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibia0_u {
-       u64 ii_ibia0_regval;
-       struct {
-               u64 i_rsvd_2:1;
-               u64 i_node_id:11;
-               u64 i_rsvd_1:4;
-               u64 i_level:7;
-               u64 i_rsvd:41;
-       } ii_ibia0_fld_s;
-} ii_ibia0_u_t;
-
-/************************************************************************
- *                                                                     *
- * Description:  This register is used to set up the length for a       *
- * transfer and then to monitor the progress of that transfer. This     *
- * register needs to be initialized before a transfer is started. A     *
- * legitimate write to this register will set the Busy bit, clear the   *
- * Error bit, and initialize the length to the value desired.           *
- * While the transfer is in progress, hardware will decrement the       *
- * length field with each successful block that is copied. Once the     *
- * transfer completes, hardware will clear the Busy bit. The length     *
- * field will also contain the number of cache lines left to be         *
- * transferred.                                                         *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibls1_u {
-       u64 ii_ibls1_regval;
-       struct {
-               u64 i_length:16;
-               u64 i_error:1;
-               u64 i_rsvd_1:3;
-               u64 i_busy:1;
-               u64 i_rsvd:43;
-       } ii_ibls1_fld_s;
-} ii_ibls1_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibsa1_u {
-       u64 ii_ibsa1_regval;
-       struct {
-               u64 i_rsvd_1:7;
-               u64 i_addr:33;
-               u64 i_rsvd:24;
-       } ii_ibsa1_fld_s;
-} ii_ibsa1_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibda1_u {
-       u64 ii_ibda1_regval;
-       struct {
-               u64 i_rsvd_1:7;
-               u64 i_addr:33;
-               u64 i_rsvd:24;
-       } ii_ibda1_fld_s;
-} ii_ibda1_u_t;
-
-/************************************************************************
- *                                                                     *
- *  Writing to this register sets up the attributes of the transfer     *
- * and initiates the transfer operation. Reading this register has      *
- * the side effect of terminating any transfer in progress. Note:       *
- * stopping a transfer midstream could have an adverse impact on the    *
- * other BTE. If a BTE stream has to be stopped (due to error           *
- * handling for example), both BTE streams should be stopped and        *
- * their transfers discarded.                                           *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibct1_u {
-       u64 ii_ibct1_regval;
-       struct {
-               u64 i_zerofill:1;
-               u64 i_rsvd_2:3;
-               u64 i_notify:1;
-               u64 i_rsvd_1:3;
-               u64 i_poison:1;
-               u64 i_rsvd:55;
-       } ii_ibct1_fld_s;
-} ii_ibct1_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register contains the address to which the WINV is sent.       *
- * This address has to be cache line aligned.                           *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibna1_u {
-       u64 ii_ibna1_regval;
-       struct {
-               u64 i_rsvd_1:7;
-               u64 i_addr:33;
-               u64 i_rsvd:24;
-       } ii_ibna1_fld_s;
-} ii_ibna1_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register contains the programmable level as well as the node   *
- * ID and PI unit of the processor to which the interrupt will be       *
- * sent.                                                               *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ibia1_u {
-       u64 ii_ibia1_regval;
-       struct {
-               u64 i_pi_id:1;
-               u64 i_node_id:8;
-               u64 i_rsvd_1:7;
-               u64 i_level:7;
-               u64 i_rsvd:41;
-       } ii_ibia1_fld_s;
-} ii_ibia1_u_t;
-
-/************************************************************************
- *                                                                     *
- *  This register defines the resources that feed information into      *
- * the two performance counters located in the IO Performance           *
- * Profiling Register. There are 17 different quantities that can be    *
- * measured. Given these 17 different options, the two performance      *
- * counters have 15 of them in common; menu selections 0 through 0xE    *
- * are identical for each performance counter. As for the other two     *
- * options, one is available from one performance counter and the       *
- * other is available from the other performance counter. Hence, the    *
- * II supports all 17*16=272 possible combinations of quantities to     *
- * measure.                                                             *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ipcr_u {
-       u64 ii_ipcr_regval;
-       struct {
-               u64 i_ippr0_c:4;
-               u64 i_ippr1_c:4;
-               u64 i_icct:8;
-               u64 i_rsvd:48;
-       } ii_ipcr_fld_s;
-} ii_ipcr_u_t;
-
-/************************************************************************
- *                                                                     *
- *                                                                     *
- *                                                                     *
- ************************************************************************/
-
-typedef union ii_ippr_u {
-       u64 ii_ippr_regval;
-       struct {
-               u64 i_ippr0:32;
-               u64 i_ippr1:32;
-       } ii_ippr_fld_s;
-} ii_ippr_u_t;
-
-/************************************************************************
- *                                                                     *
- * The following defines which were not formed into structures are     *
- * probably identical to another register, and the name of the         *
- * register is provided against each of these registers. This          *
- * information needs to be checked carefully                           *
- *                                                                     *
- *             IIO_ICRB1_A             IIO_ICRB0_A                     *
- *             IIO_ICRB1_B             IIO_ICRB0_B                     *
- *             IIO_ICRB1_C             IIO_ICRB0_C                     *
- *             IIO_ICRB1_D             IIO_ICRB0_D                     *
- *             IIO_ICRB1_E             IIO_ICRB0_E                     *
- *             IIO_ICRB2_A             IIO_ICRB0_A                     *
- *             IIO_ICRB2_B             IIO_ICRB0_B                     *
- *             IIO_ICRB2_C             IIO_ICRB0_C                     *
- *             IIO_ICRB2_D             IIO_ICRB0_D                     *
- *             IIO_ICRB2_E             IIO_ICRB0_E                     *
- *             IIO_ICRB3_A             IIO_ICRB0_A                     *
- *             IIO_ICRB3_B             IIO_ICRB0_B                     *
- *             IIO_ICRB3_C             IIO_ICRB0_C                     *
- *             IIO_ICRB3_D             IIO_ICRB0_D                     *
- *             IIO_ICRB3_E             IIO_ICRB0_E                     *
- *             IIO_ICRB4_A             IIO_ICRB0_A                     *
- *             IIO_ICRB4_B             IIO_ICRB0_B                     *
- *             IIO_ICRB4_C             IIO_ICRB0_C                     *
- *             IIO_ICRB4_D             IIO_ICRB0_D                     *
- *             IIO_ICRB4_E             IIO_ICRB0_E                     *
- *             IIO_ICRB5_A             IIO_ICRB0_A                     *
- *             IIO_ICRB5_B             IIO_ICRB0_B                     *
- *             IIO_ICRB5_C             IIO_ICRB0_C                     *
- *             IIO_ICRB5_D             IIO_ICRB0_D                     *
- *             IIO_ICRB5_E             IIO_ICRB0_E                     *
- *             IIO_ICRB6_A             IIO_ICRB0_A                     *
- *             IIO_ICRB6_B             IIO_ICRB0_B                     *
- *             IIO_ICRB6_C             IIO_ICRB0_C                     *
- *             IIO_ICRB6_D             IIO_ICRB0_D                     *
- *             IIO_ICRB6_E             IIO_ICRB0_E                     *
- *             IIO_ICRB7_A             IIO_ICRB0_A                     *
- *             IIO_ICRB7_B             IIO_ICRB0_B                     *
- *             IIO_ICRB7_C             IIO_ICRB0_C                     *
- *             IIO_ICRB7_D             IIO_ICRB0_D                     *
- *             IIO_ICRB7_E             IIO_ICRB0_E                     *
- *             IIO_ICRB8_A             IIO_ICRB0_A                     *
- *             IIO_ICRB8_B             IIO_ICRB0_B                     *
- *             IIO_ICRB8_C             IIO_ICRB0_C                     *
- *             IIO_ICRB8_D             IIO_ICRB0_D                     *
- *             IIO_ICRB8_E             IIO_ICRB0_E                     *
- *             IIO_ICRB9_A             IIO_ICRB0_A                     *
- *             IIO_ICRB9_B             IIO_ICRB0_B                     *
- *             IIO_ICRB9_C             IIO_ICRB0_C                     *
- *             IIO_ICRB9_D             IIO_ICRB0_D                     *
- *             IIO_ICRB9_E             IIO_ICRB0_E                     *
- *             IIO_ICRBA_A             IIO_ICRB0_A                     *
- *             IIO_ICRBA_B             IIO_ICRB0_B                     *
- *             IIO_ICRBA_C             IIO_ICRB0_C                     *
- *             IIO_ICRBA_D             IIO_ICRB0_D                     *
- *             IIO_ICRBA_E             IIO_ICRB0_E                     *
- *             IIO_ICRBB_A             IIO_ICRB0_A                     *
- *             IIO_ICRBB_B             IIO_ICRB0_B                     *
- *             IIO_ICRBB_C             IIO_ICRB0_C                     *
- *             IIO_ICRBB_D             IIO_ICRB0_D                     *
- *             IIO_ICRBB_E             IIO_ICRB0_E                     *
- *             IIO_ICRBC_A             IIO_ICRB0_A                     *
- *             IIO_ICRBC_B             IIO_ICRB0_B                     *
- *             IIO_ICRBC_C             IIO_ICRB0_C                     *
- *             IIO_ICRBC_D             IIO_ICRB0_D                     *
- *             IIO_ICRBC_E             IIO_ICRB0_E                     *
- *             IIO_ICRBD_A             IIO_ICRB0_A                     *
- *             IIO_ICRBD_B             IIO_ICRB0_B                     *
- *             IIO_ICRBD_C             IIO_ICRB0_C                     *
- *             IIO_ICRBD_D             IIO_ICRB0_D                     *
- *             IIO_ICRBD_E             IIO_ICRB0_E                     *
- *             IIO_ICRBE_A             IIO_ICRB0_A                     *
- *             IIO_ICRBE_B             IIO_ICRB0_B                     *
- *             IIO_ICRBE_C             IIO_ICRB0_C                     *
- *             IIO_ICRBE_D             IIO_ICRB0_D                     *
- *             IIO_ICRBE_E             IIO_ICRB0_E                     *
- *                                                                     *
- ************************************************************************/
-
-/*
- * Slightly friendlier names for some common registers.
- */
-#define IIO_WIDGET              IIO_WID                /* Widget identification */
-#define IIO_WIDGET_STAT         IIO_WSTAT      /* Widget status register */
-#define IIO_WIDGET_CTRL         IIO_WCR                /* Widget control register */
-#define IIO_PROTECT             IIO_ILAPR      /* IO interface protection */
-#define IIO_PROTECT_OVRRD       IIO_ILAPO      /* IO protect override */
-#define IIO_OUTWIDGET_ACCESS    IIO_IOWA       /* Outbound widget access */
-#define IIO_INWIDGET_ACCESS     IIO_IIWA       /* Inbound widget access */
-#define IIO_INDEV_ERR_MASK      IIO_IIDEM      /* Inbound device error mask */
-#define IIO_LLP_CSR             IIO_ILCSR      /* LLP control and status */
-#define IIO_LLP_LOG             IIO_ILLR       /* LLP log */
-#define IIO_XTALKCC_TOUT        IIO_IXCC       /* Xtalk credit count timeout */
-#define IIO_XTALKTT_TOUT        IIO_IXTT       /* Xtalk tail timeout */
-#define IIO_IO_ERR_CLR          IIO_IECLR      /* IO error clear */
-#define IIO_IGFX_0             IIO_IGFX0
-#define IIO_IGFX_1             IIO_IGFX1
-#define IIO_IBCT_0             IIO_IBCT0
-#define IIO_IBCT_1             IIO_IBCT1
-#define IIO_IBLS_0             IIO_IBLS0
-#define IIO_IBLS_1             IIO_IBLS1
-#define IIO_IBSA_0             IIO_IBSA0
-#define IIO_IBSA_1             IIO_IBSA1
-#define IIO_IBDA_0             IIO_IBDA0
-#define IIO_IBDA_1             IIO_IBDA1
-#define IIO_IBNA_0             IIO_IBNA0
-#define IIO_IBNA_1             IIO_IBNA1
-#define IIO_IBIA_0             IIO_IBIA0
-#define IIO_IBIA_1             IIO_IBIA1
-#define IIO_IOPRB_0            IIO_IPRB0
-
-#define IIO_PRTE_A(_x)         (IIO_IPRTE0_A + (8 * (_x)))
-#define IIO_PRTE_B(_x)         (IIO_IPRTE0_B + (8 * (_x)))
-#define IIO_NUM_PRTES          8       /* Total number of PRB table entries */
-#define IIO_WIDPRTE_A(x)       IIO_PRTE_A(((x) - 8))   /* widget ID to its PRTE num */
-#define IIO_WIDPRTE_B(x)       IIO_PRTE_B(((x) - 8))   /* widget ID to its PRTE num */
-
-#define IIO_NUM_IPRBS          9
-
-#define IIO_LLP_CSR_IS_UP              0x00002000
-#define IIO_LLP_CSR_LLP_STAT_MASK       0x00003000
-#define IIO_LLP_CSR_LLP_STAT_SHFT       12
-
-#define IIO_LLP_CB_MAX  0xffff /* in ILLR CB_CNT, Max Check Bit errors */
-#define IIO_LLP_SN_MAX  0xffff /* in ILLR SN_CNT, Max Sequence Number errors */
-
-/* key to IIO_PROTECT_OVRRD */
-#define IIO_PROTECT_OVRRD_KEY   0x53474972756c6573ull  /* "SGIrules" */
-
-/* BTE register names */
-#define IIO_BTE_STAT_0          IIO_IBLS_0     /* Also BTE length/status 0 */
-#define IIO_BTE_SRC_0           IIO_IBSA_0     /* Also BTE source address  0 */
-#define IIO_BTE_DEST_0          IIO_IBDA_0     /* Also BTE dest. address 0 */
-#define IIO_BTE_CTRL_0          IIO_IBCT_0     /* Also BTE control/terminate 0 */
-#define IIO_BTE_NOTIFY_0        IIO_IBNA_0     /* Also BTE notification 0 */
-#define IIO_BTE_INT_0           IIO_IBIA_0     /* Also BTE interrupt 0 */
-#define IIO_BTE_OFF_0           0      /* Base offset from BTE 0 regs. */
-#define IIO_BTE_OFF_1          (IIO_IBLS_1 - IIO_IBLS_0)       /* Offset from base to BTE 1 */
-
-/* BTE register offsets from base */
-#define BTEOFF_STAT             0
-#define BTEOFF_SRC             (IIO_BTE_SRC_0 - IIO_BTE_STAT_0)
-#define BTEOFF_DEST            (IIO_BTE_DEST_0 - IIO_BTE_STAT_0)
-#define BTEOFF_CTRL            (IIO_BTE_CTRL_0 - IIO_BTE_STAT_0)
-#define BTEOFF_NOTIFY          (IIO_BTE_NOTIFY_0 - IIO_BTE_STAT_0)
-#define BTEOFF_INT             (IIO_BTE_INT_0 - IIO_BTE_STAT_0)
-
-/* names used in shub diags */
-#define IIO_BASE_BTE0   IIO_IBLS_0
-#define IIO_BASE_BTE1   IIO_IBLS_1
-
-/*
- * Macro which takes the widget number, and returns the
- * IO PRB address of that widget.
- * value _x is expected to be a widget number in the range
- * 0, 8 - 0xF
- */
-#define IIO_IOPRB(_x)  (IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \
-                       (_x) : \
-                       (_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
-
-/* GFX Flow Control Node/Widget Register */
-#define IIO_IGFX_W_NUM_BITS    4       /* size of widget num field */
-#define IIO_IGFX_W_NUM_MASK    ((1<<IIO_IGFX_W_NUM_BITS)-1)
-#define IIO_IGFX_W_NUM_SHIFT   0
-#define IIO_IGFX_PI_NUM_BITS   1       /* size of PI num field */
-#define IIO_IGFX_PI_NUM_MASK   ((1<<IIO_IGFX_PI_NUM_BITS)-1)
-#define IIO_IGFX_PI_NUM_SHIFT  4
-#define IIO_IGFX_N_NUM_BITS    8       /* size of node num field */
-#define IIO_IGFX_N_NUM_MASK    ((1<<IIO_IGFX_N_NUM_BITS)-1)
-#define IIO_IGFX_N_NUM_SHIFT   5
-#define IIO_IGFX_P_NUM_BITS    1       /* size of processor num field */
-#define IIO_IGFX_P_NUM_MASK    ((1<<IIO_IGFX_P_NUM_BITS)-1)
-#define IIO_IGFX_P_NUM_SHIFT   16
-#define IIO_IGFX_INIT(widget, pi, node, cpu)                           (\
-       (((widget) & IIO_IGFX_W_NUM_MASK) << IIO_IGFX_W_NUM_SHIFT) |     \
-       (((pi)     & IIO_IGFX_PI_NUM_MASK)<< IIO_IGFX_PI_NUM_SHIFT)|     \
-       (((node)   & IIO_IGFX_N_NUM_MASK) << IIO_IGFX_N_NUM_SHIFT) |     \
-       (((cpu)    & IIO_IGFX_P_NUM_MASK) << IIO_IGFX_P_NUM_SHIFT))
-
-/* Scratch registers (all bits available) */
-#define IIO_SCRATCH_REG0        IIO_ISCR0
-#define IIO_SCRATCH_REG1        IIO_ISCR1
-#define IIO_SCRATCH_MASK        0xffffffffffffffffUL
-
-#define IIO_SCRATCH_BIT0_0      0x0000000000000001UL
-#define IIO_SCRATCH_BIT0_1      0x0000000000000002UL
-#define IIO_SCRATCH_BIT0_2      0x0000000000000004UL
-#define IIO_SCRATCH_BIT0_3      0x0000000000000008UL
-#define IIO_SCRATCH_BIT0_4      0x0000000000000010UL
-#define IIO_SCRATCH_BIT0_5      0x0000000000000020UL
-#define IIO_SCRATCH_BIT0_6      0x0000000000000040UL
-#define IIO_SCRATCH_BIT0_7      0x0000000000000080UL
-#define IIO_SCRATCH_BIT0_8      0x0000000000000100UL
-#define IIO_SCRATCH_BIT0_9      0x0000000000000200UL
-#define IIO_SCRATCH_BIT0_A      0x0000000000000400UL
-
-#define IIO_SCRATCH_BIT1_0      0x0000000000000001UL
-#define IIO_SCRATCH_BIT1_1      0x0000000000000002UL
-/* IO Translation Table Entries */
-#define IIO_NUM_ITTES   7      /* ITTEs numbered 0..6 */
-                                       /* Hw manuals number them 1..7! */
-/*
- * IIO_IMEM Register fields.
- */
-#define IIO_IMEM_W0ESD  0x1UL  /* Widget 0 shut down due to error */
-#define IIO_IMEM_B0ESD (1UL << 4)      /* BTE 0 shut down due to error */
-#define IIO_IMEM_B1ESD (1UL << 8)      /* BTE 1 Shut down due to error */
-
-/*
- * As a permanent workaround for a bug in the PI side of the shub, we've
- * redefined big window 7 as small window 0.
- XXX does this still apply for SN1??
- */
-#define HUB_NUM_BIG_WINDOW     (IIO_NUM_ITTES - 1)
-
-/*
- * Use the top big window as a surrogate for the first small window
- */
-#define SWIN0_BIGWIN            HUB_NUM_BIG_WINDOW
-
-#define ILCSR_WARM_RESET        0x100
-
-/*
- * CRB manipulation macros
- *     The CRB macros are slightly complicated, since there are up to
- *     four registers associated with each CRB entry.
- */
-#define IIO_NUM_CRBS            15     /* Number of CRBs */
-#define IIO_NUM_PC_CRBS         4      /* Number of partial cache CRBs */
-#define IIO_ICRB_OFFSET         8
-#define IIO_ICRB_0              IIO_ICRB0_A
-#define IIO_ICRB_ADDR_SHFT     2       /* Shift to get proper address */
-/* XXX - This is now tuneable:
-        #define IIO_FIRST_PC_ENTRY 12
- */
-
-#define IIO_ICRB_A(_x) ((u64)(IIO_ICRB_0 + (6 * IIO_ICRB_OFFSET * (_x))))
-#define IIO_ICRB_B(_x) ((u64)((char *)IIO_ICRB_A(_x) + 1*IIO_ICRB_OFFSET))
-#define IIO_ICRB_C(_x) ((u64)((char *)IIO_ICRB_A(_x) + 2*IIO_ICRB_OFFSET))
-#define IIO_ICRB_D(_x) ((u64)((char *)IIO_ICRB_A(_x) + 3*IIO_ICRB_OFFSET))
-#define IIO_ICRB_E(_x) ((u64)((char *)IIO_ICRB_A(_x) + 4*IIO_ICRB_OFFSET))
-
-#define TNUM_TO_WIDGET_DEV(_tnum)      (_tnum & 0x7)
-
-/*
- * values for "ecode" field
- */
-#define IIO_ICRB_ECODE_DERR     0      /* Directory error due to IIO access */
-#define IIO_ICRB_ECODE_PERR     1      /* Poison error on IO access */
-#define IIO_ICRB_ECODE_WERR     2      /* Write error by IIO access
-                                        * e.g. WINV to a Read only line. */
-#define IIO_ICRB_ECODE_AERR     3      /* Access error caused by IIO access */
-#define IIO_ICRB_ECODE_PWERR    4      /* Error on partial write */
-#define IIO_ICRB_ECODE_PRERR    5      /* Error on partial read  */
-#define IIO_ICRB_ECODE_TOUT     6      /* CRB timeout before deallocating */
-#define IIO_ICRB_ECODE_XTERR    7      /* Incoming xtalk pkt had error bit */
-
-/*
- * Values for field imsgtype
- */
-#define IIO_ICRB_IMSGT_XTALK    0      /* Incoming message from Xtalk */
-#define IIO_ICRB_IMSGT_BTE      1      /* Incoming message from BTE    */
-#define IIO_ICRB_IMSGT_SN1NET   2      /* Incoming message from SN1 net */
-#define IIO_ICRB_IMSGT_CRB      3      /* Incoming message from CRB ???  */
-
-/*
- * values for field initiator.
- */
-#define IIO_ICRB_INIT_XTALK     0      /* Message originated in xtalk  */
-#define IIO_ICRB_INIT_BTE0      0x1    /* Message originated in BTE 0  */
-#define IIO_ICRB_INIT_SN1NET    0x2    /* Message originated in SN1net */
-#define IIO_ICRB_INIT_CRB       0x3    /* Message originated in CRB ?  */
-#define IIO_ICRB_INIT_BTE1      0x5    /* MEssage originated in BTE 1  */
-
-/*
- * Number of credits Hub widget has while sending req/response to
- * xbow.
- * Value of 3 is required by Xbow 1.1
- * We may be able to increase this to 4 with Xbow 1.2.
- */
-#define                   HUBII_XBOW_CREDIT       3
-#define                   HUBII_XBOW_REV2_CREDIT  4
-
-/*
- * Number of credits that xtalk devices should use when communicating
- * with a SHub (depth of SHub's queue).
- */
-#define HUB_CREDIT 4
-
-/*
- * Some IIO_PRB fields
- */
-#define IIO_PRB_MULTI_ERR      (1LL << 63)
-#define IIO_PRB_SPUR_RD                (1LL << 51)
-#define IIO_PRB_SPUR_WR                (1LL << 50)
-#define IIO_PRB_RD_TO          (1LL << 49)
-#define IIO_PRB_ERROR          (1LL << 48)
-
-/*************************************************************************
-
- Some of the IIO field masks and shifts are defined here.
- This is in order to maintain compatibility in SN0 and SN1 code
-**************************************************************************/
-
-/*
- * ICMR register fields
- * (Note: the IIO_ICMR_P_CNT and IIO_ICMR_PC_VLD from Hub are not
- * present in SHub)
- */
-
-#define IIO_ICMR_CRB_VLD_SHFT   20
-#define IIO_ICMR_CRB_VLD_MASK  (0x7fffUL << IIO_ICMR_CRB_VLD_SHFT)
-
-#define IIO_ICMR_FC_CNT_SHFT    16
-#define IIO_ICMR_FC_CNT_MASK   (0xf << IIO_ICMR_FC_CNT_SHFT)
-
-#define IIO_ICMR_C_CNT_SHFT     4
-#define IIO_ICMR_C_CNT_MASK    (0xf << IIO_ICMR_C_CNT_SHFT)
-
-#define IIO_ICMR_PRECISE       (1UL << 52)
-#define IIO_ICMR_CLR_RPPD      (1UL << 13)
-#define IIO_ICMR_CLR_RQPD      (1UL << 12)
-
-/*
- * IIO PIO Deallocation register field masks : (IIO_IPDR)
- XXX present but not needed in bedrock?  See the manual.
- */
-#define IIO_IPDR_PND           (1 << 4)
-
-/*
- * IIO CRB deallocation register field masks: (IIO_ICDR)
- */
-#define IIO_ICDR_PND           (1 << 4)
-
-/* 
- * IO BTE Length/Status (IIO_IBLS) register bit field definitions
- */
-#define IBLS_BUSY              (0x1UL << 20)
-#define IBLS_ERROR_SHFT                16
-#define IBLS_ERROR             (0x1UL << IBLS_ERROR_SHFT)
-#define IBLS_LENGTH_MASK       0xffff
-
-/*
- * IO BTE Control/Terminate register (IBCT) register bit field definitions
- */
-#define IBCT_POISON            (0x1UL << 8)
-#define IBCT_NOTIFY            (0x1UL << 4)
-#define IBCT_ZFIL_MODE         (0x1UL << 0)
-
-/*
- * IIO Incoming Error Packet Header (IIO_IIEPH1/IIO_IIEPH2)
- */
-#define IIEPH1_VALID           (1UL << 44)
-#define IIEPH1_OVERRUN         (1UL << 40)
-#define IIEPH1_ERR_TYPE_SHFT   32
-#define IIEPH1_ERR_TYPE_MASK   0xf
-#define IIEPH1_SOURCE_SHFT     20
-#define IIEPH1_SOURCE_MASK     11
-#define IIEPH1_SUPPL_SHFT      8
-#define IIEPH1_SUPPL_MASK      11
-#define IIEPH1_CMD_SHFT                0
-#define IIEPH1_CMD_MASK                7
-
-#define IIEPH2_TAIL            (1UL << 40)
-#define IIEPH2_ADDRESS_SHFT    0
-#define IIEPH2_ADDRESS_MASK    38
-
-#define IIEPH1_ERR_SHORT_REQ   2
-#define IIEPH1_ERR_SHORT_REPLY 3
-#define IIEPH1_ERR_LONG_REQ    4
-#define IIEPH1_ERR_LONG_REPLY  5
-
-/*
- * IO Error Clear register bit field definitions
- */
-#define IECLR_PI1_FWD_INT      (1UL << 31)     /* clear PI1_FORWARD_INT in iidsr */
-#define IECLR_PI0_FWD_INT      (1UL << 30)     /* clear PI0_FORWARD_INT in iidsr */
-#define IECLR_SPUR_RD_HDR      (1UL << 29)     /* clear valid bit in ixss reg */
-#define IECLR_BTE1             (1UL << 18)     /* clear bte error 1 */
-#define IECLR_BTE0             (1UL << 17)     /* clear bte error 0 */
-#define IECLR_CRAZY            (1UL << 16)     /* clear crazy bit in wstat reg */
-#define IECLR_PRB_F            (1UL << 15)     /* clear err bit in PRB_F reg */
-#define IECLR_PRB_E            (1UL << 14)     /* clear err bit in PRB_E reg */
-#define IECLR_PRB_D            (1UL << 13)     /* clear err bit in PRB_D reg */
-#define IECLR_PRB_C            (1UL << 12)     /* clear err bit in PRB_C reg */
-#define IECLR_PRB_B            (1UL << 11)     /* clear err bit in PRB_B reg */
-#define IECLR_PRB_A            (1UL << 10)     /* clear err bit in PRB_A reg */
-#define IECLR_PRB_9            (1UL << 9)      /* clear err bit in PRB_9 reg */
-#define IECLR_PRB_8            (1UL << 8)      /* clear err bit in PRB_8 reg */
-#define IECLR_PRB_0            (1UL << 0)      /* clear err bit in PRB_0 reg */
-
-/*
- * IIO CRB control register Fields: IIO_ICCR 
- */
-#define        IIO_ICCR_PENDING        0x10000
-#define        IIO_ICCR_CMD_MASK       0xFF
-#define        IIO_ICCR_CMD_SHFT       7
-#define        IIO_ICCR_CMD_NOP        0x0     /* No Op */
-#define        IIO_ICCR_CMD_WAKE       0x100   /* Reactivate CRB entry and process */
-#define        IIO_ICCR_CMD_TIMEOUT    0x200   /* Make CRB timeout & mark invalid */
-#define        IIO_ICCR_CMD_EJECT      0x400   /* Contents of entry written to memory
-                                        * via a WB
-                                        */
-#define        IIO_ICCR_CMD_FLUSH      0x800
-
-/*
- *
- * CRB Register description.
- *
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- *
- * Many of the fields in CRB are status bits used by hardware
- * for implementation of the protocol. It's very dangerous to
- * mess around with the CRB registers.
- *
- * It's OK to read the CRB registers and try to make sense out of the
- * fields in CRB.
- *
- * Updating CRB requires all activities in Hub IIO to be quiesced.
- * otherwise, a write to CRB could corrupt other CRB entries.
- * CRBs are here only as a back door peek to shub IIO's status.
- * Quiescing implies  no dmas no PIOs
- * either directly from the cpu or from sn0net.
- * this is not something that can be done easily. So, AVOID updating
- * CRBs.
- */
-
-/*
- * Easy access macros for CRBs, all 5 registers (A-E)
- */
-typedef ii_icrb0_a_u_t icrba_t;
-#define a_sidn         ii_icrb0_a_fld_s.ia_sidn
-#define a_tnum         ii_icrb0_a_fld_s.ia_tnum
-#define a_addr          ii_icrb0_a_fld_s.ia_addr
-#define a_valid         ii_icrb0_a_fld_s.ia_vld
-#define a_iow           ii_icrb0_a_fld_s.ia_iow
-#define a_regvalue     ii_icrb0_a_regval
-
-typedef ii_icrb0_b_u_t icrbb_t;
-#define b_use_old       ii_icrb0_b_fld_s.ib_use_old
-#define b_imsgtype      ii_icrb0_b_fld_s.ib_imsgtype
-#define b_imsg          ii_icrb0_b_fld_s.ib_imsg
-#define b_initiator     ii_icrb0_b_fld_s.ib_init
-#define b_exc           ii_icrb0_b_fld_s.ib_exc
-#define b_ackcnt        ii_icrb0_b_fld_s.ib_ack_cnt
-#define b_resp          ii_icrb0_b_fld_s.ib_resp
-#define b_ack           ii_icrb0_b_fld_s.ib_ack
-#define b_hold          ii_icrb0_b_fld_s.ib_hold
-#define b_wb            ii_icrb0_b_fld_s.ib_wb
-#define b_intvn         ii_icrb0_b_fld_s.ib_intvn
-#define b_stall_ib      ii_icrb0_b_fld_s.ib_stall_ib
-#define b_stall_int     ii_icrb0_b_fld_s.ib_stall__intr
-#define b_stall_bte_0   ii_icrb0_b_fld_s.ib_stall__bte_0
-#define b_stall_bte_1   ii_icrb0_b_fld_s.ib_stall__bte_1
-#define b_error         ii_icrb0_b_fld_s.ib_error
-#define b_ecode         ii_icrb0_b_fld_s.ib_errcode
-#define b_lnetuce       ii_icrb0_b_fld_s.ib_ln_uce
-#define b_mark          ii_icrb0_b_fld_s.ib_mark
-#define b_xerr          ii_icrb0_b_fld_s.ib_xt_err
-#define b_regvalue     ii_icrb0_b_regval
-
-typedef ii_icrb0_c_u_t icrbc_t;
-#define c_suppl         ii_icrb0_c_fld_s.ic_suppl
-#define c_barrop        ii_icrb0_c_fld_s.ic_bo
-#define c_doresp        ii_icrb0_c_fld_s.ic_resprqd
-#define c_gbr           ii_icrb0_c_fld_s.ic_gbr
-#define c_btenum        ii_icrb0_c_fld_s.ic_bte_num
-#define c_cohtrans      ii_icrb0_c_fld_s.ic_ct
-#define c_xtsize        ii_icrb0_c_fld_s.ic_size
-#define c_source        ii_icrb0_c_fld_s.ic_source
-#define c_regvalue     ii_icrb0_c_regval
-
-typedef ii_icrb0_d_u_t icrbd_t;
-#define d_sleep         ii_icrb0_d_fld_s.id_sleep
-#define d_pricnt        ii_icrb0_d_fld_s.id_pr_cnt
-#define d_pripsc        ii_icrb0_d_fld_s.id_pr_psc
-#define d_bteop         ii_icrb0_d_fld_s.id_bte_op
-#define d_bteaddr       ii_icrb0_d_fld_s.id_pa_be      /* ic_pa_be fld has 2 names */
-#define d_benable       ii_icrb0_d_fld_s.id_pa_be      /* ic_pa_be fld has 2 names */
-#define d_regvalue     ii_icrb0_d_regval
-
-typedef ii_icrb0_e_u_t icrbe_t;
-#define icrbe_ctxtvld   ii_icrb0_e_fld_s.ie_cvld
-#define icrbe_toutvld   ii_icrb0_e_fld_s.ie_tvld
-#define icrbe_context   ii_icrb0_e_fld_s.ie_context
-#define icrbe_timeout   ii_icrb0_e_fld_s.ie_timeout
-#define e_regvalue     ii_icrb0_e_regval
-
-/* Number of widgets supported by shub */
-#define HUB_NUM_WIDGET          9
-#define HUB_WIDGET_ID_MIN       0x8
-#define HUB_WIDGET_ID_MAX       0xf
-
-#define HUB_WIDGET_PART_NUM     0xc120
-#define MAX_HUBS_PER_XBOW       2
-
-/* A few more #defines for backwards compatibility */
-#define iprb_t          ii_iprb0_u_t
-#define iprb_regval     ii_iprb0_regval
-#define iprb_mult_err  ii_iprb0_fld_s.i_mult_err
-#define iprb_spur_rd   ii_iprb0_fld_s.i_spur_rd
-#define iprb_spur_wr   ii_iprb0_fld_s.i_spur_wr
-#define iprb_rd_to     ii_iprb0_fld_s.i_rd_to
-#define iprb_ovflow     ii_iprb0_fld_s.i_of_cnt
-#define iprb_error      ii_iprb0_fld_s.i_error
-#define iprb_ff         ii_iprb0_fld_s.i_f
-#define iprb_mode       ii_iprb0_fld_s.i_m
-#define iprb_bnakctr    ii_iprb0_fld_s.i_nb
-#define iprb_anakctr    ii_iprb0_fld_s.i_na
-#define iprb_xtalkctr   ii_iprb0_fld_s.i_c
-
-#define LNK_STAT_WORKING        0x2            /* LLP is working */
-
-#define IIO_WSTAT_ECRAZY       (1ULL << 32)    /* Hub gone crazy */
-#define IIO_WSTAT_TXRETRY      (1ULL << 9)     /* Hub Tx Retry timeout */
-#define IIO_WSTAT_TXRETRY_MASK  0x7F           /* should be 0xFF?? */
-#define IIO_WSTAT_TXRETRY_SHFT  16
-#define IIO_WSTAT_TXRETRY_CNT(w)       (((w) >> IIO_WSTAT_TXRETRY_SHFT) & \
-                                       IIO_WSTAT_TXRETRY_MASK)
-
-/* Number of II perf. counters we can multiplex at once */
-
-#define IO_PERF_SETS   32
-
-/* Bit for the widget in inbound access register */
-#define IIO_IIWA_WIDGET(_w)    ((u64)(1ULL << _w))
-/* Bit for the widget in outbound access register */
-#define IIO_IOWA_WIDGET(_w)    ((u64)(1ULL << _w))
-
-/* NOTE: The following define assumes that we are going to get
- * widget numbers from 8 thru F and the device numbers within
- * widget from 0 thru 7.
- */
-#define IIO_IIDEM_WIDGETDEV_MASK(w, d) ((u64)(1ULL << (8 * ((w) - 8) + (d))))
-
-/* IO Interrupt Destination Register */
-#define IIO_IIDSR_SENT_SHIFT    28
-#define IIO_IIDSR_SENT_MASK     0x30000000
-#define IIO_IIDSR_ENB_SHIFT     24
-#define IIO_IIDSR_ENB_MASK      0x01000000
-#define IIO_IIDSR_NODE_SHIFT    9
-#define IIO_IIDSR_NODE_MASK     0x000ff700
-#define IIO_IIDSR_PI_ID_SHIFT   8
-#define IIO_IIDSR_PI_ID_MASK    0x00000100
-#define IIO_IIDSR_LVL_SHIFT     0
-#define IIO_IIDSR_LVL_MASK      0x000000ff
-
-/* Xtalk timeout threshold register (IIO_IXTT) */
-#define IXTT_RRSP_TO_SHFT      55      /* read response timeout */
-#define IXTT_RRSP_TO_MASK      (0x1FULL << IXTT_RRSP_TO_SHFT)
-#define IXTT_RRSP_PS_SHFT      32      /* read responsed TO prescalar */
-#define IXTT_RRSP_PS_MASK      (0x7FFFFFULL << IXTT_RRSP_PS_SHFT)
-#define IXTT_TAIL_TO_SHFT      0       /* tail timeout counter threshold */
-#define IXTT_TAIL_TO_MASK      (0x3FFFFFFULL << IXTT_TAIL_TO_SHFT)
-
-/*
- * The IO LLP control status register and widget control register
- */
-
-typedef union hubii_wcr_u {
-       u64 wcr_reg_value;
-       struct {
-               u64 wcr_widget_id:4,    /* LLP crossbar credit */
-                wcr_tag_mode:1,        /* Tag mode */
-                wcr_rsvd1:8,   /* Reserved */
-                wcr_xbar_crd:3,        /* LLP crossbar credit */
-                wcr_f_bad_pkt:1,       /* Force bad llp pkt enable */
-                wcr_dir_con:1, /* widget direct connect */
-                wcr_e_thresh:5,        /* elasticity threshold */
-                wcr_rsvd:41;   /* unused */
-       } wcr_fields_s;
-} hubii_wcr_t;
-
-#define iwcr_dir_con    wcr_fields_s.wcr_dir_con
-
-/* The structures below are defined to extract and modify the ii
-performance registers */
-
-/* io_perf_sel allows the caller to specify what tests will be
-   performed */
-
-typedef union io_perf_sel {
-       u64 perf_sel_reg;
-       struct {
-               u64 perf_ippr0:4, perf_ippr1:4, perf_icct:8, perf_rsvd:48;
-       } perf_sel_bits;
-} io_perf_sel_t;
-
-/* io_perf_cnt is to extract the count from the shub registers. Due to
-   hardware problems there is only one counter, not two. */
-
-typedef union io_perf_cnt {
-       u64 perf_cnt;
-       struct {
-               u64 perf_cnt:20, perf_rsvd2:12, perf_rsvd1:32;
-       } perf_cnt_bits;
-
-} io_perf_cnt_t;
-
-typedef union iprte_a {
-       u64 entry;
-       struct {
-               u64 i_rsvd_1:3;
-               u64 i_addr:38;
-               u64 i_init:3;
-               u64 i_source:8;
-               u64 i_rsvd:2;
-               u64 i_widget:4;
-               u64 i_to_cnt:5;
-               u64 i_vld:1;
-       } iprte_fields;
-} iprte_a_t;
-
-#endif                         /* _ASM_IA64_SN_SHUBIO_H */
diff --git a/arch/ia64/include/asm/sn/simulator.h b/arch/ia64/include/asm/sn/simulator.h
deleted file mode 100644 (file)
index c2611f6..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SIMULATOR_H
-#define _ASM_IA64_SN_SIMULATOR_H
-
-#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) || defined(CONFIG_IA64_SGI_UV)
-#define SNMAGIC 0xaeeeeeee8badbeefL
-#define IS_MEDUSA()                    ({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;})
-
-#define SIMULATOR_SLEEP()              asm("nop.i 0x8beef")
-#define IS_RUNNING_ON_SIMULATOR()      (sn_prom_type)
-#define IS_RUNNING_ON_FAKE_PROM()      (sn_prom_type == 2)
-extern int sn_prom_type;               /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */
-#else
-#define IS_MEDUSA()                    0
-#define SIMULATOR_SLEEP()
-#define IS_RUNNING_ON_SIMULATOR()      0
-#endif
-
-#endif /* _ASM_IA64_SN_SIMULATOR_H */
diff --git a/arch/ia64/include/asm/sn/sn2/sn_hwperf.h b/arch/ia64/include/asm/sn/sn2/sn_hwperf.h
deleted file mode 100644 (file)
index e61ebac..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved.
- *
- * Data types used by the SN_SAL_HWPERF_OP SAL call for monitoring
- * SGI Altix node and router hardware
- *
- * Mark Goodwin <markgw@sgi.com> Mon Aug 30 12:23:46 EST 2004
- */
-
-#ifndef SN_HWPERF_H
-#define SN_HWPERF_H
-
-/*
- * object structure. SN_HWPERF_ENUM_OBJECTS and SN_HWPERF_GET_CPU_INFO
- * return an array of these. Do not change this without also
- * changing the corresponding SAL code.
- */
-#define SN_HWPERF_MAXSTRING            128
-struct sn_hwperf_object_info {
-       u32 id;
-       union {
-               struct {
-                       u64 this_part:1;
-                       u64 is_shared:1;
-               } fields;
-               struct {
-                       u64 flags;
-                       u64 reserved;
-               } b;
-       } f;
-       char name[SN_HWPERF_MAXSTRING];
-       char location[SN_HWPERF_MAXSTRING];
-       u32 ports;
-};
-
-#define sn_hwp_this_part       f.fields.this_part
-#define sn_hwp_is_shared       f.fields.is_shared
-#define sn_hwp_flags           f.b.flags
-
-/* macros for object classification */
-#define SN_HWPERF_IS_NODE(x)           ((x) && strstr((x)->name, "SHub"))
-#define SN_HWPERF_IS_NODE_SHUB2(x)     ((x) && strstr((x)->name, "SHub 2."))
-#define SN_HWPERF_IS_IONODE(x)         ((x) && strstr((x)->name, "TIO"))
-#define SN_HWPERF_IS_NL3ROUTER(x)      ((x) && strstr((x)->name, "NL3Router"))
-#define SN_HWPERF_IS_NL4ROUTER(x)      ((x) && strstr((x)->name, "NL4Router"))
-#define SN_HWPERF_IS_OLDROUTER(x)      ((x) && strstr((x)->name, "Router"))
-#define SN_HWPERF_IS_ROUTER(x)         (SN_HWPERF_IS_NL3ROUTER(x) ||           \
-                                               SN_HWPERF_IS_NL4ROUTER(x) ||    \
-                                               SN_HWPERF_IS_OLDROUTER(x))
-#define SN_HWPERF_FOREIGN(x)           ((x) && !(x)->sn_hwp_this_part && !(x)->sn_hwp_is_shared)
-#define SN_HWPERF_SAME_OBJTYPE(x,y)    ((SN_HWPERF_IS_NODE(x) && SN_HWPERF_IS_NODE(y)) ||\
-                                       (SN_HWPERF_IS_IONODE(x) && SN_HWPERF_IS_IONODE(y)) ||\
-                                       (SN_HWPERF_IS_ROUTER(x) && SN_HWPERF_IS_ROUTER(y)))
-
-/* numa port structure, SN_HWPERF_ENUM_PORTS returns an array of these */
-struct sn_hwperf_port_info {
-       u32 port;
-       u32 conn_id;
-       u32 conn_port;
-};
-
-/* for HWPERF_{GET,SET}_MMRS */
-struct sn_hwperf_data {
-       u64 addr;
-       u64 data;
-};
-
-/* user ioctl() argument, see below */
-struct sn_hwperf_ioctl_args {
-        u64 arg;               /* argument, usually an object id */
-        u64 sz;                 /* size of transfer */
-        void *ptr;              /* pointer to source/target */
-        u32 v0;                        /* second return value */
-};
-
-/*
- * For SN_HWPERF_{GET,SET}_MMRS and SN_HWPERF_OBJECT_DISTANCE,
- * sn_hwperf_ioctl_args.arg can be used to specify a CPU on which
- * to call SAL, and whether to use an interprocessor interrupt
- * or task migration in order to do so. If the CPU specified is
- * SN_HWPERF_ARG_ANY_CPU, then the current CPU will be used.
- */
-#define SN_HWPERF_ARG_ANY_CPU          0x7fffffffUL
-#define SN_HWPERF_ARG_CPU_MASK         0x7fffffff00000000ULL
-#define SN_HWPERF_ARG_USE_IPI_MASK     0x8000000000000000ULL
-#define SN_HWPERF_ARG_OBJID_MASK       0x00000000ffffffffULL
-
-/* 
- * ioctl requests on the "sn_hwperf" misc device that call SAL.
- */
-#define SN_HWPERF_OP_MEM_COPYIN                0x1000
-#define SN_HWPERF_OP_MEM_COPYOUT       0x2000
-#define SN_HWPERF_OP_MASK              0x0fff
-
-/*
- * Determine mem requirement.
- * arg don't care
- * sz  8
- * p   pointer to u64 integer
- */
-#define        SN_HWPERF_GET_HEAPSIZE          1
-
-/*
- * Install mem for SAL drvr
- * arg don't care
- * sz  sizeof buffer pointed to by p
- * p   pointer to buffer for scratch area
- */
-#define SN_HWPERF_INSTALL_HEAP         2
-
-/*
- * Determine number of objects
- * arg don't care
- * sz  8
- * p   pointer to u64 integer
- */
-#define SN_HWPERF_OBJECT_COUNT         (10|SN_HWPERF_OP_MEM_COPYOUT)
-
-/*
- * Determine object "distance", relative to a cpu. This operation can
- * execute on a designated logical cpu number, using either an IPI or
- * via task migration. If the cpu number is SN_HWPERF_ANY_CPU, then
- * the current CPU is used. See the SN_HWPERF_ARG_* macros above.
- *
- * arg bitmap of IPI flag, cpu number and object id
- * sz  8
- * p   pointer to u64 integer
- */
-#define SN_HWPERF_OBJECT_DISTANCE      (11|SN_HWPERF_OP_MEM_COPYOUT)
-
-/*
- * Enumerate objects. Special case if sz == 8, returns the required
- * buffer size.
- * arg don't care
- * sz  sizeof buffer pointed to by p
- * p   pointer to array of struct sn_hwperf_object_info
- */
-#define SN_HWPERF_ENUM_OBJECTS         (12|SN_HWPERF_OP_MEM_COPYOUT)
-
-/*
- * Enumerate NumaLink ports for an object. Special case if sz == 8,
- * returns the required buffer size.
- * arg object id
- * sz  sizeof buffer pointed to by p
- * p   pointer to array of struct sn_hwperf_port_info
- */
-#define SN_HWPERF_ENUM_PORTS           (13|SN_HWPERF_OP_MEM_COPYOUT)
-
-/*
- * SET/GET memory mapped registers. These operations can execute
- * on a designated logical cpu number, using either an IPI or via
- * task migration. If the cpu number is SN_HWPERF_ANY_CPU, then
- * the current CPU is used. See the SN_HWPERF_ARG_* macros above.
- *
- * arg bitmap of ipi flag, cpu number and object id
- * sz  sizeof buffer pointed to by p
- * p   pointer to array of struct sn_hwperf_data
- */
-#define SN_HWPERF_SET_MMRS             (14|SN_HWPERF_OP_MEM_COPYIN)
-#define SN_HWPERF_GET_MMRS             (15|SN_HWPERF_OP_MEM_COPYOUT| \
-                                           SN_HWPERF_OP_MEM_COPYIN)
-/*
- * Lock a shared object
- * arg object id
- * sz  don't care
- * p   don't care
- */
-#define SN_HWPERF_ACQUIRE              16
-
-/*
- * Unlock a shared object
- * arg object id
- * sz  don't care
- * p   don't care
- */
-#define SN_HWPERF_RELEASE              17
-
-/*
- * Break a lock on a shared object
- * arg object id
- * sz  don't care
- * p   don't care
- */
-#define SN_HWPERF_FORCE_RELEASE                18
-
-/*
- * ioctl requests on "sn_hwperf" that do not call SAL
- */
-
-/*
- * get cpu info as an array of hwperf_object_info_t. 
- * id is logical CPU number, name is description, location
- * is geoid (e.g. 001c04#1c). Special case if sz == 8,
- * returns the required buffer size.
- *
- * arg don't care
- * sz  sizeof buffer pointed to by p
- * p   pointer to array of struct sn_hwperf_object_info
- */
-#define SN_HWPERF_GET_CPU_INFO         (100|SN_HWPERF_OP_MEM_COPYOUT)
-
-/*
- * Given an object id, return it's node number (aka cnode).
- * arg object id
- * sz  8
- * p   pointer to u64 integer
- */
-#define SN_HWPERF_GET_OBJ_NODE         (101|SN_HWPERF_OP_MEM_COPYOUT)
-
-/*
- * Given a node number (cnode), return it's nasid.
- * arg ordinal node number (aka cnodeid)
- * sz  8
- * p   pointer to u64 integer
- */
-#define SN_HWPERF_GET_NODE_NASID       (102|SN_HWPERF_OP_MEM_COPYOUT)
-
-/*
- * Given a node id, determine the id of the nearest node with CPUs
- * and the id of the nearest node that has memory. The argument
- * node would normally be a "headless" node, e.g. an "IO node".
- * Return 0 on success.
- */
-extern int sn_hwperf_get_nearest_node(cnodeid_t node,
-       cnodeid_t *near_mem, cnodeid_t *near_cpu);
-
-/* return codes */
-#define SN_HWPERF_OP_OK                        0
-#define SN_HWPERF_OP_NOMEM             1
-#define SN_HWPERF_OP_NO_PERM           2
-#define SN_HWPERF_OP_IO_ERROR          3
-#define SN_HWPERF_OP_BUSY              4
-#define SN_HWPERF_OP_RECONFIGURE       253
-#define SN_HWPERF_OP_INVAL             254
-
-int sn_topology_open(struct inode *inode, struct file *file);
-int sn_topology_release(struct inode *inode, struct file *file);
-#endif                         /* SN_HWPERF_H */
diff --git a/arch/ia64/include/asm/sn/sn_cpuid.h b/arch/ia64/include/asm/sn/sn_cpuid.h
deleted file mode 100644 (file)
index a676dd9..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/* 
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#ifndef _ASM_IA64_SN_SN_CPUID_H
-#define _ASM_IA64_SN_SN_CPUID_H
-
-#include <linux/smp.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/pda.h>
-#include <asm/intrinsics.h>
-
-
-/*
- * Functions for converting between cpuids, nodeids and NASIDs.
- * 
- * These are for SGI platforms only.
- *
- */
-
-
-
-
-/*
- *  Definitions of terms (these definitions are for IA64 ONLY. Other architectures
- *  use cpuid/cpunum quite defferently):
- *
- *        CPUID - a number in range of 0..NR_CPUS-1 that uniquely identifies
- *             the cpu. The value cpuid has no significance on IA64 other than
- *             the boot cpu is 0.
- *                     smp_processor_id() returns the cpuid of the current cpu.
- *
- *        CPU_PHYSICAL_ID (also known as HARD_PROCESSOR_ID)
- *             This is the same as 31:24 of the processor LID register
- *                     hard_smp_processor_id()- cpu_physical_id of current processor
- *                     cpu_physical_id(cpuid) - convert a <cpuid> to a <physical_cpuid>
- *                     cpu_logical_id(phy_id) - convert a <physical_cpuid> to a <cpuid> 
- *                             * not real efficient - don't use in perf critical code
- *
- *         SLICE - a number in the range of 0 - 3 (typically) that represents the
- *             cpu number on a brick.
- *
- *        SUBNODE - (almost obsolete) the number of the FSB that a cpu is
- *             connected to. This is also the same as the PI number. Usually 0 or 1.
- *
- *     NOTE!!!: the value of the bits in the cpu physical id (SAPICid or LID) of a cpu has no 
- *     significance. The SAPIC id (LID) is a 16-bit cookie that has meaning only to the PROM.
- *
- *
- * The macros convert between cpu physical ids & slice/nasid/cnodeid.
- * These terms are described below:
- *
- *
- * Brick
- *          -----   -----           -----   -----       CPU
- *          | 0 |   | 1 |           | 0 |   | 1 |       SLICE
- *          -----   -----           -----   -----
- *            |       |               |       |
- *            |       |               |       |
- *          0 |       | 2           0 |       | 2       FSB SLOT
- *             -------                 -------  
- *                |                       |
- *                |                       |
- *                |                       |
- *             ------------      -------------
- *             |          |      |           |
- *             |    SHUB  |      |   SHUB    |        NASID   (0..MAX_NASIDS)
- *             |          |----- |           |        CNODEID (0..num_compact_nodes-1)
- *             |          |      |           |
- *             |          |      |           |
- *             ------------      -------------
- *                   |                 |
- *                           
- *
- */
-
-#define get_node_number(addr)                  NASID_GET(addr)
-
-/*
- * NOTE: on non-MP systems, only cpuid 0 exists
- */
-
-extern short physical_node_map[];      /* indexed by nasid to get cnode */
-
-/*
- * Macros for retrieving info about current cpu
- */
-#define get_nasid()    (sn_nodepda->phys_cpuid[smp_processor_id()].nasid)
-#define get_subnode()  (sn_nodepda->phys_cpuid[smp_processor_id()].subnode)
-#define get_slice()    (sn_nodepda->phys_cpuid[smp_processor_id()].slice)
-#define get_cnode()    (sn_nodepda->phys_cpuid[smp_processor_id()].cnode)
-#define get_sapicid()  ((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff)
-
-/*
- * Macros for retrieving info about an arbitrary cpu
- *     cpuid - logical cpu id
- */
-#define cpuid_to_nasid(cpuid)          (sn_nodepda->phys_cpuid[cpuid].nasid)
-#define cpuid_to_subnode(cpuid)                (sn_nodepda->phys_cpuid[cpuid].subnode)
-#define cpuid_to_slice(cpuid)          (sn_nodepda->phys_cpuid[cpuid].slice)
-
-
-/*
- * Dont use the following in performance critical code. They require scans
- * of potentially large tables.
- */
-extern int nasid_slice_to_cpuid(int, int);
-
-/*
- * cnodeid_to_nasid - convert a cnodeid to a NASID
- */
-#define cnodeid_to_nasid(cnodeid)      (sn_cnodeid_to_nasid[cnodeid])
-/*
- * nasid_to_cnodeid - convert a NASID to a cnodeid
- */
-#define nasid_to_cnodeid(nasid)                (physical_node_map[nasid])
-
-/*
- * partition_coherence_id - get the coherence ID of the current partition
- */
-extern u8 sn_coherency_id;
-#define partition_coherence_id()       (sn_coherency_id)
-
-#endif /* _ASM_IA64_SN_SN_CPUID_H */
-
diff --git a/arch/ia64/include/asm/sn/sn_feature_sets.h b/arch/ia64/include/asm/sn/sn_feature_sets.h
deleted file mode 100644 (file)
index 8e83ac1..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#ifndef _ASM_IA64_SN_FEATURE_SETS_H
-#define _ASM_IA64_SN_FEATURE_SETS_H
-
-/*
- * SN PROM Features
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2005-2006 Silicon Graphics, Inc.  All rights reserved.
- */
-
-
-/* --------------------- PROM Features -----------------------------*/
-extern int sn_prom_feature_available(int id);
-
-#define MAX_PROM_FEATURE_SETS                  2
-
-/*
- * The following defines features that may or may not be supported by the
- * current PROM. The OS uses sn_prom_feature_available(feature) to test for
- * the presence of a PROM feature. Down rev (old) PROMs will always test
- * "false" for new features.
- *
- * Use:
- *             if (sn_prom_feature_available(PRF_XXX))
- *                     ...
- */
-
-#define PRF_PAL_CACHE_FLUSH_SAFE       0
-#define PRF_DEVICE_FLUSH_LIST          1
-#define PRF_HOTPLUG_SUPPORT            2
-#define PRF_CPU_DISABLE_SUPPORT                3
-
-/* --------------------- OS Features -------------------------------*/
-
-/*
- * The following defines OS features that are optionally present in
- * the operating system.
- * During boot, PROM is notified of these features via a series of calls:
- *
- *             ia64_sn_set_os_feature(feature1);
- *
- * Once enabled, a feature cannot be disabled.
- *
- * By default, features are disabled unless explicitly enabled.
- *
- * These defines must be kept in sync with the corresponding
- * PROM definitions in feature_sets.h.
- */
-#define  OSF_MCA_SLV_TO_OS_INIT_SLV    0
-#define  OSF_FEAT_LOG_SBES             1
-#define  OSF_ACPI_ENABLE               2
-#define  OSF_PCISEGMENT_ENABLE         3
-
-
-#endif /* _ASM_IA64_SN_FEATURE_SETS_H */
index 1f5ff47..d437aa4 100644 (file)
  * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All rights reserved.
  */
 
-
+#include <linux/types.h>
 #include <asm/sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/geo.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/shub_mmr.h>
 
 // SGI Specific Calls
-#define  SN_SAL_POD_MODE                           0x02000001
-#define  SN_SAL_SYSTEM_RESET                       0x02000002
-#define  SN_SAL_PROBE                              0x02000003
-#define  SN_SAL_GET_MASTER_NASID                   0x02000004
-#define         SN_SAL_GET_KLCONFIG_ADDR                  0x02000005
-#define  SN_SAL_LOG_CE                            0x02000006
-#define  SN_SAL_REGISTER_CE                       0x02000007
 #define  SN_SAL_GET_PARTITION_ADDR                0x02000009
-#define  SN_SAL_XP_ADDR_REGION                    0x0200000f
-#define  SN_SAL_NO_FAULT_ZONE_VIRTUAL             0x02000010
-#define  SN_SAL_NO_FAULT_ZONE_PHYSICAL            0x02000011
-#define  SN_SAL_PRINT_ERROR                       0x02000012
-#define  SN_SAL_REGISTER_PMI_HANDLER              0x02000014
-#define  SN_SAL_SET_ERROR_HANDLING_FEATURES       0x0200001a   // reentrant
-#define  SN_SAL_GET_FIT_COMPT                     0x0200001b   // reentrant
-#define  SN_SAL_GET_SAPIC_INFO                     0x0200001d
-#define  SN_SAL_GET_SN_INFO                        0x0200001e
-#define  SN_SAL_CONSOLE_PUTC                       0x02000021
-#define  SN_SAL_CONSOLE_GETC                       0x02000022
-#define  SN_SAL_CONSOLE_PUTS                       0x02000023
-#define  SN_SAL_CONSOLE_GETS                       0x02000024
-#define  SN_SAL_CONSOLE_GETS_TIMEOUT               0x02000025
-#define  SN_SAL_CONSOLE_POLL                       0x02000026
-#define  SN_SAL_CONSOLE_INTR                       0x02000027
-#define  SN_SAL_CONSOLE_PUTB                      0x02000028
-#define  SN_SAL_CONSOLE_XMIT_CHARS                0x0200002a
-#define  SN_SAL_CONSOLE_READC                     0x0200002b
-#define  SN_SAL_SYSCTL_OP                         0x02000030
-#define  SN_SAL_SYSCTL_MODID_GET                  0x02000031
-#define  SN_SAL_SYSCTL_GET                         0x02000032
-#define  SN_SAL_SYSCTL_IOBRICK_MODULE_GET          0x02000033
-#define  SN_SAL_SYSCTL_IO_PORTSPEED_GET            0x02000035
-#define  SN_SAL_SYSCTL_SLAB_GET                    0x02000036
-#define  SN_SAL_BUS_CONFIG                        0x02000037
-#define  SN_SAL_SYS_SERIAL_GET                    0x02000038
-#define  SN_SAL_PARTITION_SERIAL_GET              0x02000039
-#define  SN_SAL_SYSCTL_PARTITION_GET               0x0200003a
-#define  SN_SAL_SYSTEM_POWER_DOWN                 0x0200003b
-#define  SN_SAL_GET_MASTER_BASEIO_NASID                   0x0200003c
-#define  SN_SAL_COHERENCE                          0x0200003d
 #define  SN_SAL_MEMPROTECT                         0x0200003e
-#define  SN_SAL_SYSCTL_FRU_CAPTURE                0x0200003f
-
-#define  SN_SAL_SYSCTL_IOBRICK_PCI_OP             0x02000042   // reentrant
-#define         SN_SAL_IROUTER_OP                         0x02000043
-#define  SN_SAL_SYSCTL_EVENT                       0x02000044
-#define  SN_SAL_IOIF_INTERRUPT                    0x0200004a
-#define  SN_SAL_HWPERF_OP                         0x02000050   // lock
-#define  SN_SAL_IOIF_ERROR_INTERRUPT              0x02000051
-#define  SN_SAL_IOIF_PCI_SAFE                     0x02000052
-#define  SN_SAL_IOIF_SLOT_ENABLE                  0x02000053
-#define  SN_SAL_IOIF_SLOT_DISABLE                 0x02000054
-#define  SN_SAL_IOIF_GET_HUBDEV_INFO              0x02000055
-#define  SN_SAL_IOIF_GET_PCIBUS_INFO              0x02000056
-#define  SN_SAL_IOIF_GET_PCIDEV_INFO              0x02000057
-#define  SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST     0x02000058   // deprecated
-#define  SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST     0x0200005a
-
-#define SN_SAL_IOIF_INIT                          0x0200005f
-#define SN_SAL_HUB_ERROR_INTERRUPT                0x02000060
-#define SN_SAL_BTE_RECOVER                        0x02000061
-#define SN_SAL_RESERVED_DO_NOT_USE                0x02000062
-#define SN_SAL_IOIF_GET_PCI_TOPOLOGY              0x02000064
-
-#define  SN_SAL_GET_PROM_FEATURE_SET              0x02000065
-#define  SN_SAL_SET_OS_FEATURE_SET                0x02000066
-#define  SN_SAL_INJECT_ERROR                      0x02000067
-#define  SN_SAL_SET_CPU_NUMBER                    0x02000068
 
-#define  SN_SAL_KERNEL_LAUNCH_EVENT               0x02000069
 #define  SN_SAL_WATCHLIST_ALLOC                           0x02000070
 #define  SN_SAL_WATCHLIST_FREE                    0x02000071
 
 /*
- * Service-specific constants
- */
-
-/* Console interrupt manipulation */
-       /* action codes */
-#define SAL_CONSOLE_INTR_OFF    0       /* turn the interrupt off */
-#define SAL_CONSOLE_INTR_ON     1       /* turn the interrupt on */
-#define SAL_CONSOLE_INTR_STATUS 2      /* retrieve the interrupt status */
-       /* interrupt specification & status return codes */
-#define SAL_CONSOLE_INTR_XMIT  1       /* output interrupt */
-#define SAL_CONSOLE_INTR_RECV  2       /* input interrupt */
-
-/* interrupt handling */
-#define SAL_INTR_ALLOC         1
-#define SAL_INTR_FREE          2
-#define SAL_INTR_REDIRECT      3
-
-/*
- * operations available on the generic SN_SAL_SYSCTL_OP
- * runtime service
- */
-#define SAL_SYSCTL_OP_IOBOARD          0x0001  /*  retrieve board type */
-#define SAL_SYSCTL_OP_TIO_JLCK_RST      0x0002  /* issue TIO clock reset */
-
-/*
- * IRouter (i.e. generalized system controller) operations
- */
-#define SAL_IROUTER_OPEN       0       /* open a subchannel */
-#define SAL_IROUTER_CLOSE      1       /* close a subchannel */
-#define SAL_IROUTER_SEND       2       /* send part of an IRouter packet */
-#define SAL_IROUTER_RECV       3       /* receive part of an IRouter packet */
-#define SAL_IROUTER_INTR_STATUS        4       /* check the interrupt status for
-                                        * an open subchannel
-                                        */
-#define SAL_IROUTER_INTR_ON    5       /* enable an interrupt */
-#define SAL_IROUTER_INTR_OFF   6       /* disable an interrupt */
-#define SAL_IROUTER_INIT       7       /* initialize IRouter driver */
-
-/* IRouter interrupt mask bits */
-#define SAL_IROUTER_INTR_XMIT  SAL_CONSOLE_INTR_XMIT
-#define SAL_IROUTER_INTR_RECV  SAL_CONSOLE_INTR_RECV
-
-/*
- * Error Handling Features
- */
-#define SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV    0x1     // obsolete
-#define SAL_ERR_FEAT_LOG_SBES                  0x2     // obsolete
-#define SAL_ERR_FEAT_MFR_OVERRIDE              0x4
-#define SAL_ERR_FEAT_SBE_THRESHOLD             0xffff0000
-
-/*
  * SAL Error Codes
  */
 #define SALRET_MORE_PASSES     1
 #define SALRET_INVALID_ARG     (-2)
 #define SALRET_ERROR           (-3)
 
-#define SN_SAL_FAKE_PROM                          0x02009999
-
-/**
-  * sn_sal_revision - get the SGI SAL revision number
-  *
-  * The SGI PROM stores its version in the sal_[ab]_rev_(major|minor).
-  * This routine simply extracts the major and minor values and
-  * presents them in a u32 format.
-  *
-  * For example, version 4.05 would be represented at 0x0405.
-  */
-static inline u32
-sn_sal_rev(void)
-{
-       struct ia64_sal_systab *systab = __va(efi.sal_systab);
-
-       return (u32)(systab->sal_b_rev_major << 8 | systab->sal_b_rev_minor);
-}
-
-/*
- * Returns the master console nasid, if the call fails, return an illegal
- * value.
- */
-static inline u64
-ia64_sn_get_console_nasid(void)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_NASID, 0, 0, 0, 0, 0, 0, 0);
-
-       if (ret_stuff.status < 0)
-               return ret_stuff.status;
-
-       /* Master console nasid is in 'v0' */
-       return ret_stuff.v0;
-}
-
-/*
- * Returns the master baseio nasid, if the call fails, return an illegal
- * value.
- */
-static inline u64
-ia64_sn_get_master_baseio_nasid(void)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_BASEIO_NASID, 0, 0, 0, 0, 0, 0, 0);
-
-       if (ret_stuff.status < 0)
-               return ret_stuff.status;
-
-       /* Master baseio nasid is in 'v0' */
-       return ret_stuff.v0;
-}
-
-static inline void *
-ia64_sn_get_klconfig_addr(nasid_t nasid)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0);
-       return ret_stuff.v0 ? __va(ret_stuff.v0) : NULL;
-}
-
-/*
- * Returns the next console character.
- */
-static inline u64
-ia64_sn_console_getc(int *ch)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_GETC, 0, 0, 0, 0, 0, 0, 0);
-
-       /* character is in 'v0' */
-       *ch = (int)ret_stuff.v0;
-
-       return ret_stuff.status;
-}
-
-/*
- * Read a character from the SAL console device, after a previous interrupt
- * or poll operation has given us to know that a character is available
- * to be read.
- */
-static inline u64
-ia64_sn_console_readc(void)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_READC, 0, 0, 0, 0, 0, 0, 0);
-
-       /* character is in 'v0' */
-       return ret_stuff.v0;
-}
-
-/*
- * Sends the given character to the console.
- */
-static inline u64
-ia64_sn_console_putc(char ch)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTC, (u64)ch, 0, 0, 0, 0, 0, 0);
-
-       return ret_stuff.status;
-}
-
-/*
- * Sends the given buffer to the console.
- */
-static inline u64
-ia64_sn_console_putb(const char *buf, int len)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0; 
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTB, (u64)buf, (u64)len, 0, 0, 0, 0, 0);
-
-       if ( ret_stuff.status == 0 ) {
-               return ret_stuff.v0;
-       }
-       return (u64)0;
-}
-
-/*
- * Print a platform error record
- */
-static inline u64
-ia64_sn_plat_specific_err_print(int (*hook)(const char*, ...), char *rec)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_REENTRANT(ret_stuff, SN_SAL_PRINT_ERROR, (u64)hook, (u64)rec, 0, 0, 0, 0, 0);
-
-       return ret_stuff.status;
-}
-
-/*
- * Check for Platform errors
- */
-static inline u64
-ia64_sn_plat_cpei_handler(void)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_LOG_CE, 0, 0, 0, 0, 0, 0, 0);
-
-       return ret_stuff.status;
-}
-
-/*
- * Set Error Handling Features (Obsolete)
- */
-static inline u64
-ia64_sn_plat_set_error_handling_features(void)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_REENTRANT(ret_stuff, SN_SAL_SET_ERROR_HANDLING_FEATURES,
-               SAL_ERR_FEAT_LOG_SBES,
-               0, 0, 0, 0, 0, 0);
-
-       return ret_stuff.status;
-}
-
-/*
- * Checks for console input.
- */
-static inline u64
-ia64_sn_console_check(int *result)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_POLL, 0, 0, 0, 0, 0, 0, 0);
-
-       /* result is in 'v0' */
-       *result = (int)ret_stuff.v0;
-
-       return ret_stuff.status;
-}
-
-/*
- * Checks console interrupt status
- */
-static inline u64
-ia64_sn_console_intr_status(void)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
-                0, SAL_CONSOLE_INTR_STATUS,
-                0, 0, 0, 0, 0);
-
-       if (ret_stuff.status == 0) {
-           return ret_stuff.v0;
-       }
-       
-       return 0;
-}
-
-/*
- * Enable an interrupt on the SAL console device.
- */
-static inline void
-ia64_sn_console_intr_enable(u64 intr)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
-                intr, SAL_CONSOLE_INTR_ON,
-                0, 0, 0, 0, 0);
-}
-
-/*
- * Disable an interrupt on the SAL console device.
- */
-static inline void
-ia64_sn_console_intr_disable(u64 intr)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
-                intr, SAL_CONSOLE_INTR_OFF,
-                0, 0, 0, 0, 0);
-}
-
-/*
- * Sends a character buffer to the console asynchronously.
- */
-static inline u64
-ia64_sn_console_xmit_chars(char *buf, int len)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_XMIT_CHARS,
-                (u64)buf, (u64)len,
-                0, 0, 0, 0, 0);
-
-       if (ret_stuff.status == 0) {
-           return ret_stuff.v0;
-       }
-
-       return 0;
-}
-
-/*
- * Returns the iobrick module Id
- */
-static inline u64
-ia64_sn_sysctl_iobrick_module_get(nasid_t nasid, int *result)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYSCTL_IOBRICK_MODULE_GET, nasid, 0, 0, 0, 0, 0, 0);
-
-       /* result is in 'v0' */
-       *result = (int)ret_stuff.v0;
-
-       return ret_stuff.status;
-}
-
-/**
- * ia64_sn_pod_mode - call the SN_SAL_POD_MODE function
- *
- * SN_SAL_POD_MODE actually takes an argument, but it's always
- * 0 when we call it from the kernel, so we don't have to expose
- * it to the caller.
- */
-static inline u64
-ia64_sn_pod_mode(void)
-{
-       struct ia64_sal_retval isrv;
-       SAL_CALL_REENTRANT(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0);
-       if (isrv.status)
-               return 0;
-       return isrv.v0;
-}
-
-/**
- * ia64_sn_probe_mem - read from memory safely
- * @addr: address to probe
- * @size: number bytes to read (1,2,4,8)
- * @data_ptr: address to store value read by probe (-1 returned if probe fails)
- *
- * Call into the SAL to do a memory read.  If the read generates a machine
- * check, this routine will recover gracefully and return -1 to the caller.
- * @addr is usually a kernel virtual address in uncached space (i.e. the
- * address starts with 0xc), but if called in physical mode, @addr should
- * be a physical address.
- *
- * Return values:
- *  0 - probe successful
- *  1 - probe failed (generated MCA)
- *  2 - Bad arg
- * <0 - PAL error
- */
-static inline u64
-ia64_sn_probe_mem(long addr, long size, void *data_ptr)
-{
-       struct ia64_sal_retval isrv;
-
-       SAL_CALL(isrv, SN_SAL_PROBE, addr, size, 0, 0, 0, 0, 0);
-
-       if (data_ptr) {
-               switch (size) {
-               case 1:
-                       *((u8*)data_ptr) = (u8)isrv.v0;
-                       break;
-               case 2:
-                       *((u16*)data_ptr) = (u16)isrv.v0;
-                       break;
-               case 4:
-                       *((u32*)data_ptr) = (u32)isrv.v0;
-                       break;
-               case 8:
-                       *((u64*)data_ptr) = (u64)isrv.v0;
-                       break;
-               default:
-                       isrv.status = 2;
-               }
-       }
-       return isrv.status;
-}
-
-/*
- * Retrieve the system serial number as an ASCII string.
- */
-static inline u64
-ia64_sn_sys_serial_get(char *buf)
-{
-       struct ia64_sal_retval ret_stuff;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYS_SERIAL_GET, buf, 0, 0, 0, 0, 0, 0);
-       return ret_stuff.status;
-}
-
-extern char sn_system_serial_number_string[];
-extern u64 sn_partition_serial_number;
-
-static inline char *
-sn_system_serial_number(void) {
-       if (sn_system_serial_number_string[0]) {
-               return(sn_system_serial_number_string);
-       } else {
-               ia64_sn_sys_serial_get(sn_system_serial_number_string);
-               return(sn_system_serial_number_string);
-       }
-}
-       
-
-/*
- * Returns a unique id number for this system and partition (suitable for
- * use with license managers), based in part on the system serial number.
- */
-static inline u64
-ia64_sn_partition_serial_get(void)
-{
-       struct ia64_sal_retval ret_stuff;
-       ia64_sal_oemcall_reentrant(&ret_stuff, SN_SAL_PARTITION_SERIAL_GET, 0,
-                                  0, 0, 0, 0, 0, 0);
-       if (ret_stuff.status != 0)
-           return 0;
-       return ret_stuff.v0;
-}
-
-static inline u64
-sn_partition_serial_number_val(void) {
-       if (unlikely(sn_partition_serial_number == 0)) {
-               sn_partition_serial_number = ia64_sn_partition_serial_get();
-       }
-       return sn_partition_serial_number;
-}
-
-/*
- * Returns the partition id of the nasid passed in as an argument,
- * or INVALID_PARTID if the partition id cannot be retrieved.
- */
-static inline partid_t
-ia64_sn_sysctl_partition_get(nasid_t nasid)
-{
-       struct ia64_sal_retval ret_stuff;
-       SAL_CALL(ret_stuff, SN_SAL_SYSCTL_PARTITION_GET, nasid,
-               0, 0, 0, 0, 0, 0);
-       if (ret_stuff.status != 0)
-           return -1;
-       return ((partid_t)ret_stuff.v0);
-}
-
 /*
  * Returns the physical address of the partition's reserved page through
  * an iterative number of calls.
@@ -634,96 +59,6 @@ sn_partition_reserved_page_pa(u64 buf, u64 *cookie, u64 *addr, u64 *len)
 }
 
 /*
- * Register or unregister a physical address range being referenced across
- * a partition boundary for which certain SAL errors should be scanned for,
- * cleaned up and ignored.  This is of value for kernel partitioning code only.
- * Values for the operation argument:
- *     1 = register this address range with SAL
- *     0 = unregister this address range with SAL
- * 
- * SAL maintains a reference count on an address range in case it is registered
- * multiple times.
- * 
- * On success, returns the reference count of the address range after the SAL
- * call has performed the current registration/unregistration.  Returns a
- * negative value if an error occurred.
- */
-static inline int
-sn_register_xp_addr_region(u64 paddr, u64 len, int operation)
-{
-       struct ia64_sal_retval ret_stuff;
-       ia64_sal_oemcall(&ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len,
-                        (u64)operation, 0, 0, 0, 0);
-       return ret_stuff.status;
-}
-
-/*
- * Register or unregister an instruction range for which SAL errors should
- * be ignored.  If an error occurs while in the registered range, SAL jumps
- * to return_addr after ignoring the error.  Values for the operation argument:
- *     1 = register this instruction range with SAL
- *     0 = unregister this instruction range with SAL
- *
- * Returns 0 on success, or a negative value if an error occurred.
- */
-static inline int
-sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr,
-                        int virtual, int operation)
-{
-       struct ia64_sal_retval ret_stuff;
-       u64 call;
-       if (virtual) {
-               call = SN_SAL_NO_FAULT_ZONE_VIRTUAL;
-       } else {
-               call = SN_SAL_NO_FAULT_ZONE_PHYSICAL;
-       }
-       ia64_sal_oemcall(&ret_stuff, call, start_addr, end_addr, return_addr,
-                        (u64)1, 0, 0, 0);
-       return ret_stuff.status;
-}
-
-/*
- * Register or unregister a function to handle a PMI received by a CPU.
- * Before calling the registered handler, SAL sets r1 to the value that
- * was passed in as the global_pointer.
- *
- * If the handler pointer is NULL, then the currently registered handler
- * will be unregistered.
- *
- * Returns 0 on success, or a negative value if an error occurred.
- */
-static inline int
-sn_register_pmi_handler(u64 handler, u64 global_pointer)
-{
-       struct ia64_sal_retval ret_stuff;
-       ia64_sal_oemcall(&ret_stuff, SN_SAL_REGISTER_PMI_HANDLER, handler,
-                        global_pointer, 0, 0, 0, 0, 0);
-       return ret_stuff.status;
-}
-
-/*
- * Change or query the coherence domain for this partition. Each cpu-based
- * nasid is represented by a bit in an array of 64-bit words:
- *      0 = not in this partition's coherency domain
- *      1 = in this partition's coherency domain
- *
- * It is not possible for the local system's nasids to be removed from
- * the coherency domain.  Purpose of the domain arguments:
- *      new_domain = set the coherence domain to the given nasids
- *      old_domain = return the current coherence domain
- *
- * Returns 0 on success, or a negative value if an error occurred.
- */
-static inline int
-sn_change_coherence(u64 *new_domain, u64 *old_domain)
-{
-       struct ia64_sal_retval ret_stuff;
-       ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_COHERENCE, (u64)new_domain,
-                               (u64)old_domain, 0, 0, 0, 0, 0);
-       return ret_stuff.status;
-}
-
-/*
  * Change memory access protections for a physical address range.
  * nasid_array is not used on Altix, but may be in future architectures.
  * Available memory protection access classes are defined after the function.
@@ -744,450 +79,6 @@ sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array)
 #define SN_MEMPROT_ACCESS_CLASS_6              0x084080
 #define SN_MEMPROT_ACCESS_CLASS_7              0x021080
 
-/*
- * Turns off system power.
- */
-static inline void
-ia64_sn_power_down(void)
-{
-       struct ia64_sal_retval ret_stuff;
-       SAL_CALL(ret_stuff, SN_SAL_SYSTEM_POWER_DOWN, 0, 0, 0, 0, 0, 0, 0);
-       while(1)
-               cpu_relax();
-       /* never returns */
-}
-
-/**
- * ia64_sn_fru_capture - tell the system controller to capture hw state
- *
- * This routine will call the SAL which will tell the system controller(s)
- * to capture hw mmr information from each SHub in the system.
- */
-static inline u64
-ia64_sn_fru_capture(void)
-{
-        struct ia64_sal_retval isrv;
-        SAL_CALL(isrv, SN_SAL_SYSCTL_FRU_CAPTURE, 0, 0, 0, 0, 0, 0, 0);
-        if (isrv.status)
-                return 0;
-        return isrv.v0;
-}
-
-/*
- * Performs an operation on a PCI bus or slot -- power up, power down
- * or reset.
- */
-static inline u64
-ia64_sn_sysctl_iobrick_pci_op(nasid_t n, u64 connection_type, 
-                             u64 bus, char slot, 
-                             u64 action)
-{
-       struct ia64_sal_retval rv = {0, 0, 0, 0};
-
-       SAL_CALL_NOLOCK(rv, SN_SAL_SYSCTL_IOBRICK_PCI_OP, connection_type, n, action,
-                bus, (u64) slot, 0, 0);
-       if (rv.status)
-               return rv.v0;
-       return 0;
-}
-
-
-/*
- * Open a subchannel for sending arbitrary data to the system
- * controller network via the system controller device associated with
- * 'nasid'.  Return the subchannel number or a negative error code.
- */
-static inline int
-ia64_sn_irtr_open(nasid_t nasid)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_OPEN, nasid,
-                          0, 0, 0, 0, 0);
-       return (int) rv.v0;
-}
-
-/*
- * Close system controller subchannel 'subch' previously opened on 'nasid'.
- */
-static inline int
-ia64_sn_irtr_close(nasid_t nasid, int subch)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_CLOSE,
-                          (u64) nasid, (u64) subch, 0, 0, 0, 0);
-       return (int) rv.status;
-}
-
-/*
- * Read data from system controller associated with 'nasid' on
- * subchannel 'subch'.  The buffer to be filled is pointed to by
- * 'buf', and its capacity is in the integer pointed to by 'len'.  The
- * referent of 'len' is set to the number of bytes read by the SAL
- * call.  The return value is either SALRET_OK (for bytes read) or
- * SALRET_ERROR (for error or "no data available").
- */
-static inline int
-ia64_sn_irtr_recv(nasid_t nasid, int subch, char *buf, int *len)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_RECV,
-                          (u64) nasid, (u64) subch, (u64) buf, (u64) len,
-                          0, 0);
-       return (int) rv.status;
-}
-
-/*
- * Write data to the system controller network via the system
- * controller associated with 'nasid' on suchannel 'subch'.  The
- * buffer to be written out is pointed to by 'buf', and 'len' is the
- * number of bytes to be written.  The return value is either the
- * number of bytes written (which could be zero) or a negative error
- * code.
- */
-static inline int
-ia64_sn_irtr_send(nasid_t nasid, int subch, char *buf, int len)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_SEND,
-                          (u64) nasid, (u64) subch, (u64) buf, (u64) len,
-                          0, 0);
-       return (int) rv.v0;
-}
-
-/*
- * Check whether any interrupts are pending for the system controller
- * associated with 'nasid' and its subchannel 'subch'.  The return
- * value is a mask of pending interrupts (SAL_IROUTER_INTR_XMIT and/or
- * SAL_IROUTER_INTR_RECV).
- */
-static inline int
-ia64_sn_irtr_intr(nasid_t nasid, int subch)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_INTR_STATUS,
-                          (u64) nasid, (u64) subch, 0, 0, 0, 0);
-       return (int) rv.v0;
-}
-
-/*
- * Enable the interrupt indicated by the intr parameter (either
- * SAL_IROUTER_INTR_XMIT or SAL_IROUTER_INTR_RECV).
- */
-static inline int
-ia64_sn_irtr_intr_enable(nasid_t nasid, int subch, u64 intr)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_INTR_ON,
-                          (u64) nasid, (u64) subch, intr, 0, 0, 0);
-       return (int) rv.v0;
-}
-
-/*
- * Disable the interrupt indicated by the intr parameter (either
- * SAL_IROUTER_INTR_XMIT or SAL_IROUTER_INTR_RECV).
- */
-static inline int
-ia64_sn_irtr_intr_disable(nasid_t nasid, int subch, u64 intr)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_INTR_OFF,
-                          (u64) nasid, (u64) subch, intr, 0, 0, 0);
-       return (int) rv.v0;
-}
-
-/*
- * Set up a node as the point of contact for system controller
- * environmental event delivery.
- */
-static inline int
-ia64_sn_sysctl_event_init(nasid_t nasid)
-{
-        struct ia64_sal_retval rv;
-        SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_EVENT, (u64) nasid,
-                          0, 0, 0, 0, 0, 0);
-        return (int) rv.v0;
-}
-
-/*
- * Ask the system controller on the specified nasid to reset
- * the CX corelet clock.  Only valid on TIO nodes.
- */
-static inline int
-ia64_sn_sysctl_tio_clock_reset(nasid_t nasid)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_TIO_JLCK_RST,
-                       nasid, 0, 0, 0, 0, 0);
-       if (rv.status != 0)
-               return (int)rv.status;
-       if (rv.v0 != 0)
-               return (int)rv.v0;
-
-       return 0;
-}
-
-/*
- * Get the associated ioboard type for a given nasid.
- */
-static inline long
-ia64_sn_sysctl_ioboard_get(nasid_t nasid, u16 *ioboard)
-{
-       struct ia64_sal_retval isrv;
-       SAL_CALL_REENTRANT(isrv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_IOBOARD,
-                          nasid, 0, 0, 0, 0, 0);
-       if (isrv.v0 != 0) {
-               *ioboard = isrv.v0;
-               return isrv.status;
-       }
-       if (isrv.v1 != 0) {
-               *ioboard = isrv.v1;
-               return isrv.status;
-       }
-
-       return isrv.status;
-}
-
-/**
- * ia64_sn_get_fit_compt - read a FIT entry from the PROM header
- * @nasid: NASID of node to read
- * @index: FIT entry index to be retrieved (0..n)
- * @fitentry: 16 byte buffer where FIT entry will be stored.
- * @banbuf: optional buffer for retrieving banner
- * @banlen: length of banner buffer
- *
- * Access to the physical PROM chips needs to be serialized since reads and
- * writes can't occur at the same time, so we need to call into the SAL when
- * we want to look at the FIT entries on the chips.
- *
- * Returns:
- *     %SALRET_OK if ok
- *     %SALRET_INVALID_ARG if index too big
- *     %SALRET_NOT_IMPLEMENTED if running on older PROM
- *     ??? if nasid invalid OR banner buffer not large enough
- */
-static inline int
-ia64_sn_get_fit_compt(u64 nasid, u64 index, void *fitentry, void *banbuf,
-                     u64 banlen)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_NOLOCK(rv, SN_SAL_GET_FIT_COMPT, nasid, index, fitentry,
-                       banbuf, banlen, 0, 0);
-       return (int) rv.status;
-}
-
-/*
- * Initialize the SAL components of the system controller
- * communication driver; specifically pass in a sizable buffer that
- * can be used for allocation of subchannel queues as new subchannels
- * are opened.  "buf" points to the buffer, and "len" specifies its
- * length.
- */
-static inline int
-ia64_sn_irtr_init(nasid_t nasid, void *buf, int len)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_REENTRANT(rv, SN_SAL_IROUTER_OP, SAL_IROUTER_INIT,
-                          (u64) nasid, (u64) buf, (u64) len, 0, 0, 0);
-       return (int) rv.status;
-}
-
-/*
- * Returns the nasid, subnode & slice corresponding to a SAPIC ID
- *
- *  In:
- *     arg0 - SN_SAL_GET_SAPIC_INFO
- *     arg1 - sapicid (lid >> 16) 
- *  Out:
- *     v0 - nasid
- *     v1 - subnode
- *     v2 - slice
- */
-static inline u64
-ia64_sn_get_sapic_info(int sapicid, int *nasid, int *subnode, int *slice)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SAPIC_INFO, sapicid, 0, 0, 0, 0, 0, 0);
-
-/***** BEGIN HACK - temp til old proms no longer supported ********/
-       if (ret_stuff.status == SALRET_NOT_IMPLEMENTED) {
-               if (nasid) *nasid = sapicid & 0xfff;
-               if (subnode) *subnode = (sapicid >> 13) & 1;
-               if (slice) *slice = (sapicid >> 12) & 3;
-               return 0;
-       }
-/***** END HACK *******/
-
-       if (ret_stuff.status < 0)
-               return ret_stuff.status;
-
-       if (nasid) *nasid = (int) ret_stuff.v0;
-       if (subnode) *subnode = (int) ret_stuff.v1;
-       if (slice) *slice = (int) ret_stuff.v2;
-       return 0;
-}
-/*
- * Returns information about the HUB/SHUB.
- *  In:
- *     arg0 - SN_SAL_GET_SN_INFO
- *     arg1 - 0 (other values reserved for future use)
- *  Out:
- *     v0 
- *             [7:0]   - shub type (0=shub1, 1=shub2)
- *             [15:8]  - Log2 max number of nodes in entire system (includes
- *                       C-bricks, I-bricks, etc)
- *             [23:16] - Log2 of nodes per sharing domain                       
- *             [31:24] - partition ID
- *             [39:32] - coherency_id
- *             [47:40] - regionsize
- *     v1 
- *             [15:0]  - nasid mask (ex., 0x7ff for 11 bit nasid)
- *             [23:15] - bit position of low nasid bit
- */
-static inline u64
-ia64_sn_get_sn_info(int fc, u8 *shubtype, u16 *nasid_bitmask, u8 *nasid_shift, 
-               u8 *systemsize, u8 *sharing_domain_size, u8 *partid, u8 *coher, u8 *reg)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       ret_stuff.v1 = 0;
-       ret_stuff.v2 = 0;
-       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SN_INFO, fc, 0, 0, 0, 0, 0, 0);
-
-/***** BEGIN HACK - temp til old proms no longer supported ********/
-       if (ret_stuff.status == SALRET_NOT_IMPLEMENTED) {
-               int nasid = get_sapicid() & 0xfff;
-#define SH_SHUB_ID_NODES_PER_BIT_MASK 0x001f000000000000UL
-#define SH_SHUB_ID_NODES_PER_BIT_SHFT 48
-               if (shubtype) *shubtype = 0;
-               if (nasid_bitmask) *nasid_bitmask = 0x7ff;
-               if (nasid_shift) *nasid_shift = 38;
-               if (systemsize) *systemsize = 10;
-               if (sharing_domain_size) *sharing_domain_size = 8;
-               if (partid) *partid = ia64_sn_sysctl_partition_get(nasid);
-               if (coher) *coher = nasid >> 9;
-               if (reg) *reg = (HUB_L((u64 *) LOCAL_MMR_ADDR(SH1_SHUB_ID)) & SH_SHUB_ID_NODES_PER_BIT_MASK) >>
-                       SH_SHUB_ID_NODES_PER_BIT_SHFT;
-               return 0;
-       }
-/***** END HACK *******/
-
-       if (ret_stuff.status < 0)
-               return ret_stuff.status;
-
-       if (shubtype) *shubtype = ret_stuff.v0 & 0xff;
-       if (systemsize) *systemsize = (ret_stuff.v0 >> 8) & 0xff;
-       if (sharing_domain_size) *sharing_domain_size = (ret_stuff.v0 >> 16) & 0xff;
-       if (partid) *partid = (ret_stuff.v0 >> 24) & 0xff;
-       if (coher) *coher = (ret_stuff.v0 >> 32) & 0xff;
-       if (reg) *reg = (ret_stuff.v0 >> 40) & 0xff;
-       if (nasid_bitmask) *nasid_bitmask = (ret_stuff.v1 & 0xffff);
-       if (nasid_shift) *nasid_shift = (ret_stuff.v1 >> 16) & 0xff;
-       return 0;
-}
-/*
- * This is the access point to the Altix PROM hardware performance
- * and status monitoring interface. For info on using this, see
- * arch/ia64/include/asm/sn/sn2/sn_hwperf.h
- */
-static inline int
-ia64_sn_hwperf_op(nasid_t nasid, u64 opcode, u64 a0, u64 a1, u64 a2,
-                  u64 a3, u64 a4, int *v0)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_NOLOCK(rv, SN_SAL_HWPERF_OP, (u64)nasid,
-               opcode, a0, a1, a2, a3, a4);
-       if (v0)
-               *v0 = (int) rv.v0;
-       return (int) rv.status;
-}
-
-static inline int
-ia64_sn_ioif_get_pci_topology(u64 buf, u64 len)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_NOLOCK(rv, SN_SAL_IOIF_GET_PCI_TOPOLOGY, buf, len, 0, 0, 0, 0, 0);
-       return (int) rv.status;
-}
-
-/*
- * BTE error recovery is implemented in SAL
- */
-static inline int
-ia64_sn_bte_recovery(nasid_t nasid)
-{
-       struct ia64_sal_retval rv;
-
-       rv.status = 0;
-       SAL_CALL_NOLOCK(rv, SN_SAL_BTE_RECOVER, (u64)nasid, 0, 0, 0, 0, 0, 0);
-       if (rv.status == SALRET_NOT_IMPLEMENTED)
-               return 0;
-       return (int) rv.status;
-}
-
-static inline int
-ia64_sn_is_fake_prom(void)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_NOLOCK(rv, SN_SAL_FAKE_PROM, 0, 0, 0, 0, 0, 0, 0);
-       return (rv.status == 0);
-}
-
-static inline int
-ia64_sn_get_prom_feature_set(int set, unsigned long *feature_set)
-{
-       struct ia64_sal_retval rv;
-
-       SAL_CALL_NOLOCK(rv, SN_SAL_GET_PROM_FEATURE_SET, set, 0, 0, 0, 0, 0, 0);
-       if (rv.status != 0)
-               return rv.status;
-       *feature_set = rv.v0;
-       return 0;
-}
-
-static inline int
-ia64_sn_set_os_feature(int feature)
-{
-       struct ia64_sal_retval rv;
-
-       SAL_CALL_NOLOCK(rv, SN_SAL_SET_OS_FEATURE_SET, feature, 0, 0, 0, 0, 0, 0);
-       return rv.status;
-}
-
-static inline int
-sn_inject_error(u64 paddr, u64 *data, u64 *ecc)
-{
-       struct ia64_sal_retval ret_stuff;
-
-       ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_INJECT_ERROR, paddr, (u64)data,
-                               (u64)ecc, 0, 0, 0, 0);
-       return ret_stuff.status;
-}
-
-static inline int
-ia64_sn_set_cpu_number(int cpu)
-{
-       struct ia64_sal_retval rv;
-
-       SAL_CALL_NOLOCK(rv, SN_SAL_SET_CPU_NUMBER, cpu, 0, 0, 0, 0, 0, 0);
-       return rv.status;
-}
-static inline int
-ia64_sn_kernel_launch_event(void)
-{
-       struct ia64_sal_retval rv;
-       SAL_CALL_NOLOCK(rv, SN_SAL_KERNEL_LAUNCH_EVENT, 0, 0, 0, 0, 0, 0, 0);
-       return rv.status;
-}
-
 union sn_watchlist_u {
        u64     val;
        struct {
diff --git a/arch/ia64/include/asm/sn/tioca.h b/arch/ia64/include/asm/sn/tioca.h
deleted file mode 100644 (file)
index 666222d..0000000
+++ /dev/null
@@ -1,596 +0,0 @@
-#ifndef _ASM_IA64_SN_TIO_TIOCA_H
-#define _ASM_IA64_SN_TIO_TIOCA_H
-
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2003-2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#define TIOCA_PART_NUM 0xE020
-#define TIOCA_MFGR_NUM 0x24
-#define TIOCA_REV_A    0x1
-
-/*
- * Register layout for TIO:CA.  See below for bitmasks for each register.
- */
-
-struct tioca {
-       u64     ca_id;                          /* 0x000000 */
-       u64     ca_control1;                    /* 0x000008 */
-       u64     ca_control2;                    /* 0x000010 */
-       u64     ca_status1;                     /* 0x000018 */
-       u64     ca_status2;                     /* 0x000020 */
-       u64     ca_gart_aperature;              /* 0x000028 */
-       u64     ca_gfx_detach;                  /* 0x000030 */
-       u64     ca_inta_dest_addr;              /* 0x000038 */
-       u64     ca_intb_dest_addr;              /* 0x000040 */
-       u64     ca_err_int_dest_addr;           /* 0x000048 */
-       u64     ca_int_status;                  /* 0x000050 */
-       u64     ca_int_status_alias;            /* 0x000058 */
-       u64     ca_mult_error;                  /* 0x000060 */
-       u64     ca_mult_error_alias;            /* 0x000068 */
-       u64     ca_first_error;                 /* 0x000070 */
-       u64     ca_int_mask;                    /* 0x000078 */
-       u64     ca_crm_pkterr_type;             /* 0x000080 */
-       u64     ca_crm_pkterr_type_alias;       /* 0x000088 */
-       u64     ca_crm_ct_error_detail_1;       /* 0x000090 */
-       u64     ca_crm_ct_error_detail_2;       /* 0x000098 */
-       u64     ca_crm_tnumto;                  /* 0x0000A0 */
-       u64     ca_gart_err;                    /* 0x0000A8 */
-       u64     ca_pcierr_type;                 /* 0x0000B0 */
-       u64     ca_pcierr_addr;                 /* 0x0000B8 */
-
-       u64     ca_pad_0000C0[3];               /* 0x0000{C0..D0} */
-
-       u64     ca_pci_rd_buf_flush;            /* 0x0000D8 */
-       u64     ca_pci_dma_addr_extn;           /* 0x0000E0 */
-       u64     ca_agp_dma_addr_extn;           /* 0x0000E8 */
-       u64     ca_force_inta;                  /* 0x0000F0 */
-       u64     ca_force_intb;                  /* 0x0000F8 */
-       u64     ca_debug_vector_sel;            /* 0x000100 */
-       u64     ca_debug_mux_core_sel;          /* 0x000108 */
-       u64     ca_debug_mux_pci_sel;           /* 0x000110 */
-       u64     ca_debug_domain_sel;            /* 0x000118 */
-
-       u64     ca_pad_000120[28];              /* 0x0001{20..F8} */
-
-       u64     ca_gart_ptr_table;              /* 0x200 */
-       u64     ca_gart_tlb_addr[8];            /* 0x2{08..40} */
-};
-
-/*
- * Mask/shift definitions for TIO:CA registers.  The convention here is
- * to mainly use the names as they appear in the "TIO AEGIS Programmers'
- * Reference" with a CA_ prefix added.  Some exceptions were made to fix
- * duplicate field names or to generalize fields that are common to
- * different registers (ca_debug_mux_core_sel and ca_debug_mux_pci_sel for
- * example).
- *
- * Fields consisting of a single bit have a single #define have a single
- * macro declaration to mask the bit.  Fields consisting of multiple bits
- * have two declarations: one to mask the proper bits in a register, and 
- * a second with the suffix "_SHFT" to identify how far the mask needs to
- * be shifted right to get its base value.
- */
-
-/* ==== ca_control1 */
-#define CA_SYS_BIG_END                 (1ull << 0)
-#define CA_DMA_AGP_SWAP                        (1ull << 1)
-#define CA_DMA_PCI_SWAP                        (1ull << 2)
-#define CA_PIO_IO_SWAP                 (1ull << 3)
-#define CA_PIO_MEM_SWAP                        (1ull << 4)
-#define CA_GFX_WR_SWAP                 (1ull << 5)
-#define CA_AGP_FW_ENABLE               (1ull << 6)
-#define CA_AGP_CAL_CYCLE               (0x7ull << 7)
-#define CA_AGP_CAL_CYCLE_SHFT          7
-#define CA_AGP_CAL_PRSCL_BYP           (1ull << 10)
-#define CA_AGP_INIT_CAL_ENB            (1ull << 11)
-#define CA_INJ_ADDR_PERR               (1ull << 12)
-#define CA_INJ_DATA_PERR               (1ull << 13)
-       /* bits 15:14 unused */
-#define CA_PCIM_IO_NBE_AD              (0x7ull << 16)
-#define CA_PCIM_IO_NBE_AD_SHFT         16
-#define CA_PCIM_FAST_BTB_ENB           (1ull << 19)
-       /* bits 23:20 unused */
-#define CA_PIO_ADDR_OFFSET             (0xffull << 24)
-#define CA_PIO_ADDR_OFFSET_SHFT                24
-       /* bits 35:32 unused */
-#define CA_AGPDMA_OP_COMBDELAY         (0x1full << 36)
-#define CA_AGPDMA_OP_COMBDELAY_SHFT    36
-       /* bit 41 unused */
-#define CA_AGPDMA_OP_ENB_COMBDELAY     (1ull << 42)
-#define        CA_PCI_INT_LPCNT                (0xffull << 44)
-#define CA_PCI_INT_LPCNT_SHFT          44
-       /* bits 63:52 unused */
-
-/* ==== ca_control2 */
-#define CA_AGP_LATENCY_TO              (0xffull << 0)
-#define CA_AGP_LATENCY_TO_SHFT         0
-#define CA_PCI_LATENCY_TO              (0xffull << 8)
-#define CA_PCI_LATENCY_TO_SHFT         8
-#define CA_PCI_MAX_RETRY               (0x3ffull << 16)
-#define CA_PCI_MAX_RETRY_SHFT          16
-       /* bits 27:26 unused */
-#define CA_RT_INT_EN                   (0x3ull << 28)
-#define CA_RT_INT_EN_SHFT                      28
-#define CA_MSI_INT_ENB                 (1ull << 30)
-#define CA_PCI_ARB_ERR_ENB             (1ull << 31)
-#define CA_GART_MEM_PARAM              (0x3ull << 32)
-#define CA_GART_MEM_PARAM_SHFT         32
-#define CA_GART_RD_PREFETCH_ENB                (1ull << 34)
-#define CA_GART_WR_PREFETCH_ENB                (1ull << 35)
-#define CA_GART_FLUSH_TLB              (1ull << 36)
-       /* bits 39:37 unused */
-#define CA_CRM_TNUMTO_PERIOD           (0x1fffull << 40)
-#define CA_CRM_TNUMTO_PERIOD_SHFT      40
-       /* bits 55:53 unused */
-#define CA_CRM_TNUMTO_ENB              (1ull << 56)
-#define CA_CRM_PRESCALER_BYP           (1ull << 57)
-       /* bits 59:58 unused */
-#define CA_CRM_MAX_CREDIT              (0x7ull << 60)
-#define CA_CRM_MAX_CREDIT_SHFT         60
-       /* bit 63 unused */
-
-/* ==== ca_status1 */
-#define CA_CORELET_ID                  (0x3ull << 0)
-#define CA_CORELET_ID_SHFT             0
-#define CA_INTA_N                      (1ull << 2)
-#define CA_INTB_N                      (1ull << 3)
-#define CA_CRM_CREDIT_AVAIL            (0x7ull << 4)
-#define CA_CRM_CREDIT_AVAIL_SHFT       4
-       /* bit 7 unused */
-#define CA_CRM_SPACE_AVAIL             (0x7full << 8)
-#define CA_CRM_SPACE_AVAIL_SHFT                8
-       /* bit 15 unused */
-#define CA_GART_TLB_VAL                        (0xffull << 16)
-#define CA_GART_TLB_VAL_SHFT           16
-       /* bits 63:24 unused */
-
-/* ==== ca_status2 */
-#define CA_GFX_CREDIT_AVAIL            (0xffull << 0)
-#define CA_GFX_CREDIT_AVAIL_SHFT       0
-#define CA_GFX_OPQ_AVAIL               (0xffull << 8)
-#define CA_GFX_OPQ_AVAIL_SHFT          8
-#define CA_GFX_WRBUFF_AVAIL            (0xffull << 16)
-#define CA_GFX_WRBUFF_AVAIL_SHFT       16
-#define CA_ADMA_OPQ_AVAIL              (0xffull << 24)
-#define CA_ADMA_OPQ_AVAIL_SHFT         24
-#define CA_ADMA_WRBUFF_AVAIL           (0xffull << 32)
-#define CA_ADMA_WRBUFF_AVAIL_SHFT      32
-#define CA_ADMA_RDBUFF_AVAIL           (0x7full << 40)
-#define CA_ADMA_RDBUFF_AVAIL_SHFT      40
-#define CA_PCI_PIO_OP_STAT             (1ull << 47)
-#define CA_PDMA_OPQ_AVAIL              (0xfull << 48)
-#define CA_PDMA_OPQ_AVAIL_SHFT         48
-#define CA_PDMA_WRBUFF_AVAIL           (0xfull << 52)
-#define CA_PDMA_WRBUFF_AVAIL_SHFT      52
-#define CA_PDMA_RDBUFF_AVAIL           (0x3ull << 56)
-#define CA_PDMA_RDBUFF_AVAIL_SHFT      56
-       /* bits 63:58 unused */
-
-/* ==== ca_gart_aperature */
-#define CA_GART_AP_ENB_AGP             (1ull << 0)
-#define CA_GART_PAGE_SIZE              (1ull << 1)
-#define CA_GART_AP_ENB_PCI             (1ull << 2)
-       /* bits 11:3 unused */
-#define CA_GART_AP_SIZE                        (0x3ffull << 12)
-#define CA_GART_AP_SIZE_SHFT           12
-#define CA_GART_AP_BASE                        (0x3ffffffffffull << 22)
-#define CA_GART_AP_BASE_SHFT           22
-
-/* ==== ca_inta_dest_addr
-   ==== ca_intb_dest_addr 
-   ==== ca_err_int_dest_addr */
-       /* bits 2:0 unused */
-#define CA_INT_DEST_ADDR               (0x7ffffffffffffull << 3)
-#define CA_INT_DEST_ADDR_SHFT          3
-       /* bits 55:54 unused */
-#define CA_INT_DEST_VECT               (0xffull << 56)
-#define CA_INT_DEST_VECT_SHFT          56
-
-/* ==== ca_int_status */
-/* ==== ca_int_status_alias */
-/* ==== ca_mult_error */
-/* ==== ca_mult_error_alias */
-/* ==== ca_first_error */
-/* ==== ca_int_mask */
-#define CA_PCI_ERR                     (1ull << 0)
-       /* bits 3:1 unused */
-#define CA_GART_FETCH_ERR              (1ull << 4)
-#define CA_GFX_WR_OVFLW                        (1ull << 5)
-#define CA_PIO_REQ_OVFLW               (1ull << 6)
-#define CA_CRM_PKTERR                  (1ull << 7)
-#define CA_CRM_DVERR                   (1ull << 8)
-#define CA_TNUMTO                      (1ull << 9)
-#define CA_CXM_RSP_CRED_OVFLW          (1ull << 10)
-#define CA_CXM_REQ_CRED_OVFLW          (1ull << 11)
-#define CA_PIO_INVALID_ADDR            (1ull << 12)
-#define CA_PCI_ARB_TO                  (1ull << 13)
-#define CA_AGP_REQ_OFLOW               (1ull << 14)
-#define CA_SBA_TYPE1_ERR               (1ull << 15)
-       /* bit 16 unused */
-#define CA_INTA                                (1ull << 17)
-#define CA_INTB                                (1ull << 18)
-#define CA_MULT_INTA                   (1ull << 19)
-#define CA_MULT_INTB                   (1ull << 20)
-#define CA_GFX_CREDIT_OVFLW            (1ull << 21)
-       /* bits 63:22 unused */
-
-/* ==== ca_crm_pkterr_type */
-/* ==== ca_crm_pkterr_type_alias */
-#define CA_CRM_PKTERR_SBERR_HDR                (1ull << 0)
-#define CA_CRM_PKTERR_DIDN             (1ull << 1)
-#define CA_CRM_PKTERR_PACTYPE          (1ull << 2)
-#define CA_CRM_PKTERR_INV_TNUM         (1ull << 3)
-#define CA_CRM_PKTERR_ADDR_RNG         (1ull << 4)
-#define CA_CRM_PKTERR_ADDR_ALGN                (1ull << 5)
-#define CA_CRM_PKTERR_HDR_PARAM                (1ull << 6)
-#define CA_CRM_PKTERR_CW_ERR           (1ull << 7)
-#define CA_CRM_PKTERR_SBERR_NH         (1ull << 8)
-#define CA_CRM_PKTERR_EARLY_TERM       (1ull << 9)
-#define CA_CRM_PKTERR_EARLY_TAIL       (1ull << 10)
-#define CA_CRM_PKTERR_MSSNG_TAIL       (1ull << 11)
-#define CA_CRM_PKTERR_MSSNG_HDR                (1ull << 12)
-       /* bits 15:13 unused */
-#define CA_FIRST_CRM_PKTERR_SBERR_HDR  (1ull << 16)
-#define CA_FIRST_CRM_PKTERR_DIDN       (1ull << 17)
-#define CA_FIRST_CRM_PKTERR_PACTYPE    (1ull << 18)
-#define CA_FIRST_CRM_PKTERR_INV_TNUM   (1ull << 19)
-#define CA_FIRST_CRM_PKTERR_ADDR_RNG   (1ull << 20)
-#define CA_FIRST_CRM_PKTERR_ADDR_ALGN  (1ull << 21)
-#define CA_FIRST_CRM_PKTERR_HDR_PARAM  (1ull << 22)
-#define CA_FIRST_CRM_PKTERR_CW_ERR     (1ull << 23)
-#define CA_FIRST_CRM_PKTERR_SBERR_NH   (1ull << 24)
-#define CA_FIRST_CRM_PKTERR_EARLY_TERM (1ull << 25)
-#define CA_FIRST_CRM_PKTERR_EARLY_TAIL (1ull << 26)
-#define CA_FIRST_CRM_PKTERR_MSSNG_TAIL (1ull << 27)
-#define CA_FIRST_CRM_PKTERR_MSSNG_HDR  (1ull << 28)
-       /* bits 63:29 unused */
-
-/* ==== ca_crm_ct_error_detail_1 */
-#define CA_PKT_TYPE                    (0xfull << 0)
-#define CA_PKT_TYPE_SHFT               0
-#define CA_SRC_ID                      (0x3ull << 4)
-#define CA_SRC_ID_SHFT                 4
-#define CA_DATA_SZ                     (0x3ull << 6)
-#define CA_DATA_SZ_SHFT                        6
-#define CA_TNUM                                (0xffull << 8)
-#define CA_TNUM_SHFT                   8
-#define CA_DW_DATA_EN                  (0xffull << 16)
-#define CA_DW_DATA_EN_SHFT             16
-#define CA_GFX_CRED                    (0xffull << 24)
-#define CA_GFX_CRED_SHFT               24
-#define CA_MEM_RD_PARAM                        (0x3ull << 32)
-#define CA_MEM_RD_PARAM_SHFT           32
-#define CA_PIO_OP                      (1ull << 34)
-#define CA_CW_ERR                      (1ull << 35)
-       /* bits 62:36 unused */
-#define CA_VALID                       (1ull << 63)
-
-/* ==== ca_crm_ct_error_detail_2 */
-       /* bits 2:0 unused */
-#define CA_PKT_ADDR                    (0x1fffffffffffffull << 3)
-#define CA_PKT_ADDR_SHFT               3
-       /* bits 63:56 unused */
-
-/* ==== ca_crm_tnumto */
-#define CA_CRM_TNUMTO_VAL              (0xffull << 0)
-#define CA_CRM_TNUMTO_VAL_SHFT         0
-#define CA_CRM_TNUMTO_WR               (1ull << 8)
-       /* bits 63:9 unused */
-
-/* ==== ca_gart_err */
-#define CA_GART_ERR_SOURCE             (0x3ull << 0)
-#define CA_GART_ERR_SOURCE_SHFT                0
-       /* bits 3:2 unused */
-#define CA_GART_ERR_ADDR               (0xfffffffffull << 4)
-#define CA_GART_ERR_ADDR_SHFT          4
-       /* bits 63:40 unused */
-
-/* ==== ca_pcierr_type */
-#define CA_PCIERR_DATA                 (0xffffffffull << 0)
-#define CA_PCIERR_DATA_SHFT            0
-#define CA_PCIERR_ENB                  (0xfull << 32)
-#define CA_PCIERR_ENB_SHFT             32
-#define CA_PCIERR_CMD                  (0xfull << 36)
-#define CA_PCIERR_CMD_SHFT             36
-#define CA_PCIERR_A64                  (1ull << 40)
-#define CA_PCIERR_SLV_SERR             (1ull << 41)
-#define CA_PCIERR_SLV_WR_PERR          (1ull << 42)
-#define CA_PCIERR_SLV_RD_PERR          (1ull << 43)
-#define CA_PCIERR_MST_SERR             (1ull << 44)
-#define CA_PCIERR_MST_WR_PERR          (1ull << 45)
-#define CA_PCIERR_MST_RD_PERR          (1ull << 46)
-#define CA_PCIERR_MST_MABT             (1ull << 47)
-#define CA_PCIERR_MST_TABT             (1ull << 48)
-#define CA_PCIERR_MST_RETRY_TOUT       (1ull << 49)
-
-#define CA_PCIERR_TYPES \
-       (CA_PCIERR_A64|CA_PCIERR_SLV_SERR| \
-        CA_PCIERR_SLV_WR_PERR|CA_PCIERR_SLV_RD_PERR| \
-        CA_PCIERR_MST_SERR|CA_PCIERR_MST_WR_PERR|CA_PCIERR_MST_RD_PERR| \
-        CA_PCIERR_MST_MABT|CA_PCIERR_MST_TABT|CA_PCIERR_MST_RETRY_TOUT)
-
-       /* bits 63:50 unused */
-
-/* ==== ca_pci_dma_addr_extn */
-#define CA_UPPER_NODE_OFFSET           (0x3full << 0)
-#define CA_UPPER_NODE_OFFSET_SHFT      0
-       /* bits 7:6 unused */
-#define CA_CHIPLET_ID                  (0x3ull << 8)
-#define CA_CHIPLET_ID_SHFT             8
-       /* bits 11:10 unused */
-#define CA_PCI_DMA_NODE_ID             (0xffffull << 12)
-#define CA_PCI_DMA_NODE_ID_SHFT                12
-       /* bits 27:26 unused */
-#define CA_PCI_DMA_PIO_MEM_TYPE                (1ull << 28)
-       /* bits 63:29 unused */
-
-
-/* ==== ca_agp_dma_addr_extn */
-       /* bits 19:0 unused */
-#define CA_AGP_DMA_NODE_ID             (0xffffull << 20)
-#define CA_AGP_DMA_NODE_ID_SHFT                20
-       /* bits 27:26 unused */
-#define CA_AGP_DMA_PIO_MEM_TYPE                (1ull << 28)
-       /* bits 63:29 unused */
-
-/* ==== ca_debug_vector_sel */
-#define CA_DEBUG_MN_VSEL               (0xfull << 0)
-#define CA_DEBUG_MN_VSEL_SHFT          0
-#define CA_DEBUG_PP_VSEL               (0xfull << 4)
-#define CA_DEBUG_PP_VSEL_SHFT          4
-#define CA_DEBUG_GW_VSEL               (0xfull << 8)
-#define CA_DEBUG_GW_VSEL_SHFT          8
-#define CA_DEBUG_GT_VSEL               (0xfull << 12)
-#define CA_DEBUG_GT_VSEL_SHFT          12
-#define CA_DEBUG_PD_VSEL               (0xfull << 16)
-#define CA_DEBUG_PD_VSEL_SHFT          16
-#define CA_DEBUG_AD_VSEL               (0xfull << 20)
-#define CA_DEBUG_AD_VSEL_SHFT          20
-#define CA_DEBUG_CX_VSEL               (0xfull << 24)
-#define CA_DEBUG_CX_VSEL_SHFT          24
-#define CA_DEBUG_CR_VSEL               (0xfull << 28)
-#define CA_DEBUG_CR_VSEL_SHFT          28
-#define CA_DEBUG_BA_VSEL               (0xfull << 32)
-#define CA_DEBUG_BA_VSEL_SHFT          32
-#define CA_DEBUG_PE_VSEL               (0xfull << 36)
-#define CA_DEBUG_PE_VSEL_SHFT          36
-#define CA_DEBUG_BO_VSEL               (0xfull << 40)
-#define CA_DEBUG_BO_VSEL_SHFT          40
-#define CA_DEBUG_BI_VSEL               (0xfull << 44)
-#define CA_DEBUG_BI_VSEL_SHFT          44
-#define CA_DEBUG_AS_VSEL               (0xfull << 48)
-#define CA_DEBUG_AS_VSEL_SHFT          48
-#define CA_DEBUG_PS_VSEL               (0xfull << 52)
-#define CA_DEBUG_PS_VSEL_SHFT          52
-#define CA_DEBUG_PM_VSEL               (0xfull << 56)
-#define CA_DEBUG_PM_VSEL_SHFT          56
-       /* bits 63:60 unused */
-
-/* ==== ca_debug_mux_core_sel */
-/* ==== ca_debug_mux_pci_sel */
-#define CA_DEBUG_MSEL0                 (0x7ull << 0)
-#define CA_DEBUG_MSEL0_SHFT            0
-       /* bit 3 unused */
-#define CA_DEBUG_NSEL0                 (0x7ull << 4)
-#define CA_DEBUG_NSEL0_SHFT            4
-       /* bit 7 unused */
-#define CA_DEBUG_MSEL1                 (0x7ull << 8)
-#define CA_DEBUG_MSEL1_SHFT            8
-       /* bit 11 unused */
-#define CA_DEBUG_NSEL1                 (0x7ull << 12)
-#define CA_DEBUG_NSEL1_SHFT            12
-       /* bit 15 unused */
-#define CA_DEBUG_MSEL2                 (0x7ull << 16)
-#define CA_DEBUG_MSEL2_SHFT            16
-       /* bit 19 unused */
-#define CA_DEBUG_NSEL2                 (0x7ull << 20)
-#define CA_DEBUG_NSEL2_SHFT            20
-       /* bit 23 unused */
-#define CA_DEBUG_MSEL3                 (0x7ull << 24)
-#define CA_DEBUG_MSEL3_SHFT            24
-       /* bit 27 unused */
-#define CA_DEBUG_NSEL3                 (0x7ull << 28)
-#define CA_DEBUG_NSEL3_SHFT            28
-       /* bit 31 unused */
-#define CA_DEBUG_MSEL4                 (0x7ull << 32)
-#define CA_DEBUG_MSEL4_SHFT            32
-       /* bit 35 unused */
-#define CA_DEBUG_NSEL4                 (0x7ull << 36)
-#define CA_DEBUG_NSEL4_SHFT            36
-       /* bit 39 unused */
-#define CA_DEBUG_MSEL5                 (0x7ull << 40)
-#define CA_DEBUG_MSEL5_SHFT            40
-       /* bit 43 unused */
-#define CA_DEBUG_NSEL5                 (0x7ull << 44)
-#define CA_DEBUG_NSEL5_SHFT            44
-       /* bit 47 unused */
-#define CA_DEBUG_MSEL6                 (0x7ull << 48)
-#define CA_DEBUG_MSEL6_SHFT            48
-       /* bit 51 unused */
-#define CA_DEBUG_NSEL6                 (0x7ull << 52)
-#define CA_DEBUG_NSEL6_SHFT            52
-       /* bit 55 unused */
-#define CA_DEBUG_MSEL7                 (0x7ull << 56)
-#define CA_DEBUG_MSEL7_SHFT            56
-       /* bit 59 unused */
-#define CA_DEBUG_NSEL7                 (0x7ull << 60)
-#define CA_DEBUG_NSEL7_SHFT            60
-       /* bit 63 unused */
-
-
-/* ==== ca_debug_domain_sel */
-#define CA_DEBUG_DOMAIN_L              (1ull << 0)
-#define CA_DEBUG_DOMAIN_H              (1ull << 1)
-       /* bits 63:2 unused */
-
-/* ==== ca_gart_ptr_table */
-#define CA_GART_PTR_VAL                        (1ull << 0)
-       /* bits 11:1 unused */
-#define CA_GART_PTR_ADDR               (0xfffffffffffull << 12)
-#define CA_GART_PTR_ADDR_SHFT          12
-       /* bits 63:56 unused */
-
-/* ==== ca_gart_tlb_addr[0-7] */
-#define CA_GART_TLB_ADDR               (0xffffffffffffffull << 0)
-#define CA_GART_TLB_ADDR_SHFT          0
-       /* bits 62:56 unused */
-#define CA_GART_TLB_ENTRY_VAL          (1ull << 63)
-
-/*
- * PIO address space ranges for TIO:CA
- */
-
-/* CA internal registers */
-#define CA_PIO_ADMIN                   0x00000000
-#define CA_PIO_ADMIN_LEN               0x00010000
-
-/* GFX Write Buffer - Diagnostics */
-#define CA_PIO_GFX                     0x00010000
-#define CA_PIO_GFX_LEN                 0x00010000
-
-/* AGP DMA Write Buffer - Diagnostics */
-#define CA_PIO_AGP_DMAWRITE            0x00020000
-#define CA_PIO_AGP_DMAWRITE_LEN                0x00010000
-
-/* AGP DMA READ Buffer - Diagnostics */
-#define CA_PIO_AGP_DMAREAD             0x00030000
-#define CA_PIO_AGP_DMAREAD_LEN         0x00010000
-
-/* PCI Config Type 0 */
-#define CA_PIO_PCI_TYPE0_CONFIG                0x01000000
-#define CA_PIO_PCI_TYPE0_CONFIG_LEN    0x01000000
-
-/* PCI Config Type 1 */
-#define CA_PIO_PCI_TYPE1_CONFIG                0x02000000
-#define CA_PIO_PCI_TYPE1_CONFIG_LEN    0x01000000
-
-/* PCI I/O Cycles - mapped to PCI Address 0x00000000-0x04ffffff */
-#define CA_PIO_PCI_IO                  0x03000000
-#define CA_PIO_PCI_IO_LEN              0x05000000
-
-/* PCI MEM Cycles - mapped to PCI with CA_PIO_ADDR_OFFSET of ca_control1 */
-/*     use Fast Write if enabled and coretalk packet type is a GFX request */
-#define CA_PIO_PCI_MEM_OFFSET          0x08000000
-#define CA_PIO_PCI_MEM_OFFSET_LEN      0x08000000
-
-/* PCI MEM Cycles - mapped to PCI Address 0x00000000-0xbfffffff */
-/*     use Fast Write if enabled and coretalk packet type is a GFX request */
-#define CA_PIO_PCI_MEM                 0x40000000
-#define CA_PIO_PCI_MEM_LEN             0xc0000000
-
-/*
- * DMA space
- *
- * The CA aperature (ie. bus address range) mapped by the GART is segmented into
- * two parts.  The lower portion of the aperature is used for mapping 32 bit
- * PCI addresses which are managed by the dma interfaces in this file.  The
- * upper poprtion of the aperature is used for mapping 48 bit AGP addresses.
- * The AGP portion of the aperature is managed by the agpgart_be.c driver
- * in drivers/linux/agp.  There are ca-specific hooks in that driver to
- * manipulate the gart, but management of the AGP portion of the aperature
- * is the responsibility of that driver.
- *
- * CA allows three main types of DMA mapping:
- *
- * PCI 64-bit  Managed by this driver
- * PCI 32-bit  Managed by this driver
- * AGP 48-bit  Managed by hooks in the /dev/agpgart driver
- *
- * All of the above can optionally be remapped through the GART.  The following
- * table lists the combinations of addressing types and GART remapping that
- * is currently supported by the driver (h/w supports all, s/w limits this):
- *
- *             PCI64           PCI32           AGP48
- * GART                no              yes             yes
- * Direct      yes             yes             no
- *
- * GART remapping of PCI64 is not done because there is no need to.  The
- * 64 bit PCI address holds all of the information necessary to target any
- * memory in the system.
- *
- * AGP48 is always mapped through the GART.  Management of the AGP48 portion
- * of the aperature is the responsibility of code in the agpgart_be driver.
- *
- * The non-64 bit bus address space will currently be partitioned like this:
- *
- *     0xffff_ffff_ffff        +--------
- *                             | AGP48 direct
- *                             | Space managed by this driver
- *     CA_AGP_DIRECT_BASE      +--------
- *                             | AGP GART mapped (gfx aperature)
- *                             | Space managed by /dev/agpgart driver
- *                             | This range is exposed to the agpgart
- *                             | driver as the "graphics aperature"
- *     CA_AGP_MAPPED_BASE      +-----
- *                             | PCI GART mapped
- *                             | Space managed by this driver          
- *     CA_PCI32_MAPPED_BASE    +----
- *                             | PCI32 direct
- *                             | Space managed by this driver
- *     0xC000_0000             +--------
- *     (CA_PCI32_DIRECT_BASE)
- *
- * The bus address range CA_PCI32_MAPPED_BASE through CA_AGP_DIRECT_BASE
- * is what we call the CA aperature.  Addresses falling in this range will
- * be remapped using the GART.
- *
- * The bus address range CA_AGP_MAPPED_BASE through CA_AGP_DIRECT_BASE
- * is what we call the graphics aperature.  This is a subset of the CA
- * aperature and is under the control of the agpgart_be driver.
- *
- * CA_PCI32_MAPPED_BASE, CA_AGP_MAPPED_BASE, and CA_AGP_DIRECT_BASE are
- * somewhat arbitrary values.  The known constraints on choosing these is:
- *
- * 1)  CA_AGP_DIRECT_BASE-CA_PCI32_MAPPED_BASE+1 (the CA aperature size)
- *     must be one of the values supported by the ca_gart_aperature register.
- *     Currently valid values are: 4MB through 4096MB in powers of 2 increments
- *
- * 2)  CA_AGP_DIRECT_BASE-CA_AGP_MAPPED_BASE+1 (the gfx aperature size)
- *     must be in MB units since that's what the agpgart driver assumes.
- */
-
-/*
- * Define Bus DMA ranges.  These are configurable (see constraints above)
- * and will probably need tuning based on experience.
- */
-
-
-/*
- * 11/24/03
- * CA has an addressing glitch w.r.t. PCI direct 32 bit DMA that makes it
- * generally unusable.  The problem is that for PCI direct 32 
- * DMA's, all 32 bits of the bus address are used to form the lower 32 bits
- * of the coretalk address, and coretalk bits 38:32 come from a register.
- * Since only PCI bus addresses 0xC0000000-0xFFFFFFFF (1GB) are available
- * for DMA (the rest is allocated to PIO), host node addresses need to be
- * such that their lower 32 bits fall in the 0xC0000000-0xffffffff range
- * as well.  So there can be no PCI32 direct DMA below 3GB!!  For this
- * reason we set the CA_PCI32_DIRECT_SIZE to 0 which essentially makes
- * tioca_dma_direct32() a noop but preserves the code flow should this issue
- * be fixed in a respin.
- *
- * For now, all PCI32 DMA's must be mapped through the GART.
- */
-
-#define CA_PCI32_DIRECT_BASE   0xC0000000UL    /* BASE not configurable */
-#define CA_PCI32_DIRECT_SIZE   0x00000000UL    /* 0 MB */
-
-#define CA_PCI32_MAPPED_BASE   0xC0000000UL
-#define CA_PCI32_MAPPED_SIZE   0x40000000UL    /* 2GB */
-
-#define CA_AGP_MAPPED_BASE     0x80000000UL
-#define CA_AGP_MAPPED_SIZE     0x40000000UL    /* 2GB */
-
-#define CA_AGP_DIRECT_BASE     0x40000000UL    /* 2GB */
-#define CA_AGP_DIRECT_SIZE     0x40000000UL
-
-#define CA_APERATURE_BASE      (CA_AGP_MAPPED_BASE)
-#define CA_APERATURE_SIZE      (CA_AGP_MAPPED_SIZE+CA_PCI32_MAPPED_SIZE)
-
-#endif  /* _ASM_IA64_SN_TIO_TIOCA_H */
diff --git a/arch/ia64/include/asm/sn/tioca_provider.h b/arch/ia64/include/asm/sn/tioca_provider.h
deleted file mode 100644 (file)
index 9a820ac..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2003-2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H
-#define _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H
-
-#include <asm/sn/tioca.h>
-
-/*
- * WAR enables
- * Defines for individual WARs. Each is a bitmask of applicable
- * part revision numbers. (1 << 1) == rev A, (1 << 2) == rev B,
- * (3 << 1) == (rev A or rev B), etc
- */
-
-#define TIOCA_WAR_ENABLED(pv, tioca_common) \
-       ((1 << tioca_common->ca_rev) & pv)
-
-  /* TIO:ICE:FRZ:Freezer loses a PIO data ucred on PIO RD RSP with CW error */
-#define PV907908 (1 << 1)
-  /* ATI config space problems after BIOS execution starts */
-#define PV908234 (1 << 1)
-  /* CA:AGPDMA write request data mismatch with ABC1CL merge */
-#define PV895469 (1 << 1)
-  /* TIO:CA TLB invalidate of written GART entries possibly not occurring in CA*/
-#define PV910244 (1 << 1)
-
-struct tioca_dmamap{
-       struct list_head        cad_list;       /* headed by ca_list */
-
-       dma_addr_t              cad_dma_addr;   /* Linux dma handle */
-       uint                    cad_gart_entry; /* start entry in ca_gart_pagemap */
-       uint                    cad_gart_size;  /* #entries for this map */
-};
-
-/*
- * Kernel only fields.  Prom may look at this stuff for debugging only.
- * Access this structure through the ca_kernel_private ptr.
- */
-
-struct tioca_common ;
-
-struct tioca_kernel {
-       struct tioca_common     *ca_common;     /* tioca this belongs to */
-       struct list_head        ca_list;        /* list of all ca's */
-       struct list_head        ca_dmamaps;
-       spinlock_t              ca_lock;        /* Kernel lock */
-       cnodeid_t               ca_closest_node;
-       struct list_head        *ca_devices;    /* bus->devices */
-
-       /*
-        * General GART stuff
-        */
-       u64     ca_ap_size;             /* size of aperature in bytes */
-       u32     ca_gart_entries;        /* # u64 entries in gart */
-       u32     ca_ap_pagesize;         /* aperature page size in bytes */
-       u64     ca_ap_bus_base;         /* bus address of CA aperature */
-       u64     ca_gart_size;           /* gart size in bytes */
-       u64     *ca_gart;               /* gart table vaddr */
-       u64     ca_gart_coretalk_addr;  /* gart coretalk addr */
-       u8              ca_gart_iscoherent;     /* used in tioca_tlbflush */
-
-       /* PCI GART convenience values */
-       u64     ca_pciap_base;          /* pci aperature bus base address */
-       u64     ca_pciap_size;          /* pci aperature size (bytes) */
-       u64     ca_pcigart_base;        /* gfx GART bus base address */
-       u64     *ca_pcigart;            /* gfx GART vm address */
-       u32     ca_pcigart_entries;
-       u32     ca_pcigart_start;       /* PCI start index in ca_gart */
-       void            *ca_pcigart_pagemap;
-
-       /* AGP GART convenience values */
-       u64     ca_gfxap_base;          /* gfx aperature bus base address */
-       u64     ca_gfxap_size;          /* gfx aperature size (bytes) */
-       u64     ca_gfxgart_base;        /* gfx GART bus base address */
-       u64     *ca_gfxgart;            /* gfx GART vm address */
-       u32     ca_gfxgart_entries;
-       u32     ca_gfxgart_start;       /* agpgart start index in ca_gart */
-};
-
-/*
- * Common tioca info shared between kernel and prom
- *
- * DO NOT CHANGE THIS STRUCT WITHOUT MAKING CORRESPONDING CHANGES
- * TO THE PROM VERSION.
- */
-
-struct tioca_common {
-       struct pcibus_bussoft   ca_common;      /* common pciio header */
-
-       u32             ca_rev;
-       u32             ca_closest_nasid;
-
-       u64             ca_prom_private;
-       u64             ca_kernel_private;
-};
-
-/**
- * tioca_paddr_to_gart - Convert an SGI coretalk address to a CA GART entry
- * @paddr: page address to convert
- *
- * Convert a system [coretalk] address to a GART entry.  GART entries are
- * formed using the following:
- *
- *     data = ( (1<<63) |  ( (REMAP_NODE_ID << 40) | (MD_CHIPLET_ID << 38) | 
- * (REMAP_SYS_ADDR) ) >> 12 )
- *
- * DATA written to 1 GART TABLE Entry in system memory is remapped system
- * addr for 1 page 
- *
- * The data is for coretalk address format right shifted 12 bits with a
- * valid bit.
- *
- *     GART_TABLE_ENTRY [ 25:0 ]  -- REMAP_SYS_ADDRESS[37:12].
- *     GART_TABLE_ENTRY [ 27:26 ] -- SHUB MD chiplet id.
- *     GART_TABLE_ENTRY [ 41:28 ] -- REMAP_NODE_ID.
- *     GART_TABLE_ENTRY [ 63 ]    -- Valid Bit 
- */
-static inline u64
-tioca_paddr_to_gart(unsigned long paddr)
-{
-       /*
-        * We are assuming right now that paddr already has the correct
-        * format since the address from xtalk_dmaXXX should already have
-        * NODE_ID, CHIPLET_ID, and SYS_ADDR in the correct locations.
-        */
-
-       return ((paddr) >> 12) | (1UL << 63);
-}
-
-/**
- * tioca_physpage_to_gart - Map a host physical page for SGI CA based DMA
- * @page_addr: system page address to map
- */
-
-static inline unsigned long
-tioca_physpage_to_gart(u64 page_addr)
-{
-       u64 coretalk_addr;
-
-       coretalk_addr = PHYS_TO_TIODMA(page_addr);
-       if (!coretalk_addr) {
-               return 0;
-       }
-
-       return tioca_paddr_to_gart(coretalk_addr);
-}
-
-/**
- * tioca_tlbflush - invalidate cached SGI CA GART TLB entries
- * @tioca_kernel: CA context 
- *
- * Invalidate tlb entries for a given CA GART.  Main complexity is to account
- * for revA bug.
- */
-static inline void
-tioca_tlbflush(struct tioca_kernel *tioca_kernel)
-{
-       volatile u64 tmp;
-       volatile struct tioca __iomem *ca_base;
-       struct tioca_common *tioca_common;
-
-       tioca_common = tioca_kernel->ca_common;
-       ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
-
-       /*
-        * Explicit flushes not needed if GART is in cached mode
-        */
-       if (tioca_kernel->ca_gart_iscoherent) {
-               if (TIOCA_WAR_ENABLED(PV910244, tioca_common)) {
-                       /*
-                        * PV910244:  RevA CA needs explicit flushes.
-                        * Need to put GART into uncached mode before
-                        * flushing otherwise the explicit flush is ignored.
-                        *
-                        * Alternate WAR would be to leave GART cached and
-                        * touch every CL aligned GART entry.
-                        */
-
-                       __sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM);
-                       __sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB);
-                       __sn_setq_relaxed(&ca_base->ca_control2,
-                           (0x2ull << CA_GART_MEM_PARAM_SHFT));
-                       tmp = __sn_readq_relaxed(&ca_base->ca_control2);
-               }
-
-               return;
-       }
-
-       /*
-        * Gart in uncached mode ... need an explicit flush.
-        */
-
-       __sn_setq_relaxed(&ca_base->ca_control2, CA_GART_FLUSH_TLB);
-       tmp = __sn_readq_relaxed(&ca_base->ca_control2);
-}
-
-extern u32     tioca_gart_found;
-extern struct list_head tioca_list;
-extern int tioca_init_provider(void);
-extern void tioca_fastwrite_enable(struct tioca_kernel *tioca_kern);
-#endif /* _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H */
diff --git a/arch/ia64/include/asm/sn/tioce.h b/arch/ia64/include/asm/sn/tioce.h
deleted file mode 100644 (file)
index 6eae8ad..0000000
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2003-2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef __ASM_IA64_SN_TIOCE_H__
-#define __ASM_IA64_SN_TIOCE_H__
-
-/* CE ASIC part & mfgr information  */
-#define TIOCE_PART_NUM                 0xCE00
-#define TIOCE_SRC_ID                   0x01
-#define TIOCE_REV_A                    0x1
-
-/* CE Virtual PPB Vendor/Device IDs */
-#define CE_VIRT_PPB_VENDOR_ID          0x10a9
-#define CE_VIRT_PPB_DEVICE_ID          0x4002
-
-/* CE Host Bridge Vendor/Device IDs */
-#define CE_HOST_BRIDGE_VENDOR_ID       0x10a9
-#define CE_HOST_BRIDGE_DEVICE_ID       0x4001
-
-
-#define TIOCE_NUM_M40_ATES             4096
-#define TIOCE_NUM_M3240_ATES           2048
-#define TIOCE_NUM_PORTS                        2
-
-/*
- * Register layout for TIOCE.  MMR offsets are shown at the far right of the
- * structure definition.
- */
-typedef volatile struct tioce {
-       /*
-        * ADMIN : Administration Registers
-        */
-       u64     ce_adm_id;                              /* 0x000000 */
-       u64     ce_pad_000008;                          /* 0x000008 */
-       u64     ce_adm_dyn_credit_status;               /* 0x000010 */
-       u64     ce_adm_last_credit_status;              /* 0x000018 */
-       u64     ce_adm_credit_limit;                    /* 0x000020 */
-       u64     ce_adm_force_credit;                    /* 0x000028 */
-       u64     ce_adm_control;                         /* 0x000030 */
-       u64     ce_adm_mmr_chn_timeout;                 /* 0x000038 */
-       u64     ce_adm_ssp_ure_timeout;                 /* 0x000040 */
-       u64     ce_adm_ssp_dre_timeout;                 /* 0x000048 */
-       u64     ce_adm_ssp_debug_sel;                   /* 0x000050 */
-       u64     ce_adm_int_status;                      /* 0x000058 */
-       u64     ce_adm_int_status_alias;                /* 0x000060 */
-       u64     ce_adm_int_mask;                        /* 0x000068 */
-       u64     ce_adm_int_pending;                     /* 0x000070 */
-       u64     ce_adm_force_int;                       /* 0x000078 */
-       u64     ce_adm_ure_ups_buf_barrier_flush;       /* 0x000080 */
-       u64     ce_adm_int_dest[15];        /* 0x000088 -- 0x0000F8 */
-       u64     ce_adm_error_summary;                   /* 0x000100 */
-       u64     ce_adm_error_summary_alias;             /* 0x000108 */
-       u64     ce_adm_error_mask;                      /* 0x000110 */
-       u64     ce_adm_first_error;                     /* 0x000118 */
-       u64     ce_adm_error_overflow;                  /* 0x000120 */
-       u64     ce_adm_error_overflow_alias;            /* 0x000128 */
-       u64     ce_pad_000130[2];           /* 0x000130 -- 0x000138 */
-       u64     ce_adm_tnum_error;                      /* 0x000140 */
-       u64     ce_adm_mmr_err_detail;                  /* 0x000148 */
-       u64     ce_adm_msg_sram_perr_detail;            /* 0x000150 */
-       u64     ce_adm_bap_sram_perr_detail;            /* 0x000158 */
-       u64     ce_adm_ce_sram_perr_detail;             /* 0x000160 */
-       u64     ce_adm_ce_credit_oflow_detail;          /* 0x000168 */
-       u64     ce_adm_tx_link_idle_max_timer;          /* 0x000170 */
-       u64     ce_adm_pcie_debug_sel;                  /* 0x000178 */
-       u64     ce_pad_000180[16];          /* 0x000180 -- 0x0001F8 */
-
-       u64     ce_adm_pcie_debug_sel_top;              /* 0x000200 */
-       u64     ce_adm_pcie_debug_lat_sel_lo_top;       /* 0x000208 */
-       u64     ce_adm_pcie_debug_lat_sel_hi_top;       /* 0x000210 */
-       u64     ce_adm_pcie_debug_trig_sel_top;         /* 0x000218 */
-       u64     ce_adm_pcie_debug_trig_lat_sel_lo_top;  /* 0x000220 */
-       u64     ce_adm_pcie_debug_trig_lat_sel_hi_top;  /* 0x000228 */
-       u64     ce_adm_pcie_trig_compare_top;           /* 0x000230 */
-       u64     ce_adm_pcie_trig_compare_en_top;        /* 0x000238 */
-       u64     ce_adm_ssp_debug_sel_top;               /* 0x000240 */
-       u64     ce_adm_ssp_debug_lat_sel_lo_top;        /* 0x000248 */
-       u64     ce_adm_ssp_debug_lat_sel_hi_top;        /* 0x000250 */
-       u64     ce_adm_ssp_debug_trig_sel_top;          /* 0x000258 */
-       u64     ce_adm_ssp_debug_trig_lat_sel_lo_top;   /* 0x000260 */
-       u64     ce_adm_ssp_debug_trig_lat_sel_hi_top;   /* 0x000268 */
-       u64     ce_adm_ssp_trig_compare_top;            /* 0x000270 */
-       u64     ce_adm_ssp_trig_compare_en_top;         /* 0x000278 */
-       u64     ce_pad_000280[48];          /* 0x000280 -- 0x0003F8 */
-
-       u64     ce_adm_bap_ctrl;                        /* 0x000400 */
-       u64     ce_pad_000408[127];         /* 0x000408 -- 0x0007F8 */
-
-       u64     ce_msg_buf_data63_0[35];    /* 0x000800 -- 0x000918 */
-       u64     ce_pad_000920[29];          /* 0x000920 -- 0x0009F8 */
-
-       u64     ce_msg_buf_data127_64[35];  /* 0x000A00 -- 0x000B18 */
-       u64     ce_pad_000B20[29];          /* 0x000B20 -- 0x000BF8 */
-
-       u64     ce_msg_buf_parity[35];      /* 0x000C00 -- 0x000D18 */
-       u64     ce_pad_000D20[29];          /* 0x000D20 -- 0x000DF8 */
-
-       u64     ce_pad_000E00[576];         /* 0x000E00 -- 0x001FF8 */
-
-       /*
-        * LSI : LSI's PCI Express Link Registers (Link#1 and Link#2)
-        * Link#1 MMRs at start at 0x002000, Link#2 MMRs at 0x003000
-        * NOTE: the comment offsets at far right: let 'z' = {2 or 3}
-        */
-       #define ce_lsi(link_num)        ce_lsi[link_num-1]
-       struct ce_lsi_reg {
-               u64     ce_lsi_lpu_id;                  /* 0x00z000 */
-               u64     ce_lsi_rst;                     /* 0x00z008 */
-               u64     ce_lsi_dbg_stat;                /* 0x00z010 */
-               u64     ce_lsi_dbg_cfg;                 /* 0x00z018 */
-               u64     ce_lsi_ltssm_ctrl;              /* 0x00z020 */
-               u64     ce_lsi_lk_stat;                 /* 0x00z028 */
-               u64     ce_pad_00z030[2];   /* 0x00z030 -- 0x00z038 */
-               u64     ce_lsi_int_and_stat;            /* 0x00z040 */
-               u64     ce_lsi_int_mask;                /* 0x00z048 */
-               u64     ce_pad_00z050[22];  /* 0x00z050 -- 0x00z0F8 */
-               u64     ce_lsi_lk_perf_cnt_sel;         /* 0x00z100 */
-               u64     ce_pad_00z108;                  /* 0x00z108 */
-               u64     ce_lsi_lk_perf_cnt_ctrl;        /* 0x00z110 */
-               u64     ce_pad_00z118;                  /* 0x00z118 */
-               u64     ce_lsi_lk_perf_cnt1;            /* 0x00z120 */
-               u64     ce_lsi_lk_perf_cnt1_test;       /* 0x00z128 */
-               u64     ce_lsi_lk_perf_cnt2;            /* 0x00z130 */
-               u64     ce_lsi_lk_perf_cnt2_test;       /* 0x00z138 */
-               u64     ce_pad_00z140[24];  /* 0x00z140 -- 0x00z1F8 */
-               u64     ce_lsi_lk_lyr_cfg;              /* 0x00z200 */
-               u64     ce_lsi_lk_lyr_status;           /* 0x00z208 */
-               u64     ce_lsi_lk_lyr_int_stat;         /* 0x00z210 */
-               u64     ce_lsi_lk_ly_int_stat_test;     /* 0x00z218 */
-               u64     ce_lsi_lk_ly_int_stat_mask;     /* 0x00z220 */
-               u64     ce_pad_00z228[3];   /* 0x00z228 -- 0x00z238 */
-               u64     ce_lsi_fc_upd_ctl;              /* 0x00z240 */
-               u64     ce_pad_00z248[3];   /* 0x00z248 -- 0x00z258 */
-               u64     ce_lsi_flw_ctl_upd_to_timer;    /* 0x00z260 */
-               u64     ce_lsi_flw_ctl_upd_timer0;      /* 0x00z268 */
-               u64     ce_lsi_flw_ctl_upd_timer1;      /* 0x00z270 */
-               u64     ce_pad_00z278[49];  /* 0x00z278 -- 0x00z3F8 */
-               u64     ce_lsi_freq_nak_lat_thrsh;      /* 0x00z400 */
-               u64     ce_lsi_ack_nak_lat_tmr;         /* 0x00z408 */
-               u64     ce_lsi_rply_tmr_thr;            /* 0x00z410 */
-               u64     ce_lsi_rply_tmr;                /* 0x00z418 */
-               u64     ce_lsi_rply_num_stat;           /* 0x00z420 */
-               u64     ce_lsi_rty_buf_max_addr;        /* 0x00z428 */
-               u64     ce_lsi_rty_fifo_ptr;            /* 0x00z430 */
-               u64     ce_lsi_rty_fifo_rd_wr_ptr;      /* 0x00z438 */
-               u64     ce_lsi_rty_fifo_cred;           /* 0x00z440 */
-               u64     ce_lsi_seq_cnt;                 /* 0x00z448 */
-               u64     ce_lsi_ack_sent_seq_num;        /* 0x00z450 */
-               u64     ce_lsi_seq_cnt_fifo_max_addr;   /* 0x00z458 */
-               u64     ce_lsi_seq_cnt_fifo_ptr;        /* 0x00z460 */
-               u64     ce_lsi_seq_cnt_rd_wr_ptr;       /* 0x00z468 */
-               u64     ce_lsi_tx_lk_ts_ctl;            /* 0x00z470 */
-               u64     ce_pad_00z478;                  /* 0x00z478 */
-               u64     ce_lsi_mem_addr_ctl;            /* 0x00z480 */
-               u64     ce_lsi_mem_d_ld0;               /* 0x00z488 */
-               u64     ce_lsi_mem_d_ld1;               /* 0x00z490 */
-               u64     ce_lsi_mem_d_ld2;               /* 0x00z498 */
-               u64     ce_lsi_mem_d_ld3;               /* 0x00z4A0 */
-               u64     ce_lsi_mem_d_ld4;               /* 0x00z4A8 */
-               u64     ce_pad_00z4B0[2];   /* 0x00z4B0 -- 0x00z4B8 */
-               u64     ce_lsi_rty_d_cnt;               /* 0x00z4C0 */
-               u64     ce_lsi_seq_buf_cnt;             /* 0x00z4C8 */
-               u64     ce_lsi_seq_buf_bt_d;            /* 0x00z4D0 */
-               u64     ce_pad_00z4D8;                  /* 0x00z4D8 */
-               u64     ce_lsi_ack_lat_thr;             /* 0x00z4E0 */
-               u64     ce_pad_00z4E8[3];   /* 0x00z4E8 -- 0x00z4F8 */
-               u64     ce_lsi_nxt_rcv_seq_1_cntr;      /* 0x00z500 */
-               u64     ce_lsi_unsp_dllp_rcvd;          /* 0x00z508 */
-               u64     ce_lsi_rcv_lk_ts_ctl;           /* 0x00z510 */
-               u64     ce_pad_00z518[29];  /* 0x00z518 -- 0x00z5F8 */
-               u64     ce_lsi_phy_lyr_cfg;             /* 0x00z600 */
-               u64     ce_pad_00z608;                  /* 0x00z608 */
-               u64     ce_lsi_phy_lyr_int_stat;        /* 0x00z610 */
-               u64     ce_lsi_phy_lyr_int_stat_test;   /* 0x00z618 */
-               u64     ce_lsi_phy_lyr_int_mask;        /* 0x00z620 */
-               u64     ce_pad_00z628[11];  /* 0x00z628 -- 0x00z678 */
-               u64     ce_lsi_rcv_phy_cfg;             /* 0x00z680 */
-               u64     ce_lsi_rcv_phy_stat1;           /* 0x00z688 */
-               u64     ce_lsi_rcv_phy_stat2;           /* 0x00z690 */
-               u64     ce_lsi_rcv_phy_stat3;           /* 0x00z698 */
-               u64     ce_lsi_rcv_phy_int_stat;        /* 0x00z6A0 */
-               u64     ce_lsi_rcv_phy_int_stat_test;   /* 0x00z6A8 */
-               u64     ce_lsi_rcv_phy_int_mask;        /* 0x00z6B0 */
-               u64     ce_pad_00z6B8[9];   /* 0x00z6B8 -- 0x00z6F8 */
-               u64     ce_lsi_tx_phy_cfg;              /* 0x00z700 */
-               u64     ce_lsi_tx_phy_stat;             /* 0x00z708 */
-               u64     ce_lsi_tx_phy_int_stat;         /* 0x00z710 */
-               u64     ce_lsi_tx_phy_int_stat_test;    /* 0x00z718 */
-               u64     ce_lsi_tx_phy_int_mask;         /* 0x00z720 */
-               u64     ce_lsi_tx_phy_stat2;            /* 0x00z728 */
-               u64     ce_pad_00z730[10];  /* 0x00z730 -- 0x00z77F */
-               u64     ce_lsi_ltssm_cfg1;              /* 0x00z780 */
-               u64     ce_lsi_ltssm_cfg2;              /* 0x00z788 */
-               u64     ce_lsi_ltssm_cfg3;              /* 0x00z790 */
-               u64     ce_lsi_ltssm_cfg4;              /* 0x00z798 */
-               u64     ce_lsi_ltssm_cfg5;              /* 0x00z7A0 */
-               u64     ce_lsi_ltssm_stat1;             /* 0x00z7A8 */
-               u64     ce_lsi_ltssm_stat2;             /* 0x00z7B0 */
-               u64     ce_lsi_ltssm_int_stat;          /* 0x00z7B8 */
-               u64     ce_lsi_ltssm_int_stat_test;     /* 0x00z7C0 */
-               u64     ce_lsi_ltssm_int_mask;          /* 0x00z7C8 */
-               u64     ce_lsi_ltssm_stat_wr_en;        /* 0x00z7D0 */
-               u64     ce_pad_00z7D8[5];   /* 0x00z7D8 -- 0x00z7F8 */
-               u64     ce_lsi_gb_cfg1;                 /* 0x00z800 */
-               u64     ce_lsi_gb_cfg2;                 /* 0x00z808 */
-               u64     ce_lsi_gb_cfg3;                 /* 0x00z810 */
-               u64     ce_lsi_gb_cfg4;                 /* 0x00z818 */
-               u64     ce_lsi_gb_stat;                 /* 0x00z820 */
-               u64     ce_lsi_gb_int_stat;             /* 0x00z828 */
-               u64     ce_lsi_gb_int_stat_test;        /* 0x00z830 */
-               u64     ce_lsi_gb_int_mask;             /* 0x00z838 */
-               u64     ce_lsi_gb_pwr_dn1;              /* 0x00z840 */
-               u64     ce_lsi_gb_pwr_dn2;              /* 0x00z848 */
-               u64     ce_pad_00z850[246]; /* 0x00z850 -- 0x00zFF8 */
-       } ce_lsi[2];
-
-       u64     ce_pad_004000[10];          /* 0x004000 -- 0x004048 */
-
-       /*
-        * CRM: Coretalk Receive Module Registers
-        */
-       u64     ce_crm_debug_mux;                       /* 0x004050 */
-       u64     ce_pad_004058;                          /* 0x004058 */
-       u64     ce_crm_ssp_err_cmd_wrd;                 /* 0x004060 */
-       u64     ce_crm_ssp_err_addr;                    /* 0x004068 */
-       u64     ce_crm_ssp_err_syn;                     /* 0x004070 */
-
-       u64     ce_pad_004078[499];         /* 0x004078 -- 0x005008 */
-
-       /*
-         * CXM: Coretalk Xmit Module Registers
-         */
-       u64     ce_cxm_dyn_credit_status;               /* 0x005010 */
-       u64     ce_cxm_last_credit_status;              /* 0x005018 */
-       u64     ce_cxm_credit_limit;                    /* 0x005020 */
-       u64     ce_cxm_force_credit;                    /* 0x005028 */
-       u64     ce_cxm_disable_bypass;                  /* 0x005030 */
-       u64     ce_pad_005038[3];           /* 0x005038 -- 0x005048 */
-       u64     ce_cxm_debug_mux;                       /* 0x005050 */
-
-        u64        ce_pad_005058[501];         /* 0x005058 -- 0x005FF8 */
-
-       /*
-        * DTL: Downstream Transaction Layer Regs (Link#1 and Link#2)
-        * DTL: Link#1 MMRs at start at 0x006000, Link#2 MMRs at 0x008000
-        * DTL: the comment offsets at far right: let 'y' = {6 or 8}
-        *
-        * UTL: Downstream Transaction Layer Regs (Link#1 and Link#2)
-        * UTL: Link#1 MMRs at start at 0x007000, Link#2 MMRs at 0x009000
-        * UTL: the comment offsets at far right: let 'z' = {7 or 9}
-        */
-       #define ce_dtl(link_num)        ce_dtl_utl[link_num-1]
-       #define ce_utl(link_num)        ce_dtl_utl[link_num-1]
-       struct ce_dtl_utl_reg {
-               /* DTL */
-               u64     ce_dtl_dtdr_credit_limit;       /* 0x00y000 */
-               u64     ce_dtl_dtdr_credit_force;       /* 0x00y008 */
-               u64     ce_dtl_dyn_credit_status;       /* 0x00y010 */
-               u64     ce_dtl_dtl_last_credit_stat;    /* 0x00y018 */
-               u64     ce_dtl_dtl_ctrl;                /* 0x00y020 */
-               u64     ce_pad_00y028[5];   /* 0x00y028 -- 0x00y048 */
-               u64     ce_dtl_debug_sel;               /* 0x00y050 */
-               u64     ce_pad_00y058[501]; /* 0x00y058 -- 0x00yFF8 */
-
-               /* UTL */
-               u64     ce_utl_utl_ctrl;                /* 0x00z000 */
-               u64     ce_utl_debug_sel;               /* 0x00z008 */
-               u64     ce_pad_00z010[510]; /* 0x00z010 -- 0x00zFF8 */
-       } ce_dtl_utl[2];
-
-       u64     ce_pad_00A000[514];         /* 0x00A000 -- 0x00B008 */
-
-       /*
-        * URE: Upstream Request Engine
-         */
-       u64     ce_ure_dyn_credit_status;               /* 0x00B010 */
-       u64     ce_ure_last_credit_status;              /* 0x00B018 */
-       u64     ce_ure_credit_limit;                    /* 0x00B020 */
-       u64     ce_pad_00B028;                          /* 0x00B028 */
-       u64     ce_ure_control;                         /* 0x00B030 */
-       u64     ce_ure_status;                          /* 0x00B038 */
-       u64     ce_pad_00B040[2];           /* 0x00B040 -- 0x00B048 */
-       u64     ce_ure_debug_sel;                       /* 0x00B050 */
-       u64     ce_ure_pcie_debug_sel;                  /* 0x00B058 */
-       u64     ce_ure_ssp_err_cmd_wrd;                 /* 0x00B060 */
-       u64     ce_ure_ssp_err_addr;                    /* 0x00B068 */
-       u64     ce_ure_page_map;                        /* 0x00B070 */
-       u64     ce_ure_dir_map[TIOCE_NUM_PORTS];        /* 0x00B078 */
-       u64     ce_ure_pipe_sel1;                       /* 0x00B088 */
-       u64     ce_ure_pipe_mask1;                      /* 0x00B090 */
-       u64     ce_ure_pipe_sel2;                       /* 0x00B098 */
-       u64     ce_ure_pipe_mask2;                      /* 0x00B0A0 */
-       u64     ce_ure_pcie1_credits_sent;              /* 0x00B0A8 */
-       u64     ce_ure_pcie1_credits_used;              /* 0x00B0B0 */
-       u64     ce_ure_pcie1_credit_limit;              /* 0x00B0B8 */
-       u64     ce_ure_pcie2_credits_sent;              /* 0x00B0C0 */
-       u64     ce_ure_pcie2_credits_used;              /* 0x00B0C8 */
-       u64     ce_ure_pcie2_credit_limit;              /* 0x00B0D0 */
-       u64     ce_ure_pcie_force_credit;               /* 0x00B0D8 */
-       u64     ce_ure_rd_tnum_val;                     /* 0x00B0E0 */
-       u64     ce_ure_rd_tnum_rsp_rcvd;                /* 0x00B0E8 */
-       u64     ce_ure_rd_tnum_esent_timer;             /* 0x00B0F0 */
-       u64     ce_ure_rd_tnum_error;                   /* 0x00B0F8 */
-       u64     ce_ure_rd_tnum_first_cl;                /* 0x00B100 */
-       u64     ce_ure_rd_tnum_link_buf;                /* 0x00B108 */
-       u64     ce_ure_wr_tnum_val;                     /* 0x00B110 */
-       u64     ce_ure_sram_err_addr0;                  /* 0x00B118 */
-       u64     ce_ure_sram_err_addr1;                  /* 0x00B120 */
-       u64     ce_ure_sram_err_addr2;                  /* 0x00B128 */
-       u64     ce_ure_sram_rd_addr0;                   /* 0x00B130 */
-       u64     ce_ure_sram_rd_addr1;                   /* 0x00B138 */
-       u64     ce_ure_sram_rd_addr2;                   /* 0x00B140 */
-       u64     ce_ure_sram_wr_addr0;                   /* 0x00B148 */
-       u64     ce_ure_sram_wr_addr1;                   /* 0x00B150 */
-       u64     ce_ure_sram_wr_addr2;                   /* 0x00B158 */
-       u64     ce_ure_buf_flush10;                     /* 0x00B160 */
-       u64     ce_ure_buf_flush11;                     /* 0x00B168 */
-       u64     ce_ure_buf_flush12;                     /* 0x00B170 */
-       u64     ce_ure_buf_flush13;                     /* 0x00B178 */
-       u64     ce_ure_buf_flush20;                     /* 0x00B180 */
-       u64     ce_ure_buf_flush21;                     /* 0x00B188 */
-       u64     ce_ure_buf_flush22;                     /* 0x00B190 */
-       u64     ce_ure_buf_flush23;                     /* 0x00B198 */
-       u64     ce_ure_pcie_control1;                   /* 0x00B1A0 */
-       u64     ce_ure_pcie_control2;                   /* 0x00B1A8 */
-
-       u64     ce_pad_00B1B0[458];         /* 0x00B1B0 -- 0x00BFF8 */
-
-       /* Upstream Data Buffer, Port1 */
-       struct ce_ure_maint_ups_dat1_data {
-               u64     data63_0[512];      /* 0x00C000 -- 0x00CFF8 */
-               u64     data127_64[512];    /* 0x00D000 -- 0x00DFF8 */
-               u64     parity[512];        /* 0x00E000 -- 0x00EFF8 */
-       } ce_ure_maint_ups_dat1;
-
-       /* Upstream Header Buffer, Port1 */
-       struct ce_ure_maint_ups_hdr1_data {
-               u64     data63_0[512];      /* 0x00F000 -- 0x00FFF8 */
-               u64     data127_64[512];    /* 0x010000 -- 0x010FF8 */
-               u64     parity[512];        /* 0x011000 -- 0x011FF8 */
-       } ce_ure_maint_ups_hdr1;
-
-       /* Upstream Data Buffer, Port2 */
-       struct ce_ure_maint_ups_dat2_data {
-               u64     data63_0[512];      /* 0x012000 -- 0x012FF8 */
-               u64     data127_64[512];    /* 0x013000 -- 0x013FF8 */
-               u64     parity[512];        /* 0x014000 -- 0x014FF8 */
-       } ce_ure_maint_ups_dat2;
-
-       /* Upstream Header Buffer, Port2 */
-       struct ce_ure_maint_ups_hdr2_data {
-               u64     data63_0[512];      /* 0x015000 -- 0x015FF8 */
-               u64     data127_64[512];    /* 0x016000 -- 0x016FF8 */
-               u64     parity[512];        /* 0x017000 -- 0x017FF8 */
-       } ce_ure_maint_ups_hdr2;
-
-       /* Downstream Data Buffer */
-       struct ce_ure_maint_dns_dat_data {
-               u64     data63_0[512];      /* 0x018000 -- 0x018FF8 */
-               u64     data127_64[512];    /* 0x019000 -- 0x019FF8 */
-               u64     parity[512];        /* 0x01A000 -- 0x01AFF8 */
-       } ce_ure_maint_dns_dat;
-
-       /* Downstream Header Buffer */
-       struct  ce_ure_maint_dns_hdr_data {
-               u64     data31_0[64];       /* 0x01B000 -- 0x01B1F8 */
-               u64     data95_32[64];      /* 0x01B200 -- 0x01B3F8 */
-               u64     parity[64];         /* 0x01B400 -- 0x01B5F8 */
-       } ce_ure_maint_dns_hdr;
-
-       /* RCI Buffer Data */
-       struct  ce_ure_maint_rci_data {
-               u64     data41_0[64];       /* 0x01B600 -- 0x01B7F8 */
-               u64     data69_42[64];      /* 0x01B800 -- 0x01B9F8 */
-       } ce_ure_maint_rci;
-
-       /* Response Queue */
-       u64     ce_ure_maint_rspq[64];      /* 0x01BA00 -- 0x01BBF8 */
-
-       u64     ce_pad_01C000[4224];        /* 0x01BC00 -- 0x023FF8 */
-
-       /* Admin Build-a-Packet Buffer */
-       struct  ce_adm_maint_bap_buf_data {
-               u64     data63_0[258];      /* 0x024000 -- 0x024808 */
-               u64     data127_64[258];    /* 0x024810 -- 0x025018 */
-               u64     parity[258];        /* 0x025020 -- 0x025828 */
-       } ce_adm_maint_bap_buf;
-
-       u64     ce_pad_025830[5370];        /* 0x025830 -- 0x02FFF8 */
-
-       /* URE: 40bit PMU ATE Buffer */             /* 0x030000 -- 0x037FF8 */
-       u64     ce_ure_ate40[TIOCE_NUM_M40_ATES];
-
-       /* URE: 32/40bit PMU ATE Buffer */          /* 0x038000 -- 0x03BFF8 */
-       u64     ce_ure_ate3240[TIOCE_NUM_M3240_ATES];
-
-       u64     ce_pad_03C000[2050];        /* 0x03C000 -- 0x040008 */
-
-       /*
-        * DRE: Down Stream Request Engine
-         */
-       u64     ce_dre_dyn_credit_status1;              /* 0x040010 */
-       u64     ce_dre_dyn_credit_status2;              /* 0x040018 */
-       u64     ce_dre_last_credit_status1;             /* 0x040020 */
-       u64     ce_dre_last_credit_status2;             /* 0x040028 */
-       u64     ce_dre_credit_limit1;                   /* 0x040030 */
-       u64     ce_dre_credit_limit2;                   /* 0x040038 */
-       u64     ce_dre_force_credit1;                   /* 0x040040 */
-       u64     ce_dre_force_credit2;                   /* 0x040048 */
-       u64     ce_dre_debug_mux1;                      /* 0x040050 */
-       u64     ce_dre_debug_mux2;                      /* 0x040058 */
-       u64     ce_dre_ssp_err_cmd_wrd;                 /* 0x040060 */
-       u64     ce_dre_ssp_err_addr;                    /* 0x040068 */
-       u64     ce_dre_comp_err_cmd_wrd;                /* 0x040070 */
-       u64     ce_dre_comp_err_addr;                   /* 0x040078 */
-       u64     ce_dre_req_status;                      /* 0x040080 */
-       u64     ce_dre_config1;                         /* 0x040088 */
-       u64     ce_dre_config2;                         /* 0x040090 */
-       u64     ce_dre_config_req_status;               /* 0x040098 */
-       u64     ce_pad_0400A0[12];          /* 0x0400A0 -- 0x0400F8 */
-       u64     ce_dre_dyn_fifo;                        /* 0x040100 */
-       u64     ce_pad_040108[3];           /* 0x040108 -- 0x040118 */
-       u64     ce_dre_last_fifo;                       /* 0x040120 */
-
-       u64     ce_pad_040128[27];          /* 0x040128 -- 0x0401F8 */
-
-       /* DRE Downstream Head Queue */
-       struct  ce_dre_maint_ds_head_queue {
-               u64     data63_0[32];       /* 0x040200 -- 0x0402F8 */
-               u64     data127_64[32];     /* 0x040300 -- 0x0403F8 */
-               u64     parity[32];         /* 0x040400 -- 0x0404F8 */
-       } ce_dre_maint_ds_head_q;
-
-       u64     ce_pad_040500[352];         /* 0x040500 -- 0x040FF8 */
-
-       /* DRE Downstream Data Queue */
-       struct  ce_dre_maint_ds_data_queue {
-               u64     data63_0[256];      /* 0x041000 -- 0x0417F8 */
-               u64     ce_pad_041800[256]; /* 0x041800 -- 0x041FF8 */
-               u64     data127_64[256];    /* 0x042000 -- 0x0427F8 */
-               u64     ce_pad_042800[256]; /* 0x042800 -- 0x042FF8 */
-               u64     parity[256];        /* 0x043000 -- 0x0437F8 */
-               u64     ce_pad_043800[256]; /* 0x043800 -- 0x043FF8 */
-       } ce_dre_maint_ds_data_q;
-
-       /* DRE URE Upstream Response Queue */
-       struct  ce_dre_maint_ure_us_rsp_queue {
-               u64     data63_0[8];        /* 0x044000 -- 0x044038 */
-               u64     ce_pad_044040[24];  /* 0x044040 -- 0x0440F8 */
-               u64     data127_64[8];      /* 0x044100 -- 0x044138 */
-               u64     ce_pad_044140[24];  /* 0x044140 -- 0x0441F8 */
-               u64     parity[8];          /* 0x044200 -- 0x044238 */
-               u64     ce_pad_044240[24];  /* 0x044240 -- 0x0442F8 */
-       } ce_dre_maint_ure_us_rsp_q;
-
-       u64     ce_dre_maint_us_wrt_rsp[32];/* 0x044300 -- 0x0443F8 */
-
-       u64     ce_end_of_struct;                       /* 0x044400 */
-} tioce_t;
-
-/* ce_lsiX_gb_cfg1 register bit masks & shifts */
-#define CE_LSI_GB_CFG1_RXL0S_THS_SHFT  0
-#define CE_LSI_GB_CFG1_RXL0S_THS_MASK  (0xffULL << 0)
-#define CE_LSI_GB_CFG1_RXL0S_SMP_SHFT  8
-#define CE_LSI_GB_CFG1_RXL0S_SMP_MASK  (0xfULL << 8)
-#define CE_LSI_GB_CFG1_RXL0S_ADJ_SHFT  12
-#define CE_LSI_GB_CFG1_RXL0S_ADJ_MASK  (0x7ULL << 12)
-#define CE_LSI_GB_CFG1_RXL0S_FLT_SHFT  15
-#define CE_LSI_GB_CFG1_RXL0S_FLT_MASK  (0x1ULL << 15)
-#define CE_LSI_GB_CFG1_LPBK_SEL_SHFT   16
-#define CE_LSI_GB_CFG1_LPBK_SEL_MASK   (0x3ULL << 16)
-#define CE_LSI_GB_CFG1_LPBK_EN_SHFT    18
-#define CE_LSI_GB_CFG1_LPBK_EN_MASK    (0x1ULL << 18)
-#define CE_LSI_GB_CFG1_RVRS_LB_SHFT    19
-#define CE_LSI_GB_CFG1_RVRS_LB_MASK    (0x1ULL << 19)
-#define CE_LSI_GB_CFG1_RVRS_CLK_SHFT   20
-#define CE_LSI_GB_CFG1_RVRS_CLK_MASK   (0x3ULL << 20)
-#define CE_LSI_GB_CFG1_SLF_TS_SHFT     24
-#define CE_LSI_GB_CFG1_SLF_TS_MASK     (0xfULL << 24)
-
-/* ce_adm_int_mask/ce_adm_int_status register bit defines */
-#define CE_ADM_INT_CE_ERROR_SHFT               0
-#define CE_ADM_INT_LSI1_IP_ERROR_SHFT          1
-#define CE_ADM_INT_LSI2_IP_ERROR_SHFT          2
-#define CE_ADM_INT_PCIE_ERROR_SHFT             3
-#define CE_ADM_INT_PORT1_HOTPLUG_EVENT_SHFT    4
-#define CE_ADM_INT_PORT2_HOTPLUG_EVENT_SHFT    5
-#define CE_ADM_INT_PCIE_PORT1_DEV_A_SHFT       6
-#define CE_ADM_INT_PCIE_PORT1_DEV_B_SHFT       7
-#define CE_ADM_INT_PCIE_PORT1_DEV_C_SHFT       8
-#define CE_ADM_INT_PCIE_PORT1_DEV_D_SHFT       9
-#define CE_ADM_INT_PCIE_PORT2_DEV_A_SHFT       10
-#define CE_ADM_INT_PCIE_PORT2_DEV_B_SHFT       11
-#define CE_ADM_INT_PCIE_PORT2_DEV_C_SHFT       12
-#define CE_ADM_INT_PCIE_PORT2_DEV_D_SHFT       13
-#define CE_ADM_INT_PCIE_MSG_SHFT               14 /*see int_dest_14*/
-#define CE_ADM_INT_PCIE_MSG_SLOT_0_SHFT                14
-#define CE_ADM_INT_PCIE_MSG_SLOT_1_SHFT                15
-#define CE_ADM_INT_PCIE_MSG_SLOT_2_SHFT                16
-#define CE_ADM_INT_PCIE_MSG_SLOT_3_SHFT                17
-#define CE_ADM_INT_PORT1_PM_PME_MSG_SHFT       22
-#define CE_ADM_INT_PORT2_PM_PME_MSG_SHFT       23
-
-/* ce_adm_force_int register bit defines */
-#define CE_ADM_FORCE_INT_PCIE_PORT1_DEV_A_SHFT 0
-#define CE_ADM_FORCE_INT_PCIE_PORT1_DEV_B_SHFT 1
-#define CE_ADM_FORCE_INT_PCIE_PORT1_DEV_C_SHFT 2
-#define CE_ADM_FORCE_INT_PCIE_PORT1_DEV_D_SHFT 3
-#define CE_ADM_FORCE_INT_PCIE_PORT2_DEV_A_SHFT 4
-#define CE_ADM_FORCE_INT_PCIE_PORT2_DEV_B_SHFT 5
-#define CE_ADM_FORCE_INT_PCIE_PORT2_DEV_C_SHFT 6
-#define CE_ADM_FORCE_INT_PCIE_PORT2_DEV_D_SHFT 7
-#define CE_ADM_FORCE_INT_ALWAYS_SHFT           8
-
-/* ce_adm_int_dest register bit masks & shifts */
-#define INTR_VECTOR_SHFT                       56
-
-/* ce_adm_error_mask and ce_adm_error_summary register bit masks */
-#define CE_ADM_ERR_CRM_SSP_REQ_INVALID                 (0x1ULL <<  0)
-#define CE_ADM_ERR_SSP_REQ_HEADER                      (0x1ULL <<  1)
-#define CE_ADM_ERR_SSP_RSP_HEADER                      (0x1ULL <<  2)
-#define CE_ADM_ERR_SSP_PROTOCOL_ERROR                  (0x1ULL <<  3)
-#define CE_ADM_ERR_SSP_SBE                             (0x1ULL <<  4)
-#define CE_ADM_ERR_SSP_MBE                             (0x1ULL <<  5)
-#define CE_ADM_ERR_CXM_CREDIT_OFLOW                    (0x1ULL <<  6)
-#define CE_ADM_ERR_DRE_SSP_REQ_INVAL                   (0x1ULL <<  7)
-#define CE_ADM_ERR_SSP_REQ_LONG                                (0x1ULL <<  8)
-#define CE_ADM_ERR_SSP_REQ_OFLOW                       (0x1ULL <<  9)
-#define CE_ADM_ERR_SSP_REQ_SHORT                       (0x1ULL << 10)
-#define CE_ADM_ERR_SSP_REQ_SIDEBAND                    (0x1ULL << 11)
-#define CE_ADM_ERR_SSP_REQ_ADDR_ERR                    (0x1ULL << 12)
-#define CE_ADM_ERR_SSP_REQ_BAD_BE                      (0x1ULL << 13)
-#define CE_ADM_ERR_PCIE_COMPL_TIMEOUT                  (0x1ULL << 14)
-#define CE_ADM_ERR_PCIE_UNEXP_COMPL                    (0x1ULL << 15)
-#define CE_ADM_ERR_PCIE_ERR_COMPL                      (0x1ULL << 16)
-#define CE_ADM_ERR_DRE_CREDIT_OFLOW                    (0x1ULL << 17)
-#define CE_ADM_ERR_DRE_SRAM_PE                         (0x1ULL << 18)
-#define CE_ADM_ERR_SSP_RSP_INVALID                     (0x1ULL << 19)
-#define CE_ADM_ERR_SSP_RSP_LONG                                (0x1ULL << 20)
-#define CE_ADM_ERR_SSP_RSP_SHORT                       (0x1ULL << 21)
-#define CE_ADM_ERR_SSP_RSP_SIDEBAND                    (0x1ULL << 22)
-#define CE_ADM_ERR_URE_SSP_RSP_UNEXP                   (0x1ULL << 23)
-#define CE_ADM_ERR_URE_SSP_WR_REQ_TIMEOUT              (0x1ULL << 24)
-#define CE_ADM_ERR_URE_SSP_RD_REQ_TIMEOUT              (0x1ULL << 25)
-#define CE_ADM_ERR_URE_ATE3240_PAGE_FAULT              (0x1ULL << 26)
-#define CE_ADM_ERR_URE_ATE40_PAGE_FAULT                        (0x1ULL << 27)
-#define CE_ADM_ERR_URE_CREDIT_OFLOW                    (0x1ULL << 28)
-#define CE_ADM_ERR_URE_SRAM_PE                         (0x1ULL << 29)
-#define CE_ADM_ERR_ADM_SSP_RSP_UNEXP                   (0x1ULL << 30)
-#define CE_ADM_ERR_ADM_SSP_REQ_TIMEOUT                 (0x1ULL << 31)
-#define CE_ADM_ERR_MMR_ACCESS_ERROR                    (0x1ULL << 32)
-#define CE_ADM_ERR_MMR_ADDR_ERROR                      (0x1ULL << 33)
-#define CE_ADM_ERR_ADM_CREDIT_OFLOW                    (0x1ULL << 34)
-#define CE_ADM_ERR_ADM_SRAM_PE                         (0x1ULL << 35)
-#define CE_ADM_ERR_DTL1_MIN_PDATA_CREDIT_ERR           (0x1ULL << 36)
-#define CE_ADM_ERR_DTL1_INF_COMPL_CRED_UPDT_ERR                (0x1ULL << 37)
-#define CE_ADM_ERR_DTL1_INF_POSTED_CRED_UPDT_ERR       (0x1ULL << 38)
-#define CE_ADM_ERR_DTL1_INF_NPOSTED_CRED_UPDT_ERR      (0x1ULL << 39)
-#define CE_ADM_ERR_DTL1_COMP_HD_CRED_MAX_ERR           (0x1ULL << 40)
-#define CE_ADM_ERR_DTL1_COMP_D_CRED_MAX_ERR            (0x1ULL << 41)
-#define CE_ADM_ERR_DTL1_NPOSTED_HD_CRED_MAX_ERR                (0x1ULL << 42)
-#define CE_ADM_ERR_DTL1_NPOSTED_D_CRED_MAX_ERR         (0x1ULL << 43)
-#define CE_ADM_ERR_DTL1_POSTED_HD_CRED_MAX_ERR         (0x1ULL << 44)
-#define CE_ADM_ERR_DTL1_POSTED_D_CRED_MAX_ERR          (0x1ULL << 45)
-#define CE_ADM_ERR_DTL2_MIN_PDATA_CREDIT_ERR           (0x1ULL << 46)
-#define CE_ADM_ERR_DTL2_INF_COMPL_CRED_UPDT_ERR                (0x1ULL << 47)
-#define CE_ADM_ERR_DTL2_INF_POSTED_CRED_UPDT_ERR       (0x1ULL << 48)
-#define CE_ADM_ERR_DTL2_INF_NPOSTED_CRED_UPDT_ERR      (0x1ULL << 49)
-#define CE_ADM_ERR_DTL2_COMP_HD_CRED_MAX_ERR           (0x1ULL << 50)
-#define CE_ADM_ERR_DTL2_COMP_D_CRED_MAX_ERR            (0x1ULL << 51)
-#define CE_ADM_ERR_DTL2_NPOSTED_HD_CRED_MAX_ERR                (0x1ULL << 52)
-#define CE_ADM_ERR_DTL2_NPOSTED_D_CRED_MAX_ERR         (0x1ULL << 53)
-#define CE_ADM_ERR_DTL2_POSTED_HD_CRED_MAX_ERR         (0x1ULL << 54)
-#define CE_ADM_ERR_DTL2_POSTED_D_CRED_MAX_ERR          (0x1ULL << 55)
-#define CE_ADM_ERR_PORT1_PCIE_COR_ERR                  (0x1ULL << 56)
-#define CE_ADM_ERR_PORT1_PCIE_NFAT_ERR                 (0x1ULL << 57)
-#define CE_ADM_ERR_PORT1_PCIE_FAT_ERR                  (0x1ULL << 58)
-#define CE_ADM_ERR_PORT2_PCIE_COR_ERR                  (0x1ULL << 59)
-#define CE_ADM_ERR_PORT2_PCIE_NFAT_ERR                 (0x1ULL << 60)
-#define CE_ADM_ERR_PORT2_PCIE_FAT_ERR                  (0x1ULL << 61)
-
-/* ce_adm_ure_ups_buf_barrier_flush register bit masks and shifts */
-#define FLUSH_SEL_PORT1_PIPE0_SHFT     0
-#define FLUSH_SEL_PORT1_PIPE1_SHFT     4
-#define FLUSH_SEL_PORT1_PIPE2_SHFT     8
-#define FLUSH_SEL_PORT1_PIPE3_SHFT     12
-#define FLUSH_SEL_PORT2_PIPE0_SHFT     16
-#define FLUSH_SEL_PORT2_PIPE1_SHFT     20
-#define FLUSH_SEL_PORT2_PIPE2_SHFT     24
-#define FLUSH_SEL_PORT2_PIPE3_SHFT     28
-
-/* ce_dre_config1 register bit masks and shifts */
-#define CE_DRE_RO_ENABLE               (0x1ULL << 0)
-#define CE_DRE_DYN_RO_ENABLE           (0x1ULL << 1)
-#define CE_DRE_SUP_CONFIG_COMP_ERROR   (0x1ULL << 2)
-#define CE_DRE_SUP_IO_COMP_ERROR       (0x1ULL << 3)
-#define CE_DRE_ADDR_MODE_SHFT          4
-
-/* ce_dre_config_req_status register bit masks */
-#define CE_DRE_LAST_CONFIG_COMPLETION  (0x7ULL << 0)
-#define CE_DRE_DOWNSTREAM_CONFIG_ERROR (0x1ULL << 3)
-#define CE_DRE_CONFIG_COMPLETION_VALID (0x1ULL << 4)
-#define CE_DRE_CONFIG_REQUEST_ACTIVE   (0x1ULL << 5)
-
-/* ce_ure_control register bit masks & shifts */
-#define CE_URE_RD_MRG_ENABLE           (0x1ULL << 0)
-#define CE_URE_WRT_MRG_ENABLE1         (0x1ULL << 4)
-#define CE_URE_WRT_MRG_ENABLE2         (0x1ULL << 5)
-#define CE_URE_WRT_MRG_TIMER_SHFT      12
-#define CE_URE_WRT_MRG_TIMER_MASK      (0x7FFULL << CE_URE_WRT_MRG_TIMER_SHFT)
-#define CE_URE_WRT_MRG_TIMER(x)                (((u64)(x) << \
-                                         CE_URE_WRT_MRG_TIMER_SHFT) & \
-                                        CE_URE_WRT_MRG_TIMER_MASK)
-#define CE_URE_RSPQ_BYPASS_DISABLE     (0x1ULL << 24)
-#define CE_URE_UPS_DAT1_PAR_DISABLE    (0x1ULL << 32)
-#define CE_URE_UPS_HDR1_PAR_DISABLE    (0x1ULL << 33)
-#define CE_URE_UPS_DAT2_PAR_DISABLE    (0x1ULL << 34)
-#define CE_URE_UPS_HDR2_PAR_DISABLE    (0x1ULL << 35)
-#define CE_URE_ATE_PAR_DISABLE         (0x1ULL << 36)
-#define CE_URE_RCI_PAR_DISABLE         (0x1ULL << 37)
-#define CE_URE_RSPQ_PAR_DISABLE                (0x1ULL << 38)
-#define CE_URE_DNS_DAT_PAR_DISABLE     (0x1ULL << 39)
-#define CE_URE_DNS_HDR_PAR_DISABLE     (0x1ULL << 40)
-#define CE_URE_MALFORM_DISABLE         (0x1ULL << 44)
-#define CE_URE_UNSUP_DISABLE           (0x1ULL << 45)
-
-/* ce_ure_page_map register bit masks & shifts */
-#define CE_URE_ATE3240_ENABLE          (0x1ULL << 0)
-#define CE_URE_ATE40_ENABLE            (0x1ULL << 1)
-#define CE_URE_PAGESIZE_SHFT           4
-#define CE_URE_PAGESIZE_MASK           (0x7ULL << CE_URE_PAGESIZE_SHFT)
-#define CE_URE_4K_PAGESIZE             (0x0ULL << CE_URE_PAGESIZE_SHFT)
-#define CE_URE_16K_PAGESIZE            (0x1ULL << CE_URE_PAGESIZE_SHFT)
-#define CE_URE_64K_PAGESIZE            (0x2ULL << CE_URE_PAGESIZE_SHFT)
-#define CE_URE_128K_PAGESIZE           (0x3ULL << CE_URE_PAGESIZE_SHFT)
-#define CE_URE_256K_PAGESIZE           (0x4ULL << CE_URE_PAGESIZE_SHFT)
-
-/* ce_ure_pipe_sel register bit masks & shifts */
-#define PKT_TRAFIC_SHRT                        16
-#define BUS_SRC_ID_SHFT                        8
-#define DEV_SRC_ID_SHFT                        3
-#define FNC_SRC_ID_SHFT                        0
-#define CE_URE_TC_MASK                 (0x07ULL << PKT_TRAFIC_SHRT)
-#define CE_URE_BUS_MASK                        (0xFFULL << BUS_SRC_ID_SHFT)
-#define CE_URE_DEV_MASK                        (0x1FULL << DEV_SRC_ID_SHFT)
-#define CE_URE_FNC_MASK                        (0x07ULL << FNC_SRC_ID_SHFT)
-#define CE_URE_PIPE_BUS(b)             (((u64)(b) << BUS_SRC_ID_SHFT) & \
-                                        CE_URE_BUS_MASK)
-#define CE_URE_PIPE_DEV(d)             (((u64)(d) << DEV_SRC_ID_SHFT) & \
-                                        CE_URE_DEV_MASK)
-#define CE_URE_PIPE_FNC(f)             (((u64)(f) << FNC_SRC_ID_SHFT) & \
-                                        CE_URE_FNC_MASK)
-
-#define CE_URE_SEL1_SHFT               0
-#define CE_URE_SEL2_SHFT               20
-#define CE_URE_SEL3_SHFT               40
-#define CE_URE_SEL1_MASK               (0x7FFFFULL << CE_URE_SEL1_SHFT)
-#define CE_URE_SEL2_MASK               (0x7FFFFULL << CE_URE_SEL2_SHFT)
-#define CE_URE_SEL3_MASK               (0x7FFFFULL << CE_URE_SEL3_SHFT)
-
-
-/* ce_ure_pipe_mask register bit masks & shifts */
-#define CE_URE_MASK1_SHFT              0
-#define CE_URE_MASK2_SHFT              20
-#define CE_URE_MASK3_SHFT              40
-#define CE_URE_MASK1_MASK              (0x7FFFFULL << CE_URE_MASK1_SHFT)
-#define CE_URE_MASK2_MASK              (0x7FFFFULL << CE_URE_MASK2_SHFT)
-#define CE_URE_MASK3_MASK              (0x7FFFFULL << CE_URE_MASK3_SHFT)
-
-
-/* ce_ure_pcie_control1 register bit masks & shifts */
-#define CE_URE_SI                      (0x1ULL << 0)
-#define CE_URE_ELAL_SHFT               4
-#define CE_URE_ELAL_MASK               (0x7ULL << CE_URE_ELAL_SHFT)
-#define CE_URE_ELAL_SET(n)             (((u64)(n) << CE_URE_ELAL_SHFT) & \
-                                        CE_URE_ELAL_MASK)
-#define CE_URE_ELAL1_SHFT              8
-#define CE_URE_ELAL1_MASK              (0x7ULL << CE_URE_ELAL1_SHFT)
-#define CE_URE_ELAL1_SET(n)            (((u64)(n) << CE_URE_ELAL1_SHFT) & \
-                                        CE_URE_ELAL1_MASK)
-#define CE_URE_SCC                     (0x1ULL << 12)
-#define CE_URE_PN1_SHFT                        16
-#define CE_URE_PN1_MASK                        (0xFFULL << CE_URE_PN1_SHFT)
-#define CE_URE_PN2_SHFT                        24
-#define CE_URE_PN2_MASK                        (0xFFULL << CE_URE_PN2_SHFT)
-#define CE_URE_PN1_SET(n)              (((u64)(n) << CE_URE_PN1_SHFT) & \
-                                        CE_URE_PN1_MASK)
-#define CE_URE_PN2_SET(n)              (((u64)(n) << CE_URE_PN2_SHFT) & \
-                                        CE_URE_PN2_MASK)
-
-/* ce_ure_pcie_control2 register bit masks & shifts */
-#define CE_URE_ABP                     (0x1ULL << 0)
-#define CE_URE_PCP                     (0x1ULL << 1)
-#define CE_URE_MSP                     (0x1ULL << 2)
-#define CE_URE_AIP                     (0x1ULL << 3)
-#define CE_URE_PIP                     (0x1ULL << 4)
-#define CE_URE_HPS                     (0x1ULL << 5)
-#define CE_URE_HPC                     (0x1ULL << 6)
-#define CE_URE_SPLV_SHFT               7
-#define CE_URE_SPLV_MASK               (0xFFULL << CE_URE_SPLV_SHFT)
-#define CE_URE_SPLV_SET(n)             (((u64)(n) << CE_URE_SPLV_SHFT) & \
-                                        CE_URE_SPLV_MASK)
-#define CE_URE_SPLS_SHFT               15
-#define CE_URE_SPLS_MASK               (0x3ULL << CE_URE_SPLS_SHFT)
-#define CE_URE_SPLS_SET(n)             (((u64)(n) << CE_URE_SPLS_SHFT) & \
-                                        CE_URE_SPLS_MASK)
-#define CE_URE_PSN1_SHFT               19
-#define CE_URE_PSN1_MASK               (0x1FFFULL << CE_URE_PSN1_SHFT)
-#define CE_URE_PSN2_SHFT               32
-#define CE_URE_PSN2_MASK               (0x1FFFULL << CE_URE_PSN2_SHFT)
-#define CE_URE_PSN1_SET(n)             (((u64)(n) << CE_URE_PSN1_SHFT) & \
-                                        CE_URE_PSN1_MASK)
-#define CE_URE_PSN2_SET(n)             (((u64)(n) << CE_URE_PSN2_SHFT) & \
-                                        CE_URE_PSN2_MASK)
-
-/*
- * PIO address space ranges for CE
- */
-
-/* Local CE Registers Space */
-#define CE_PIO_MMR                     0x00000000
-#define CE_PIO_MMR_LEN                 0x04000000
-
-/* PCI Compatible Config Space */
-#define CE_PIO_CONFIG_SPACE            0x04000000
-#define CE_PIO_CONFIG_SPACE_LEN                0x04000000
-
-/* PCI I/O Space Alias */
-#define CE_PIO_IO_SPACE_ALIAS          0x08000000
-#define CE_PIO_IO_SPACE_ALIAS_LEN      0x08000000
-
-/* PCI Enhanced Config Space */
-#define CE_PIO_E_CONFIG_SPACE          0x10000000
-#define CE_PIO_E_CONFIG_SPACE_LEN      0x10000000
-
-/* PCI I/O Space */
-#define CE_PIO_IO_SPACE                        0x100000000
-#define CE_PIO_IO_SPACE_LEN            0x100000000
-
-/* PCI MEM Space */
-#define CE_PIO_MEM_SPACE               0x200000000
-#define CE_PIO_MEM_SPACE_LEN           TIO_HWIN_SIZE
-
-
-/*
- * CE PCI Enhanced Config Space shifts & masks
- */
-#define CE_E_CONFIG_BUS_SHFT           20
-#define CE_E_CONFIG_BUS_MASK           (0xFF << CE_E_CONFIG_BUS_SHFT)
-#define CE_E_CONFIG_DEVICE_SHFT                15
-#define CE_E_CONFIG_DEVICE_MASK                (0x1F << CE_E_CONFIG_DEVICE_SHFT)
-#define CE_E_CONFIG_FUNC_SHFT          12
-#define CE_E_CONFIG_FUNC_MASK          (0x7  << CE_E_CONFIG_FUNC_SHFT)
-
-#endif /* __ASM_IA64_SN_TIOCE_H__ */
diff --git a/arch/ia64/include/asm/sn/tioce_provider.h b/arch/ia64/include/asm/sn/tioce_provider.h
deleted file mode 100644 (file)
index 32c32f3..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2003-2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_CE_PROVIDER_H
-#define _ASM_IA64_SN_CE_PROVIDER_H
-
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/tioce.h>
-
-/*
- * Common TIOCE structure shared between the prom and kernel
- *
- * DO NOT CHANGE THIS STRUCT WITHOUT MAKING CORRESPONDING CHANGES TO THE
- * PROM VERSION.
- */
-struct tioce_common {
-       struct pcibus_bussoft   ce_pcibus;      /* common pciio header */
-
-       u32             ce_rev;
-       u64             ce_kernel_private;
-       u64             ce_prom_private;
-};
-
-struct tioce_kernel {
-       struct tioce_common     *ce_common;
-       spinlock_t              ce_lock;
-       struct list_head        ce_dmamap_list;
-
-       u64             ce_ate40_shadow[TIOCE_NUM_M40_ATES];
-       u64             ce_ate3240_shadow[TIOCE_NUM_M3240_ATES];
-       u32             ce_ate3240_pagesize;
-
-       u8                      ce_port1_secondary;
-
-       /* per-port resources */
-       struct {
-               int             dirmap_refcnt;
-               u64     dirmap_shadow;
-       } ce_port[TIOCE_NUM_PORTS];
-};
-
-struct tioce_dmamap {
-       struct list_head        ce_dmamap_list; /* headed by tioce_kernel */
-       u32             refcnt;
-
-       u64             nbytes;         /* # bytes mapped */
-
-       u64             ct_start;       /* coretalk start address */
-       u64             pci_start;      /* bus start address */
-
-       u64             __iomem *ate_hw;/* hw ptr of first ate in map */
-       u64             *ate_shadow;    /* shadow ptr of firat ate */
-       u16             ate_count;      /* # ate's in the map */
-};
-
-extern int tioce_init_provider(void);
-
-#endif  /* __ASM_IA64_SN_CE_PROVIDER_H */
diff --git a/arch/ia64/include/asm/sn/tiocp.h b/arch/ia64/include/asm/sn/tiocp.h
deleted file mode 100644 (file)
index e8ad0bb..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2003-2005 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_PCI_TIOCP_H
-#define _ASM_IA64_SN_PCI_TIOCP_H
-
-#define TIOCP_HOST_INTR_ADDR            0x003FFFFFFFFFFFFFUL
-#define TIOCP_PCI64_CMDTYPE_MEM         (0x1ull << 60)
-#define TIOCP_PCI64_CMDTYPE_MSI         (0x3ull << 60)
-
-
-/*****************************************************************************
- *********************** TIOCP MMR structure mapping ***************************
- *****************************************************************************/
-
-struct tiocp{
-
-    /* 0x000000-0x00FFFF -- Local Registers */
-
-    /* 0x000000-0x000057 -- (Legacy Widget Space) Configuration */
-    u64                cp_id;                          /* 0x000000 */
-    u64                cp_stat;                        /* 0x000008 */
-    u64                cp_err_upper;                   /* 0x000010 */
-    u64                cp_err_lower;                   /* 0x000018 */
-    #define cp_err cp_err_lower
-    u64                cp_control;                     /* 0x000020 */
-    u64                cp_req_timeout;                 /* 0x000028 */
-    u64                cp_intr_upper;                  /* 0x000030 */
-    u64                cp_intr_lower;                  /* 0x000038 */
-    #define cp_intr cp_intr_lower
-    u64                cp_err_cmdword;                 /* 0x000040 */
-    u64                _pad_000048;                    /* 0x000048 */
-    u64                cp_tflush;                      /* 0x000050 */
-
-    /* 0x000058-0x00007F -- Bridge-specific Configuration */
-    u64                cp_aux_err;                     /* 0x000058 */
-    u64                cp_resp_upper;                  /* 0x000060 */
-    u64                cp_resp_lower;                  /* 0x000068 */
-    #define cp_resp cp_resp_lower
-    u64                cp_tst_pin_ctrl;                /* 0x000070 */
-    u64                cp_addr_lkerr;                  /* 0x000078 */
-
-    /* 0x000080-0x00008F -- PMU & MAP */
-    u64                cp_dir_map;                     /* 0x000080 */
-    u64                _pad_000088;                    /* 0x000088 */
-
-    /* 0x000090-0x00009F -- SSRAM */
-    u64                cp_map_fault;                   /* 0x000090 */
-    u64                _pad_000098;                    /* 0x000098 */
-
-    /* 0x0000A0-0x0000AF -- Arbitration */
-    u64                cp_arb;                         /* 0x0000A0 */
-    u64                _pad_0000A8;                    /* 0x0000A8 */
-
-    /* 0x0000B0-0x0000BF -- Number In A Can or ATE Parity Error */
-    u64                cp_ate_parity_err;              /* 0x0000B0 */
-    u64                _pad_0000B8;                    /* 0x0000B8 */
-
-    /* 0x0000C0-0x0000FF -- PCI/GIO */
-    u64                cp_bus_timeout;                 /* 0x0000C0 */
-    u64                cp_pci_cfg;                     /* 0x0000C8 */
-    u64                cp_pci_err_upper;               /* 0x0000D0 */
-    u64                cp_pci_err_lower;               /* 0x0000D8 */
-    #define cp_pci_err cp_pci_err_lower
-    u64                _pad_0000E0[4];                 /* 0x0000{E0..F8} */
-
-    /* 0x000100-0x0001FF -- Interrupt */
-    u64                cp_int_status;                  /* 0x000100 */
-    u64                cp_int_enable;                  /* 0x000108 */
-    u64                cp_int_rst_stat;                /* 0x000110 */
-    u64                cp_int_mode;                    /* 0x000118 */
-    u64                cp_int_device;                  /* 0x000120 */
-    u64                cp_int_host_err;                /* 0x000128 */
-    u64                cp_int_addr[8];                 /* 0x0001{30,,,68} */
-    u64                cp_err_int_view;                /* 0x000170 */
-    u64                cp_mult_int;                    /* 0x000178 */
-    u64                cp_force_always[8];             /* 0x0001{80,,,B8} */
-    u64                cp_force_pin[8];                /* 0x0001{C0,,,F8} */
-
-    /* 0x000200-0x000298 -- Device */
-    u64                cp_device[4];                   /* 0x0002{00,,,18} */
-    u64                _pad_000220[4];                 /* 0x0002{20,,,38} */
-    u64                cp_wr_req_buf[4];               /* 0x0002{40,,,58} */
-    u64                _pad_000260[4];                 /* 0x0002{60,,,78} */
-    u64                cp_rrb_map[2];                  /* 0x0002{80,,,88} */
-    #define cp_even_resp cp_rrb_map[0]                 /* 0x000280 */
-    #define cp_odd_resp  cp_rrb_map[1]                 /* 0x000288 */
-    u64                cp_resp_status;                 /* 0x000290 */
-    u64                cp_resp_clear;                  /* 0x000298 */
-
-    u64                _pad_0002A0[12];                /* 0x0002{A0..F8} */
-
-    /* 0x000300-0x0003F8 -- Buffer Address Match Registers */
-    struct {
-       u64     upper;                          /* 0x0003{00,,,F0} */
-       u64     lower;                          /* 0x0003{08,,,F8} */
-    } cp_buf_addr_match[16];
-
-    /* 0x000400-0x0005FF -- Performance Monitor Registers (even only) */
-    struct {
-       u64     flush_w_touch;                  /* 0x000{400,,,5C0} */
-       u64     flush_wo_touch;                 /* 0x000{408,,,5C8} */
-       u64     inflight;                       /* 0x000{410,,,5D0} */
-       u64     prefetch;                       /* 0x000{418,,,5D8} */
-       u64     total_pci_retry;                /* 0x000{420,,,5E0} */
-       u64     max_pci_retry;                  /* 0x000{428,,,5E8} */
-       u64     max_latency;                    /* 0x000{430,,,5F0} */
-       u64     clear_all;                      /* 0x000{438,,,5F8} */
-    } cp_buf_count[8];
-
-
-    /* 0x000600-0x0009FF -- PCI/X registers */
-    u64                cp_pcix_bus_err_addr;           /* 0x000600 */
-    u64                cp_pcix_bus_err_attr;           /* 0x000608 */
-    u64                cp_pcix_bus_err_data;           /* 0x000610 */
-    u64                cp_pcix_pio_split_addr;         /* 0x000618 */
-    u64                cp_pcix_pio_split_attr;         /* 0x000620 */
-    u64                cp_pcix_dma_req_err_attr;       /* 0x000628 */
-    u64                cp_pcix_dma_req_err_addr;       /* 0x000630 */
-    u64                cp_pcix_timeout;                /* 0x000638 */
-
-    u64                _pad_000640[24];                /* 0x000{640,,,6F8} */
-
-    /* 0x000700-0x000737 -- Debug Registers */
-    u64                cp_ct_debug_ctl;                /* 0x000700 */
-    u64                cp_br_debug_ctl;                /* 0x000708 */
-    u64                cp_mux3_debug_ctl;              /* 0x000710 */
-    u64                cp_mux4_debug_ctl;              /* 0x000718 */
-    u64                cp_mux5_debug_ctl;              /* 0x000720 */
-    u64                cp_mux6_debug_ctl;              /* 0x000728 */
-    u64                cp_mux7_debug_ctl;              /* 0x000730 */
-
-    u64                _pad_000738[89];                /* 0x000{738,,,9F8} */
-
-    /* 0x000A00-0x000BFF -- PCI/X Read&Write Buffer */
-    struct {
-       u64     cp_buf_addr;                    /* 0x000{A00,,,AF0} */
-       u64     cp_buf_attr;                    /* 0X000{A08,,,AF8} */
-    } cp_pcix_read_buf_64[16];
-
-    struct {
-       u64     cp_buf_addr;                    /* 0x000{B00,,,BE0} */
-       u64     cp_buf_attr;                    /* 0x000{B08,,,BE8} */
-       u64     cp_buf_valid;                   /* 0x000{B10,,,BF0} */
-       u64     __pad1;                         /* 0x000{B18,,,BF8} */
-    } cp_pcix_write_buf_64[8];
-
-    /* End of Local Registers -- Start of Address Map space */
-
-    char       _pad_000c00[0x010000 - 0x000c00];
-
-    /* 0x010000-0x011FF8 -- Internal ATE RAM (Auto Parity Generation) */
-    u64                cp_int_ate_ram[1024];           /* 0x010000-0x011FF8 */
-
-    char       _pad_012000[0x14000 - 0x012000];
-
-    /* 0x014000-0x015FF8 -- Internal ATE RAM (Manual Parity Generation) */
-    u64                cp_int_ate_ram_mp[1024];        /* 0x014000-0x015FF8 */
-
-    char       _pad_016000[0x18000 - 0x016000];
-
-    /* 0x18000-0x197F8 -- TIOCP Write Request Ram */
-    u64                cp_wr_req_lower[256];           /* 0x18000 - 0x187F8 */
-    u64                cp_wr_req_upper[256];           /* 0x18800 - 0x18FF8 */
-    u64                cp_wr_req_parity[256];          /* 0x19000 - 0x197F8 */
-
-    char       _pad_019800[0x1C000 - 0x019800];
-
-    /* 0x1C000-0x1EFF8 -- TIOCP Read Response Ram */
-    u64                cp_rd_resp_lower[512];          /* 0x1C000 - 0x1CFF8 */
-    u64                cp_rd_resp_upper[512];          /* 0x1D000 - 0x1DFF8 */
-    u64                cp_rd_resp_parity[512];         /* 0x1E000 - 0x1EFF8 */
-
-    char       _pad_01F000[0x20000 - 0x01F000];
-
-    /* 0x020000-0x021FFF -- Host Device (CP) Configuration Space (not used)  */
-    char       _pad_020000[0x021000 - 0x20000];
-
-    /* 0x021000-0x027FFF -- PCI Device Configuration Spaces */
-    union {
-       u8      c[0x1000 / 1];                  /* 0x02{0000,,,7FFF} */
-       u16     s[0x1000 / 2];                  /* 0x02{0000,,,7FFF} */
-       u32     l[0x1000 / 4];                  /* 0x02{0000,,,7FFF} */
-       u64     d[0x1000 / 8];                  /* 0x02{0000,,,7FFF} */
-       union {
-           u8  c[0x100 / 1];
-           u16 s[0x100 / 2];
-           u32 l[0x100 / 4];
-           u64 d[0x100 / 8];
-       } f[8];
-    } cp_type0_cfg_dev[7];                             /* 0x02{1000,,,7FFF} */
-
-    /* 0x028000-0x028FFF -- PCI Type 1 Configuration Space */
-    union {
-       u8      c[0x1000 / 1];                  /* 0x028000-0x029000 */
-       u16     s[0x1000 / 2];                  /* 0x028000-0x029000 */
-       u32     l[0x1000 / 4];                  /* 0x028000-0x029000 */
-       u64     d[0x1000 / 8];                  /* 0x028000-0x029000 */
-       union {
-           u8  c[0x100 / 1];
-           u16 s[0x100 / 2];
-           u32 l[0x100 / 4];
-           u64 d[0x100 / 8];
-       } f[8];
-    } cp_type1_cfg;                                    /* 0x028000-0x029000 */
-
-    char               _pad_029000[0x030000-0x029000];
-
-    /* 0x030000-0x030007 -- PCI Interrupt Acknowledge Cycle */
-    union {
-       u8      c[8 / 1];
-       u16     s[8 / 2];
-       u32     l[8 / 4];
-       u64     d[8 / 8];
-    } cp_pci_iack;                                     /* 0x030000-0x030007 */
-
-    char               _pad_030007[0x040000-0x030008];
-
-    /* 0x040000-0x040007 -- PCIX Special Cycle */
-    union {
-       u8      c[8 / 1];
-       u16     s[8 / 2];
-       u32     l[8 / 4];
-       u64     d[8 / 8];
-    } cp_pcix_cycle;                                   /* 0x040000-0x040007 */
-
-    char               _pad_040007[0x200000-0x040008];
-
-    /* 0x200000-0x7FFFFF -- PCI/GIO Device Spaces */
-    union {
-       u8      c[0x100000 / 1];
-       u16     s[0x100000 / 2];
-       u32     l[0x100000 / 4];
-       u64     d[0x100000 / 8];
-    } cp_devio_raw[6];                                 /* 0x200000-0x7FFFFF */
-
-    #define cp_devio(n)  cp_devio_raw[((n)<2)?(n*2):(n+2)]
-
-    char               _pad_800000[0xA00000-0x800000];
-
-    /* 0xA00000-0xBFFFFF -- PCI/GIO Device Spaces w/flush  */
-    union {
-       u8      c[0x100000 / 1];
-       u16     s[0x100000 / 2];
-       u32     l[0x100000 / 4];
-       u64     d[0x100000 / 8];
-    } cp_devio_raw_flush[6];                           /* 0xA00000-0xBFFFFF */
-
-    #define cp_devio_flush(n)  cp_devio_raw_flush[((n)<2)?(n*2):(n+2)]
-
-};
-
-#endif         /* _ASM_IA64_SN_PCI_TIOCP_H */
diff --git a/arch/ia64/include/asm/sn/tiocx.h b/arch/ia64/include/asm/sn/tiocx.h
deleted file mode 100644 (file)
index d297284..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_TIO_TIOCX_H
-#define _ASM_IA64_SN_TIO_TIOCX_H
-
-#ifdef __KERNEL__
-
-struct cx_id_s {
-       unsigned int part_num;
-       unsigned int mfg_num;
-       int nasid;
-};
-
-struct cx_dev {
-       struct cx_id_s cx_id;
-       int bt;                         /* board/blade type */
-       void *soft;                     /* driver specific */
-       struct hubdev_info *hubdev;
-       struct device dev;
-       struct cx_drv *driver;
-};
-
-struct cx_device_id {
-       unsigned int part_num;
-       unsigned int mfg_num;
-};
-
-struct cx_drv {
-       char *name;
-       const struct cx_device_id *id_table;
-       struct device_driver driver;
-       int (*probe) (struct cx_dev * dev, const struct cx_device_id * id);
-       int (*remove) (struct cx_dev * dev);
-};
-
-/* create DMA address by stripping AS bits */
-#define TIOCX_DMA_ADDR(a) (u64)((u64)(a) & 0xffffcfffffffffUL)
-
-#define TIOCX_TO_TIOCX_DMA_ADDR(a) (u64)(((u64)(a) & 0xfffffffff) |  \
-                                  ((((u64)(a)) & 0xffffc000000000UL) <<2))
-
-#define TIO_CE_ASIC_PARTNUM 0xce00
-#define TIOCX_CORELET 3
-
-/* These are taken from tio_mmr_as.h */
-#define TIO_ICE_FRZ_CFG               TIO_MMR_ADDR_MOD(0x00000000b0008100UL)
-#define TIO_ICE_PMI_TX_CFG            TIO_MMR_ADDR_MOD(0x00000000b000b100UL)
-#define TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3 TIO_MMR_ADDR_MOD(0x00000000b000be18UL)
-#define TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3_CREDIT_CNT_MASK 0x000000000000000fUL
-
-#define to_cx_dev(n) container_of(n, struct cx_dev, dev)
-#define to_cx_driver(drv) container_of(drv, struct cx_drv, driver)
-
-extern struct sn_irq_info *tiocx_irq_alloc(nasid_t, int, int, nasid_t, int);
-extern void tiocx_irq_free(struct sn_irq_info *);
-extern int cx_device_unregister(struct cx_dev *);
-extern int cx_device_register(nasid_t, int, int, struct hubdev_info *, int);
-extern int cx_driver_unregister(struct cx_drv *);
-extern int cx_driver_register(struct cx_drv *);
-extern u64 tiocx_dma_addr(u64 addr);
-extern u64 tiocx_swin_base(int nasid);
-extern void tiocx_mmr_store(int nasid, u64 offset, u64 value);
-extern u64 tiocx_mmr_load(int nasid, u64 offset);
-
-#endif                         //  __KERNEL__
-#endif                         // _ASM_IA64_SN_TIO_TIOCX__
diff --git a/arch/ia64/include/asm/sn/types.h b/arch/ia64/include/asm/sn/types.h
deleted file mode 100644 (file)
index 8e04ee2..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
- * Copyright (C) 1999 by Ralf Baechle
- */
-#ifndef _ASM_IA64_SN_TYPES_H
-#define _ASM_IA64_SN_TYPES_H
-
-#include <linux/types.h>
-
-typedef unsigned long  cpuid_t;
-typedef signed short   nasid_t;        /* node id in numa-as-id space */
-typedef signed char    partid_t;       /* partition ID type */
-typedef unsigned int    moduleid_t;     /* user-visible module number type */
-typedef unsigned int    cmoduleid_t;    /* kernel compact module id type */
-typedef unsigned char  slotid_t;       /* slot (blade) within module */
-typedef unsigned char  slabid_t;       /* slab (asic) within slot */
-typedef u64 nic_t;
-typedef unsigned long iopaddr_t;
-typedef unsigned long paddr_t;
-typedef short cnodeid_t;
-
-#endif /* _ASM_IA64_SN_TYPES_H */
index b10f31e..9011e90 100644 (file)
@@ -69,7 +69,6 @@ extern void ia64_load_extra (struct task_struct *task);
        if (unlikely((current->thread.flags & IA64_THREAD_MIGRATION) &&        \
                     (task_cpu(current) !=                                     \
                                      task_thread_info(current)->last_cpu))) { \
-               platform_migrate(current);                                     \
                task_thread_info(current)->last_cpu = task_cpu(current);       \
        }                                                                      \
 } while (0)
index 86ec034..f1f257d 100644 (file)
@@ -45,7 +45,6 @@
 #include <asm/pgalloc.h>
 #include <asm/processor.h>
 #include <asm/tlbflush.h>
-#include <asm/machvec.h>
 
 #include <asm-generic/tlb.h>
 
index 71df93e..48d4526 100644 (file)
@@ -2,12 +2,29 @@
 #ifndef _ASM_IA64_UV_UV_H
 #define _ASM_IA64_UV_UV_H
 
-#include <asm/sn/simulator.h>
+#ifdef CONFIG_IA64_SGI_UV
+extern bool ia64_is_uv;
 
 static inline int is_uv_system(void)
 {
-       /* temporary support for running on hardware simulator */
-       return IS_MEDUSA() || ia64_platform_is("uv");
+       return ia64_is_uv;
 }
 
+void __init uv_probe_system_type(void);
+void __init uv_setup(char **cmdline_p);
+#else /* CONFIG_IA64_SGI_UV */
+static inline int is_uv_system(void)
+{
+       return false;
+}
+
+static inline void __init uv_probe_system_type(void)
+{
+}
+
+static inline void __init uv_setup(char **cmdline_p)
+{
+}
+#endif /* CONFIG_IA64_SGI_UV */
+
 #endif /* _ASM_IA64_UV_UV_H */
index 4ba0514..1a8df66 100644 (file)
@@ -10,15 +10,14 @@ endif
 extra-y        := head.o vmlinux.lds
 
 obj-y := entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o     \
-        irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o          \
+        irq_lsapic.o ivt.o pal.o patch.o process.o perfmon.o ptrace.o sal.o            \
         salinfo.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o \
-        unwind.o mca.o mca_asm.o topology.o dma-mapping.o
+        unwind.o mca.o mca_asm.o topology.o dma-mapping.o iosapic.o acpi.o \
+        acpi-ext.o
 
-obj-$(CONFIG_ACPI)             += acpi.o acpi-ext.o
 obj-$(CONFIG_IA64_BRL_EMU)     += brl_emu.o
 
 obj-$(CONFIG_IA64_PALINFO)     += palinfo.o
-obj-$(CONFIG_IOSAPIC)          += iosapic.o
 obj-$(CONFIG_MODULES)          += module.o
 obj-$(CONFIG_SMP)              += smp.o smpboot.o
 obj-$(CONFIG_NUMA)             += numa.o
@@ -31,7 +30,7 @@ obj-$(CONFIG_KEXEC)           += machine_kexec.o relocate_kernel.o crash.o
 obj-$(CONFIG_CRASH_DUMP)       += crash_dump.o
 obj-$(CONFIG_IA64_UNCACHED_ALLOCATOR)  += uncached.o
 obj-$(CONFIG_AUDIT)            += audit.o
-obj-$(CONFIG_PCI_MSI)          += msi_ia64.o
+obj-y                          += msi_ia64.o
 mca_recovery-y                 += mca_drv.o mca_drv_asm.o
 obj-$(CONFIG_IA64_MC_ERR_INJECT)+= err_inject.o
 obj-$(CONFIG_STACKTRACE)       += stacktrace.o
index c597ab5..70d1587 100644 (file)
@@ -31,7 +31,6 @@
 #include <acpi/processor.h>
 #include <asm/io.h>
 #include <asm/iosapic.h>
-#include <asm/machvec.h>
 #include <asm/page.h>
 #include <asm/numa.h>
 #include <asm/sal.h>
@@ -45,77 +44,6 @@ unsigned int acpi_cpei_phys_cpuid;
 
 unsigned long acpi_wakeup_address = 0;
 
-#ifdef CONFIG_IA64_GENERIC
-static unsigned long __init acpi_find_rsdp(void)
-{
-       unsigned long rsdp_phys = 0;
-
-       if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
-               rsdp_phys = efi.acpi20;
-       else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
-               printk(KERN_WARNING PREFIX
-                      "v1.0/r0.71 tables no longer supported\n");
-       return rsdp_phys;
-}
-
-const char __init *
-acpi_get_sysname(void)
-{
-       unsigned long rsdp_phys;
-       struct acpi_table_rsdp *rsdp;
-       struct acpi_table_xsdt *xsdt;
-       struct acpi_table_header *hdr;
-#ifdef CONFIG_INTEL_IOMMU
-       u64 i, nentries;
-#endif
-
-       rsdp_phys = acpi_find_rsdp();
-       if (!rsdp_phys) {
-               printk(KERN_ERR
-                      "ACPI 2.0 RSDP not found, default to \"dig\"\n");
-               return "dig";
-       }
-
-       rsdp = (struct acpi_table_rsdp *)__va(rsdp_phys);
-       if (strncmp(rsdp->signature, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)) {
-               printk(KERN_ERR
-                      "ACPI 2.0 RSDP signature incorrect, default to \"dig\"\n");
-               return "dig";
-       }
-
-       xsdt = (struct acpi_table_xsdt *)__va(rsdp->xsdt_physical_address);
-       hdr = &xsdt->header;
-       if (strncmp(hdr->signature, ACPI_SIG_XSDT, sizeof(ACPI_SIG_XSDT) - 1)) {
-               printk(KERN_ERR
-                      "ACPI 2.0 XSDT signature incorrect, default to \"dig\"\n");
-               return "dig";
-       }
-
-       if (!strcmp(hdr->oem_id, "HP")) {
-               return "hpzx1";
-       } else if (!strcmp(hdr->oem_id, "SGI")) {
-               if (!strcmp(hdr->oem_table_id + 4, "UV"))
-                       return "uv";
-               else
-                       return "sn2";
-       }
-
-#ifdef CONFIG_INTEL_IOMMU
-       /* Look for Intel IOMMU */
-       nentries = (hdr->length - sizeof(*hdr)) /
-                        sizeof(xsdt->table_offset_entry[0]);
-       for (i = 0; i < nentries; i++) {
-               hdr = __va(xsdt->table_offset_entry[i]);
-               if (strncmp(hdr->signature, ACPI_SIG_DMAR,
-                       sizeof(ACPI_SIG_DMAR) - 1) == 0)
-                       return "dig_vtd";
-       }
-#endif
-
-       return "dig";
-}
-#endif /* CONFIG_IA64_GENERIC */
-
 #define ACPI_MAX_PLATFORM_INTERRUPTS   256
 
 /* Array to record platform interrupt vectors for generic interrupt routing. */
@@ -407,7 +335,7 @@ get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa)
        int pxm;
 
        pxm = pa->proximity_domain_lo;
-       if (ia64_platform_is("sn2") || acpi_srat_revision >= 2)
+       if (acpi_srat_revision >= 2)
                pxm += pa->proximity_domain_hi[0] << 8;
        return pxm;
 }
@@ -418,7 +346,7 @@ get_memory_proximity_domain(struct acpi_srat_mem_affinity *ma)
        int pxm;
 
        pxm = ma->proximity_domain;
-       if (!ia64_platform_is("sn2") && acpi_srat_revision <= 1)
+       if (acpi_srat_revision <= 1)
                pxm &= 0xff;
 
        return pxm;
@@ -710,9 +638,8 @@ int __init acpi_boot_init(void)
 
        if (acpi_table_parse_madt
            (ACPI_MADT_TYPE_IO_SAPIC, acpi_parse_iosapic, NR_IOSAPICS) < 1) {
-               if (!ia64_platform_is("sn2"))
-                       printk(KERN_ERR PREFIX
-                              "Error parsing MADT - no IOSAPIC entries\n");
+               printk(KERN_ERR PREFIX
+                      "Error parsing MADT - no IOSAPIC entries\n");
        }
 
        /* System-Level Interrupt Routing */
index ad7d996..4a32627 100644 (file)
@@ -1,6 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/dma-direct.h>
-#include <linux/swiotlb.h>
 #include <linux/export.h>
 
 /* Set this to 1 if there is a HW IOMMU in the system */
@@ -9,13 +8,6 @@ int iommu_detected __read_mostly;
 const struct dma_map_ops *dma_ops;
 EXPORT_SYMBOL(dma_ops);
 
-const struct dma_map_ops *dma_get_ops(struct device *dev)
-{
-       return dma_ops;
-}
-EXPORT_SYMBOL(dma_get_ops);
-
-#ifdef CONFIG_SWIOTLB
 void *arch_dma_alloc(struct device *dev, size_t size,
                dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
 {
@@ -33,9 +25,3 @@ long arch_dma_coherent_to_pfn(struct device *dev, void *cpu_addr,
 {
        return page_to_pfn(virt_to_page(cpu_addr));
 }
-
-void __init swiotlb_dma_init(void)
-{
-       swiotlb_init(1);
-}
-#endif
index fe6e494..fad4db2 100644 (file)
  *     used as architecture-independent interrupt handling mechanism in Linux.
  *     As an IRQ is a number, we have to have
  *     IA-64 interrupt vector number <-> IRQ number mapping.  On smaller
- *     systems, we use one-to-one mapping between IA-64 vector and IRQ.  A
- *     platform can implement platform_irq_to_vector(irq) and
- *     platform_local_vector_to_irq(vector) APIs to differentiate the mapping.
- *     Please see also arch/ia64/include/asm/hw_irq.h for those APIs.
+ *     systems, we use one-to-one mapping between IA-64 vector and IRQ.
  *
  * To sum up, there are three levels of mappings involved:
  *
@@ -96,7 +93,6 @@
 #include <asm/hw_irq.h>
 #include <asm/io.h>
 #include <asm/iosapic.h>
-#include <asm/machvec.h>
 #include <asm/processor.h>
 #include <asm/ptrace.h>
 
@@ -646,10 +642,8 @@ get_target_cpu (unsigned int gsi, int irq)
        if (!cpu_online(smp_processor_id()))
                return cpu_physical_id(smp_processor_id());
 
-#ifdef CONFIG_ACPI
        if (cpe_vector > 0 && irq_to_vector(irq) == IA64_CPEP_VECTOR)
                return get_cpei_target_cpu();
-#endif
 
 #ifdef CONFIG_NUMA
        {
index 8ed81b2..0a8e5e5 100644 (file)
@@ -35,18 +35,6 @@ void ack_bad_irq(unsigned int irq)
        printk(KERN_ERR "Unexpected irq vector 0x%x on CPU %u!\n", irq, smp_processor_id());
 }
 
-#ifdef CONFIG_IA64_GENERIC
-ia64_vector __ia64_irq_to_vector(int irq)
-{
-       return irq_cfg[irq].vector;
-}
-
-unsigned int __ia64_local_vector_to_irq (ia64_vector vec)
-{
-       return __this_cpu_read(vector_irq[vec]);
-}
-#endif
-
 /*
  * Interrupt statistics:
  */
@@ -73,17 +61,6 @@ void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
                irq_redir[irq] = (char) (redir & 0xff);
        }
 }
-
-bool is_affinity_mask_valid(const struct cpumask *cpumask)
-{
-       if (ia64_platform_is("sn2")) {
-               /* Only allow one CPU to be specified in the smp_affinity mask */
-               if (cpumask_weight(cpumask) != 1)
-                       return false;
-       }
-       return true;
-}
-
 #endif /* CONFIG_SMP */
 
 int __init arch_early_irq_init(void)
index ab87d6c..f102084 100644 (file)
@@ -37,7 +37,6 @@
 #include <asm/intrinsics.h>
 #include <asm/io.h>
 #include <asm/hw_irq.h>
-#include <asm/machvec.h>
 #include <asm/pgtable.h>
 #include <asm/tlbflush.h>
 
@@ -53,7 +52,6 @@
 #define IRQ_USED               (1)
 #define IRQ_RSVD               (2)
 
-/* These can be overridden in platform_irq_init */
 int ia64_first_device_vector = IA64_DEF_FIRST_DEVICE_VECTOR;
 int ia64_last_device_vector = IA64_DEF_LAST_DEVICE_VECTOR;
 
@@ -250,7 +248,7 @@ void __setup_vector_irq(int cpu)
        }
 }
 
-#if defined(CONFIG_SMP) && (defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG))
+#ifdef CONFIG_SMP
 
 static enum vector_domain_type {
        VECTOR_DOMAIN_NONE,
@@ -314,7 +312,7 @@ void irq_complete_move(unsigned irq)
        cpumask_and(&cleanup_mask, &cfg->old_domain, cpu_online_mask);
        cfg->move_cleanup_count = cpumask_weight(&cleanup_mask);
        for_each_cpu(i, &cleanup_mask)
-               platform_send_ipi(i, IA64_IRQ_MOVE_VECTOR, IA64_IPI_DM_INT, 0);
+               ia64_send_ipi(i, IA64_IRQ_MOVE_VECTOR, IA64_IPI_DM_INT, 0);
        cfg->move_in_progress = 0;
 }
 
@@ -634,21 +632,16 @@ ia64_native_register_ipi(void)
 void __init
 init_IRQ (void)
 {
-#ifdef CONFIG_ACPI
        acpi_boot_init();
-#endif
        ia64_register_ipi();
        register_percpu_irq(IA64_SPURIOUS_INT_VECTOR, NULL);
 #ifdef CONFIG_SMP
-#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_DIG)
        if (vector_domain_type != VECTOR_DOMAIN_NONE)
                register_percpu_irq(IA64_IRQ_MOVE_VECTOR, &irq_move_irqaction);
 #endif
-#endif
 #ifdef CONFIG_PERFMON
        pfm_init_percpu();
 #endif
-       platform_irq_init();
 }
 
 void
index 5de801a..b8356ed 100644 (file)
@@ -979,32 +979,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
        return ret;
 }
 
-struct param_bsp_cfm {
-       unsigned long ip;
-       unsigned long *bsp;
-       unsigned long cfm;
-};
-
-static void ia64_get_bsp_cfm(struct unw_frame_info *info, void *arg)
-{
-       unsigned long ip;
-       struct param_bsp_cfm *lp = arg;
-
-       do {
-               unw_get_ip(info, &ip);
-               if (ip == 0)
-                       break;
-               if (ip == lp->ip) {
-                       unw_get_bsp(info, (unsigned long*)&lp->bsp);
-                       unw_get_cfm(info, (unsigned long*)&lp->cfm);
-                       return;
-               }
-       } while (unw_unwind(info) >= 0);
-       lp->bsp = NULL;
-       lp->cfm = 0;
-       return;
-}
-
 unsigned long arch_deref_entry_point(void *entry)
 {
        return ((struct fnptr *)entry)->ip;
index 3b1dd54..efc9b56 100644 (file)
@@ -127,7 +127,6 @@ static void ia64_machine_kexec(struct unw_frame_info *info, void *arg)
        ia64_srlz_d();
        while (ia64_get_ivr() != IA64_SPURIOUS_INT_VECTOR)
                ia64_eoi();
-       platform_kernel_launch_event();
        rnk = (relocate_new_kernel_t)&code_addr;
        (*rnk)(image->head, image->start, ia64_boot_param,
                     GRANULEROUNDDOWN((unsigned long) pal_addr));
diff --git a/arch/ia64/kernel/machvec.c b/arch/ia64/kernel/machvec.c
deleted file mode 100644 (file)
index ebd8253..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <asm/machvec.h>
-
-#ifdef CONFIG_IA64_GENERIC
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-
-#include <asm/page.h>
-
-struct ia64_machine_vector ia64_mv = {
-       .mmiowb = ___ia64_mmiowb
-};
-EXPORT_SYMBOL(ia64_mv);
-
-static struct ia64_machine_vector * __init
-lookup_machvec (const char *name)
-{
-       extern struct ia64_machine_vector machvec_start[];
-       extern struct ia64_machine_vector machvec_end[];
-       struct ia64_machine_vector *mv;
-
-       for (mv = machvec_start; mv < machvec_end; ++mv)
-               if (strcmp (mv->name, name) == 0)
-                       return mv;
-
-       return 0;
-}
-
-void __init
-machvec_init (const char *name)
-{
-       struct ia64_machine_vector *mv;
-
-       if (!name)
-               name = acpi_get_sysname();
-       mv = lookup_machvec(name);
-       if (!mv)
-               panic("generic kernel failed to find machine vector for"
-                     " platform %s!", name);
-
-       ia64_mv = *mv;
-       printk(KERN_INFO "booting generic kernel on platform %s\n", name);
-}
-
-void __init
-machvec_init_from_cmdline(const char *cmdline)
-{
-       char str[64];
-       const char *start;
-       char *end;
-
-       if (! (start = strstr(cmdline, "machvec=")) )
-               return machvec_init(NULL);
-
-       strlcpy(str, start + strlen("machvec="), sizeof(str));
-       if ( (end = strchr(str, ' ')) )
-               *end = '\0';
-
-       return machvec_init(str);
-}
-
-#endif /* CONFIG_IA64_GENERIC */
-
-void
-machvec_setup (char **arg)
-{
-}
-EXPORT_SYMBOL(machvec_setup);
-
-void
-machvec_timer_interrupt (int irq, void *dev_id)
-{
-}
-EXPORT_SYMBOL(machvec_timer_interrupt);
index 79190d8..bf2cb92 100644 (file)
@@ -91,7 +91,6 @@
 #include <linux/gfp.h>
 
 #include <asm/delay.h>
-#include <asm/machvec.h>
 #include <asm/meminit.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
@@ -149,9 +148,7 @@ static ia64_mc_info_t               ia64_mc_info;
 #define CPE_HISTORY_LENGTH    5
 #define CMC_HISTORY_LENGTH    5
 
-#ifdef CONFIG_ACPI
 static struct timer_list cpe_poll_timer;
-#endif
 static struct timer_list cmc_poll_timer;
 /*
  * This variable tells whether we are currently in polling mode.
@@ -532,8 +529,6 @@ int mca_recover_range(unsigned long addr)
 }
 EXPORT_SYMBOL_GPL(mca_recover_range);
 
-#ifdef CONFIG_ACPI
-
 int cpe_vector = -1;
 int ia64_cpe_irq = -1;
 
@@ -595,9 +590,6 @@ out:
        return IRQ_HANDLED;
 }
 
-#endif /* CONFIG_ACPI */
-
-#ifdef CONFIG_ACPI
 /*
  * ia64_mca_register_cpev
  *
@@ -625,7 +617,6 @@ ia64_mca_register_cpev (int cpev)
        IA64_MCA_DEBUG("%s: corrected platform error "
                       "vector %#x registered\n", __func__, cpev);
 }
-#endif /* CONFIG_ACPI */
 
 /*
  * ia64_mca_cmc_vector_setup
@@ -744,7 +735,7 @@ ia64_mca_cmc_vector_enable_keventd(struct work_struct *unused)
 static void
 ia64_mca_wakeup(int cpu)
 {
-       platform_send_ipi(cpu, IA64_MCA_WAKEUP_VECTOR, IA64_IPI_DM_INT, 0);
+       ia64_send_ipi(cpu, IA64_MCA_WAKEUP_VECTOR, IA64_IPI_DM_INT, 0);
 }
 
 /*
@@ -1490,7 +1481,7 @@ ia64_mca_cmc_int_caller(int cmc_irq, void *arg)
        cpuid = cpumask_next(cpuid+1, cpu_online_mask);
 
        if (cpuid < nr_cpu_ids) {
-               platform_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
+               ia64_send_ipi(cpuid, IA64_CMCP_VECTOR, IA64_IPI_DM_INT, 0);
        } else {
                /* If no log record, switch out of polling mode */
                if (start_count == IA64_LOG_COUNT(SAL_INFO_TYPE_CMC)) {
@@ -1523,7 +1514,7 @@ static void
 ia64_mca_cmc_poll (struct timer_list *unused)
 {
        /* Trigger a CMC interrupt cascade  */
-       platform_send_ipi(cpumask_first(cpu_online_mask), IA64_CMCP_VECTOR,
+       ia64_send_ipi(cpumask_first(cpu_online_mask), IA64_CMCP_VECTOR,
                                                        IA64_IPI_DM_INT, 0);
 }
 
@@ -1540,8 +1531,6 @@ ia64_mca_cmc_poll (struct timer_list *unused)
  * Outputs
  *     handled
  */
-#ifdef CONFIG_ACPI
-
 static irqreturn_t
 ia64_mca_cpe_int_caller(int cpe_irq, void *arg)
 {
@@ -1560,7 +1549,7 @@ ia64_mca_cpe_int_caller(int cpe_irq, void *arg)
        cpuid = cpumask_next(cpuid+1, cpu_online_mask);
 
        if (cpuid < NR_CPUS) {
-               platform_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
+               ia64_send_ipi(cpuid, IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
        } else {
                /*
                 * If a log was recorded, increase our polling frequency,
@@ -1600,12 +1589,10 @@ static void
 ia64_mca_cpe_poll (struct timer_list *unused)
 {
        /* Trigger a CPE interrupt cascade  */
-       platform_send_ipi(cpumask_first(cpu_online_mask), IA64_CPEP_VECTOR,
+       ia64_send_ipi(cpumask_first(cpu_online_mask), IA64_CPEP_VECTOR,
                                                        IA64_IPI_DM_INT, 0);
 }
 
-#endif /* CONFIG_ACPI */
-
 static int
 default_monarch_init_process(struct notifier_block *self, unsigned long val, void *data)
 {
@@ -1799,7 +1786,6 @@ static struct irqaction mca_wkup_irqaction = {
        .name =         "mca_wkup"
 };
 
-#ifdef CONFIG_ACPI
 static struct irqaction mca_cpe_irqaction = {
        .handler =      ia64_mca_cpe_int_handler,
        .name =         "cpe_hndlr"
@@ -1809,7 +1795,6 @@ static struct irqaction mca_cpep_irqaction = {
        .handler =      ia64_mca_cpe_int_caller,
        .name =         "cpe_poll"
 };
-#endif /* CONFIG_ACPI */
 
 /* Minimal format of the MCA/INIT stacks.  The pseudo processes that run on
  * these stacks can never sleep, they cannot return from the kernel to user
@@ -2081,10 +2066,8 @@ void __init ia64_mca_irq_init(void)
        /* Setup the MCA wakeup interrupt vector */
        register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction);
 
-#ifdef CONFIG_ACPI
        /* Setup the CPEI/P handler */
        register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
-#endif
 }
 
 /*
@@ -2112,7 +2095,6 @@ ia64_mca_late_init(void)
                          ia64_mca_cpu_online, NULL);
        IA64_MCA_DEBUG("%s: CMCI/P setup and enabled.\n", __func__);
 
-#ifdef CONFIG_ACPI
        /* Setup the CPEI/P vector and handler */
        cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
        timer_setup(&cpe_poll_timer, ia64_mca_cpe_poll, 0);
@@ -2143,7 +2125,6 @@ ia64_mca_late_init(void)
                        IA64_MCA_DEBUG("%s: CPEP setup and enabled.\n", __func__);
                }
        }
-#endif
 
        return 0;
 }
index cd7972e..4d0ab32 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/slab.h>
 
 #include <asm/delay.h>
-#include <asm/machvec.h>
 #include <asm/page.h>
 #include <asm/ptrace.h>
 #include <asm/sal.h>
index 326448f..1a42ba8 100644 (file)
@@ -914,10 +914,14 @@ module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mo
 void
 module_arch_cleanup (struct module *mod)
 {
-       if (mod->arch.init_unw_table)
+       if (mod->arch.init_unw_table) {
                unw_remove_unwind_table(mod->arch.init_unw_table);
-       if (mod->arch.core_unw_table)
+               mod->arch.init_unw_table = NULL;
+       }
+       if (mod->arch.core_unw_table) {
                unw_remove_unwind_table(mod->arch.core_unw_table);
+               mod->arch.core_unw_table = NULL;
+       }
 }
 
 void *dereference_module_function_descriptor(struct module *mod, void *ptr)
index 519d943..df5c28f 100644 (file)
@@ -43,7 +43,7 @@ static int ia64_set_msi_irq_affinity(struct irq_data *idata,
 }
 #endif /* CONFIG_SMP */
 
-int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
 {
        struct msi_msg  msg;
        unsigned long   dest_phys_id;
@@ -77,7 +77,7 @@ int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
        return 0;
 }
 
-void ia64_teardown_msi_irq(unsigned int irq)
+void arch_teardown_msi_irq(unsigned int irq)
 {
        destroy_irq(irq);
 }
@@ -111,23 +111,6 @@ static struct irq_chip ia64_msi_chip = {
        .irq_retrigger          = ia64_msi_retrigger_irq,
 };
 
-
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
-{
-       if (platform_setup_msi_irq)
-               return platform_setup_msi_irq(pdev, desc);
-
-       return ia64_setup_msi_irq(pdev, desc);
-}
-
-void arch_teardown_msi_irq(unsigned int irq)
-{
-       if (platform_teardown_msi_irq)
-               return platform_teardown_msi_irq(irq);
-
-       return ia64_teardown_msi_irq(irq);
-}
-
 #ifdef CONFIG_INTEL_IOMMU
 #ifdef CONFIG_SMP
 static int dmar_msi_set_affinity(struct irq_data *data,
index fe988c4..c902217 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/module.h>
 #include <linux/dmar.h>
 #include <asm/iommu.h>
-#include <asm/machvec.h>
 #include <linux/dma-mapping.h>
 #include <linux/kernel.h>
 #include <asm/page.h>
@@ -22,8 +21,6 @@ int force_iommu __read_mostly = 1;
 int force_iommu __read_mostly;
 #endif
 
-int iommu_pass_through;
-
 static int __init pci_iommu_init(void)
 {
        if (iommu_detected)
@@ -34,24 +31,3 @@ static int __init pci_iommu_init(void)
 
 /* Must execute after PCI subsystem */
 fs_initcall(pci_iommu_init);
-
-void __init pci_iommu_alloc(void)
-{
-       /*
-        * The order of these functions is important for
-        * fall-back/fail-over reasons
-        */
-       detect_intel_iommu();
-
-#ifdef CONFIG_SWIOTLB
-       if (!iommu_detected) {
-#ifdef CONFIG_IA64_GENERIC
-               printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n");
-               machvec_init("dig");
-               swiotlb_dma_init();
-#else
-               panic("Unable to find Intel IOMMU");
-#endif /* CONFIG_IA64_GENERIC */
-       }
-#endif /* CONFIG_SWIOTLB */
-}
index 9b2331a..c455ece 100644 (file)
@@ -110,13 +110,6 @@ check_versions (struct ia64_sal_systab *systab)
                sal_revision = SAL_VERSION_CODE(2, 8);
                sal_version = SAL_VERSION_CODE(0, 0);
        }
-
-       if (ia64_platform_is("sn2") && (sal_revision == SAL_VERSION_CODE(2, 9)))
-               /*
-                * SGI Altix has hard-coded version 2.9 in their prom
-                * but they actually implement 3.2, so let's fix it here.
-                */
-               sal_revision = SAL_VERSION_CODE(3, 2);
 }
 
 static void __init
@@ -256,7 +249,7 @@ check_sal_cache_flush (void)
         * Send ourselves a timer interrupt, wait until it's reported, and see
         * if SAL_CACHE_FLUSH drops it.
         */
-       platform_send_ipi(cpu, IA64_TIMER_VECTOR, IA64_IPI_DM_INT, 0);
+       ia64_send_ipi(cpu, IA64_TIMER_VECTOR, IA64_IPI_DM_INT, 0);
 
        while (!ia64_get_irr(IA64_TIMER_VECTOR))
                cpu_relax();
index c9cfa76..18de565 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/console.h>
 #include <linux/delay.h>
 #include <linux/cpu.h>
+#include <linux/kdev_t.h>
 #include <linux/kernel.h>
 #include <linux/memblock.h>
 #include <linux/reboot.h>
@@ -41,6 +42,7 @@
 #include <linux/threads.h>
 #include <linux/screen_info.h>
 #include <linux/dmi.h>
+#include <linux/root_dev.h>
 #include <linux/serial.h>
 #include <linux/serial_core.h>
 #include <linux/efi.h>
@@ -50,7 +52,6 @@
 #include <linux/kexec.h>
 #include <linux/crash_dump.h>
 
-#include <asm/machvec.h>
 #include <asm/mca.h>
 #include <asm/meminit.h>
 #include <asm/page.h>
 #include <asm/smp.h>
 #include <asm/tlbflush.h>
 #include <asm/unistd.h>
-#include <asm/hpsim.h>
+#include <asm/uv/uv.h>
 
 #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
 # error "struct cpuinfo_ia64 too big!"
 #endif
 
+char ia64_platform_name[64];
+
 #ifdef CONFIG_SMP
 unsigned long __per_cpu_offset[NR_CPUS];
 EXPORT_SYMBOL(__per_cpu_offset);
@@ -260,11 +263,11 @@ __initcall(register_memory);
  * in kdump case. See the comment in sba_init() in sba_iommu.c.
  *
  * So, the only machvec that really supports loading the kdump kernel
- * over 4 GB is "sn2".
+ * over 4 GB is "uv".
  */
 static int __init check_crashkernel_memory(unsigned long pbase, size_t size)
 {
-       if (ia64_platform_is("sn2") || ia64_platform_is("uv"))
+       if (is_uv_system())
                return 1;
        else
                return pbase < (1UL << 32);
@@ -461,23 +464,44 @@ io_port_init (void)
 static inline int __init
 early_console_setup (char *cmdline)
 {
-       int earlycons = 0;
-
-#ifdef CONFIG_SERIAL_SGI_L1_CONSOLE
-       {
-               extern int sn_serial_console_early_setup(void);
-               if (!sn_serial_console_early_setup())
-                       earlycons++;
-       }
-#endif
 #ifdef CONFIG_EFI_PCDP
        if (!efi_setup_pcdp_console(cmdline))
-               earlycons++;
+               return 0;
 #endif
-       if (!simcons_register())
-               earlycons++;
+       return -1;
+}
+
+static void __init
+screen_info_setup(void)
+{
+       unsigned int orig_x, orig_y, num_cols, num_rows, font_height;
+
+       memset(&screen_info, 0, sizeof(screen_info));
+
+       if (!ia64_boot_param->console_info.num_rows ||
+           !ia64_boot_param->console_info.num_cols) {
+               printk(KERN_WARNING "invalid screen-info, guessing 80x25\n");
+               orig_x = 0;
+               orig_y = 0;
+               num_cols = 80;
+               num_rows = 25;
+               font_height = 16;
+       } else {
+               orig_x = ia64_boot_param->console_info.orig_x;
+               orig_y = ia64_boot_param->console_info.orig_y;
+               num_cols = ia64_boot_param->console_info.num_cols;
+               num_rows = ia64_boot_param->console_info.num_rows;
+               font_height = 400 / num_rows;
+       }
 
-       return (earlycons) ? 0 : -1;
+       screen_info.orig_x = orig_x;
+       screen_info.orig_y = orig_y;
+       screen_info.orig_video_cols  = num_cols;
+       screen_info.orig_video_lines = num_rows;
+       screen_info.orig_video_points = font_height;
+       screen_info.orig_video_mode = 3;        /* XXX fake */
+       screen_info.orig_video_isVGA = 1;       /* XXX fake */
+       screen_info.orig_video_ega_bx = 3;      /* XXX fake */
 }
 
 static inline void
@@ -536,35 +560,25 @@ setup_arch (char **cmdline_p)
        efi_init();
        io_port_init();
 
-#ifdef CONFIG_IA64_GENERIC
-       /* machvec needs to be parsed from the command line
-        * before parse_early_param() is called to ensure
-        * that ia64_mv is initialised before any command line
-        * settings may cause console setup to occur
-        */
-       machvec_init_from_cmdline(*cmdline_p);
-#endif
-
+       uv_probe_system_type();
        parse_early_param();
 
        if (early_console_setup(*cmdline_p) == 0)
                mark_bsp_online();
 
-#ifdef CONFIG_ACPI
        /* Initialize the ACPI boot-time table parser */
        acpi_table_init();
        early_acpi_boot_init();
-# ifdef CONFIG_ACPI_NUMA
+#ifdef CONFIG_ACPI_NUMA
        acpi_numa_init();
        acpi_numa_fixup();
-#  ifdef CONFIG_ACPI_HOTPLUG_CPU
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
        prefill_possible_map();
-#  endif
+#endif
        per_cpu_scan_finalize((cpumask_weight(&early_cpu_possible_map) == 0 ?
                32 : cpumask_weight(&early_cpu_possible_map)),
                additional_cpus > 0 ? additional_cpus : 0);
-# endif
-#endif /* CONFIG_APCI_BOOT */
+#endif /* CONFIG_ACPI_NUMA */
 
 #ifdef CONFIG_SMP
        smp_build_cpu_map();
@@ -614,10 +628,21 @@ setup_arch (char **cmdline_p)
        if (!nomca)
                ia64_mca_init();
 
-       platform_setup(cmdline_p);
-#ifndef CONFIG_IA64_HP_SIM
-       check_sal_cache_flush();
+       /*
+        * Default to /dev/sda2.  This assumes that the EFI partition
+        * is physical disk 1 partition 1 and the Linux root disk is
+        * physical disk 1 partition 2.
+        */
+       ROOT_DEV = Root_SDA2;           /* default to second partition on first drive */
+
+       if (is_uv_system())
+               uv_setup(cmdline_p);
+#ifdef CONFIG_SMP
+       else
+               init_smp_config();
 #endif
+
+       screen_info_setup();
        paging_init();
 
        clear_sched_clock_stable();
@@ -1046,7 +1071,6 @@ cpu_init (void)
                ia64_patch_phys_stack_reg(num_phys_stacked*8 + 8);
                max_num_phys_stacked = num_phys_stacked;
        }
-       platform_cpu_init();
 }
 
 void __init
index e5044ae..d07ed65 100644 (file)
@@ -363,19 +363,19 @@ ia64_do_signal (struct sigscratch *scr, long in_syscall)
 
                if (unlikely(restart)) {
                        switch (errno) {
-                             case ERESTART_RESTARTBLOCK:
-                             case ERESTARTNOHAND:
+                       case ERESTART_RESTARTBLOCK:
+                       case ERESTARTNOHAND:
                                scr->pt.r8 = EINTR;
                                /* note: scr->pt.r10 is already -1 */
                                break;
-
-                             case ERESTARTSYS:
+                       case ERESTARTSYS:
                                if ((ksig.ka.sa.sa_flags & SA_RESTART) == 0) {
                                        scr->pt.r8 = EINTR;
                                        /* note: scr->pt.r10 is already -1 */
                                        break;
                                }
-                             case ERESTARTNOINTR:
+                               /*FALLTHRU*/
+                       case ERESTARTNOINTR:
                                ia64_decrement_ip(&scr->pt);
                                restart = 0; /* don't restart twice if handle_signal() fails... */
                        }
index 133b633..de35c54 100644 (file)
@@ -36,7 +36,6 @@
 #include <linux/atomic.h>
 #include <asm/current.h>
 #include <asm/delay.h>
-#include <asm/machvec.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/page.h>
@@ -146,7 +145,7 @@ static inline void
 send_IPI_single (int dest_cpu, int op)
 {
        set_bit(op, &per_cpu(ipi_operation, dest_cpu));
-       platform_send_ipi(dest_cpu, IA64_IPI_VECTOR, IA64_IPI_DM_INT, 0);
+       ia64_send_ipi(dest_cpu, IA64_IPI_VECTOR, IA64_IPI_DM_INT, 0);
 }
 
 /*
@@ -213,7 +212,7 @@ kdump_smp_send_init(void)
        for_each_online_cpu(cpu) {
                if (cpu != self_cpu) {
                        if(kdump_status[cpu] == 0)
-                               platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
+                               ia64_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
                }
        }
 }
@@ -224,7 +223,7 @@ kdump_smp_send_init(void)
 void
 smp_send_reschedule (int cpu)
 {
-       platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
+       ia64_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
 }
 EXPORT_SYMBOL_GPL(smp_send_reschedule);
 
@@ -234,7 +233,7 @@ EXPORT_SYMBOL_GPL(smp_send_reschedule);
 static void
 smp_send_local_flush_tlb (int cpu)
 {
-       platform_send_ipi(cpu, IA64_IPI_LOCAL_TLB_FLUSH, IA64_IPI_DM_INT, 0);
+       ia64_send_ipi(cpu, IA64_IPI_LOCAL_TLB_FLUSH, IA64_IPI_DM_INT, 0);
 }
 
 void
index d0474a0..6501d9a 100644 (file)
@@ -47,7 +47,6 @@
 #include <asm/delay.h>
 #include <asm/io.h>
 #include <asm/irq.h>
-#include <asm/machvec.h>
 #include <asm/mca.h>
 #include <asm/page.h>
 #include <asm/pgalloc.h>
@@ -57,7 +56,6 @@
 #include <asm/sal.h>
 #include <asm/tlbflush.h>
 #include <asm/unistd.h>
-#include <asm/sn/arch.h>
 
 #define SMP_DEBUG 0
 
@@ -468,7 +466,7 @@ do_boot_cpu (int sapicid, int cpu, struct task_struct *idle)
        Dprintk("Sending wakeup vector %lu to AP 0x%x/0x%x.\n", ap_wakeup_vector, cpu, sapicid);
 
        set_brendez_area(cpu);
-       platform_send_ipi(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0);
+       ia64_send_ipi(cpu, ap_wakeup_vector, IA64_IPI_DM_INT, 0);
 
        /*
         * Wait 10s total for the AP to start
@@ -658,11 +656,6 @@ int __cpu_disable(void)
                return (-EBUSY);
        }
 
-       if (ia64_platform_is("sn2")) {
-               if (!sn_cpu_disable_allowed(cpu))
-                       return -EBUSY;
-       }
-
        set_cpu_online(cpu, false);
 
        if (migrate_platform_irqs(cpu)) {
index 9ebe1d6..e14db25 100644 (file)
@@ -166,21 +166,3 @@ ia64_mremap (unsigned long addr, unsigned long old_len, unsigned long new_len, u
                force_successful_syscall_return();
        return addr;
 }
-
-#ifndef CONFIG_PCI
-
-asmlinkage long
-sys_pciconfig_read (unsigned long bus, unsigned long dfn, unsigned long off, unsigned long len,
-                   void *buf)
-{
-       return -ENOSYS;
-}
-
-asmlinkage long
-sys_pciconfig_write (unsigned long bus, unsigned long dfn, unsigned long off, unsigned long len,
-                    void *buf)
-{
-       return -ENOSYS;
-}
-
-#endif /* CONFIG_PCI */
index 4ecd81b..1e95d32 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/platform_device.h>
 #include <linux/sched/cputime.h>
 
-#include <asm/machvec.h>
 #include <asm/delay.h>
 #include <asm/hw_irq.h>
 #include <asm/ptrace.h>
@@ -167,8 +166,6 @@ timer_interrupt (int irq, void *dev_id)
                return IRQ_HANDLED;
        }
 
-       platform_timer_interrupt(irq, dev_id);
-
        new_itm = local_cpu_data->itm_next;
 
        if (!time_after(ia64_get_itc(), new_itm))
index e311ee1..09fc385 100644 (file)
@@ -42,7 +42,6 @@ EXPORT_SYMBOL_GPL(arch_fix_phys_package_id);
 #ifdef CONFIG_HOTPLUG_CPU
 int __ref arch_register_cpu(int num)
 {
-#ifdef CONFIG_ACPI
        /*
         * If CPEI can be re-targeted or if this is not
         * CPEI target, then it is hotpluggable
@@ -50,7 +49,6 @@ int __ref arch_register_cpu(int num)
        if (can_cpei_retarget() || !is_cpu_cpei_target(num))
                sysfs_cpus[num].cpu.hotpluggable = 1;
        map_cpu_to_node(num, node_cpuid[num].nid);
-#endif
        return register_cpu(&sysfs_cpus[num].cpu, num);
 }
 EXPORT_SYMBOL(arch_register_cpu);
@@ -58,9 +56,7 @@ EXPORT_SYMBOL(arch_register_cpu);
 void __ref arch_unregister_cpu(int num)
 {
        unregister_cpu(&sysfs_cpus[num].cpu);
-#ifdef CONFIG_ACPI
        unmap_cpu_from_node(num, cpu_to_node(num));
-#endif
 }
 EXPORT_SYMBOL(arch_unregister_cpu);
 #else
index eb7d5df..2d4e65b 100644 (file)
@@ -1431,7 +1431,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
                if (u.insn.x)
                        /* oops, really a semaphore op (cmpxchg, etc) */
                        goto failure;
-               /* no break */
+               /*FALLTHRU*/
              case LDS_IMM_OP:
              case LDSA_IMM_OP:
              case LDFS_OP:
@@ -1459,7 +1459,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
                if (u.insn.x)
                        /* oops, really a semaphore op (cmpxchg, etc) */
                        goto failure;
-               /* no break */
+               /*FALLTHRU*/
              case LD_IMM_OP:
              case LDA_IMM_OP:
              case LDBIAS_IMM_OP:
@@ -1475,7 +1475,7 @@ ia64_handle_unaligned (unsigned long ifa, struct pt_regs *regs)
                if (u.insn.x)
                        /* oops, really a semaphore op (cmpxchg, etc) */
                        goto failure;
-               /* no break */
+               /*FALLTHRU*/
              case ST_IMM_OP:
              case STREL_IMM_OP:
                ret = emulate_store_int(ifa, u.insn, regs);
index 16c6d37..3776ef2 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/pgtable.h>
 #include <linux/atomic.h>
 #include <asm/tlbflush.h>
-#include <asm/sn/arch.h>
 
 
 extern void __init efi_memmap_walk_uc(efi_freemem_callback_t, void *);
@@ -129,10 +128,7 @@ static int uncached_add_chunk(struct uncached_pool *uc_pool, int nid)
 
        preempt_disable();
 
-       if (ia64_platform_is("sn2"))
-               sn_flush_all_caches(uc_addr, IA64_GRANULE_SIZE);
-       else
-               flush_icache_range(uc_addr, uc_addr + IA64_GRANULE_SIZE);
+       flush_icache_range(uc_addr, uc_addr + IA64_GRANULE_SIZE);
 
        /* flush the just introduced uncached translation from the TLB */
        local_flush_tlb_all();
index 0da58cf..d9d4e21 100644 (file)
@@ -141,16 +141,6 @@ SECTIONS {
                __end___mckinley_e9_bundles = .;
        }
 
-#if defined(CONFIG_IA64_GENERIC)
-       /* Machine Vector */
-       . = ALIGN(16);
-       .machvec : AT(ADDR(.machvec) - LOAD_OFFSET) {
-               machvec_start = .;
-               *(.machvec)
-               machvec_end = .;
-       }
-#endif
-
 #ifdef CONFIG_SMP
        . = ALIGN(PERCPU_PAGE_SIZE);
        __cpu0_per_cpu = .;
index d107eaf..c3e0246 100644 (file)
@@ -49,117 +49,3 @@ void memset_io(volatile void __iomem *dst, int c, long count)
        }
 }
 EXPORT_SYMBOL(memset_io);
-
-#ifdef CONFIG_IA64_GENERIC
-
-#undef __ia64_inb
-#undef __ia64_inw
-#undef __ia64_inl
-#undef __ia64_outb
-#undef __ia64_outw
-#undef __ia64_outl
-#undef __ia64_readb
-#undef __ia64_readw
-#undef __ia64_readl
-#undef __ia64_readq
-#undef __ia64_readb_relaxed
-#undef __ia64_readw_relaxed
-#undef __ia64_readl_relaxed
-#undef __ia64_readq_relaxed
-#undef __ia64_writeb
-#undef __ia64_writew
-#undef __ia64_writel
-#undef __ia64_writeq
-#undef __ia64_mmiowb
-
-unsigned int
-__ia64_inb (unsigned long port)
-{
-       return ___ia64_inb(port);
-}
-
-unsigned int
-__ia64_inw (unsigned long port)
-{
-       return ___ia64_inw(port);
-}
-
-unsigned int
-__ia64_inl (unsigned long port)
-{
-       return ___ia64_inl(port);
-}
-
-void
-__ia64_outb (unsigned char val, unsigned long port)
-{
-       ___ia64_outb(val, port);
-}
-
-void
-__ia64_outw (unsigned short val, unsigned long port)
-{
-       ___ia64_outw(val, port);
-}
-
-void
-__ia64_outl (unsigned int val, unsigned long port)
-{
-       ___ia64_outl(val, port);
-}
-
-unsigned char
-__ia64_readb (void __iomem *addr)
-{
-       return ___ia64_readb (addr);
-}
-
-unsigned short
-__ia64_readw (void __iomem *addr)
-{
-       return ___ia64_readw (addr);
-}
-
-unsigned int
-__ia64_readl (void __iomem *addr)
-{
-       return ___ia64_readl (addr);
-}
-
-unsigned long
-__ia64_readq (void __iomem *addr)
-{
-       return ___ia64_readq (addr);
-}
-
-unsigned char
-__ia64_readb_relaxed (void __iomem *addr)
-{
-       return ___ia64_readb (addr);
-}
-
-unsigned short
-__ia64_readw_relaxed (void __iomem *addr)
-{
-       return ___ia64_readw (addr);
-}
-
-unsigned int
-__ia64_readl_relaxed (void __iomem *addr)
-{
-       return ___ia64_readl (addr);
-}
-
-unsigned long
-__ia64_readq_relaxed (void __iomem *addr)
-{
-       return ___ia64_readq (addr);
-}
-
-void
-__ia64_mmiowb(void)
-{
-       ___ia64_mmiowb();
-}
-
-#endif /* CONFIG_IA64_GENERIC */
index 05490dd..921f3ef 100644 (file)
@@ -396,8 +396,7 @@ static void __meminit scatter_node_data(void)
  *
  * Each node's per-node area has a copy of the global pg_data_t list, so
  * we copy that to each node here, as well as setting the per-cpu pointer
- * to the local node data structure.  The active_cpus field of the per-node
- * structure gets setup by the platform_cpu_init() function later.
+ * to the local node data structure.
  */
 static void __init initialize_pernode_data(void)
 {
index aae75fd..678b98a 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/init.h>
 
 #include <linux/dma-noncoherent.h>
+#include <linux/dmar.h>
 #include <linux/efi.h>
 #include <linux/elf.h>
 #include <linux/memblock.h>
 #include <linux/proc_fs.h>
 #include <linux/bitops.h>
 #include <linux/kexec.h>
+#include <linux/swiotlb.h>
 
 #include <asm/dma.h>
 #include <asm/io.h>
-#include <asm/machvec.h>
 #include <asm/numa.h>
 #include <asm/patch.h>
 #include <asm/pgalloc.h>
@@ -67,7 +68,6 @@ __ia64_sync_icache_dcache (pte_t pte)
        set_bit(PG_arch_1, &page->flags);       /* mark page as clean */
 }
 
-#ifdef CONFIG_SWIOTLB
 /*
  * Since DMA is i-cache coherent, any (complete) pages that were written via
  * DMA can be marked as "clean" so that lazy_mmu_prot_update() doesn't have to
@@ -82,7 +82,6 @@ void arch_sync_dma_for_cpu(struct device *dev, phys_addr_t paddr,
                set_bit(PG_arch_1, &pfn_to_page(pfn)->flags);
        } while (++pfn <= PHYS_PFN(paddr + size - 1));
 }
-#endif
 
 inline void
 ia64_set_rbs_bot (void)
@@ -632,13 +631,17 @@ mem_init (void)
        BUG_ON(PTRS_PER_PMD * sizeof(pmd_t) != PAGE_SIZE);
        BUG_ON(PTRS_PER_PTE * sizeof(pte_t) != PAGE_SIZE);
 
-#ifdef CONFIG_PCI
        /*
-        * This needs to be called _after_ the command line has been parsed but _before_
-        * any drivers that may need the PCI DMA interface are initialized or bootmem has
-        * been freed.
+        * This needs to be called _after_ the command line has been parsed but
+        * _before_ any drivers that may need the PCI DMA interface are
+        * initialized or bootmem has been freed.
         */
-       platform_dma_init();
+#ifdef CONFIG_INTEL_IOMMU
+       detect_intel_iommu();
+       if (!iommu_detected)
+#endif
+#ifdef CONFIG_SWIOTLB
+               swiotlb_init(1);
 #endif
 
 #ifdef CONFIG_FLATMEM
index 0714df1..72cc568 100644 (file)
@@ -245,7 +245,8 @@ resetsema:
        spinaphore_init(&ptcg_sem, max_purges);
 }
 
-void
+#ifdef CONFIG_SMP
+static void
 ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
                       unsigned long end, unsigned long nbits)
 {
@@ -282,6 +283,7 @@ ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
                 activate_context(active_mm);
         }
 }
+#endif /* CONFIG_SMP */
 
 void
 local_flush_tlb_all (void)
@@ -332,7 +334,7 @@ __flush_tlb_range (struct vm_area_struct *vma, unsigned long start,
        preempt_disable();
 #ifdef CONFIG_SMP
        if (mm != current->active_mm || cpumask_weight(mm_cpumask(mm)) != 1) {
-               platform_global_tlb_purge(mm, start, end, nbits);
+               ia64_global_tlb_purge(mm, start, end, nbits);
                preempt_enable();
                return;
        }
index e1fa45b..acb55a4 100644 (file)
@@ -8,8 +8,7 @@
 #include <linux/init.h>
 #include <linux/vgaarb.h>
 #include <linux/screen_info.h>
-
-#include <asm/machvec.h>
+#include <asm/uv/uv.h>
 
 /*
  * Fixup to mark boot BIOS video selected by BIOS before it changes
@@ -35,8 +34,7 @@ static void pci_fixup_video(struct pci_dev *pdev)
        u16 config;
        struct resource *res;
 
-       if ((strcmp(ia64_platform_name, "dig") != 0)
-           && (strcmp(ia64_platform_name, "hpzx1")  != 0))
+       if (is_uv_system())
                return;
        /* Maybe, this machine supports legacy memory map. */
 
index 165e561..211757e 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/memblock.h>
 #include <linux/export.h>
 
-#include <asm/machvec.h>
 #include <asm/page.h>
 #include <asm/io.h>
 #include <asm/sal.h>
@@ -372,7 +371,6 @@ void pcibios_fixup_bus(struct pci_bus *b)
        }
        list_for_each_entry(dev, &b->devices, bus_list)
                pcibios_fixup_device_resources(dev);
-       platform_pci_fixup_bus(b);
 }
 
 void pcibios_add_bus(struct pci_bus *bus)
@@ -413,7 +411,7 @@ pcibios_disable_device (struct pci_dev *dev)
 }
 
 /**
- * ia64_pci_get_legacy_mem - generic legacy mem routine
+ * pci_get_legacy_mem - generic legacy mem routine
  * @bus: bus to get legacy memory base address for
  *
  * Find the base of legacy memory for @bus.  This is typically the first
@@ -424,7 +422,7 @@ pcibios_disable_device (struct pci_dev *dev)
  * This is the ia64 generic version of this routine.  Other platforms
  * are free to override it with a machine vector.
  */
-char *ia64_pci_get_legacy_mem(struct pci_bus *bus)
+char *pci_get_legacy_mem(struct pci_bus *bus)
 {
        return (char *)__IA64_UNCACHED_OFFSET;
 }
@@ -473,7 +471,7 @@ pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma,
 }
 
 /**
- * ia64_pci_legacy_read - read from legacy I/O space
+ * pci_legacy_read - read from legacy I/O space
  * @bus: bus to read
  * @port: legacy port value
  * @val: caller allocated storage for returned value
@@ -485,7 +483,7 @@ pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma,
  * overridden by the platform.  This is necessary on platforms that don't
  * support legacy I/O routing or that hard fail on legacy I/O timeouts.
  */
-int ia64_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
+int pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
 {
        int ret = size;
 
@@ -508,7 +506,7 @@ int ia64_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
 }
 
 /**
- * ia64_pci_legacy_write - perform a legacy I/O write
+ * pci_legacy_write - perform a legacy I/O write
  * @bus: bus pointer
  * @port: port to write
  * @val: value to write
@@ -516,7 +514,7 @@ int ia64_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
  *
  * Simply writes @size bytes of @val to @port.
  */
-int ia64_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
+int pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
 {
        int ret = size;
 
diff --git a/arch/ia64/sn/Makefile b/arch/ia64/sn/Makefile
deleted file mode 100644 (file)
index 79a7df0..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-# arch/ia64/sn/Makefile
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 2004 Silicon Graphics, Inc.  All Rights Reserved.
-#
-# Makefile for the sn ia64 subplatform
-#
-
-obj-y += kernel/ pci/
diff --git a/arch/ia64/sn/include/ioerror.h b/arch/ia64/sn/include/ioerror.h
deleted file mode 100644 (file)
index e68f2b0..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_IOERROR_H
-#define _ASM_IA64_SN_IOERROR_H
-
-/*
- * IO error structure.
- *
- * This structure would expand to hold the information retrieved from
- * all IO related error registers.
- *
- * This structure is defined to hold all system specific
- * information related to a single error.
- *
- * This serves a couple of purpose.
- *      - Error handling often involves translating one form of address to other
- *        form. So, instead of having different data structures at each level,
- *        we have a single structure, and the appropriate fields get filled in
- *        at each layer.
- *      - This provides a way to dump all error related information in any layer
- *        of erorr handling (debugging aid).
- *
- * A second possibility is to allow each layer to define its own error
- * data structure, and fill in the proper fields. This has the advantage
- * of isolating the layers.
- * A big concern is the potential stack usage (and overflow), if each layer
- * defines these structures on stack (assuming we don't want to do kmalloc.
- *
- * Any layer wishing to pass extra information to a layer next to it in
- * error handling hierarchy, can do so as a separate parameter.
- */
-
-typedef struct io_error_s {
-    /* Bit fields indicating which structure fields are valid */
-    union {
-       struct {
-           unsigned                ievb_errortype:1;
-           unsigned                ievb_widgetnum:1;
-           unsigned                ievb_widgetdev:1;
-           unsigned                ievb_srccpu:1;
-           unsigned                ievb_srcnode:1;
-           unsigned                ievb_errnode:1;
-           unsigned                ievb_sysioaddr:1;
-           unsigned                ievb_xtalkaddr:1;
-           unsigned                ievb_busspace:1;
-           unsigned                ievb_busaddr:1;
-           unsigned                ievb_vaddr:1;
-           unsigned                ievb_memaddr:1;
-           unsigned                ievb_epc:1;
-           unsigned                ievb_ef:1;
-           unsigned                ievb_tnum:1;
-       } iev_b;
-       unsigned                iev_a;
-    } ie_v;
-
-    short                   ie_errortype;      /* error type: extra info about error */
-    short                   ie_widgetnum;      /* Widget number that's in error */
-    short                   ie_widgetdev;      /* Device within widget in error */
-    cpuid_t                 ie_srccpu; /* CPU on srcnode generating error */
-    cnodeid_t               ie_srcnode;                /* Node which caused the error   */
-    cnodeid_t               ie_errnode;                /* Node where error was noticed  */
-    iopaddr_t               ie_sysioaddr;      /* Sys specific IO address       */
-    iopaddr_t               ie_xtalkaddr;      /* Xtalk (48bit) addr of Error   */
-    iopaddr_t               ie_busspace;       /* Bus specific address space    */
-    iopaddr_t               ie_busaddr;                /* Bus specific address          */
-    caddr_t                 ie_vaddr;  /* Virtual address of error      */
-    iopaddr_t               ie_memaddr;                /* Physical memory address       */
-    caddr_t                ie_epc;             /* pc when error reported        */
-    caddr_t                ie_ef;              /* eframe when error reported    */
-    short                  ie_tnum;            /* Xtalk TNUM field */
-} ioerror_t;
-
-#define        IOERROR_INIT(e)         do { (e)->ie_v.iev_a = 0; } while (0)
-#define        IOERROR_SETVALUE(e,f,v) do { (e)->ie_ ## f = (v); (e)->ie_v.iev_b.ievb_ ## f = 1; } while (0)
-
-#endif /* _ASM_IA64_SN_IOERROR_H */
diff --git a/arch/ia64/sn/include/tio.h b/arch/ia64/sn/include/tio.h
deleted file mode 100644 (file)
index 6b2e7b7..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_TIO_H
-#define _ASM_IA64_SN_TIO_H
-
-#define        TIO_MMR_ADDR_MOD
-
-#define TIO_NODE_ID     TIO_MMR_ADDR_MOD(0x0000000090060e80)
-
-#define TIO_ITTE_BASE   0xb0008800        /* base of translation table entries */
-#define TIO_ITTE(bigwin)        (TIO_ITTE_BASE + 8*(bigwin))
-
-#define TIO_ITTE_OFFSET_BITS    8       /* size of offset field */
-#define TIO_ITTE_OFFSET_MASK    ((1<<TIO_ITTE_OFFSET_BITS)-1)
-#define TIO_ITTE_OFFSET_SHIFT   0
-
-#define TIO_ITTE_WIDGET_BITS    2       /* size of widget field */
-#define TIO_ITTE_WIDGET_MASK    ((1<<TIO_ITTE_WIDGET_BITS)-1)
-#define TIO_ITTE_WIDGET_SHIFT   12
-#define TIO_ITTE_VALID_MASK    0x1
-#define TIO_ITTE_VALID_SHIFT   16
-
-#define TIO_ITTE_WIDGET(itte) \
-       (((itte) >> TIO_ITTE_WIDGET_SHIFT) & TIO_ITTE_WIDGET_MASK)
-#define TIO_ITTE_VALID(itte) \
-       (((itte) >> TIO_ITTE_VALID_SHIFT) & TIO_ITTE_VALID_MASK)
-
-#define TIO_ITTE_PUT(nasid, bigwin, widget, addr, valid) \
-        REMOTE_HUB_S((nasid), TIO_ITTE(bigwin), \
-                (((((addr) >> TIO_BWIN_SIZE_BITS) & \
-                   TIO_ITTE_OFFSET_MASK) << TIO_ITTE_OFFSET_SHIFT) | \
-                (((widget) & TIO_ITTE_WIDGET_MASK) << TIO_ITTE_WIDGET_SHIFT)) | \
-               (( (valid) & TIO_ITTE_VALID_MASK) << TIO_ITTE_VALID_SHIFT))
-
-#endif /*  _ASM_IA64_SN_TIO_H */
diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h
deleted file mode 100644 (file)
index 8182583..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_XTALK_HUBDEV_H
-#define _ASM_IA64_SN_XTALK_HUBDEV_H
-
-#include "xtalk/xwidgetdev.h"
-
-#define HUB_WIDGET_ID_MAX 0xf
-#define DEV_PER_WIDGET (2*2*8)
-#define IIO_ITTE_WIDGET_BITS    4       /* size of widget field */
-#define IIO_ITTE_WIDGET_MASK    ((1<<IIO_ITTE_WIDGET_BITS)-1)
-#define IIO_ITTE_WIDGET_SHIFT   8
-
-#define IIO_ITTE_WIDGET(itte)  \
-       (((itte) >> IIO_ITTE_WIDGET_SHIFT) & IIO_ITTE_WIDGET_MASK)
-
-/*
- * Use the top big window as a surrogate for the first small window
- */
-#define SWIN0_BIGWIN            HUB_NUM_BIG_WINDOW
-#define IIO_NUM_ITTES   7
-#define HUB_NUM_BIG_WINDOW      (IIO_NUM_ITTES - 1)
-
-/* This struct is shared between the PROM and the kernel.
- * Changes to this struct will require corresponding changes to the kernel.
- */
-struct sn_flush_device_common {
-       int sfdl_bus;
-       int sfdl_slot;
-       int sfdl_pin;
-       struct common_bar_list {
-               unsigned long start;
-               unsigned long end;
-       } sfdl_bar_list[6];
-       unsigned long sfdl_force_int_addr;
-       unsigned long sfdl_flush_value;
-       volatile unsigned long *sfdl_flush_addr;
-       u32 sfdl_persistent_busnum;
-       u32 sfdl_persistent_segment;
-       struct pcibus_info *sfdl_pcibus_info;
-};
-
-/* This struct is kernel only and is not used by the PROM */
-struct sn_flush_device_kernel {
-       spinlock_t sfdl_flush_lock;
-       struct sn_flush_device_common *common;
-};
-
-/* 01/16/06 This struct is the old PROM/kernel struct and needs to be included
- * for older official PROMs to function on the new kernel base.  This struct
- * will be removed when the next official PROM release occurs. */
-
-struct sn_flush_device_war {
-       struct sn_flush_device_common common;
-       u32 filler; /* older PROMs expect the default size of a spinlock_t */
-};
-
-/*
- * **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel.
- */
-struct sn_flush_nasid_entry  {
-       struct sn_flush_device_kernel **widget_p; // Used as an array of wid_num
-       u64 iio_itte[8];
-};
-
-struct hubdev_info {
-       geoid_t                         hdi_geoid;
-       short                           hdi_nasid;
-       short                           hdi_peer_nasid;   /* Dual Porting Peer */
-
-       struct sn_flush_nasid_entry     hdi_flush_nasid_list;
-       struct xwidget_info             hdi_xwidget_info[HUB_WIDGET_ID_MAX + 1];
-
-
-       void                            *hdi_nodepda;
-       void                            *hdi_node_vertex;
-       u32                             max_segment_number;
-       u32                             max_pcibus_number;
-};
-
-extern void hubdev_init_node(nodepda_t *, cnodeid_t);
-extern void hub_error_init(struct hubdev_info *);
-extern void ice_error_init(struct hubdev_info *);
-
-
-#endif /* _ASM_IA64_SN_XTALK_HUBDEV_H */
diff --git a/arch/ia64/sn/include/xtalk/xbow.h b/arch/ia64/sn/include/xtalk/xbow.h
deleted file mode 100644 (file)
index 90f37a4..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2006 Silicon Graphics, Inc. All Rights
- * Reserved.
- */
-#ifndef _ASM_IA64_SN_XTALK_XBOW_H
-#define _ASM_IA64_SN_XTALK_XBOW_H
-
-#define XBOW_PORT_8    0x8
-#define XBOW_PORT_C    0xc
-#define XBOW_PORT_F    0xf
-
-#define MAX_XBOW_PORTS 8       /* number of ports on xbow chip */
-#define BASE_XBOW_PORT XBOW_PORT_8     /* Lowest external port */
-
-#define        XBOW_CREDIT     4
-
-#define MAX_XBOW_NAME  16
-
-/* Register set for each xbow link */
-typedef volatile struct xb_linkregs_s {
-/*
- * we access these through synergy unswizzled space, so the address
- * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.)
- * That's why we put the register first and filler second.
- */
-       u32 link_ibf;
-       u32 filler0;    /* filler for proper alignment */
-       u32 link_control;
-       u32 filler1;
-       u32 link_status;
-       u32 filler2;
-       u32 link_arb_upper;
-       u32 filler3;
-       u32 link_arb_lower;
-       u32 filler4;
-       u32 link_status_clr;
-       u32 filler5;
-       u32 link_reset;
-       u32 filler6;
-       u32 link_aux_status;
-       u32 filler7;
-} xb_linkregs_t;
-
-typedef volatile struct xbow_s {
-       /* standard widget configuration 0x000000-0x000057 */
-       struct widget_cfg xb_widget;  /* 0x000000 */
-
-       /* helper fieldnames for accessing bridge widget */
-
-#define xb_wid_id              xb_widget.w_id
-#define xb_wid_stat            xb_widget.w_status
-#define xb_wid_err_upper       xb_widget.w_err_upper_addr
-#define xb_wid_err_lower       xb_widget.w_err_lower_addr
-#define xb_wid_control         xb_widget.w_control
-#define xb_wid_req_timeout     xb_widget.w_req_timeout
-#define xb_wid_int_upper       xb_widget.w_intdest_upper_addr
-#define xb_wid_int_lower       xb_widget.w_intdest_lower_addr
-#define xb_wid_err_cmdword     xb_widget.w_err_cmd_word
-#define xb_wid_llp             xb_widget.w_llp_cfg
-#define xb_wid_stat_clr        xb_widget.w_tflush
-
-/*
- * we access these through synergy unswizzled space, so the address
- * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.)
- * That's why we put the register first and filler second.
- */
-       /* xbow-specific widget configuration    0x000058-0x0000FF */
-       u32 xb_wid_arb_reload; /* 0x00005C */
-       u32 _pad_000058;
-       u32 xb_perf_ctr_a;      /* 0x000064 */
-       u32 _pad_000060;
-       u32 xb_perf_ctr_b;      /* 0x00006c */
-       u32 _pad_000068;
-       u32 xb_nic;             /* 0x000074 */
-       u32 _pad_000070;
-
-       /* Xbridge only */
-       u32 xb_w0_rst_fnc;      /* 0x00007C */
-       u32 _pad_000078;
-       u32 xb_l8_rst_fnc;      /* 0x000084 */
-       u32 _pad_000080;
-       u32 xb_l9_rst_fnc;      /* 0x00008c */
-       u32 _pad_000088;
-       u32 xb_la_rst_fnc;      /* 0x000094 */
-       u32 _pad_000090;
-       u32 xb_lb_rst_fnc;      /* 0x00009c */
-       u32 _pad_000098;
-       u32 xb_lc_rst_fnc;      /* 0x0000a4 */
-       u32 _pad_0000a0;
-       u32 xb_ld_rst_fnc;      /* 0x0000ac */
-       u32 _pad_0000a8;
-       u32 xb_le_rst_fnc;      /* 0x0000b4 */
-       u32 _pad_0000b0;
-       u32 xb_lf_rst_fnc;      /* 0x0000bc */
-       u32 _pad_0000b8;
-       u32 xb_lock;            /* 0x0000c4 */
-       u32 _pad_0000c0;
-       u32 xb_lock_clr;        /* 0x0000cc */
-       u32 _pad_0000c8;
-       /* end of Xbridge only */
-       u32 _pad_0000d0[12];
-
-       /* Link Specific Registers, port 8..15   0x000100-0x000300 */
-       xb_linkregs_t xb_link_raw[MAX_XBOW_PORTS];
-} xbow_t;
-
-#define xb_link(p) xb_link_raw[(p) & (MAX_XBOW_PORTS - 1)]
-
-#define XB_FLAGS_EXISTS                0x1     /* device exists */
-#define XB_FLAGS_MASTER                0x2
-#define XB_FLAGS_SLAVE         0x0
-#define XB_FLAGS_GBR           0x4
-#define XB_FLAGS_16BIT         0x8
-#define XB_FLAGS_8BIT          0x0
-
-/* is widget port number valid?  (based on version 7.0 of xbow spec) */
-#define XBOW_WIDGET_IS_VALID(wid) ((wid) >= XBOW_PORT_8 && (wid) <= XBOW_PORT_F)
-
-/* whether to use upper or lower arbitration register, given source widget id */
-#define XBOW_ARB_IS_UPPER(wid)         ((wid) >= XBOW_PORT_8 && (wid) <= XBOW_PORT_B)
-#define XBOW_ARB_IS_LOWER(wid)         ((wid) >= XBOW_PORT_C && (wid) <= XBOW_PORT_F)
-
-/* offset of arbitration register, given source widget id */
-#define XBOW_ARB_OFF(wid)      (XBOW_ARB_IS_UPPER(wid) ? 0x1c : 0x24)
-
-#define        XBOW_WID_ID             WIDGET_ID
-#define        XBOW_WID_STAT           WIDGET_STATUS
-#define        XBOW_WID_ERR_UPPER      WIDGET_ERR_UPPER_ADDR
-#define        XBOW_WID_ERR_LOWER      WIDGET_ERR_LOWER_ADDR
-#define        XBOW_WID_CONTROL        WIDGET_CONTROL
-#define        XBOW_WID_REQ_TO         WIDGET_REQ_TIMEOUT
-#define        XBOW_WID_INT_UPPER      WIDGET_INTDEST_UPPER_ADDR
-#define        XBOW_WID_INT_LOWER      WIDGET_INTDEST_LOWER_ADDR
-#define        XBOW_WID_ERR_CMDWORD    WIDGET_ERR_CMD_WORD
-#define        XBOW_WID_LLP            WIDGET_LLP_CFG
-#define        XBOW_WID_STAT_CLR       WIDGET_TFLUSH
-#define XBOW_WID_ARB_RELOAD    0x5c
-#define XBOW_WID_PERF_CTR_A    0x64
-#define XBOW_WID_PERF_CTR_B    0x6c
-#define XBOW_WID_NIC           0x74
-
-/* Xbridge only */
-#define XBOW_W0_RST_FNC                0x00007C
-#define        XBOW_L8_RST_FNC         0x000084
-#define        XBOW_L9_RST_FNC         0x00008c
-#define        XBOW_LA_RST_FNC         0x000094
-#define        XBOW_LB_RST_FNC         0x00009c
-#define        XBOW_LC_RST_FNC         0x0000a4
-#define        XBOW_LD_RST_FNC         0x0000ac
-#define        XBOW_LE_RST_FNC         0x0000b4
-#define        XBOW_LF_RST_FNC         0x0000bc
-#define XBOW_RESET_FENCE(x) ((x) > 7 && (x) < 16) ? \
-                               (XBOW_W0_RST_FNC + ((x) - 7) * 8) : \
-                               ((x) == 0) ? XBOW_W0_RST_FNC : 0
-#define XBOW_LOCK              0x0000c4
-#define XBOW_LOCK_CLR          0x0000cc
-/* End of Xbridge only */
-
-/* used only in ide, but defined here within the reserved portion */
-/* of the widget0 address space (before 0xf4) */
-#define        XBOW_WID_UNDEF          0xe4
-
-/* xbow link register set base, legal value for x is 0x8..0xf */
-#define        XB_LINK_BASE            0x100
-#define        XB_LINK_OFFSET          0x40
-#define        XB_LINK_REG_BASE(x)     (XB_LINK_BASE + ((x) & (MAX_XBOW_PORTS - 1)) * XB_LINK_OFFSET)
-
-#define        XB_LINK_IBUF_FLUSH(x)   (XB_LINK_REG_BASE(x) + 0x4)
-#define        XB_LINK_CTRL(x)         (XB_LINK_REG_BASE(x) + 0xc)
-#define        XB_LINK_STATUS(x)       (XB_LINK_REG_BASE(x) + 0x14)
-#define        XB_LINK_ARB_UPPER(x)    (XB_LINK_REG_BASE(x) + 0x1c)
-#define        XB_LINK_ARB_LOWER(x)    (XB_LINK_REG_BASE(x) + 0x24)
-#define        XB_LINK_STATUS_CLR(x)   (XB_LINK_REG_BASE(x) + 0x2c)
-#define        XB_LINK_RESET(x)        (XB_LINK_REG_BASE(x) + 0x34)
-#define        XB_LINK_AUX_STATUS(x)   (XB_LINK_REG_BASE(x) + 0x3c)
-
-/* link_control(x) */
-#define        XB_CTRL_LINKALIVE_IE            0x80000000      /* link comes alive */
-/* reserved:                   0x40000000 */
-#define        XB_CTRL_PERF_CTR_MODE_MSK       0x30000000      /* perf counter mode */
-#define        XB_CTRL_IBUF_LEVEL_MSK          0x0e000000      /* input packet buffer
-                                                          level */
-#define        XB_CTRL_8BIT_MODE               0x01000000      /* force link into 8
-                                                          bit mode */
-#define XB_CTRL_BAD_LLP_PKT            0x00800000      /* force bad LLP
-                                                          packet */
-#define XB_CTRL_WIDGET_CR_MSK          0x007c0000      /* LLP widget credit
-                                                          mask */
-#define XB_CTRL_WIDGET_CR_SHFT 18                      /* LLP widget credit
-                                                          shift */
-#define XB_CTRL_ILLEGAL_DST_IE         0x00020000      /* illegal destination
-                                                        */
-#define XB_CTRL_OALLOC_IBUF_IE         0x00010000      /* overallocated input
-                                                          buffer */
-/* reserved:                   0x0000fe00 */
-#define XB_CTRL_BNDWDTH_ALLOC_IE       0x00000100      /* bandwidth alloc */
-#define XB_CTRL_RCV_CNT_OFLOW_IE       0x00000080      /* rcv retry overflow */
-#define XB_CTRL_XMT_CNT_OFLOW_IE       0x00000040      /* xmt retry overflow */
-#define XB_CTRL_XMT_MAX_RTRY_IE                0x00000020      /* max transmit retry */
-#define XB_CTRL_RCV_IE                 0x00000010      /* receive */
-#define XB_CTRL_XMT_RTRY_IE            0x00000008      /* transmit retry */
-/* reserved:                   0x00000004 */
-#define        XB_CTRL_MAXREQ_TOUT_IE          0x00000002      /* maximum request
-                                                          timeout */
-#define        XB_CTRL_SRC_TOUT_IE             0x00000001      /* source timeout */
-
-/* link_status(x) */
-#define        XB_STAT_LINKALIVE               XB_CTRL_LINKALIVE_IE
-/* reserved:                   0x7ff80000 */
-#define        XB_STAT_MULTI_ERR               0x00040000      /* multi error */
-#define        XB_STAT_ILLEGAL_DST_ERR         XB_CTRL_ILLEGAL_DST_IE
-#define        XB_STAT_OALLOC_IBUF_ERR         XB_CTRL_OALLOC_IBUF_IE
-#define        XB_STAT_BNDWDTH_ALLOC_ID_MSK    0x0000ff00      /* port bitmask */
-#define        XB_STAT_RCV_CNT_OFLOW_ERR       XB_CTRL_RCV_CNT_OFLOW_IE
-#define        XB_STAT_XMT_CNT_OFLOW_ERR       XB_CTRL_XMT_CNT_OFLOW_IE
-#define        XB_STAT_XMT_MAX_RTRY_ERR        XB_CTRL_XMT_MAX_RTRY_IE
-#define        XB_STAT_RCV_ERR                 XB_CTRL_RCV_IE
-#define        XB_STAT_XMT_RTRY_ERR            XB_CTRL_XMT_RTRY_IE
-/* reserved:                   0x00000004 */
-#define        XB_STAT_MAXREQ_TOUT_ERR         XB_CTRL_MAXREQ_TOUT_IE
-#define        XB_STAT_SRC_TOUT_ERR            XB_CTRL_SRC_TOUT_IE
-
-/* link_aux_status(x) */
-#define        XB_AUX_STAT_RCV_CNT     0xff000000
-#define        XB_AUX_STAT_XMT_CNT     0x00ff0000
-#define        XB_AUX_STAT_TOUT_DST    0x0000ff00
-#define        XB_AUX_LINKFAIL_RST_BAD 0x00000040
-#define        XB_AUX_STAT_PRESENT     0x00000020
-#define        XB_AUX_STAT_PORT_WIDTH  0x00000010
-/*     reserved:               0x0000000f */
-
-/*
- * link_arb_upper/link_arb_lower(x), (reg) should be the link_arb_upper
- * register if (x) is 0x8..0xb, link_arb_lower if (x) is 0xc..0xf
- */
-#define        XB_ARB_GBR_MSK          0x1f
-#define        XB_ARB_RR_MSK           0x7
-#define        XB_ARB_GBR_SHFT(x)      (((x) & 0x3) * 8)
-#define        XB_ARB_RR_SHFT(x)       (((x) & 0x3) * 8 + 5)
-#define        XB_ARB_GBR_CNT(reg,x)   ((reg) >> XB_ARB_GBR_SHFT(x) & XB_ARB_GBR_MSK)
-#define        XB_ARB_RR_CNT(reg,x)    ((reg) >> XB_ARB_RR_SHFT(x) & XB_ARB_RR_MSK)
-
-/* XBOW_WID_STAT */
-#define        XB_WID_STAT_LINK_INTR_SHFT      (24)
-#define        XB_WID_STAT_LINK_INTR_MASK      (0xFF << XB_WID_STAT_LINK_INTR_SHFT)
-#define        XB_WID_STAT_LINK_INTR(x) \
-       (0x1 << (((x)&7) + XB_WID_STAT_LINK_INTR_SHFT))
-#define        XB_WID_STAT_WIDGET0_INTR        0x00800000
-#define XB_WID_STAT_SRCID_MASK         0x000003c0      /* Xbridge only */
-#define        XB_WID_STAT_REG_ACC_ERR         0x00000020
-#define XB_WID_STAT_RECV_TOUT          0x00000010      /* Xbridge only */
-#define XB_WID_STAT_ARB_TOUT           0x00000008      /* Xbridge only */
-#define        XB_WID_STAT_XTALK_ERR           0x00000004
-#define XB_WID_STAT_DST_TOUT           0x00000002      /* Xbridge only */
-#define        XB_WID_STAT_MULTI_ERR           0x00000001
-
-#define XB_WID_STAT_SRCID_SHFT         6
-
-/* XBOW_WID_CONTROL */
-#define XB_WID_CTRL_REG_ACC_IE         XB_WID_STAT_REG_ACC_ERR
-#define XB_WID_CTRL_RECV_TOUT          XB_WID_STAT_RECV_TOUT
-#define XB_WID_CTRL_ARB_TOUT           XB_WID_STAT_ARB_TOUT
-#define XB_WID_CTRL_XTALK_IE           XB_WID_STAT_XTALK_ERR
-
-/* XBOW_WID_INT_UPPER */
-/* defined in xwidget.h for WIDGET_INTDEST_UPPER_ADDR */
-
-/* XBOW WIDGET part number, in the ID register */
-#define XBOW_WIDGET_PART_NUM   0x0             /* crossbow */
-#define XXBOW_WIDGET_PART_NUM  0xd000          /* Xbridge */
-#define        XBOW_WIDGET_MFGR_NUM    0x0
-#define        XXBOW_WIDGET_MFGR_NUM   0x0
-#define PXBOW_WIDGET_PART_NUM   0xd100         /* PIC */
-
-#define        XBOW_REV_1_0            0x1     /* xbow rev 1.0 is "1" */
-#define        XBOW_REV_1_1            0x2     /* xbow rev 1.1 is "2" */
-#define XBOW_REV_1_2           0x3     /* xbow rev 1.2 is "3" */
-#define XBOW_REV_1_3           0x4     /* xbow rev 1.3 is "4" */
-#define XBOW_REV_2_0           0x5     /* xbow rev 2.0 is "5" */
-
-#define XXBOW_PART_REV_1_0             (XXBOW_WIDGET_PART_NUM << 4 | 0x1 )
-#define XXBOW_PART_REV_2_0             (XXBOW_WIDGET_PART_NUM << 4 | 0x2 )
-
-/* XBOW_WID_ARB_RELOAD */
-#define        XBOW_WID_ARB_RELOAD_INT 0x3f    /* GBR reload interval */
-
-#define IS_XBRIDGE_XBOW(wid) \
-       (XWIDGET_PART_NUM(wid) == XXBOW_WIDGET_PART_NUM && \
-       XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM)
-
-#define IS_PIC_XBOW(wid) \
-       (XWIDGET_PART_NUM(wid) == PXBOW_WIDGET_PART_NUM && \
-       XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM)
-
-#define XBOW_WAR_ENABLED(pv, widid) ((1 << XWIDGET_REV_NUM(widid)) & pv)
-
-#endif /* _ASM_IA64_SN_XTALK_XBOW_H */
diff --git a/arch/ia64/sn/include/xtalk/xwidgetdev.h b/arch/ia64/sn/include/xtalk/xwidgetdev.h
deleted file mode 100644 (file)
index 2800eda..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All Rights Reserved.
- */
-#ifndef _ASM_IA64_SN_XTALK_XWIDGET_H
-#define _ASM_IA64_SN_XTALK_XWIDGET_H
-
-/* WIDGET_ID */
-#define WIDGET_REV_NUM                  0xf0000000
-#define WIDGET_PART_NUM                 0x0ffff000
-#define WIDGET_MFG_NUM                  0x00000ffe
-#define WIDGET_REV_NUM_SHFT             28
-#define WIDGET_PART_NUM_SHFT            12
-#define WIDGET_MFG_NUM_SHFT             1
-
-#define XWIDGET_PART_NUM(widgetid) (((widgetid) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT)
-#define XWIDGET_REV_NUM(widgetid) (((widgetid) & WIDGET_REV_NUM) >> WIDGET_REV_NUM_SHFT)
-#define XWIDGET_MFG_NUM(widgetid) (((widgetid) & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT)
-#define XWIDGET_PART_REV_NUM(widgetid) ((XWIDGET_PART_NUM(widgetid) << 4) | \
-                                        XWIDGET_REV_NUM(widgetid))
-#define XWIDGET_PART_REV_NUM_REV(partrev) (partrev & 0xf)
-
-/* widget configuration registers */
-struct widget_cfg{
-       u32     w_id;   /* 0x04 */
-       u32     w_pad_0;        /* 0x00 */
-       u32     w_status;       /* 0x0c */
-       u32     w_pad_1;        /* 0x08 */
-       u32     w_err_upper_addr;       /* 0x14 */
-       u32     w_pad_2;        /* 0x10 */
-       u32     w_err_lower_addr;       /* 0x1c */
-       u32     w_pad_3;        /* 0x18 */
-       u32     w_control;      /* 0x24 */
-       u32     w_pad_4;        /* 0x20 */
-       u32     w_req_timeout;  /* 0x2c */
-       u32     w_pad_5;        /* 0x28 */
-       u32     w_intdest_upper_addr;   /* 0x34 */
-       u32     w_pad_6;        /* 0x30 */
-       u32     w_intdest_lower_addr;   /* 0x3c */
-       u32     w_pad_7;        /* 0x38 */
-       u32     w_err_cmd_word; /* 0x44 */
-       u32     w_pad_8;        /* 0x40 */
-       u32     w_llp_cfg;      /* 0x4c */
-       u32     w_pad_9;        /* 0x48 */
-       u32     w_tflush;       /* 0x54 */
-       u32     w_pad_10;       /* 0x50 */
-};
-
-/*
- * Crosstalk Widget Hardware Identification, as defined in the Crosstalk spec.
- */
-struct xwidget_hwid{
-       int             mfg_num;
-       int             rev_num;
-       int             part_num;
-};
-
-struct xwidget_info{
-
-       struct xwidget_hwid     xwi_hwid;       /* Widget Identification */
-       char                    xwi_masterxid;  /* Hub's Widget Port Number */
-       void                    *xwi_hubinfo;     /* Hub's provider private info */
-       u64                     *xwi_hub_provider; /* prom provider functions */
-       void                    *xwi_vertex;
-};
-
-#endif                          /* _ASM_IA64_SN_XTALK_XWIDGET_H */
diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile
deleted file mode 100644 (file)
index 9c349dd..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-# arch/ia64/sn/kernel/Makefile
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1999,2001-2006,2008 Silicon Graphics, Inc.  All Rights Reserved.
-#
-
-ccflags-y := -I $(srctree)/arch/ia64/sn/include
-
-obj-y                          += setup.o bte.o bte_error.o irq.o mca.o idle.o \
-                                  huberror.o io_acpi_init.o io_common.o \
-                                  io_init.o iomv.o klconflib.o pio_phys.o \
-                                  sn2/
-obj-$(CONFIG_IA64_GENERIC)      += machvec.o
-obj-$(CONFIG_SGI_TIOCX)                += tiocx.o
-obj-$(CONFIG_PCI_MSI)          += msi_sn.o
diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
deleted file mode 100644 (file)
index 9900e6d..0000000
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2000-2007 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/module.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/pda.h>
-#include <asm/sn/shubio.h>
-#include <asm/nodedata.h>
-#include <asm/delay.h>
-
-#include <linux/memblock.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-
-#include <asm/sn/bte.h>
-
-#ifndef L1_CACHE_MASK
-#define L1_CACHE_MASK (L1_CACHE_BYTES - 1)
-#endif
-
-/* two interfaces on two btes */
-#define MAX_INTERFACES_TO_TRY          4
-#define MAX_NODES_TO_TRY               2
-
-static struct bteinfo_s *bte_if_on_node(nasid_t nasid, int interface)
-{
-       nodepda_t *tmp_nodepda;
-
-       if (nasid_to_cnodeid(nasid) == -1)
-               return (struct bteinfo_s *)NULL;
-
-       tmp_nodepda = NODEPDA(nasid_to_cnodeid(nasid));
-       return &tmp_nodepda->bte_if[interface];
-
-}
-
-static inline void bte_start_transfer(struct bteinfo_s *bte, u64 len, u64 mode)
-{
-       if (is_shub2()) {
-               BTE_CTRL_STORE(bte, (IBLS_BUSY | ((len) | (mode) << 24)));
-       } else {
-               BTE_LNSTAT_STORE(bte, len);
-               BTE_CTRL_STORE(bte, mode);
-       }
-}
-
-/************************************************************************
- * Block Transfer Engine copy related functions.
- *
- ***********************************************************************/
-
-/*
- * bte_copy(src, dest, len, mode, notification)
- *
- * Use the block transfer engine to move kernel memory from src to dest
- * using the assigned mode.
- *
- * Parameters:
- *   src - physical address of the transfer source.
- *   dest - physical address of the transfer destination.
- *   len - number of bytes to transfer from source to dest.
- *   mode - hardware defined.  See reference information
- *          for IBCT0/1 in the SHUB Programmers Reference
- *   notification - kernel virtual address of the notification cache
- *                  line.  If NULL, the default is used and
- *                  the bte_copy is synchronous.
- *
- * NOTE:  This function requires src, dest, and len to
- * be cacheline aligned.
- */
-bte_result_t bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
-{
-       u64 transfer_size;
-       u64 transfer_stat;
-       u64 notif_phys_addr;
-       struct bteinfo_s *bte;
-       bte_result_t bte_status;
-       unsigned long irq_flags;
-       unsigned long itc_end = 0;
-       int nasid_to_try[MAX_NODES_TO_TRY];
-       int my_nasid = cpuid_to_nasid(raw_smp_processor_id());
-       int bte_if_index, nasid_index;
-       int bte_first, btes_per_node = BTES_PER_NODE;
-
-       BTE_PRINTK(("bte_copy(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%p)\n",
-                   src, dest, len, mode, notification));
-
-       if (len == 0) {
-               return BTE_SUCCESS;
-       }
-
-       BUG_ON(len & L1_CACHE_MASK);
-       BUG_ON(src & L1_CACHE_MASK);
-       BUG_ON(dest & L1_CACHE_MASK);
-       BUG_ON(len > BTE_MAX_XFER);
-
-       /*
-        * Start with interface corresponding to cpu number
-        */
-       bte_first = raw_smp_processor_id() % btes_per_node;
-
-       if (mode & BTE_USE_DEST) {
-               /* try remote then local */
-               nasid_to_try[0] = NASID_GET(dest);
-               if (mode & BTE_USE_ANY) {
-                       nasid_to_try[1] = my_nasid;
-               } else {
-                       nasid_to_try[1] = 0;
-               }
-       } else {
-               /* try local then remote */
-               nasid_to_try[0] = my_nasid;
-               if (mode & BTE_USE_ANY) {
-                       nasid_to_try[1] = NASID_GET(dest);
-               } else {
-                       nasid_to_try[1] = 0;
-               }
-       }
-
-retry_bteop:
-       do {
-               local_irq_save(irq_flags);
-
-               bte_if_index = bte_first;
-               nasid_index = 0;
-
-               /* Attempt to lock one of the BTE interfaces. */
-               while (nasid_index < MAX_NODES_TO_TRY) {
-                       bte = bte_if_on_node(nasid_to_try[nasid_index],bte_if_index);
-
-                       if (bte == NULL) {
-                               nasid_index++;
-                               continue;
-                       }
-
-                       if (spin_trylock(&bte->spinlock)) {
-                               if (!(*bte->most_rcnt_na & BTE_WORD_AVAILABLE) ||
-                                   (BTE_LNSTAT_LOAD(bte) & BTE_ACTIVE)) {
-                                       /* Got the lock but BTE still busy */
-                                       spin_unlock(&bte->spinlock);
-                               } else {
-                                       /* we got the lock and it's not busy */
-                                       break;
-                               }
-                       }
-
-                       bte_if_index = (bte_if_index + 1) % btes_per_node; /* Next interface */
-                       if (bte_if_index == bte_first) {
-                               /*
-                                * We've tried all interfaces on this node
-                                */
-                               nasid_index++;
-                       }
-
-                       bte = NULL;
-               }
-
-               if (bte != NULL) {
-                       break;
-               }
-
-               local_irq_restore(irq_flags);
-
-               if (!(mode & BTE_WACQUIRE)) {
-                       return BTEFAIL_NOTAVAIL;
-               }
-       } while (1);
-
-       if (notification == NULL) {
-               /* User does not want to be notified. */
-               bte->most_rcnt_na = &bte->notify;
-       } else {
-               bte->most_rcnt_na = notification;
-       }
-
-       /* Calculate the number of cache lines to transfer. */
-       transfer_size = ((len >> L1_CACHE_SHIFT) & BTE_LEN_MASK);
-
-       /* Initialize the notification to a known value. */
-       *bte->most_rcnt_na = BTE_WORD_BUSY;
-       notif_phys_addr = (u64)bte->most_rcnt_na;
-
-       /* Set the source and destination registers */
-       BTE_PRINTKV(("IBSA = 0x%lx)\n", src));
-       BTE_SRC_STORE(bte, src);
-       BTE_PRINTKV(("IBDA = 0x%lx)\n", dest));
-       BTE_DEST_STORE(bte, dest);
-
-       /* Set the notification register */
-       BTE_PRINTKV(("IBNA = 0x%lx)\n", notif_phys_addr));
-       BTE_NOTIF_STORE(bte, notif_phys_addr);
-
-       /* Initiate the transfer */
-       BTE_PRINTK(("IBCT = 0x%lx)\n", BTE_VALID_MODE(mode)));
-       bte_start_transfer(bte, transfer_size, BTE_VALID_MODE(mode));
-
-       itc_end = ia64_get_itc() + (40000000 * local_cpu_data->cyc_per_usec);
-
-       spin_unlock_irqrestore(&bte->spinlock, irq_flags);
-
-       if (notification != NULL) {
-               return BTE_SUCCESS;
-       }
-
-       while ((transfer_stat = *bte->most_rcnt_na) == BTE_WORD_BUSY) {
-               cpu_relax();
-               if (ia64_get_itc() > itc_end) {
-                       BTE_PRINTK(("BTE timeout nasid 0x%x bte%d IBLS = 0x%lx na 0x%lx\n",
-                               NASID_GET(bte->bte_base_addr), bte->bte_num,
-                               BTE_LNSTAT_LOAD(bte), *bte->most_rcnt_na) );
-                       bte->bte_error_count++;
-                       bte->bh_error = IBLS_ERROR;
-                       bte_error_handler(NODEPDA(bte->bte_cnode));
-                       *bte->most_rcnt_na = BTE_WORD_AVAILABLE;
-                       goto retry_bteop;
-               }
-       }
-
-       BTE_PRINTKV((" Delay Done.  IBLS = 0x%lx, most_rcnt_na = 0x%lx\n",
-                    BTE_LNSTAT_LOAD(bte), *bte->most_rcnt_na));
-
-       if (transfer_stat & IBLS_ERROR) {
-               bte_status = BTE_GET_ERROR_STATUS(transfer_stat);
-       } else {
-               bte_status = BTE_SUCCESS;
-       }
-       *bte->most_rcnt_na = BTE_WORD_AVAILABLE;
-
-       BTE_PRINTK(("Returning status is 0x%lx and most_rcnt_na is 0x%lx\n",
-                   BTE_LNSTAT_LOAD(bte), *bte->most_rcnt_na));
-
-       return bte_status;
-}
-
-EXPORT_SYMBOL(bte_copy);
-
-/*
- * bte_unaligned_copy(src, dest, len, mode)
- *
- * use the block transfer engine to move kernel
- * memory from src to dest using the assigned mode.
- *
- * Parameters:
- *   src - physical address of the transfer source.
- *   dest - physical address of the transfer destination.
- *   len - number of bytes to transfer from source to dest.
- *   mode - hardware defined.  See reference information
- *          for IBCT0/1 in the SGI documentation.
- *
- * NOTE: If the source, dest, and len are all cache line aligned,
- * then it would be _FAR_ preferable to use bte_copy instead.
- */
-bte_result_t bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
-{
-       int destFirstCacheOffset;
-       u64 headBteSource;
-       u64 headBteLen;
-       u64 headBcopySrcOffset;
-       u64 headBcopyDest;
-       u64 headBcopyLen;
-       u64 footBteSource;
-       u64 footBteLen;
-       u64 footBcopyDest;
-       u64 footBcopyLen;
-       bte_result_t rv;
-       char *bteBlock, *bteBlock_unaligned;
-
-       if (len == 0) {
-               return BTE_SUCCESS;
-       }
-
-       /* temporary buffer used during unaligned transfers */
-       bteBlock_unaligned = kmalloc(len + 3 * L1_CACHE_BYTES, GFP_KERNEL);
-       if (bteBlock_unaligned == NULL) {
-               return BTEFAIL_NOTAVAIL;
-       }
-       bteBlock = (char *)L1_CACHE_ALIGN((u64) bteBlock_unaligned);
-
-       headBcopySrcOffset = src & L1_CACHE_MASK;
-       destFirstCacheOffset = dest & L1_CACHE_MASK;
-
-       /*
-        * At this point, the transfer is broken into
-        * (up to) three sections.  The first section is
-        * from the start address to the first physical
-        * cache line, the second is from the first physical
-        * cache line to the last complete cache line,
-        * and the third is from the last cache line to the
-        * end of the buffer.  The first and third sections
-        * are handled by bte copying into a temporary buffer
-        * and then bcopy'ing the necessary section into the
-        * final location.  The middle section is handled with
-        * a standard bte copy.
-        *
-        * One nasty exception to the above rule is when the
-        * source and destination are not symmetrically
-        * mis-aligned.  If the source offset from the first
-        * cache line is different from the destination offset,
-        * we make the first section be the entire transfer
-        * and the bcopy the entire block into place.
-        */
-       if (headBcopySrcOffset == destFirstCacheOffset) {
-
-               /*
-                * Both the source and destination are the same
-                * distance from a cache line boundary so we can
-                * use the bte to transfer the bulk of the
-                * data.
-                */
-               headBteSource = src & ~L1_CACHE_MASK;
-               headBcopyDest = dest;
-               if (headBcopySrcOffset) {
-                       headBcopyLen =
-                           (len >
-                            (L1_CACHE_BYTES -
-                             headBcopySrcOffset) ? L1_CACHE_BYTES
-                            - headBcopySrcOffset : len);
-                       headBteLen = L1_CACHE_BYTES;
-               } else {
-                       headBcopyLen = 0;
-                       headBteLen = 0;
-               }
-
-               if (len > headBcopyLen) {
-                       footBcopyLen = (len - headBcopyLen) & L1_CACHE_MASK;
-                       footBteLen = L1_CACHE_BYTES;
-
-                       footBteSource = src + len - footBcopyLen;
-                       footBcopyDest = dest + len - footBcopyLen;
-
-                       if (footBcopyDest == (headBcopyDest + headBcopyLen)) {
-                               /*
-                                * We have two contiguous bcopy
-                                * blocks.  Merge them.
-                                */
-                               headBcopyLen += footBcopyLen;
-                               headBteLen += footBteLen;
-                       } else if (footBcopyLen > 0) {
-                               rv = bte_copy(footBteSource,
-                                             ia64_tpa((unsigned long)bteBlock),
-                                             footBteLen, mode, NULL);
-                               if (rv != BTE_SUCCESS) {
-                                       kfree(bteBlock_unaligned);
-                                       return rv;
-                               }
-
-                               memcpy(__va(footBcopyDest),
-                                      (char *)bteBlock, footBcopyLen);
-                       }
-               } else {
-                       footBcopyLen = 0;
-                       footBteLen = 0;
-               }
-
-               if (len > (headBcopyLen + footBcopyLen)) {
-                       /* now transfer the middle. */
-                       rv = bte_copy((src + headBcopyLen),
-                                     (dest +
-                                      headBcopyLen),
-                                     (len - headBcopyLen -
-                                      footBcopyLen), mode, NULL);
-                       if (rv != BTE_SUCCESS) {
-                               kfree(bteBlock_unaligned);
-                               return rv;
-                       }
-
-               }
-       } else {
-
-               /*
-                * The transfer is not symmetric, we will
-                * allocate a buffer large enough for all the
-                * data, bte_copy into that buffer and then
-                * bcopy to the destination.
-                */
-
-               headBcopySrcOffset = src & L1_CACHE_MASK;
-               headBcopyDest = dest;
-               headBcopyLen = len;
-
-               headBteSource = src - headBcopySrcOffset;
-               /* Add the leading and trailing bytes from source */
-               headBteLen = L1_CACHE_ALIGN(len + headBcopySrcOffset);
-       }
-
-       if (headBcopyLen > 0) {
-               rv = bte_copy(headBteSource,
-                             ia64_tpa((unsigned long)bteBlock), headBteLen,
-                             mode, NULL);
-               if (rv != BTE_SUCCESS) {
-                       kfree(bteBlock_unaligned);
-                       return rv;
-               }
-
-               memcpy(__va(headBcopyDest), ((char *)bteBlock +
-                                            headBcopySrcOffset), headBcopyLen);
-       }
-       kfree(bteBlock_unaligned);
-       return BTE_SUCCESS;
-}
-
-EXPORT_SYMBOL(bte_unaligned_copy);
-
-/************************************************************************
- * Block Transfer Engine initialization functions.
- *
- ***********************************************************************/
-static void bte_recovery_timeout(struct timer_list *t)
-{
-       struct nodepda_s *nodepda = from_timer(nodepda, t, bte_recovery_timer);
-
-       bte_error_handler(nodepda);
-}
-
-/*
- * bte_init_node(nodepda, cnode)
- *
- * Initialize the nodepda structure with BTE base addresses and
- * spinlocks.
- */
-void bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode)
-{
-       int i;
-
-       /*
-        * Indicate that all the block transfer engines on this node
-        * are available.
-        */
-
-       /*
-        * Allocate one bte_recover_t structure per node.  It holds
-        * the recovery lock for node.  All the bte interface structures
-        * will point at this one bte_recover structure to get the lock.
-        */
-       spin_lock_init(&mynodepda->bte_recovery_lock);
-       timer_setup(&mynodepda->bte_recovery_timer, bte_recovery_timeout, 0);
-
-       for (i = 0; i < BTES_PER_NODE; i++) {
-               u64 *base_addr;
-
-               /* Which link status register should we use? */
-               base_addr = (u64 *)
-                   REMOTE_HUB_ADDR(cnodeid_to_nasid(cnode), BTE_BASE_ADDR(i));
-               mynodepda->bte_if[i].bte_base_addr = base_addr;
-               mynodepda->bte_if[i].bte_source_addr = BTE_SOURCE_ADDR(base_addr);
-               mynodepda->bte_if[i].bte_destination_addr = BTE_DEST_ADDR(base_addr);
-               mynodepda->bte_if[i].bte_control_addr = BTE_CTRL_ADDR(base_addr);
-               mynodepda->bte_if[i].bte_notify_addr = BTE_NOTIF_ADDR(base_addr);
-
-               /*
-                * Initialize the notification and spinlock
-                * so the first transfer can occur.
-                */
-               mynodepda->bte_if[i].most_rcnt_na =
-                   &(mynodepda->bte_if[i].notify);
-               mynodepda->bte_if[i].notify = BTE_WORD_AVAILABLE;
-               spin_lock_init(&mynodepda->bte_if[i].spinlock);
-
-               mynodepda->bte_if[i].bte_cnode = cnode;
-               mynodepda->bte_if[i].bte_error_count = 0;
-               mynodepda->bte_if[i].bte_num = i;
-               mynodepda->bte_if[i].cleanup_active = 0;
-               mynodepda->bte_if[i].bh_error = 0;
-       }
-
-}
diff --git a/arch/ia64/sn/kernel/bte_error.c b/arch/ia64/sn/kernel/bte_error.c
deleted file mode 100644 (file)
index d92786c..0000000
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2000-2007 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/types.h>
-#include <asm/sn/sn_sal.h>
-#include "ioerror.h"
-#include <asm/sn/addrs.h>
-#include <asm/sn/shubio.h>
-#include <asm/sn/geo.h>
-#include "xtalk/xwidgetdev.h"
-#include "xtalk/hubdev.h"
-#include <asm/sn/bte.h>
-#include <asm/param.h>
-
-/*
- * Bte error handling is done in two parts.  The first captures
- * any crb related errors.  Since there can be multiple crbs per
- * interface and multiple interfaces active, we need to wait until
- * all active crbs are completed.  This is the first job of the
- * second part error handler.  When all bte related CRBs are cleanly
- * completed, it resets the interfaces and gets them ready for new
- * transfers to be queued.
- */
-
-/*
- * Wait until all BTE related CRBs are completed
- * and then reset the interfaces.
- */
-static int shub1_bte_error_handler(struct nodepda_s *err_nodepda)
-{
-       struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer;
-       nasid_t nasid;
-       int i;
-       int valid_crbs;
-       ii_imem_u_t imem;       /* II IMEM Register */
-       ii_icrb0_d_u_t icrbd;   /* II CRB Register D */
-       ii_ibcr_u_t ibcr;
-       ii_icmr_u_t icmr;
-       ii_ieclr_u_t ieclr;
-
-       BTE_PRINTK(("shub1_bte_error_handler(%p) - %d\n", err_nodepda,
-                   smp_processor_id()));
-
-       if ((err_nodepda->bte_if[0].bh_error == BTE_SUCCESS) &&
-           (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) {
-               BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda,
-                           smp_processor_id()));
-               return 1;
-       }
-
-       /* Determine information about our hub */
-       nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode);
-
-       /*
-        * A BTE transfer can use multiple CRBs.  We need to make sure
-        * that all the BTE CRBs are complete (or timed out) before
-        * attempting to clean up the error.  Resetting the BTE while
-        * there are still BTE CRBs active will hang the BTE.
-        * We should look at all the CRBs to see if they are allocated
-        * to the BTE and see if they are still active.  When none
-        * are active, we can continue with the cleanup.
-        *
-        * We also want to make sure that the local NI port is up.
-        * When a router resets the NI port can go down, while it
-        * goes through the LLP handshake, but then comes back up.
-        */
-       icmr.ii_icmr_regval = REMOTE_HUB_L(nasid, IIO_ICMR);
-       if (icmr.ii_icmr_fld_s.i_crb_mark != 0) {
-               /*
-                * There are errors which still need to be cleaned up by
-                * hubiio_crb_error_handler
-                */
-               mod_timer(recovery_timer, jiffies + (HZ * 5));
-               BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
-                           smp_processor_id()));
-               return 1;
-       }
-       if (icmr.ii_icmr_fld_s.i_crb_vld != 0) {
-
-               valid_crbs = icmr.ii_icmr_fld_s.i_crb_vld;
-
-               for (i = 0; i < IIO_NUM_CRBS; i++) {
-                       if (!((1 << i) & valid_crbs)) {
-                               /* This crb was not marked as valid, ignore */
-                               continue;
-                       }
-                       icrbd.ii_icrb0_d_regval =
-                           REMOTE_HUB_L(nasid, IIO_ICRB_D(i));
-                       if (icrbd.d_bteop) {
-                               mod_timer(recovery_timer, jiffies + (HZ * 5));
-                               BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n",
-                                           err_nodepda, smp_processor_id(),
-                                           i));
-                               return 1;
-                       }
-               }
-       }
-
-       BTE_PRINTK(("eh:%p:%d Cleaning up\n", err_nodepda, smp_processor_id()));
-       /* Re-enable both bte interfaces */
-       imem.ii_imem_regval = REMOTE_HUB_L(nasid, IIO_IMEM);
-       imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1;
-       REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval);
-
-       /* Clear BTE0/1 error bits */
-       ieclr.ii_ieclr_regval = 0;
-       if (err_nodepda->bte_if[0].bh_error != BTE_SUCCESS)
-               ieclr.ii_ieclr_fld_s.i_e_bte_0 = 1;
-       if (err_nodepda->bte_if[1].bh_error != BTE_SUCCESS)
-               ieclr.ii_ieclr_fld_s.i_e_bte_1 = 1;
-       REMOTE_HUB_S(nasid, IIO_IECLR, ieclr.ii_ieclr_regval);
-
-       /* Reinitialize both BTE state machines. */
-       ibcr.ii_ibcr_regval = REMOTE_HUB_L(nasid, IIO_IBCR);
-       ibcr.ii_ibcr_fld_s.i_soft_reset = 1;
-       REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval);
-
-       del_timer(recovery_timer);
-       return 0;
-}
-
-/*
- * Wait until all BTE related CRBs are completed
- * and then reset the interfaces.
- */
-static int shub2_bte_error_handler(struct nodepda_s *err_nodepda)
-{
-       struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer;
-       struct bteinfo_s *bte;
-       nasid_t nasid;
-       u64 status;
-       int i;
-
-       nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode);
-
-       /*
-        * Verify that all the BTEs are complete
-        */
-       for (i = 0; i < BTES_PER_NODE; i++) {
-               bte = &err_nodepda->bte_if[i];
-               status = BTE_LNSTAT_LOAD(bte);
-               if (status & IBLS_ERROR) {
-                       bte->bh_error = BTE_SHUB2_ERROR(status);
-                       continue;
-               }
-               if (!(status & IBLS_BUSY))
-                       continue;
-               mod_timer(recovery_timer, jiffies + (HZ * 5));
-               BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
-                           smp_processor_id()));
-               return 1;
-       }
-       if (ia64_sn_bte_recovery(nasid))
-               panic("bte_error_handler(): Fatal BTE Error");
-
-       del_timer(recovery_timer);
-       return 0;
-}
-
-/*
- * Wait until all BTE related CRBs are completed
- * and then reset the interfaces.
- */
-void bte_error_handler(struct nodepda_s *err_nodepda)
-{
-       spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock;
-       int i;
-       unsigned long irq_flags;
-       volatile u64 *notify;
-       bte_result_t bh_error;
-
-       BTE_PRINTK(("bte_error_handler(%p) - %d\n", err_nodepda,
-                   smp_processor_id()));
-
-       spin_lock_irqsave(recovery_lock, irq_flags);
-
-       /*
-        * Lock all interfaces on this node to prevent new transfers
-        * from being queued.
-        */
-       for (i = 0; i < BTES_PER_NODE; i++) {
-               if (err_nodepda->bte_if[i].cleanup_active) {
-                       continue;
-               }
-               spin_lock(&err_nodepda->bte_if[i].spinlock);
-               BTE_PRINTK(("eh:%p:%d locked %d\n", err_nodepda,
-                           smp_processor_id(), i));
-               err_nodepda->bte_if[i].cleanup_active = 1;
-       }
-
-       if (is_shub1()) {
-               if (shub1_bte_error_handler(err_nodepda)) {
-                       spin_unlock_irqrestore(recovery_lock, irq_flags);
-                       return;
-               }
-       } else {
-               if (shub2_bte_error_handler(err_nodepda)) {
-                       spin_unlock_irqrestore(recovery_lock, irq_flags);
-                       return;
-               }
-       }
-
-       for (i = 0; i < BTES_PER_NODE; i++) {
-               bh_error = err_nodepda->bte_if[i].bh_error;
-               if (bh_error != BTE_SUCCESS) {
-                       /* There is an error which needs to be notified */
-                       notify = err_nodepda->bte_if[i].most_rcnt_na;
-                       BTE_PRINTK(("cnode %d bte %d error=0x%lx\n",
-                                   err_nodepda->bte_if[i].bte_cnode,
-                                   err_nodepda->bte_if[i].bte_num,
-                                   IBLS_ERROR | (u64) bh_error));
-                       *notify = IBLS_ERROR | bh_error;
-                       err_nodepda->bte_if[i].bh_error = BTE_SUCCESS;
-               }
-
-               err_nodepda->bte_if[i].cleanup_active = 0;
-               BTE_PRINTK(("eh:%p:%d Unlocked %d\n", err_nodepda,
-                           smp_processor_id(), i));
-               spin_unlock(&err_nodepda->bte_if[i].spinlock);
-       }
-
-       spin_unlock_irqrestore(recovery_lock, irq_flags);
-}
-
-/*
- * First part error handler.  This is called whenever any error CRB interrupt
- * is generated by the II.
- */
-void
-bte_crb_error_handler(cnodeid_t cnode, int btenum,
-                      int crbnum, ioerror_t * ioe, int bteop)
-{
-       struct bteinfo_s *bte;
-
-
-       bte = &(NODEPDA(cnode)->bte_if[btenum]);
-
-       /*
-        * The caller has already figured out the error type, we save that
-        * in the bte handle structure for the thread exercising the
-        * interface to consume.
-        */
-       bte->bh_error = ioe->ie_errortype + BTEFAIL_OFFSET;
-       bte->bte_error_count++;
-
-       BTE_PRINTK(("Got an error on cnode %d bte %d: HW error type 0x%x\n",
-               bte->bte_cnode, bte->bte_num, ioe->ie_errortype));
-       bte_error_handler(NODEPDA(cnode));
-}
-
diff --git a/arch/ia64/sn/kernel/huberror.c b/arch/ia64/sn/kernel/huberror.c
deleted file mode 100644 (file)
index 97fa56d..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000,2002-2007 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <asm/delay.h>
-#include <asm/sn/sn_sal.h>
-#include "ioerror.h"
-#include <asm/sn/addrs.h>
-#include <asm/sn/shubio.h>
-#include <asm/sn/geo.h>
-#include "xtalk/xwidgetdev.h"
-#include "xtalk/hubdev.h"
-#include <asm/sn/bte.h>
-
-void hubiio_crb_error_handler(struct hubdev_info *hubdev_info);
-extern void bte_crb_error_handler(cnodeid_t, int, int, ioerror_t *,
-                                 int);
-static irqreturn_t hub_eint_handler(int irq, void *arg)
-{
-       struct hubdev_info *hubdev_info;
-       struct ia64_sal_retval ret_stuff;
-       nasid_t nasid;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-       hubdev_info = (struct hubdev_info *)arg;
-       nasid = hubdev_info->hdi_nasid;
-
-       if (is_shub1()) {
-               SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT,
-                       (u64) nasid, 0, 0, 0, 0, 0, 0);
-
-               if ((int)ret_stuff.v0)
-                       panic("%s: Fatal %s Error", __func__,
-                               ((nasid & 1) ? "TIO" : "HUBII"));
-
-               if (!(nasid & 1)) /* Not a TIO, handle CRB errors */
-                       (void)hubiio_crb_error_handler(hubdev_info);
-       } else
-               if (nasid & 1) {        /* TIO errors */
-                       SAL_CALL_NOLOCK(ret_stuff, SN_SAL_HUB_ERROR_INTERRUPT,
-                               (u64) nasid, 0, 0, 0, 0, 0, 0);
-
-                       if ((int)ret_stuff.v0)
-                               panic("%s: Fatal TIO Error", __func__);
-               } else
-                       bte_error_handler(NODEPDA(nasid_to_cnodeid(nasid)));
-
-       return IRQ_HANDLED;
-}
-
-/*
- * Free the hub CRB "crbnum" which encountered an error.
- * Assumption is, error handling was successfully done,
- * and we now want to return the CRB back to Hub for normal usage.
- *
- * In order to free the CRB, all that's needed is to de-allocate it
- *
- * Assumption:
- *      No other processor is mucking around with the hub control register.
- *      So, upper layer has to single thread this.
- */
-void hubiio_crb_free(struct hubdev_info *hubdev_info, int crbnum)
-{
-       ii_icrb0_b_u_t icrbb;
-
-       /*
-        * The hardware does NOT clear the mark bit, so it must get cleared
-        * here to be sure the error is not processed twice.
-        */
-       icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(hubdev_info->hdi_nasid,
-                                              IIO_ICRB_B(crbnum));
-       icrbb.b_mark = 0;
-       REMOTE_HUB_S(hubdev_info->hdi_nasid, IIO_ICRB_B(crbnum),
-                    icrbb.ii_icrb0_b_regval);
-       /*
-        * Deallocate the register wait till hub indicates it's done.
-        */
-       REMOTE_HUB_S(hubdev_info->hdi_nasid, IIO_ICDR, (IIO_ICDR_PND | crbnum));
-       while (REMOTE_HUB_L(hubdev_info->hdi_nasid, IIO_ICDR) & IIO_ICDR_PND)
-               cpu_relax();
-
-}
-
-/*
- * hubiio_crb_error_handler
- *
- *     This routine gets invoked when a hub gets an error 
- *     interrupt. So, the routine is running in interrupt context
- *     at error interrupt level.
- * Action:
- *     It's responsible for identifying ALL the CRBs that are marked
- *     with error, and process them. 
- *     
- *     If you find the CRB that's marked with error, map this to the
- *     reason it caused error, and invoke appropriate error handler.
- *
- *     XXX Be aware of the information in the context register.
- *
- * NOTE:
- *     Use REMOTE_HUB_* macro instead of LOCAL_HUB_* so that the interrupt
- *     handler can be run on any node. (not necessarily the node 
- *     corresponding to the hub that encountered error).
- */
-
-void hubiio_crb_error_handler(struct hubdev_info *hubdev_info)
-{
-       nasid_t nasid;
-       ii_icrb0_a_u_t icrba;   /* II CRB Register A */
-       ii_icrb0_b_u_t icrbb;   /* II CRB Register B */
-       ii_icrb0_c_u_t icrbc;   /* II CRB Register C */
-       ii_icrb0_d_u_t icrbd;   /* II CRB Register D */
-       ii_icrb0_e_u_t icrbe;   /* II CRB Register D */
-       int i;
-       int num_errors = 0;     /* Num of errors handled */
-       ioerror_t ioerror;
-
-       nasid = hubdev_info->hdi_nasid;
-
-       /*
-        * XXX - Add locking for any recovery actions
-        */
-       /*
-        * Scan through all CRBs in the Hub, and handle the errors
-        * in any of the CRBs marked.
-        */
-       for (i = 0; i < IIO_NUM_CRBS; i++) {
-               /* Check this crb entry to see if it is in error. */
-               icrbb.ii_icrb0_b_regval = REMOTE_HUB_L(nasid, IIO_ICRB_B(i));
-
-               if (icrbb.b_mark == 0) {
-                       continue;
-               }
-
-               icrba.ii_icrb0_a_regval = REMOTE_HUB_L(nasid, IIO_ICRB_A(i));
-
-               IOERROR_INIT(&ioerror);
-
-               /* read other CRB error registers. */
-               icrbc.ii_icrb0_c_regval = REMOTE_HUB_L(nasid, IIO_ICRB_C(i));
-               icrbd.ii_icrb0_d_regval = REMOTE_HUB_L(nasid, IIO_ICRB_D(i));
-               icrbe.ii_icrb0_e_regval = REMOTE_HUB_L(nasid, IIO_ICRB_E(i));
-
-               IOERROR_SETVALUE(&ioerror, errortype, icrbb.b_ecode);
-
-               /* Check if this error is due to BTE operation,
-                * and handle it separately.
-                */
-               if (icrbd.d_bteop ||
-                   ((icrbb.b_initiator == IIO_ICRB_INIT_BTE0 ||
-                     icrbb.b_initiator == IIO_ICRB_INIT_BTE1) &&
-                    (icrbb.b_imsgtype == IIO_ICRB_IMSGT_BTE ||
-                     icrbb.b_imsgtype == IIO_ICRB_IMSGT_SN1NET))) {
-
-                       int bte_num;
-
-                       if (icrbd.d_bteop)
-                               bte_num = icrbc.c_btenum;
-                       else    /* b_initiator bit 2 gives BTE number */
-                               bte_num = (icrbb.b_initiator & 0x4) >> 2;
-
-                       hubiio_crb_free(hubdev_info, i);
-
-                       bte_crb_error_handler(nasid_to_cnodeid(nasid), bte_num,
-                                             i, &ioerror, icrbd.d_bteop);
-                       num_errors++;
-                       continue;
-               }
-       }
-}
-
-/*
- * Function    : hub_error_init
- * Purpose     : initialize the error handling requirements for a given hub.
- * Parameters  : cnode, the compact nodeid.
- * Assumptions : Called only once per hub, either by a local cpu. Or by a
- *                     remote cpu, when this hub is headless.(cpuless)
- * Returns     : None
- */
-void hub_error_init(struct hubdev_info *hubdev_info)
-{
-
-       if (request_irq(SGI_II_ERROR, hub_eint_handler, IRQF_SHARED,
-                       "SN_hub_error", hubdev_info)) {
-               printk(KERN_ERR "hub_error_init: Failed to request_irq for 0x%p\n",
-                   hubdev_info);
-               return;
-       }
-       irq_set_handler(SGI_II_ERROR, handle_level_irq);
-       sn_set_err_irq_affinity(SGI_II_ERROR);
-}
-
-
-/*
- * Function    : ice_error_init
- * Purpose     : initialize the error handling requirements for a given tio.
- * Parameters  : cnode, the compact nodeid.
- * Assumptions : Called only once per tio.
- * Returns     : None
- */
-void ice_error_init(struct hubdev_info *hubdev_info)
-{
-
-        if (request_irq
-            (SGI_TIO_ERROR, (void *)hub_eint_handler, IRQF_SHARED, "SN_TIO_error",
-             (void *)hubdev_info)) {
-                printk("ice_error_init: request_irq() error hubdev_info 0x%p\n",
-                       hubdev_info);
-               return;
-       }
-       irq_set_handler(SGI_TIO_ERROR, handle_level_irq);
-       sn_set_err_irq_affinity(SGI_TIO_ERROR);
-}
-
diff --git a/arch/ia64/sn/kernel/idle.c b/arch/ia64/sn/kernel/idle.c
deleted file mode 100644 (file)
index 49d178f..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2001-2004 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <asm/sn/leds.h>
-
-void snidle(int state)
-{
-       if (state) {
-               if (pda->idle_flag == 0) {
-                       /* 
-                        * Turn the activity LED off.
-                        */
-                       set_led_bits(0, LED_CPU_ACTIVITY);
-               }
-
-               pda->idle_flag = 1;
-       } else {
-               /* 
-                * Turn the activity LED on.
-                */
-               set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY);
-
-               pda->idle_flag = 0;
-       }
-}
diff --git a/arch/ia64/sn/kernel/io_acpi_init.c b/arch/ia64/sn/kernel/io_acpi_init.c
deleted file mode 100644 (file)
index c31fe63..0000000
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <asm/sn/types.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/sn_sal.h>
-#include "xtalk/hubdev.h"
-#include <linux/acpi.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-
-
-/*
- * The code in this file will only be executed when running with
- * a PROM that has ACPI IO support. (i.e., SN_ACPI_BASE_SUPPORT() == 1)
- */
-
-
-/*
- * This value must match the UUID the PROM uses
- * (io/acpi/defblk.c) when building a vendor descriptor.
- */
-struct acpi_vendor_uuid sn_uuid = {
-       .subtype = 0,
-       .data   = { 0x2c, 0xc6, 0xa6, 0xfe, 0x9c, 0x44, 0xda, 0x11,
-                   0xa2, 0x7c, 0x08, 0x00, 0x69, 0x13, 0xea, 0x51 },
-};
-
-struct sn_pcidev_match {
-       u8 bus;
-       unsigned int devfn;
-       acpi_handle handle;
-};
-
-/*
- * Perform the early IO init in PROM.
- */
-static long
-sal_ioif_init(u64 *result)
-{
-       struct ia64_sal_retval isrv = {0,0,0,0};
-
-       SAL_CALL_NOLOCK(isrv,
-                       SN_SAL_IOIF_INIT, 0, 0, 0, 0, 0, 0, 0);
-       *result = isrv.v0;
-       return isrv.status;
-}
-
-/*
- * sn_acpi_hubdev_init() - This function is called by acpi_ns_get_device_callback()
- *                        for all SGIHUB and SGITIO acpi devices defined in the
- *                        DSDT. It obtains the hubdev_info pointer from the
- *                        ACPI vendor resource, which the PROM setup, and sets up the
- *                        hubdev_info in the pda.
- */
-
-static acpi_status __init
-sn_acpi_hubdev_init(acpi_handle handle, u32 depth, void *context, void **ret)
-{
-       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-       struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-       u64 addr;
-       struct hubdev_info *hubdev;
-       struct hubdev_info *hubdev_ptr;
-       int i;
-       u64 nasid;
-       struct acpi_resource *resource;
-       acpi_status status;
-       struct acpi_resource_vendor_typed *vendor;
-       extern void sn_common_hubdev_init(struct hubdev_info *);
-
-       status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
-                                         &sn_uuid, &buffer);
-       if (ACPI_FAILURE(status)) {
-               acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
-               printk(KERN_ERR
-                      "sn_acpi_hubdev_init: acpi_get_vendor_resource() "
-                      "(0x%x) failed for: %s\n", status,
-                       (char *)name_buffer.pointer);
-               kfree(name_buffer.pointer);
-               return AE_OK;           /* Continue walking namespace */
-       }
-
-       resource = buffer.pointer;
-       vendor = &resource->data.vendor_typed;
-       if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
-           sizeof(struct hubdev_info *)) {
-               acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
-               printk(KERN_ERR
-                      "sn_acpi_hubdev_init: Invalid vendor data length: "
-                      "%d for: %s\n",
-                       vendor->byte_length, (char *)name_buffer.pointer);
-               kfree(name_buffer.pointer);
-               goto exit;
-       }
-
-       memcpy(&addr, vendor->byte_data, sizeof(struct hubdev_info *));
-       hubdev_ptr = __va((struct hubdev_info *) addr);
-
-       nasid = hubdev_ptr->hdi_nasid;
-       i = nasid_to_cnodeid(nasid);
-       hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo);
-       *hubdev = *hubdev_ptr;
-       sn_common_hubdev_init(hubdev);
-
-exit:
-       kfree(buffer.pointer);
-       return AE_OK;           /* Continue walking namespace */
-}
-
-/*
- * sn_get_bussoft_ptr() - The pcibus_bussoft pointer is found in
- *                       the ACPI Vendor resource for this bus.
- */
-static struct pcibus_bussoft *
-sn_get_bussoft_ptr(struct pci_bus *bus)
-{
-       u64 addr;
-       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-       struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-       acpi_handle handle;
-       struct pcibus_bussoft *prom_bussoft_ptr;
-       struct acpi_resource *resource;
-       acpi_status status;
-       struct acpi_resource_vendor_typed *vendor;
-
-
-       handle = acpi_device_handle(PCI_CONTROLLER(bus)->companion);
-       status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
-                                         &sn_uuid, &buffer);
-       if (ACPI_FAILURE(status)) {
-               acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
-               printk(KERN_ERR "%s: "
-                      "acpi_get_vendor_resource() failed (0x%x) for: %s\n",
-                      __func__, status, (char *)name_buffer.pointer);
-               kfree(name_buffer.pointer);
-               return NULL;
-       }
-       resource = buffer.pointer;
-       vendor = &resource->data.vendor_typed;
-
-       if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
-            sizeof(struct pcibus_bussoft *)) {
-               printk(KERN_ERR
-                      "%s: Invalid vendor data length %d\n",
-                       __func__, vendor->byte_length);
-               kfree(buffer.pointer);
-               return NULL;
-       }
-       memcpy(&addr, vendor->byte_data, sizeof(struct pcibus_bussoft *));
-       prom_bussoft_ptr = __va((struct pcibus_bussoft *) addr);
-       kfree(buffer.pointer);
-
-       return prom_bussoft_ptr;
-}
-
-/*
- * sn_extract_device_info - Extract the pcidev_info and the sn_irq_info
- *                         pointers from the vendor resource using the
- *                         provided acpi handle, and copy the structures
- *                         into the argument buffers.
- */
-static int
-sn_extract_device_info(acpi_handle handle, struct pcidev_info **pcidev_info,
-                   struct sn_irq_info **sn_irq_info)
-{
-       u64 addr;
-       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-       struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-       struct sn_irq_info *irq_info, *irq_info_prom;
-       struct pcidev_info *pcidev_ptr, *pcidev_prom_ptr;
-       struct acpi_resource *resource;
-       int ret = 0;
-       acpi_status status;
-       struct acpi_resource_vendor_typed *vendor;
-
-       /*
-        * The pointer to this device's pcidev_info structure in
-        * the PROM, is in the vendor resource.
-        */
-       status = acpi_get_vendor_resource(handle, METHOD_NAME__CRS,
-                                         &sn_uuid, &buffer);
-       if (ACPI_FAILURE(status)) {
-               acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
-               printk(KERN_ERR
-                      "%s: acpi_get_vendor_resource() failed (0x%x) for: %s\n",
-                       __func__, status, (char *)name_buffer.pointer);
-               kfree(name_buffer.pointer);
-               return 1;
-       }
-
-       resource = buffer.pointer;
-       vendor = &resource->data.vendor_typed;
-       if ((vendor->byte_length - sizeof(struct acpi_vendor_uuid)) !=
-           sizeof(struct pci_devdev_info *)) {
-               acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
-               printk(KERN_ERR
-                      "%s: Invalid vendor data length: %d for: %s\n",
-                        __func__, vendor->byte_length,
-                       (char *)name_buffer.pointer);
-               kfree(name_buffer.pointer);
-               ret = 1;
-               goto exit;
-       }
-
-       pcidev_ptr = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL);
-       if (!pcidev_ptr)
-               panic("%s: Unable to alloc memory for pcidev_info", __func__);
-
-       memcpy(&addr, vendor->byte_data, sizeof(struct pcidev_info *));
-       pcidev_prom_ptr = __va(addr);
-       memcpy(pcidev_ptr, pcidev_prom_ptr, sizeof(struct pcidev_info));
-
-       /* Get the IRQ info */
-       irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
-       if (!irq_info)
-                panic("%s: Unable to alloc memory for sn_irq_info", __func__);
-
-       if (pcidev_ptr->pdi_sn_irq_info) {
-               irq_info_prom = __va(pcidev_ptr->pdi_sn_irq_info);
-               memcpy(irq_info, irq_info_prom, sizeof(struct sn_irq_info));
-       }
-
-       *pcidev_info = pcidev_ptr;
-       *sn_irq_info = irq_info;
-
-exit:
-       kfree(buffer.pointer);
-       return ret;
-}
-
-static unsigned int
-get_host_devfn(acpi_handle device_handle, acpi_handle rootbus_handle)
-{
-       unsigned long long adr;
-       acpi_handle child;
-       unsigned int devfn;
-       int function;
-       acpi_handle parent;
-       int slot;
-       acpi_status status;
-       struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-
-       acpi_get_name(device_handle, ACPI_FULL_PATHNAME, &name_buffer);
-
-       /*
-        * Do an upward search to find the root bus device, and
-        * obtain the host devfn from the previous child device.
-        */
-       child = device_handle;
-       while (child) {
-               status = acpi_get_parent(child, &parent);
-               if (ACPI_FAILURE(status)) {
-                       printk(KERN_ERR "%s: acpi_get_parent() failed "
-                              "(0x%x) for: %s\n", __func__, status,
-                               (char *)name_buffer.pointer);
-                       panic("%s: Unable to find host devfn\n", __func__);
-               }
-               if (parent == rootbus_handle)
-                       break;
-               child = parent;
-       }
-       if (!child) {
-               printk(KERN_ERR "%s: Unable to find root bus for: %s\n",
-                      __func__, (char *)name_buffer.pointer);
-               BUG();
-       }
-
-       status = acpi_evaluate_integer(child, METHOD_NAME__ADR, NULL, &adr);
-       if (ACPI_FAILURE(status)) {
-               printk(KERN_ERR "%s: Unable to get _ADR (0x%x) for: %s\n",
-                      __func__, status, (char *)name_buffer.pointer);
-               panic("%s: Unable to find host devfn\n", __func__);
-       }
-
-       kfree(name_buffer.pointer);
-
-       slot = (adr >> 16) & 0xffff;
-       function = adr & 0xffff;
-       devfn = PCI_DEVFN(slot, function);
-       return devfn;
-}
-
-/*
- * find_matching_device - Callback routine to find the ACPI device
- *                       that matches up with our pci_dev device.
- *                       Matching is done on bus number and devfn.
- *                       To find the bus number for a particular
- *                       ACPI device, we must look at the _BBN method
- *                       of its parent.
- */
-static acpi_status
-find_matching_device(acpi_handle handle, u32 lvl, void *context, void **rv)
-{
-       unsigned long long bbn = -1;
-       unsigned long long adr;
-       acpi_handle parent = NULL;
-       acpi_status status;
-       unsigned int devfn;
-       int function;
-       int slot;
-       struct sn_pcidev_match *info = context;
-       struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-
-        status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL,
-                                       &adr);
-        if (ACPI_SUCCESS(status)) {
-               status = acpi_get_parent(handle, &parent);
-               if (ACPI_FAILURE(status)) {
-                       acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
-                       printk(KERN_ERR
-                              "%s: acpi_get_parent() failed (0x%x) for: %s\n",
-                               __func__, status, (char *)name_buffer.pointer);
-                       kfree(name_buffer.pointer);
-                       return AE_OK;
-               }
-               status = acpi_evaluate_integer(parent, METHOD_NAME__BBN,
-                                              NULL, &bbn);
-               if (ACPI_FAILURE(status)) {
-                       acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer);
-                       printk(KERN_ERR
-                         "%s: Failed to find _BBN in parent of: %s\n",
-                                       __func__, (char *)name_buffer.pointer);
-                       kfree(name_buffer.pointer);
-                       return AE_OK;
-               }
-
-                slot = (adr >> 16) & 0xffff;
-                function = adr & 0xffff;
-                devfn = PCI_DEVFN(slot, function);
-                if ((info->devfn == devfn) && (info->bus == bbn)) {
-                       /* We have a match! */
-                       info->handle = handle;
-                       return 1;
-               }
-       }
-       return AE_OK;
-}
-
-/*
- * sn_acpi_get_pcidev_info - Search ACPI namespace for the acpi
- *                          device matching the specified pci_dev,
- *                          and return the pcidev info and irq info.
- */
-int
-sn_acpi_get_pcidev_info(struct pci_dev *dev, struct pcidev_info **pcidev_info,
-                       struct sn_irq_info **sn_irq_info)
-{
-       unsigned int host_devfn;
-       struct sn_pcidev_match pcidev_match;
-       acpi_handle rootbus_handle;
-       unsigned long long segment;
-       acpi_status status;
-       struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-
-       rootbus_handle = acpi_device_handle(PCI_CONTROLLER(dev)->companion);
-        status = acpi_evaluate_integer(rootbus_handle, METHOD_NAME__SEG, NULL,
-                                       &segment);
-        if (ACPI_SUCCESS(status)) {
-               if (segment != pci_domain_nr(dev)) {
-                       acpi_get_name(rootbus_handle, ACPI_FULL_PATHNAME,
-                               &name_buffer);
-                       printk(KERN_ERR
-                              "%s: Segment number mismatch, 0x%llx vs 0x%x for: %s\n",
-                              __func__, segment, pci_domain_nr(dev),
-                              (char *)name_buffer.pointer);
-                       kfree(name_buffer.pointer);
-                       return 1;
-               }
-       } else {
-               acpi_get_name(rootbus_handle, ACPI_FULL_PATHNAME, &name_buffer);
-               printk(KERN_ERR "%s: Unable to get __SEG from: %s\n",
-                      __func__, (char *)name_buffer.pointer);
-               kfree(name_buffer.pointer);
-               return 1;
-       }
-
-       /*
-        * We want to search all devices in this segment/domain
-        * of the ACPI namespace for the matching ACPI device,
-        * which holds the pcidev_info pointer in its vendor resource.
-        */
-       pcidev_match.bus = dev->bus->number;
-       pcidev_match.devfn = dev->devfn;
-       pcidev_match.handle = NULL;
-
-       acpi_walk_namespace(ACPI_TYPE_DEVICE, rootbus_handle, ACPI_UINT32_MAX,
-                           find_matching_device, NULL, &pcidev_match, NULL);
-
-       if (!pcidev_match.handle) {
-               printk(KERN_ERR
-                      "%s: Could not find matching ACPI device for %s.\n",
-                      __func__, pci_name(dev));
-               return 1;
-       }
-
-       if (sn_extract_device_info(pcidev_match.handle, pcidev_info, sn_irq_info))
-               return 1;
-
-       /* Build up the pcidev_info.pdi_slot_host_handle */
-       host_devfn = get_host_devfn(pcidev_match.handle, rootbus_handle);
-       (*pcidev_info)->pdi_slot_host_handle =
-                       ((unsigned long) pci_domain_nr(dev) << 40) |
-                                       /* bus == 0 */
-                                       host_devfn;
-       return 0;
-}
-
-/*
- * sn_acpi_slot_fixup - Obtain the pcidev_info and sn_irq_info.
- *                     Perform any SN specific slot fixup.
- *                     At present there does not appear to be
- *                     any generic way to handle a ROM image
- *                     that has been shadowed by the PROM, so
- *                     we pass a pointer to it within the
- *                     pcidev_info structure.
- */
-
-void
-sn_acpi_slot_fixup(struct pci_dev *dev)
-{
-       struct pcidev_info *pcidev_info = NULL;
-       struct sn_irq_info *sn_irq_info = NULL;
-       struct resource *res;
-       size_t size;
-
-       if (sn_acpi_get_pcidev_info(dev, &pcidev_info, &sn_irq_info)) {
-               panic("%s:  Failure obtaining pcidev_info for %s\n",
-                     __func__, pci_name(dev));
-       }
-
-       if (pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE]) {
-               /*
-                * A valid ROM image exists and has been shadowed by the
-                * PROM. Setup the pci_dev ROM resource with the address
-                * of the shadowed copy, and the actual length of the ROM image.
-                */
-               size = pci_resource_len(dev, PCI_ROM_RESOURCE);
-
-               res = &dev->resource[PCI_ROM_RESOURCE];
-
-               pci_disable_rom(dev);
-               if (res->parent)
-                       release_resource(res);
-
-               res->start = pcidev_info->pdi_pio_mapped_addr[PCI_ROM_RESOURCE];
-               res->end = res->start + size - 1;
-               res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
-                            IORESOURCE_PCI_FIXED;
-       }
-       sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
-}
-EXPORT_SYMBOL(sn_acpi_slot_fixup);
-
-
-/*
- * sn_acpi_bus_fixup -  Perform SN specific setup of software structs
- *                     (pcibus_bussoft, pcidev_info) and hardware
- *                     registers, for the specified bus and devices under it.
- */
-void
-sn_acpi_bus_fixup(struct pci_bus *bus)
-{
-       struct pci_dev *pci_dev = NULL;
-       struct pcibus_bussoft *prom_bussoft_ptr;
-
-       if (!bus->parent) {     /* If root bus */
-               prom_bussoft_ptr = sn_get_bussoft_ptr(bus);
-               if (prom_bussoft_ptr == NULL) {
-                       printk(KERN_ERR
-                              "%s: 0x%04x:0x%02x Unable to "
-                              "obtain prom_bussoft_ptr\n",
-                              __func__, pci_domain_nr(bus), bus->number);
-                       return;
-               }
-               sn_common_bus_fixup(bus, prom_bussoft_ptr);
-       }
-       list_for_each_entry(pci_dev, &bus->devices, bus_list) {
-               sn_acpi_slot_fixup(pci_dev);
-       }
-}
-
-/*
- * sn_io_acpi_init - PROM has ACPI support for IO, defining at a minimum the
- *                  nodes and root buses in the DSDT. As a result, bus scanning
- *                  will be initiated by the Linux ACPI code.
- */
-
-void __init
-sn_io_acpi_init(void)
-{
-       u64 result;
-       long status;
-
-       /* SN Altix does not follow the IOSAPIC IRQ routing model */
-       acpi_irq_model = ACPI_IRQ_MODEL_PLATFORM;
-
-       /* Setup hubdev_info for all SGIHUB/SGITIO devices */
-       acpi_get_devices("SGIHUB", sn_acpi_hubdev_init, NULL, NULL);
-       acpi_get_devices("SGITIO", sn_acpi_hubdev_init, NULL, NULL);
-
-       status = sal_ioif_init(&result);
-       if (status || result)
-               panic("sal_ioif_init failed: [%lx] %s\n",
-                     status, ia64_sal_strerror(status));
-}
diff --git a/arch/ia64/sn/kernel/io_common.c b/arch/ia64/sn/kernel/io_common.c
deleted file mode 100644 (file)
index d468473..0000000
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/memblock.h>
-#include <linux/export.h>
-#include <linux/slab.h>
-#include <asm/sn/types.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/sn_feature_sets.h>
-#include <asm/sn/geo.h>
-#include <asm/sn/io.h>
-#include <asm/sn/l1.h>
-#include <asm/sn/module.h>
-#include <asm/sn/pcibr_provider.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/tioca_provider.h>
-#include <asm/sn/tioce_provider.h>
-#include "xtalk/hubdev.h"
-#include "xtalk/xwidgetdev.h"
-#include <linux/acpi.h>
-#include <asm/sn/sn2/sn_hwperf.h>
-#include <asm/sn/acpi.h>
-
-extern void sn_init_cpei_timer(void);
-extern void register_sn_procfs(void);
-extern void sn_io_acpi_init(void);
-extern void sn_io_init(void);
-
-
-static struct list_head sn_sysdata_list;
-
-/* sysdata list struct */
-struct sysdata_el {
-       struct list_head entry;
-       void *sysdata;
-};
-
-int sn_ioif_inited;            /* SN I/O infrastructure initialized? */
-
-int sn_acpi_rev;               /* SN ACPI revision */
-EXPORT_SYMBOL_GPL(sn_acpi_rev);
-
-struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES];      /* indexed by asic type */
-
-/*
- * Hooks and struct for unsupported pci providers
- */
-
-static dma_addr_t
-sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type)
-{
-       return 0;
-}
-
-static void
-sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction)
-{
-       return;
-}
-
-static void *
-sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller)
-{
-       return NULL;
-}
-
-static struct sn_pcibus_provider sn_pci_default_provider = {
-       .dma_map = sn_default_pci_map,
-       .dma_map_consistent = sn_default_pci_map,
-       .dma_unmap = sn_default_pci_unmap,
-       .bus_fixup = sn_default_pci_bus_fixup,
-};
-
-/*
- * Retrieve the DMA Flush List given nasid, widget, and device.
- * This list is needed to implement the WAR - Flush DMA data on PIO Reads.
- */
-static inline u64
-sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num,
-                            u64 address)
-{
-       struct ia64_sal_retval ret_stuff;
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       SAL_CALL_NOLOCK(ret_stuff,
-                       (u64) SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST,
-                       (u64) nasid, (u64) widget_num,
-                       (u64) device_num, (u64) address, 0, 0, 0);
-       return ret_stuff.status;
-}
-
-/*
- * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified
- *                       device.
- */
-inline struct pcidev_info *
-sn_pcidev_info_get(struct pci_dev *dev)
-{
-       struct pcidev_info *pcidev;
-
-       list_for_each_entry(pcidev,
-                           &(SN_PLATFORM_DATA(dev)->pcidev_info), pdi_list) {
-               if (pcidev->pdi_linux_pcidev == dev)
-                       return pcidev;
-       }
-       return NULL;
-}
-
-/* Older PROM flush WAR
- *
- * 01/16/06 -- This war will be in place until a new official PROM is released.
- * Additionally note that the struct sn_flush_device_war also has to be
- * removed from arch/ia64/sn/include/xtalk/hubdev.h
- */
-
-static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device,
-                              struct sn_flush_device_common *common)
-{
-       struct sn_flush_device_war *war_list;
-       struct sn_flush_device_war *dev_entry;
-       struct ia64_sal_retval isrv = {0,0,0,0};
-
-       printk_once(KERN_WARNING
-               "PROM version < 4.50 -- implementing old PROM flush WAR\n");
-
-       war_list = kcalloc(DEV_PER_WIDGET, sizeof(*war_list), GFP_KERNEL);
-       BUG_ON(!war_list);
-
-       SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST,
-                       nasid, widget, __pa(war_list), 0, 0, 0 ,0);
-       if (isrv.status)
-               panic("sn_device_fixup_war failed: %s\n",
-                     ia64_sal_strerror(isrv.status));
-
-       dev_entry = war_list + device;
-       memcpy(common,dev_entry, sizeof(*common));
-       kfree(war_list);
-
-       return isrv.status;
-}
-
-/*
- * sn_common_hubdev_init() - This routine is called to initialize the HUB data
- *                          structure for each node in the system.
- */
-void __init
-sn_common_hubdev_init(struct hubdev_info *hubdev)
-{
-
-       struct sn_flush_device_kernel *sn_flush_device_kernel;
-       struct sn_flush_device_kernel *dev_entry;
-       s64 status;
-       int widget, device, size;
-
-       /* Attach the error interrupt handlers */
-       if (hubdev->hdi_nasid & 1)      /* If TIO */
-               ice_error_init(hubdev);
-       else
-               hub_error_init(hubdev);
-
-       for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++)
-               hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev;
-
-       if (!hubdev->hdi_flush_nasid_list.widget_p)
-               return;
-
-       size = (HUB_WIDGET_ID_MAX + 1) *
-               sizeof(struct sn_flush_device_kernel *);
-       hubdev->hdi_flush_nasid_list.widget_p =
-               kzalloc(size, GFP_KERNEL);
-       BUG_ON(!hubdev->hdi_flush_nasid_list.widget_p);
-
-       for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) {
-               size = DEV_PER_WIDGET *
-                       sizeof(struct sn_flush_device_kernel);
-               sn_flush_device_kernel = kzalloc(size, GFP_KERNEL);
-               BUG_ON(!sn_flush_device_kernel);
-
-               dev_entry = sn_flush_device_kernel;
-               for (device = 0; device < DEV_PER_WIDGET;
-                    device++, dev_entry++) {
-                       size = sizeof(struct sn_flush_device_common);
-                       dev_entry->common = kzalloc(size, GFP_KERNEL);
-                       BUG_ON(!dev_entry->common);
-                       if (sn_prom_feature_available(PRF_DEVICE_FLUSH_LIST))
-                               status = sal_get_device_dmaflush_list(
-                                            hubdev->hdi_nasid, widget, device,
-                                            (u64)(dev_entry->common));
-                       else
-                               status = sn_device_fixup_war(hubdev->hdi_nasid,
-                                                            widget, device,
-                                                            dev_entry->common);
-                       if (status != SALRET_OK)
-                               panic("SAL call failed: %s\n",
-                                     ia64_sal_strerror(status));
-
-                       spin_lock_init(&dev_entry->sfdl_flush_lock);
-               }
-
-               if (sn_flush_device_kernel)
-                       hubdev->hdi_flush_nasid_list.widget_p[widget] =
-                                                        sn_flush_device_kernel;
-       }
-}
-
-void sn_pci_unfixup_slot(struct pci_dev *dev)
-{
-       struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev;
-
-       sn_irq_unfixup(dev);
-       pci_dev_put(host_pci_dev);
-       pci_dev_put(dev);
-}
-
-/*
- * sn_pci_fixup_slot()
- */
-void sn_pci_fixup_slot(struct pci_dev *dev, struct pcidev_info *pcidev_info,
-                      struct sn_irq_info *sn_irq_info)
-{
-       int segment = pci_domain_nr(dev->bus);
-       struct pcibus_bussoft *bs;
-       struct pci_dev *host_pci_dev;
-       unsigned int bus_no, devfn;
-
-       pci_dev_get(dev); /* for the sysdata pointer */
-
-       /* Add pcidev_info to list in pci_controller.platform_data */
-       list_add_tail(&pcidev_info->pdi_list,
-                     &(SN_PLATFORM_DATA(dev->bus)->pcidev_info));
-       /*
-        * Using the PROMs values for the PCI host bus, get the Linux
-        * PCI host_pci_dev struct and set up host bus linkages
-        */
-
-       bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff;
-       devfn = pcidev_info->pdi_slot_host_handle & 0xffffffff;
-       host_pci_dev = pci_get_domain_bus_and_slot(segment, bus_no, devfn);
-
-       pcidev_info->host_pci_dev = host_pci_dev;
-       pcidev_info->pdi_linux_pcidev = dev;
-       pcidev_info->pdi_host_pcidev_info = SN_PCIDEV_INFO(host_pci_dev);
-       bs = SN_PCIBUS_BUSSOFT(dev->bus);
-       pcidev_info->pdi_pcibus_info = bs;
-
-       if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) {
-               SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type];
-       } else {
-               SN_PCIDEV_BUSPROVIDER(dev) = &sn_pci_default_provider;
-       }
-
-       /* Only set up IRQ stuff if this device has a host bus context */
-       if (bs && sn_irq_info->irq_irq) {
-               pcidev_info->pdi_sn_irq_info = sn_irq_info;
-               dev->irq = pcidev_info->pdi_sn_irq_info->irq_irq;
-               sn_irq_fixup(dev, sn_irq_info);
-       } else {
-               pcidev_info->pdi_sn_irq_info = NULL;
-               kfree(sn_irq_info);
-       }
-}
-
-/*
- * sn_common_bus_fixup - Perform platform specific bus fixup.
- *                      Execute the ASIC specific fixup routine
- *                      for this bus.
- */
-void
-sn_common_bus_fixup(struct pci_bus *bus,
-                   struct pcibus_bussoft *prom_bussoft_ptr)
-{
-       int cnode;
-       struct pci_controller *controller;
-       struct hubdev_info *hubdev_info;
-       int nasid;
-       void *provider_soft;
-       struct sn_pcibus_provider *provider;
-       struct sn_platform_data *sn_platform_data;
-
-       controller = PCI_CONTROLLER(bus);
-       /*
-        * Per-provider fixup.  Copies the bus soft structure from prom
-        * to local area and links SN_PCIBUS_BUSSOFT().
-        */
-
-       if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) {
-               printk(KERN_WARNING "sn_common_bus_fixup: Unsupported asic type, %d",
-                      prom_bussoft_ptr->bs_asic_type);
-               return;
-       }
-
-       if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB)
-               return; /* no further fixup necessary */
-
-       provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type];
-       if (provider == NULL)
-               panic("sn_common_bus_fixup: No provider registered for this asic type, %d",
-                     prom_bussoft_ptr->bs_asic_type);
-
-       if (provider->bus_fixup)
-               provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr,
-                                controller);
-       else
-               provider_soft = NULL;
-
-       /*
-        * Generic bus fixup goes here.  Don't reference prom_bussoft_ptr
-        * after this point.
-        */
-       controller->platform_data = kzalloc(sizeof(struct sn_platform_data),
-                                           GFP_KERNEL);
-       BUG_ON(controller->platform_data == NULL);
-       sn_platform_data =
-                       (struct sn_platform_data *) controller->platform_data;
-       sn_platform_data->provider_soft = provider_soft;
-       INIT_LIST_HEAD(&((struct sn_platform_data *)
-                        controller->platform_data)->pcidev_info);
-       nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base);
-       cnode = nasid_to_cnodeid(nasid);
-       hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
-       SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info =
-           &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]);
-
-       /*
-        * If the node information we obtained during the fixup phase is
-        * invalid then set controller->node to -1 (undetermined)
-        */
-       if (controller->node >= num_online_nodes()) {
-               struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus);
-
-               printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u "
-                      "L_IO=%llx L_MEM=%llx BASE=%llx\n",
-                      b->bs_asic_type, b->bs_xid, b->bs_persist_busnum,
-                      b->bs_legacy_io, b->bs_legacy_mem, b->bs_base);
-               printk(KERN_WARNING "on node %d but only %d nodes online."
-                      "Association set to undetermined.\n",
-                      controller->node, num_online_nodes());
-               controller->node = -1;
-       }
-}
-
-void sn_bus_store_sysdata(struct pci_dev *dev)
-{
-       struct sysdata_el *element;
-
-       element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL);
-       if (!element) {
-               dev_dbg(&dev->dev, "%s: out of memory!\n", __func__);
-               return;
-       }
-       element->sysdata = SN_PCIDEV_INFO(dev);
-       list_add(&element->entry, &sn_sysdata_list);
-}
-
-void sn_bus_free_sysdata(void)
-{
-       struct sysdata_el *element;
-       struct list_head *list, *safe;
-
-       list_for_each_safe(list, safe, &sn_sysdata_list) {
-               element = list_entry(list, struct sysdata_el, entry);
-               list_del(&element->entry);
-               list_del(&(((struct pcidev_info *)
-                            (element->sysdata))->pdi_list));
-               kfree(element->sysdata);
-               kfree(element);
-       }
-       return;
-}
-
-/*
- * hubdev_init_node() - Creates the HUB data structure and link them to it's
- *                     own NODE specific data area.
- */
-void __init hubdev_init_node(nodepda_t * npda, cnodeid_t node)
-{
-       struct hubdev_info *hubdev_info;
-       int size;
-
-       size = sizeof(struct hubdev_info);
-
-       if (node >= num_online_nodes()) /* Headless/memless IO nodes */
-               node = 0;
-
-       hubdev_info = (struct hubdev_info *)memblock_alloc_node(size,
-                                                               SMP_CACHE_BYTES,
-                                                               node);
-       if (!hubdev_info)
-               panic("%s: Failed to allocate %d bytes align=0x%x nid=%d\n",
-                     __func__, size, SMP_CACHE_BYTES, node);
-
-       npda->pdinfo = (void *)hubdev_info;
-}
-
-geoid_t
-cnodeid_get_geoid(cnodeid_t cnode)
-{
-       struct hubdev_info *hubdev;
-
-       hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
-       return hubdev->hdi_geoid;
-}
-
-void sn_generate_path(struct pci_bus *pci_bus, char *address)
-{
-       nasid_t nasid;
-       cnodeid_t cnode;
-       geoid_t geoid;
-       moduleid_t moduleid;
-       u16 bricktype;
-
-       nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base);
-       cnode = nasid_to_cnodeid(nasid);
-       geoid = cnodeid_get_geoid(cnode);
-       moduleid = geo_module(geoid);
-
-       sprintf(address, "module_%c%c%c%c%.2d",
-               '0'+RACK_GET_CLASS(MODULE_GET_RACK(moduleid)),
-               '0'+RACK_GET_GROUP(MODULE_GET_RACK(moduleid)),
-               '0'+RACK_GET_NUM(MODULE_GET_RACK(moduleid)),
-               MODULE_GET_BTCHAR(moduleid), MODULE_GET_BPOS(moduleid));
-
-       /* Tollhouse requires slot id to be displayed */
-       bricktype = MODULE_GET_BTYPE(moduleid);
-       if ((bricktype == L1_BRICKTYPE_191010) ||
-           (bricktype == L1_BRICKTYPE_1932))
-                       sprintf(address + strlen(address), "^%d",
-                                               geo_slot(geoid));
-}
-
-void sn_pci_fixup_bus(struct pci_bus *bus)
-{
-
-       if (SN_ACPI_BASE_SUPPORT())
-               sn_acpi_bus_fixup(bus);
-       else
-               sn_bus_fixup(bus);
-}
-
-/*
- * sn_io_early_init - Perform early IO (and some non-IO) initialization.
- *                   In particular, setup the sn_pci_provider[] array.
- *                   This needs to be done prior to any bus scanning
- *                   (acpi_scan_init()) in the ACPI case, as the SN
- *                   bus fixup code will reference the array.
- */
-static int __init
-sn_io_early_init(void)
-{
-       int i;
-
-       if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
-               return 0;
-
-       /* we set the acpi revision to that of the DSDT table OEM rev. */
-       {
-               struct acpi_table_header *header = NULL;
-
-               acpi_get_table(ACPI_SIG_DSDT, 1, &header);
-               BUG_ON(header == NULL);
-               sn_acpi_rev = header->oem_revision;
-       }
-
-       /*
-        * prime sn_pci_provider[].  Individual provider init routines will
-        * override their respective default entries.
-        */
-
-       for (i = 0; i < PCIIO_ASIC_MAX_TYPES; i++)
-               sn_pci_provider[i] = &sn_pci_default_provider;
-
-       pcibr_init_provider();
-       tioca_init_provider();
-       tioce_init_provider();
-
-       sn_irq_lh_init();
-       INIT_LIST_HEAD(&sn_sysdata_list);
-       sn_init_cpei_timer();
-
-#ifdef CONFIG_PROC_FS
-       register_sn_procfs();
-#endif
-
-       {
-               struct acpi_table_header *header;
-               (void)acpi_get_table(ACPI_SIG_DSDT, 1, &header);
-               printk(KERN_INFO "ACPI  DSDT OEM Rev 0x%x\n",
-                       header->oem_revision);
-       }
-       if (SN_ACPI_BASE_SUPPORT())
-               sn_io_acpi_init();
-       else
-               sn_io_init();
-       return 0;
-}
-
-arch_initcall(sn_io_early_init);
-
-/*
- * sn_io_late_init() - Perform any final platform specific IO initialization.
- */
-
-int __init
-sn_io_late_init(void)
-{
-       struct pci_bus *bus;
-       struct pcibus_bussoft *bussoft;
-       cnodeid_t cnode;
-       nasid_t nasid;
-       cnodeid_t near_cnode;
-
-       if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM())
-               return 0;
-
-       /*
-        * Setup closest node in pci_controller->node for
-        * PIC, TIOCP, TIOCE (TIOCA does it during bus fixup using
-        * info from the PROM).
-        */
-       bus = NULL;
-       while ((bus = pci_find_next_bus(bus)) != NULL) {
-               bussoft = SN_PCIBUS_BUSSOFT(bus);
-               nasid = NASID_GET(bussoft->bs_base);
-               cnode = nasid_to_cnodeid(nasid);
-               if ((bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) ||
-                   (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCE) ||
-                   (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_PIC)) {
-                       /* PCI Bridge: find nearest node with CPUs */
-                       int e = sn_hwperf_get_nearest_node(cnode, NULL,
-                                                          &near_cnode);
-                       if (e < 0) {
-                               near_cnode = (cnodeid_t)-1; /* use any node */
-                               printk(KERN_WARNING "sn_io_late_init: failed "
-                                      "to find near node with CPUs for "
-                                      "node %d, err=%d\n", cnode, e);
-                       }
-                       PCI_CONTROLLER(bus)->node = near_cnode;
-               }
-       }
-
-       sn_ioif_inited = 1;     /* SN I/O infrastructure now initialized */
-
-       return 0;
-}
-
-fs_initcall(sn_io_late_init);
-
-EXPORT_SYMBOL(sn_pci_unfixup_slot);
-EXPORT_SYMBOL(sn_bus_store_sysdata);
-EXPORT_SYMBOL(sn_bus_free_sysdata);
-EXPORT_SYMBOL(sn_generate_path);
-
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
deleted file mode 100644 (file)
index d63809a..0000000
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <asm/sn/types.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/io.h>
-#include <asm/sn/module.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/sn_sal.h>
-#include "xtalk/hubdev.h"
-
-/*
- * The code in this file will only be executed when running with
- * a PROM that does _not_ have base ACPI IO support.
- * (i.e., SN_ACPI_BASE_SUPPORT() == 0)
- */
-
-static int max_segment_number;          /* Default highest segment number */
-static int max_pcibus_number = 255;    /* Default highest pci bus number */
-
-
-/*
- * Retrieve the hub device info structure for the given nasid.
- */
-static inline u64 sal_get_hubdev_info(u64 handle, u64 address)
-{
-       struct ia64_sal_retval ret_stuff;
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       SAL_CALL_NOLOCK(ret_stuff,
-                       (u64) SN_SAL_IOIF_GET_HUBDEV_INFO,
-                       (u64) handle, (u64) address, 0, 0, 0, 0, 0);
-       return ret_stuff.v0;
-}
-
-/*
- * Retrieve the pci bus information given the bus number.
- */
-static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address)
-{
-       struct ia64_sal_retval ret_stuff;
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       SAL_CALL_NOLOCK(ret_stuff,
-                       (u64) SN_SAL_IOIF_GET_PCIBUS_INFO,
-                       (u64) segment, (u64) busnum, (u64) address, 0, 0, 0, 0);
-       return ret_stuff.v0;
-}
-
-/*
- * Retrieve the pci device information given the bus and device|function number.
- */
-static inline u64
-sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev,
-                   u64 sn_irq_info)
-{
-       struct ia64_sal_retval ret_stuff;
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       SAL_CALL_NOLOCK(ret_stuff,
-                       (u64) SN_SAL_IOIF_GET_PCIDEV_INFO,
-                       (u64) segment, (u64) bus_number, (u64) devfn,
-                       (u64) pci_dev,
-                       sn_irq_info, 0, 0);
-       return ret_stuff.v0;
-}
-
-
-/*
- * sn_fixup_ionodes() - This routine initializes the HUB data structure for
- *                     each node in the system. This function is only
- *                     executed when running with a non-ACPI capable PROM.
- */
-static void __init sn_fixup_ionodes(void)
-{
-
-       struct hubdev_info *hubdev;
-       u64 status;
-       u64 nasid;
-       int i;
-       extern void sn_common_hubdev_init(struct hubdev_info *);
-
-       /*
-        * Get SGI Specific HUB chipset information.
-        * Inform Prom that this kernel can support domain bus numbering.
-        */
-       for (i = 0; i < num_cnodes; i++) {
-               hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo);
-               nasid = cnodeid_to_nasid(i);
-               hubdev->max_segment_number = 0xffffffff;
-               hubdev->max_pcibus_number = 0xff;
-               status = sal_get_hubdev_info(nasid, (u64) __pa(hubdev));
-               if (status)
-                       continue;
-
-               /* Save the largest Domain and pcibus numbers found. */
-               if (hubdev->max_segment_number) {
-                       /*
-                        * Dealing with a Prom that supports segments.
-                        */
-                       max_segment_number = hubdev->max_segment_number;
-                       max_pcibus_number = hubdev->max_pcibus_number;
-               }
-               sn_common_hubdev_init(hubdev);
-       }
-}
-
-/*
- * sn_pci_legacy_window_fixup - Setup PCI resources for
- *                             legacy IO and MEM space. This needs to
- *                             be done here, as the PROM does not have
- *                             ACPI support defining the root buses
- *                             and their resources (_CRS),
- */
-static void
-sn_legacy_pci_window_fixup(struct resource *res,
-               u64 legacy_io, u64 legacy_mem)
-{
-               res[0].name = "legacy_io";
-               res[0].flags = IORESOURCE_IO;
-               res[0].start = legacy_io;
-               res[0].end = res[0].start + 0xffff;
-               res[0].parent = &ioport_resource;
-               res[1].name = "legacy_mem";
-               res[1].flags = IORESOURCE_MEM;
-               res[1].start = legacy_mem;
-               res[1].end = res[1].start + (1024 * 1024) - 1;
-               res[1].parent = &iomem_resource;
-}
-
-/*
- * sn_io_slot_fixup() -   We are not running with an ACPI capable PROM,
- *                       and need to convert the pci_dev->resource
- *                       'start' and 'end' addresses to mapped addresses,
- *                       and setup the pci_controller->window array entries.
- */
-void
-sn_io_slot_fixup(struct pci_dev *dev)
-{
-       int idx;
-       struct resource *res;
-       unsigned long size;
-       struct pcidev_info *pcidev_info;
-       struct sn_irq_info *sn_irq_info;
-       int status;
-
-       pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL);
-       if (!pcidev_info)
-               panic("%s: Unable to alloc memory for pcidev_info", __func__);
-
-       sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
-       if (!sn_irq_info)
-               panic("%s: Unable to alloc memory for sn_irq_info", __func__);
-
-       /* Call to retrieve pci device information needed by kernel. */
-       status = sal_get_pcidev_info((u64) pci_domain_nr(dev),
-               (u64) dev->bus->number,
-               dev->devfn,
-               (u64) __pa(pcidev_info),
-               (u64) __pa(sn_irq_info));
-
-       BUG_ON(status); /* Cannot get platform pci device information */
-
-
-       /* Copy over PIO Mapped Addresses */
-       for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) {
-               if (!pcidev_info->pdi_pio_mapped_addr[idx])
-                       continue;
-
-               res = &dev->resource[idx];
-
-               size = res->end - res->start;
-               if (size == 0)
-                       continue;
-
-               res->start = pcidev_info->pdi_pio_mapped_addr[idx];
-               res->end = res->start + size;
-
-               /*
-                * if it's already in the device structure, remove it before
-                * inserting
-                */
-               if (res->parent && res->parent->child)
-                       release_resource(res);
-
-               if (res->flags & IORESOURCE_IO)
-                       insert_resource(&ioport_resource, res);
-               else
-                       insert_resource(&iomem_resource, res);
-               /*
-                * If ROM, mark as shadowed in PROM.
-                */
-               if (idx == PCI_ROM_RESOURCE) {
-                       pci_disable_rom(dev);
-                       res->flags = IORESOURCE_MEM | IORESOURCE_ROM_SHADOW |
-                                    IORESOURCE_PCI_FIXED;
-               }
-       }
-
-       sn_pci_fixup_slot(dev, pcidev_info, sn_irq_info);
-}
-EXPORT_SYMBOL(sn_io_slot_fixup);
-
-/*
- * sn_pci_controller_fixup() - This routine sets up a bus's resources
- *                            consistent with the Linux PCI abstraction layer.
- */
-static void __init
-sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
-{
-       s64 status = 0;
-       struct pci_controller *controller;
-       struct pcibus_bussoft *prom_bussoft_ptr;
-       struct resource *res;
-       LIST_HEAD(resources);
-
-       status = sal_get_pcibus_info((u64) segment, (u64) busnum,
-                                    (u64) ia64_tpa(&prom_bussoft_ptr));
-       if (status > 0)
-               return;         /*bus # does not exist */
-       prom_bussoft_ptr = __va(prom_bussoft_ptr);
-
-       controller = kzalloc(sizeof(*controller), GFP_KERNEL);
-       BUG_ON(!controller);
-       controller->segment = segment;
-
-       res = kcalloc(2, sizeof(struct resource), GFP_KERNEL);
-       BUG_ON(!res);
-
-       /*
-        * Temporarily save the prom_bussoft_ptr for use by sn_bus_fixup().
-        * (platform_data will be overwritten later in sn_common_bus_fixup())
-        */
-       controller->platform_data = prom_bussoft_ptr;
-
-       sn_legacy_pci_window_fixup(res,
-                       prom_bussoft_ptr->bs_legacy_io,
-                       prom_bussoft_ptr->bs_legacy_mem);
-       pci_add_resource_offset(&resources,     &res[0],
-                       prom_bussoft_ptr->bs_legacy_io);
-       pci_add_resource_offset(&resources,     &res[1],
-                       prom_bussoft_ptr->bs_legacy_mem);
-
-       bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller,
-                               &resources);
-       if (bus == NULL) {
-               kfree(res);
-               kfree(controller);
-               return;
-       }
-       pci_bus_add_devices(bus);
-}
-
-/*
- * sn_bus_fixup
- */
-void
-sn_bus_fixup(struct pci_bus *bus)
-{
-       struct pci_dev *pci_dev = NULL;
-       struct pcibus_bussoft *prom_bussoft_ptr;
-
-       if (!bus->parent) {  /* If root bus */
-               prom_bussoft_ptr = PCI_CONTROLLER(bus)->platform_data;
-               if (prom_bussoft_ptr == NULL) {
-                       printk(KERN_ERR
-                              "sn_bus_fixup: 0x%04x:0x%02x Unable to "
-                              "obtain prom_bussoft_ptr\n",
-                              pci_domain_nr(bus), bus->number);
-                       return;
-               }
-               sn_common_bus_fixup(bus, prom_bussoft_ptr);
-        }
-        list_for_each_entry(pci_dev, &bus->devices, bus_list) {
-                sn_io_slot_fixup(pci_dev);
-        }
-
-}
-
-/*
- * sn_io_init - PROM does not have ACPI support to define nodes or root buses,
- *             so we need to do things the hard way, including initiating the
- *             bus scanning ourselves.
- */
-
-void __init sn_io_init(void)
-{
-       int i, j;
-
-       sn_fixup_ionodes();
-
-       /* busses are not known yet ... */
-       for (i = 0; i <= max_segment_number; i++)
-               for (j = 0; j <= max_pcibus_number; j++)
-                       sn_pci_controller_fixup(i, j, NULL);
-}
diff --git a/arch/ia64/sn/kernel/iomv.c b/arch/ia64/sn/kernel/iomv.c
deleted file mode 100644 (file)
index 2b22a71..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2003, 2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/module.h>
-#include <linux/acpi.h>
-#include <asm/io.h>
-#include <asm/delay.h>
-#include <asm/vga.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/pda.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/shub_mmr.h>
-#include <asm/sn/acpi.h>
-
-#define IS_LEGACY_VGA_IOPORT(p) \
-       (((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df))
-
-/**
- * sn_io_addr - convert an in/out port to an i/o address
- * @port: port to convert
- *
- * Legacy in/out instructions are converted to ld/st instructions
- * on IA64.  This routine will convert a port number into a valid
- * SN i/o address.  Used by sn_in*() and sn_out*().
- */
-
-void *sn_io_addr(unsigned long port)
-{
-       if (!IS_RUNNING_ON_SIMULATOR()) {
-               if (IS_LEGACY_VGA_IOPORT(port))
-                       return (__ia64_mk_io_addr(port));
-               /* On sn2, legacy I/O ports don't point at anything */
-               if (port < (64 * 1024))
-                       return NULL;
-               if (SN_ACPI_BASE_SUPPORT())
-                       return (__ia64_mk_io_addr(port));
-               else
-                       return ((void *)(port | __IA64_UNCACHED_OFFSET));
-       } else {
-               /* but the simulator uses them... */
-               unsigned long addr;
-
-               /*
-                * word align port, but need more than 10 bits
-                * for accessing registers in bedrock local block
-                * (so we don't do port&0xfff)
-                */
-               addr = (is_shub2() ? 0xc00000028c000000UL : 0xc0000087cc000000UL) | ((port >> 2) << 12);
-               if ((port >= 0x1f0 && port <= 0x1f7) || port == 0x3f6 || port == 0x3f7)
-                       addr |= port;
-               return (void *)addr;
-       }
-}
-
-EXPORT_SYMBOL(sn_io_addr);
-
-/**
- * __sn_mmiowb - I/O space memory barrier
- *
- * See arch/ia64/include/asm/io.h and Documentation/driver-api/device-io.rst
- * for details.
- *
- * On SN2, we wait for the PIO_WRITE_STATUS SHub register to clear.
- * See PV 871084 for details about the WAR about zero value.
- *
- */
-void __sn_mmiowb(void)
-{
-       volatile unsigned long *adr = pda->pio_write_status_addr;
-       unsigned long val = pda->pio_write_status_val;
-
-       while ((*adr & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != val)
-               cpu_relax();
-}
-
-EXPORT_SYMBOL(__sn_mmiowb);
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
deleted file mode 100644 (file)
index d9b576d..0000000
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * Platform dependent support for SGI SN
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2000-2008 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/irq.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/rculist.h>
-#include <linux/slab.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/pcibr_provider.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/shub_mmr.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_feature_sets.h>
-
-static void register_intr_pda(struct sn_irq_info *sn_irq_info);
-static void unregister_intr_pda(struct sn_irq_info *sn_irq_info);
-
-extern int sn_ioif_inited;
-struct list_head **sn_irq_lh;
-static DEFINE_SPINLOCK(sn_irq_info_lock); /* non-IRQ lock */
-
-u64 sn_intr_alloc(nasid_t local_nasid, int local_widget,
-                                    struct sn_irq_info *sn_irq_info,
-                                    int req_irq, nasid_t req_nasid,
-                                    int req_slice)
-{
-       struct ia64_sal_retval ret_stuff;
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT,
-                       (u64) SAL_INTR_ALLOC, (u64) local_nasid,
-                       (u64) local_widget, __pa(sn_irq_info), (u64) req_irq,
-                       (u64) req_nasid, (u64) req_slice);
-
-       return ret_stuff.status;
-}
-
-void sn_intr_free(nasid_t local_nasid, int local_widget,
-                               struct sn_irq_info *sn_irq_info)
-{
-       struct ia64_sal_retval ret_stuff;
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT,
-                       (u64) SAL_INTR_FREE, (u64) local_nasid,
-                       (u64) local_widget, (u64) sn_irq_info->irq_irq,
-                       (u64) sn_irq_info->irq_cookie, 0, 0);
-}
-
-u64 sn_intr_redirect(nasid_t local_nasid, int local_widget,
-                     struct sn_irq_info *sn_irq_info,
-                     nasid_t req_nasid, int req_slice)
-{
-       struct ia64_sal_retval ret_stuff;
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT,
-                       (u64) SAL_INTR_REDIRECT, (u64) local_nasid,
-                       (u64) local_widget, __pa(sn_irq_info),
-                       (u64) req_nasid, (u64) req_slice, 0);
-
-       return ret_stuff.status;
-}
-
-static unsigned int sn_startup_irq(struct irq_data *data)
-{
-       return 0;
-}
-
-static void sn_shutdown_irq(struct irq_data *data)
-{
-}
-
-extern void ia64_mca_register_cpev(int);
-
-static void sn_disable_irq(struct irq_data *data)
-{
-       if (data->irq == local_vector_to_irq(IA64_CPE_VECTOR))
-               ia64_mca_register_cpev(0);
-}
-
-static void sn_enable_irq(struct irq_data *data)
-{
-       if (data->irq == local_vector_to_irq(IA64_CPE_VECTOR))
-               ia64_mca_register_cpev(data->irq);
-}
-
-static void sn_ack_irq(struct irq_data *data)
-{
-       u64 event_occurred, mask;
-       unsigned int irq = data->irq & 0xff;
-
-       event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED));
-       mask = event_occurred & SH_ALL_INT_MASK;
-       HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), mask);
-       __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
-
-       irq_move_irq(data);
-}
-
-struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info,
-                                      nasid_t nasid, int slice)
-{
-       int vector;
-       int cpuid;
-#ifdef CONFIG_SMP
-       int cpuphys;
-#endif
-       int64_t bridge;
-       int local_widget, status;
-       nasid_t local_nasid;
-       struct sn_irq_info *new_irq_info;
-       struct sn_pcibus_provider *pci_provider;
-
-       bridge = (u64) sn_irq_info->irq_bridge;
-       if (!bridge) {
-               return NULL; /* irq is not a device interrupt */
-       }
-
-       local_nasid = NASID_GET(bridge);
-
-       if (local_nasid & 1)
-               local_widget = TIO_SWIN_WIDGETNUM(bridge);
-       else
-               local_widget = SWIN_WIDGETNUM(bridge);
-       vector = sn_irq_info->irq_irq;
-
-       /* Make use of SAL_INTR_REDIRECT if PROM supports it */
-       status = sn_intr_redirect(local_nasid, local_widget, sn_irq_info, nasid, slice);
-       if (!status) {
-               new_irq_info = sn_irq_info;
-               goto finish_up;
-       }
-
-       /*
-        * PROM does not support SAL_INTR_REDIRECT, or it failed.
-        * Revert to old method.
-        */
-       new_irq_info = kmemdup(sn_irq_info, sizeof(struct sn_irq_info),
-                              GFP_ATOMIC);
-       if (new_irq_info == NULL)
-               return NULL;
-
-       /* Free the old PROM new_irq_info structure */
-       sn_intr_free(local_nasid, local_widget, new_irq_info);
-       unregister_intr_pda(new_irq_info);
-
-       /* allocate a new PROM new_irq_info struct */
-       status = sn_intr_alloc(local_nasid, local_widget,
-                              new_irq_info, vector,
-                              nasid, slice);
-
-       /* SAL call failed */
-       if (status) {
-               kfree(new_irq_info);
-               return NULL;
-       }
-
-       register_intr_pda(new_irq_info);
-       spin_lock(&sn_irq_info_lock);
-       list_replace_rcu(&sn_irq_info->list, &new_irq_info->list);
-       spin_unlock(&sn_irq_info_lock);
-       kfree_rcu(sn_irq_info, rcu);
-
-
-finish_up:
-       /* Update kernels new_irq_info with new target info */
-       cpuid = nasid_slice_to_cpuid(new_irq_info->irq_nasid,
-                                    new_irq_info->irq_slice);
-       new_irq_info->irq_cpuid = cpuid;
-
-       pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type];
-
-       /*
-        * If this represents a line interrupt, target it.  If it's
-        * an msi (irq_int_bit < 0), it's already targeted.
-        */
-       if (new_irq_info->irq_int_bit >= 0 &&
-           pci_provider && pci_provider->target_interrupt)
-               (pci_provider->target_interrupt)(new_irq_info);
-
-#ifdef CONFIG_SMP
-       cpuphys = cpu_physical_id(cpuid);
-       set_irq_affinity_info((vector & 0xff), cpuphys, 0);
-#endif
-
-       return new_irq_info;
-}
-
-static int sn_set_affinity_irq(struct irq_data *data,
-                              const struct cpumask *mask, bool force)
-{
-       struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
-       unsigned int irq = data->irq;
-       nasid_t nasid;
-       int slice;
-
-       nasid = cpuid_to_nasid(cpumask_first_and(mask, cpu_online_mask));
-       slice = cpuid_to_slice(cpumask_first_and(mask, cpu_online_mask));
-
-       list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe,
-                                sn_irq_lh[irq], list)
-               (void)sn_retarget_vector(sn_irq_info, nasid, slice);
-
-       return 0;
-}
-
-#ifdef CONFIG_SMP
-void sn_set_err_irq_affinity(unsigned int irq)
-{
-        /*
-         * On systems which support CPU disabling (SHub2), all error interrupts
-         * are targeted at the boot CPU.
-         */
-        if (is_shub2() && sn_prom_feature_available(PRF_CPU_DISABLE_SUPPORT))
-                set_irq_affinity_info(irq, cpu_physical_id(0), 0);
-}
-#else
-void sn_set_err_irq_affinity(unsigned int irq) { }
-#endif
-
-static void
-sn_mask_irq(struct irq_data *data)
-{
-}
-
-static void
-sn_unmask_irq(struct irq_data *data)
-{
-}
-
-struct irq_chip irq_type_sn = {
-       .name                   = "SN hub",
-       .irq_startup            = sn_startup_irq,
-       .irq_shutdown           = sn_shutdown_irq,
-       .irq_enable             = sn_enable_irq,
-       .irq_disable            = sn_disable_irq,
-       .irq_ack                = sn_ack_irq,
-       .irq_mask               = sn_mask_irq,
-       .irq_unmask             = sn_unmask_irq,
-       .irq_set_affinity       = sn_set_affinity_irq
-};
-
-ia64_vector sn_irq_to_vector(int irq)
-{
-       if (irq >= IA64_NUM_VECTORS)
-               return 0;
-       return (ia64_vector)irq;
-}
-
-unsigned int sn_local_vector_to_irq(u8 vector)
-{
-       return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector));
-}
-
-void sn_irq_init(void)
-{
-       int i;
-
-       ia64_first_device_vector = IA64_SN2_FIRST_DEVICE_VECTOR;
-       ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR;
-
-       for (i = 0; i < NR_IRQS; i++) {
-               if (irq_get_chip(i) == &no_irq_chip)
-                       irq_set_chip(i, &irq_type_sn);
-       }
-}
-
-static void register_intr_pda(struct sn_irq_info *sn_irq_info)
-{
-       int irq = sn_irq_info->irq_irq;
-       int cpu = sn_irq_info->irq_cpuid;
-
-       if (pdacpu(cpu)->sn_last_irq < irq) {
-               pdacpu(cpu)->sn_last_irq = irq;
-       }
-
-       if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq)
-               pdacpu(cpu)->sn_first_irq = irq;
-}
-
-static void unregister_intr_pda(struct sn_irq_info *sn_irq_info)
-{
-       int irq = sn_irq_info->irq_irq;
-       int cpu = sn_irq_info->irq_cpuid;
-       struct sn_irq_info *tmp_irq_info;
-       int i, foundmatch;
-
-       rcu_read_lock();
-       if (pdacpu(cpu)->sn_last_irq == irq) {
-               foundmatch = 0;
-               for (i = pdacpu(cpu)->sn_last_irq - 1;
-                    i && !foundmatch; i--) {
-                       list_for_each_entry_rcu(tmp_irq_info,
-                                               sn_irq_lh[i],
-                                               list) {
-                               if (tmp_irq_info->irq_cpuid == cpu) {
-                                       foundmatch = 1;
-                                       break;
-                               }
-                       }
-               }
-               pdacpu(cpu)->sn_last_irq = i;
-       }
-
-       if (pdacpu(cpu)->sn_first_irq == irq) {
-               foundmatch = 0;
-               for (i = pdacpu(cpu)->sn_first_irq + 1;
-                    i < NR_IRQS && !foundmatch; i++) {
-                       list_for_each_entry_rcu(tmp_irq_info,
-                                               sn_irq_lh[i],
-                                               list) {
-                               if (tmp_irq_info->irq_cpuid == cpu) {
-                                       foundmatch = 1;
-                                       break;
-                               }
-                       }
-               }
-               pdacpu(cpu)->sn_first_irq = ((i == NR_IRQS) ? 0 : i);
-       }
-       rcu_read_unlock();
-}
-
-void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info)
-{
-       nasid_t nasid = sn_irq_info->irq_nasid;
-       int slice = sn_irq_info->irq_slice;
-       int cpu = nasid_slice_to_cpuid(nasid, slice);
-#ifdef CONFIG_SMP
-       int cpuphys;
-#endif
-
-       pci_dev_get(pci_dev);
-       sn_irq_info->irq_cpuid = cpu;
-       sn_irq_info->irq_pciioinfo = SN_PCIDEV_INFO(pci_dev);
-
-       /* link it into the sn_irq[irq] list */
-       spin_lock(&sn_irq_info_lock);
-       list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]);
-       reserve_irq_vector(sn_irq_info->irq_irq);
-       if (sn_irq_info->irq_int_bit != -1)
-               irq_set_handler(sn_irq_info->irq_irq, handle_level_irq);
-       spin_unlock(&sn_irq_info_lock);
-
-       register_intr_pda(sn_irq_info);
-#ifdef CONFIG_SMP
-       cpuphys = cpu_physical_id(cpu);
-       set_irq_affinity_info(sn_irq_info->irq_irq, cpuphys, 0);
-       /*
-        * Affinity was set by the PROM, prevent it from
-        * being reset by the request_irq() path.
-        */
-       irqd_mark_affinity_was_set(irq_get_irq_data(sn_irq_info->irq_irq));
-#endif
-}
-
-void sn_irq_unfixup(struct pci_dev *pci_dev)
-{
-       struct sn_irq_info *sn_irq_info;
-
-       /* Only cleanup IRQ stuff if this device has a host bus context */
-       if (!SN_PCIDEV_BUSSOFT(pci_dev))
-               return;
-
-       sn_irq_info = SN_PCIDEV_INFO(pci_dev)->pdi_sn_irq_info;
-       if (!sn_irq_info)
-               return;
-       if (!sn_irq_info->irq_irq) {
-               kfree(sn_irq_info);
-               return;
-       }
-
-       unregister_intr_pda(sn_irq_info);
-       spin_lock(&sn_irq_info_lock);
-       list_del_rcu(&sn_irq_info->list);
-       spin_unlock(&sn_irq_info_lock);
-       if (list_empty(sn_irq_lh[sn_irq_info->irq_irq]))
-               free_irq_vector(sn_irq_info->irq_irq);
-       kfree_rcu(sn_irq_info, rcu);
-       pci_dev_put(pci_dev);
-
-}
-
-static inline void
-sn_call_force_intr_provider(struct sn_irq_info *sn_irq_info)
-{
-       struct sn_pcibus_provider *pci_provider;
-
-       pci_provider = sn_pci_provider[sn_irq_info->irq_bridge_type];
-
-       /* Don't force an interrupt if the irq has been disabled */
-       if (!irqd_irq_disabled(irq_get_irq_data(sn_irq_info->irq_irq)) &&
-           pci_provider && pci_provider->force_interrupt)
-               (*pci_provider->force_interrupt)(sn_irq_info);
-}
-
-/*
- * Check for lost interrupts.  If the PIC int_status reg. says that
- * an interrupt has been sent, but not handled, and the interrupt
- * is not pending in either the cpu irr regs or in the soft irr regs,
- * and the interrupt is not in service, then the interrupt may have
- * been lost.  Force an interrupt on that pin.  It is possible that
- * the interrupt is in flight, so we may generate a spurious interrupt,
- * but we should never miss a real lost interrupt.
- */
-static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info)
-{
-       u64 regval;
-       struct pcidev_info *pcidev_info;
-       struct pcibus_info *pcibus_info;
-
-       /*
-        * Bridge types attached to TIO (anything but PIC) do not need this WAR
-        * since they do not target Shub II interrupt registers.  If that
-        * ever changes, this check needs to accommodate.
-        */
-       if (sn_irq_info->irq_bridge_type != PCIIO_ASIC_TYPE_PIC)
-               return;
-
-       pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
-       if (!pcidev_info)
-               return;
-
-       pcibus_info =
-           (struct pcibus_info *)pcidev_info->pdi_host_pcidev_info->
-           pdi_pcibus_info;
-       regval = pcireg_intr_status_get(pcibus_info);
-
-       if (!ia64_get_irr(irq_to_vector(irq))) {
-               if (!test_bit(irq, pda->sn_in_service_ivecs)) {
-                       regval &= 0xff;
-                       if (sn_irq_info->irq_int_bit & regval &
-                           sn_irq_info->irq_last_intr) {
-                               regval &= ~(sn_irq_info->irq_int_bit & regval);
-                               sn_call_force_intr_provider(sn_irq_info);
-                       }
-               }
-       }
-       sn_irq_info->irq_last_intr = regval;
-}
-
-void sn_lb_int_war_check(void)
-{
-       struct sn_irq_info *sn_irq_info;
-       int i;
-
-       if (!sn_ioif_inited || pda->sn_first_irq == 0)
-               return;
-
-       rcu_read_lock();
-       for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) {
-               list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[i], list) {
-                       sn_check_intr(i, sn_irq_info);
-               }
-       }
-       rcu_read_unlock();
-}
-
-void __init sn_irq_lh_init(void)
-{
-       int i;
-
-       sn_irq_lh = kmalloc_array(NR_IRQS, sizeof(struct list_head *),
-                                 GFP_KERNEL);
-       if (!sn_irq_lh)
-               panic("SN PCI INIT: Failed to allocate memory for PCI init\n");
-
-       for (i = 0; i < NR_IRQS; i++) {
-               sn_irq_lh[i] = kmalloc(sizeof(struct list_head), GFP_KERNEL);
-               if (!sn_irq_lh[i])
-                       panic("SN PCI INIT: Failed IRQ memory allocation\n");
-
-               INIT_LIST_HEAD(sn_irq_lh[i]);
-       }
-}
diff --git a/arch/ia64/sn/kernel/klconflib.c b/arch/ia64/sn/kernel/klconflib.c
deleted file mode 100644 (file)
index 87682b4..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1992 - 1997, 2000-2004 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <asm/sn/types.h>
-#include <asm/sn/module.h>
-#include <asm/sn/l1.h>
-
-char brick_types[MAX_BRICK_TYPES + 1] = "cri.xdpn%#=vo^kjbf890123456789...";
-/*
- * Format a module id for printing.
- *
- * There are three possible formats:
- *
- *   MODULE_FORMAT_BRIEF       is the brief 6-character format, including
- *                             the actual brick-type as recorded in the 
- *                             moduleid_t, eg. 002c15 for a C-brick, or
- *                             101#17 for a PX-brick.
- *
- *   MODULE_FORMAT_LONG                is the hwgraph format, eg. rack/002/bay/15
- *                             of rack/101/bay/17 (note that the brick
- *                             type does not appear in this format).
- *
- *   MODULE_FORMAT_LCD         is like MODULE_FORMAT_BRIEF, except that it
- *                             ensures that the module id provided appears
- *                             exactly as it would on the LCD display of
- *                             the corresponding brick, eg. still 002c15
- *                             for a C-brick, but 101p17 for a PX-brick.
- *
- * maule (9/13/04):  Removed top-level check for (fmt == MODULE_FORMAT_LCD)
- * making MODULE_FORMAT_LCD equivalent to MODULE_FORMAT_BRIEF.  It was
- * decided that all callers should assume the returned string should be what
- * is displayed on the brick L1 LCD.
- */
-void
-format_module_id(char *buffer, moduleid_t m, int fmt)
-{
-       int rack, position;
-       unsigned char brickchar;
-
-       rack = MODULE_GET_RACK(m);
-       brickchar = MODULE_GET_BTCHAR(m);
-
-       /* Be sure we use the same brick type character as displayed
-        * on the brick's LCD
-        */
-       switch (brickchar) 
-       {
-       case L1_BRICKTYPE_GA:
-       case L1_BRICKTYPE_OPUS_TIO:
-               brickchar = L1_BRICKTYPE_C;
-               break;
-
-       case L1_BRICKTYPE_PX:
-       case L1_BRICKTYPE_PE:
-       case L1_BRICKTYPE_PA:
-       case L1_BRICKTYPE_SA: /* we can move this to the "I's" later
-                              * if that makes more sense
-                              */
-               brickchar = L1_BRICKTYPE_P;
-               break;
-
-       case L1_BRICKTYPE_IX:
-       case L1_BRICKTYPE_IA:
-
-               brickchar = L1_BRICKTYPE_I;
-               break;
-       }
-
-       position = MODULE_GET_BPOS(m);
-
-       if ((fmt == MODULE_FORMAT_BRIEF) || (fmt == MODULE_FORMAT_LCD)) {
-               /* Brief module number format, eg. 002c15 */
-
-               /* Decompress the rack number */
-               *buffer++ = '0' + RACK_GET_CLASS(rack);
-               *buffer++ = '0' + RACK_GET_GROUP(rack);
-               *buffer++ = '0' + RACK_GET_NUM(rack);
-
-               /* Add the brick type */
-               *buffer++ = brickchar;
-       }
-       else if (fmt == MODULE_FORMAT_LONG) {
-               /* Fuller hwgraph format, eg. rack/002/bay/15 */
-
-               strcpy(buffer, "rack" "/");  buffer += strlen(buffer);
-
-               *buffer++ = '0' + RACK_GET_CLASS(rack);
-               *buffer++ = '0' + RACK_GET_GROUP(rack);
-               *buffer++ = '0' + RACK_GET_NUM(rack);
-
-               strcpy(buffer, "/" "bay" "/");  buffer += strlen(buffer);
-       }
-
-       /* Add the bay position, using at least two digits */
-       if (position < 10)
-               *buffer++ = '0';
-       sprintf(buffer, "%d", position);
-}
diff --git a/arch/ia64/sn/kernel/machvec.c b/arch/ia64/sn/kernel/machvec.c
deleted file mode 100644 (file)
index 02bb915..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#define MACHVEC_PLATFORM_NAME  sn2
-#define MACHVEC_PLATFORM_HEADER        <asm/machvec_sn2.h>
-#include <asm/machvec_init.h>
diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c
deleted file mode 100644 (file)
index bc3bd93..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/vmalloc.h>
-#include <linux/mutex.h>
-#include <asm/mca.h>
-#include <asm/sal.h>
-#include <asm/sn/sn_sal.h>
-
-/*
- * Interval for calling SAL to poll for errors that do NOT cause error
- * interrupts. SAL will raise a CPEI if any errors are present that
- * need to be logged.
- */
-#define CPEI_INTERVAL  (5*HZ)
-
-struct timer_list sn_cpei_timer;
-void sn_init_cpei_timer(void);
-
-/* Printing oemdata from mca uses data that is not passed through SAL, it is
- * global.  Only one user at a time.
- */
-static DEFINE_MUTEX(sn_oemdata_mutex);
-static u8 **sn_oemdata;
-static u64 *sn_oemdata_size, sn_oemdata_bufsize;
-
-/*
- * print_hook
- *
- * This function is the callback routine that SAL calls to log error
- * info for platform errors.  buf is appended to sn_oemdata, resizing as
- * required.
- * Note: this is a SAL to OS callback, running under the same rules as the SAL
- * code.  SAL calls are run with preempt disabled so this routine must not
- * sleep.  vmalloc can sleep so print_hook cannot resize the output buffer
- * itself, instead it must set the required size and return to let the caller
- * resize the buffer then redrive the SAL call.
- */
-static int print_hook(const char *fmt, ...)
-{
-       char buf[400];
-       int len;
-       va_list args;
-       va_start(args, fmt);
-       vsnprintf(buf, sizeof(buf), fmt, args);
-       va_end(args);
-       len = strlen(buf);
-       if (*sn_oemdata_size + len <= sn_oemdata_bufsize)
-               memcpy(*sn_oemdata + *sn_oemdata_size, buf, len);
-       *sn_oemdata_size += len;
-       return 0;
-}
-
-static void sn_cpei_handler(int irq, void *devid, struct pt_regs *regs)
-{
-       /*
-        * this function's sole purpose is to call SAL when we receive
-        * a CE interrupt from SHUB or when the timer routine decides
-        * we need to call SAL to check for CEs.
-        */
-
-       /* CALL SAL_LOG_CE */
-
-       ia64_sn_plat_cpei_handler();
-}
-
-static void sn_cpei_timer_handler(struct timer_list *unused)
-{
-       sn_cpei_handler(-1, NULL, NULL);
-       mod_timer(&sn_cpei_timer, jiffies + CPEI_INTERVAL);
-}
-
-void sn_init_cpei_timer(void)
-{
-       timer_setup(&sn_cpei_timer, sn_cpei_timer_handler, 0);
-       sn_cpei_timer.expires = jiffies + CPEI_INTERVAL;
-       add_timer(&sn_cpei_timer);
-}
-
-static int
-sn_platform_plat_specific_err_print(const u8 * sect_header, u8 ** oemdata,
-                                   u64 * oemdata_size)
-{
-       mutex_lock(&sn_oemdata_mutex);
-       sn_oemdata = oemdata;
-       sn_oemdata_size = oemdata_size;
-       sn_oemdata_bufsize = 0;
-       *sn_oemdata_size = PAGE_SIZE;   /* first guess at how much data will be generated */
-       while (*sn_oemdata_size > sn_oemdata_bufsize) {
-               u8 *newbuf = vmalloc(*sn_oemdata_size);
-               if (!newbuf) {
-                       mutex_unlock(&sn_oemdata_mutex);
-                       printk(KERN_ERR "%s: unable to extend sn_oemdata\n",
-                              __func__);
-                       return 1;
-               }
-               vfree(*sn_oemdata);
-               *sn_oemdata = newbuf;
-               sn_oemdata_bufsize = *sn_oemdata_size;
-               *sn_oemdata_size = 0;
-               ia64_sn_plat_specific_err_print(print_hook, (char *)sect_header);
-       }
-       mutex_unlock(&sn_oemdata_mutex);
-       return 0;
-}
-
-/* Callback when userspace salinfo wants to decode oem data via the platform
- * kernel and/or prom.
- */
-int sn_salinfo_platform_oemdata(const u8 *sect_header, u8 **oemdata, u64 *oemdata_size)
-{
-       efi_guid_t guid = *(efi_guid_t *)sect_header;
-       int valid = 0;
-       *oemdata_size = 0;
-       vfree(*oemdata);
-       *oemdata = NULL;
-       if (efi_guidcmp(guid, SAL_PLAT_SPECIFIC_ERR_SECT_GUID) == 0) {
-               sal_log_plat_specific_err_info_t *psei = (sal_log_plat_specific_err_info_t *)sect_header;
-               valid = psei->valid.oem_data;
-       } else if (efi_guidcmp(guid, SAL_PLAT_MEM_DEV_ERR_SECT_GUID) == 0) {
-               sal_log_mem_dev_err_info_t *mdei = (sal_log_mem_dev_err_info_t *)sect_header;
-               valid = mdei->valid.oem_data;
-       }
-       if (valid)
-               return sn_platform_plat_specific_err_print(sect_header, oemdata, oemdata_size);
-       else
-               return 0;
-}
-
-static int __init sn_salinfo_init(void)
-{
-       if (ia64_platform_is("sn2"))
-               salinfo_platform_oemdata = &sn_salinfo_platform_oemdata;
-       return 0;
-}
-device_initcall(sn_salinfo_init);
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
deleted file mode 100644 (file)
index fb25065..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2006 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/types.h>
-#include <linux/irq.h>
-#include <linux/pci.h>
-#include <linux/cpumask.h>
-#include <linux/msi.h>
-#include <linux/slab.h>
-
-#include <asm/sn/addrs.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/nodepda.h>
-
-struct sn_msi_info {
-       u64 pci_addr;
-       struct sn_irq_info *sn_irq_info;
-};
-
-static struct sn_msi_info sn_msi_info[NR_IRQS];
-
-static struct irq_chip sn_msi_chip;
-
-void sn_teardown_msi_irq(unsigned int irq)
-{
-       nasid_t nasid;
-       int widget;
-       struct pci_dev *pdev;
-       struct pcidev_info *sn_pdev;
-       struct sn_irq_info *sn_irq_info;
-       struct pcibus_bussoft *bussoft;
-       struct sn_pcibus_provider *provider;
-
-       sn_irq_info = sn_msi_info[irq].sn_irq_info;
-       if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
-               return;
-
-       sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
-       pdev = sn_pdev->pdi_linux_pcidev;
-       provider = SN_PCIDEV_BUSPROVIDER(pdev);
-
-       (*provider->dma_unmap)(pdev,
-                              sn_msi_info[irq].pci_addr,
-                              PCI_DMA_FROMDEVICE);
-       sn_msi_info[irq].pci_addr = 0;
-
-       bussoft = SN_PCIDEV_BUSSOFT(pdev);
-       nasid = NASID_GET(bussoft->bs_base);
-       widget = (nasid & 1) ?
-                       TIO_SWIN_WIDGETNUM(bussoft->bs_base) :
-                       SWIN_WIDGETNUM(bussoft->bs_base);
-
-       sn_intr_free(nasid, widget, sn_irq_info);
-       sn_msi_info[irq].sn_irq_info = NULL;
-
-       destroy_irq(irq);
-}
-
-int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry)
-{
-       struct msi_msg msg;
-       int widget;
-       int status;
-       nasid_t nasid;
-       u64 bus_addr;
-       struct sn_irq_info *sn_irq_info;
-       struct pcibus_bussoft *bussoft = SN_PCIDEV_BUSSOFT(pdev);
-       struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
-       int irq;
-
-       if (!entry->msi_attrib.is_64)
-               return -EINVAL;
-
-       if (bussoft == NULL)
-               return -EINVAL;
-
-       if (provider == NULL || provider->dma_map_consistent == NULL)
-               return -EINVAL;
-
-       irq = create_irq();
-       if (irq < 0)
-               return irq;
-
-       /*
-        * Set up the vector plumbing.  Let the prom (via sn_intr_alloc)
-        * decide which cpu to direct this msi at by default.
-        */
-
-       nasid = NASID_GET(bussoft->bs_base);
-       widget = (nasid & 1) ?
-                       TIO_SWIN_WIDGETNUM(bussoft->bs_base) :
-                       SWIN_WIDGETNUM(bussoft->bs_base);
-
-       sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL);
-       if (! sn_irq_info) {
-               destroy_irq(irq);
-               return -ENOMEM;
-       }
-
-       status = sn_intr_alloc(nasid, widget, sn_irq_info, irq, -1, -1);
-       if (status) {
-               kfree(sn_irq_info);
-               destroy_irq(irq);
-               return -ENOMEM;
-       }
-
-       sn_irq_info->irq_int_bit = -1;          /* mark this as an MSI irq */
-       sn_irq_fixup(pdev, sn_irq_info);
-
-       /* Prom probably should fill these in, but doesn't ... */
-       sn_irq_info->irq_bridge_type = bussoft->bs_asic_type;
-       sn_irq_info->irq_bridge = (void *)bussoft->bs_base;
-
-       /*
-        * Map the xio address into bus space
-        */
-       bus_addr = (*provider->dma_map_consistent)(pdev,
-                                       sn_irq_info->irq_xtalkaddr,
-                                       sizeof(sn_irq_info->irq_xtalkaddr),
-                                       SN_DMA_MSI|SN_DMA_ADDR_XIO);
-       if (! bus_addr) {
-               sn_intr_free(nasid, widget, sn_irq_info);
-               kfree(sn_irq_info);
-               destroy_irq(irq);
-               return -ENOMEM;
-       }
-
-       sn_msi_info[irq].sn_irq_info = sn_irq_info;
-       sn_msi_info[irq].pci_addr = bus_addr;
-
-       msg.address_hi = (u32)(bus_addr >> 32);
-       msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
-
-       /*
-        * In the SN platform, bit 16 is a "send vector" bit which
-        * must be present in order to move the vector through the system.
-        */
-       msg.data = 0x100 + irq;
-
-       irq_set_msi_desc(irq, entry);
-       pci_write_msi_msg(irq, &msg);
-       irq_set_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq);
-
-       return 0;
-}
-
-#ifdef CONFIG_SMP
-static int sn_set_msi_irq_affinity(struct irq_data *data,
-                                  const struct cpumask *cpu_mask, bool force)
-{
-       struct msi_msg msg;
-       int slice;
-       nasid_t nasid;
-       u64 bus_addr;
-       struct pci_dev *pdev;
-       struct pcidev_info *sn_pdev;
-       struct sn_irq_info *sn_irq_info;
-       struct sn_irq_info *new_irq_info;
-       struct sn_pcibus_provider *provider;
-       unsigned int cpu, irq = data->irq;
-
-       cpu = cpumask_first_and(cpu_mask, cpu_online_mask);
-       sn_irq_info = sn_msi_info[irq].sn_irq_info;
-       if (sn_irq_info == NULL || sn_irq_info->irq_int_bit >= 0)
-               return -1;
-
-       /*
-        * Release XIO resources for the old MSI PCI address
-        */
-
-       __get_cached_msi_msg(irq_data_get_msi_desc(data), &msg);
-       sn_pdev = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
-       pdev = sn_pdev->pdi_linux_pcidev;
-       provider = SN_PCIDEV_BUSPROVIDER(pdev);
-
-       bus_addr = (u64)(msg.address_hi) << 32 | (u64)(msg.address_lo);
-       (*provider->dma_unmap)(pdev, bus_addr, PCI_DMA_FROMDEVICE);
-       sn_msi_info[irq].pci_addr = 0;
-
-       nasid = cpuid_to_nasid(cpu);
-       slice = cpuid_to_slice(cpu);
-
-       new_irq_info = sn_retarget_vector(sn_irq_info, nasid, slice);
-       sn_msi_info[irq].sn_irq_info = new_irq_info;
-       if (new_irq_info == NULL)
-               return -1;
-
-       /*
-        * Map the xio address into bus space
-        */
-
-       bus_addr = (*provider->dma_map_consistent)(pdev,
-                                       new_irq_info->irq_xtalkaddr,
-                                       sizeof(new_irq_info->irq_xtalkaddr),
-                                       SN_DMA_MSI|SN_DMA_ADDR_XIO);
-
-       sn_msi_info[irq].pci_addr = bus_addr;
-       msg.address_hi = (u32)(bus_addr >> 32);
-       msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
-
-       pci_write_msi_msg(irq, &msg);
-       cpumask_copy(irq_data_get_affinity_mask(data), cpu_mask);
-
-       return 0;
-}
-#endif /* CONFIG_SMP */
-
-static void sn_ack_msi_irq(struct irq_data *data)
-{
-       irq_move_irq(data);
-       ia64_eoi();
-}
-
-static int sn_msi_retrigger_irq(struct irq_data *data)
-{
-       unsigned int vector = data->irq;
-       ia64_resend_irq(vector);
-
-       return 1;
-}
-
-static struct irq_chip sn_msi_chip = {
-       .name                   = "PCI-MSI",
-       .irq_mask               = pci_msi_mask_irq,
-       .irq_unmask             = pci_msi_unmask_irq,
-       .irq_ack                = sn_ack_msi_irq,
-#ifdef CONFIG_SMP
-       .irq_set_affinity       = sn_set_msi_irq_affinity,
-#endif
-       .irq_retrigger          = sn_msi_retrigger_irq,
-};
diff --git a/arch/ia64/sn/kernel/pio_phys.S b/arch/ia64/sn/kernel/pio_phys.S
deleted file mode 100644 (file)
index 3c7d48d..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
- *
- * This file contains macros used to access MMR registers via
- * uncached physical addresses.
- *      pio_phys_read_mmr  - read an MMR
- *      pio_phys_write_mmr - write an MMR
- *      pio_atomic_phys_write_mmrs - atomically write 1 or 2 MMRs with psr.ic=0
- *              Second MMR will be skipped if address is NULL
- *
- * Addresses passed to these routines should be uncached physical addresses
- *     ie., 0x80000....
- */
-
-
-
-#include <asm/asmmacro.h>
-#include <asm/page.h>
-
-GLOBAL_ENTRY(pio_phys_read_mmr)
-       .prologue
-       .regstk 1,0,0,0
-       .body
-       mov r2=psr
-       rsm psr.i | psr.dt
-       ;;
-       srlz.d
-       ld8.acq r8=[r32]
-       ;;
-       mov psr.l=r2;;
-       srlz.d
-       br.ret.sptk.many rp
-END(pio_phys_read_mmr)
-
-GLOBAL_ENTRY(pio_phys_write_mmr)
-       .prologue
-       .regstk 2,0,0,0
-       .body
-       mov r2=psr
-       rsm psr.i | psr.dt
-       ;;
-       srlz.d
-       st8.rel [r32]=r33
-       ;;
-       mov psr.l=r2;;
-       srlz.d
-       br.ret.sptk.many rp
-END(pio_phys_write_mmr)
-
-GLOBAL_ENTRY(pio_atomic_phys_write_mmrs)
-       .prologue
-       .regstk 4,0,0,0
-       .body
-       mov r2=psr
-       cmp.ne p9,p0=r34,r0;
-       rsm psr.i | psr.dt | psr.ic
-       ;;
-       srlz.d
-       st8.rel [r32]=r33
-(p9)   st8.rel [r34]=r35
-       ;;
-       mov psr.l=r2;;
-       srlz.d
-       br.ret.sptk.many rp
-END(pio_atomic_phys_write_mmrs)
-
-
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
deleted file mode 100644 (file)
index e6a5049..0000000
+++ /dev/null
@@ -1,786 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999,2001-2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/kdev_t.h>
-#include <linux/string.h>
-#include <linux/screen_info.h>
-#include <linux/console.h>
-#include <linux/timex.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/mm.h>
-#include <linux/serial.h>
-#include <linux/irq.h>
-#include <linux/memblock.h>
-#include <linux/mmzone.h>
-#include <linux/interrupt.h>
-#include <linux/acpi.h>
-#include <linux/compiler.h>
-#include <linux/root_dev.h>
-#include <linux/nodemask.h>
-#include <linux/pm.h>
-#include <linux/efi.h>
-
-#include <asm/io.h>
-#include <asm/sal.h>
-#include <asm/machvec.h>
-#include <asm/processor.h>
-#include <asm/vga.h>
-#include <asm/setup.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/pda.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/leds.h>
-#include <asm/sn/bte.h>
-#include <asm/sn/shub_mmr.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/geo.h>
-#include <asm/sn/sn_feature_sets.h>
-#include "xtalk/xwidgetdev.h"
-#include "xtalk/hubdev.h"
-#include <asm/sn/klconfig.h>
-
-
-DEFINE_PER_CPU(struct pda_s, pda_percpu);
-
-#define MAX_PHYS_MEMORY                (1UL << IA64_MAX_PHYS_BITS)     /* Max physical address supported */
-
-extern void bte_init_node(nodepda_t *, cnodeid_t);
-
-extern void sn_timer_init(void);
-extern unsigned long last_time_offset;
-extern void (*ia64_mark_idle) (int);
-extern void snidle(int);
-
-unsigned long sn_rtc_cycles_per_second;
-EXPORT_SYMBOL(sn_rtc_cycles_per_second);
-
-DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
-EXPORT_PER_CPU_SYMBOL(__sn_hub_info);
-
-DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]);
-EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid);
-
-DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda);
-EXPORT_PER_CPU_SYMBOL(__sn_nodepda);
-
-char sn_system_serial_number_string[128];
-EXPORT_SYMBOL(sn_system_serial_number_string);
-u64 sn_partition_serial_number;
-EXPORT_SYMBOL(sn_partition_serial_number);
-u8 sn_partition_id;
-EXPORT_SYMBOL(sn_partition_id);
-u8 sn_system_size;
-EXPORT_SYMBOL(sn_system_size);
-u8 sn_sharing_domain_size;
-EXPORT_SYMBOL(sn_sharing_domain_size);
-u8 sn_coherency_id;
-EXPORT_SYMBOL(sn_coherency_id);
-u8 sn_region_size;
-EXPORT_SYMBOL(sn_region_size);
-int sn_prom_type;      /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */
-
-short physical_node_map[MAX_NUMALINK_NODES];
-static unsigned long sn_prom_features[MAX_PROM_FEATURE_SETS];
-
-EXPORT_SYMBOL(physical_node_map);
-
-int num_cnodes;
-
-static void sn_init_pdas(char **);
-static void build_cnode_tables(void);
-
-static nodepda_t *nodepdaindr[MAX_COMPACT_NODES];
-
-/*
- * The format of "screen_info" is strange, and due to early i386-setup
- * code. This is just enough to make the console code think we're on a
- * VGA color display.
- */
-struct screen_info sn_screen_info = {
-       .orig_x = 0,
-       .orig_y = 0,
-       .orig_video_mode = 3,
-       .orig_video_cols = 80,
-       .orig_video_ega_bx = 3,
-       .orig_video_lines = 25,
-       .orig_video_isVGA = 1,
-       .orig_video_points = 16
-};
-
-/*
- * This routine can only be used during init, since
- * smp_boot_data is an init data structure.
- * We have to use smp_boot_data.cpu_phys_id to find
- * the physical id of the processor because the normal
- * cpu_physical_id() relies on data structures that
- * may not be initialized yet.
- */
-
-static int __init pxm_to_nasid(int pxm)
-{
-       int i;
-       int nid;
-
-       nid = pxm_to_node(pxm);
-       for (i = 0; i < num_node_memblks; i++) {
-               if (node_memblk[i].nid == nid) {
-                       return NASID_GET(node_memblk[i].start_paddr);
-               }
-       }
-       return -1;
-}
-
-/**
- * early_sn_setup - early setup routine for SN platforms
- *
- * Sets up an initial console to aid debugging.  Intended primarily
- * for bringup.  See start_kernel() in init/main.c.
- */
-
-void __init early_sn_setup(void)
-{
-       efi_system_table_t *efi_systab;
-       efi_config_table_t *config_tables;
-       struct ia64_sal_systab *sal_systab;
-       struct ia64_sal_desc_entry_point *ep;
-       char *p;
-       int i, j;
-
-       /*
-        * Parse enough of the SAL tables to locate the SAL entry point. Since, console
-        * IO on SN2 is done via SAL calls, early_printk won't work without this.
-        *
-        * This code duplicates some of the ACPI table parsing that is in efi.c & sal.c.
-        * Any changes to those file may have to be made here as well.
-        */
-       efi_systab = (efi_system_table_t *) __va(ia64_boot_param->efi_systab);
-       config_tables = __va(efi_systab->tables);
-       for (i = 0; i < efi_systab->nr_tables; i++) {
-               if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) ==
-                   0) {
-                       sal_systab = __va(config_tables[i].table);
-                       p = (char *)(sal_systab + 1);
-                       for (j = 0; j < sal_systab->entry_count; j++) {
-                               if (*p == SAL_DESC_ENTRY_POINT) {
-                                       ep = (struct ia64_sal_desc_entry_point
-                                             *)p;
-                                       ia64_sal_handler_init(__va
-                                                             (ep->sal_proc),
-                                                             __va(ep->gp));
-                                       return;
-                               }
-                               p += SAL_DESC_SIZE(*p);
-                       }
-               }
-       }
-       /* Uh-oh, SAL not available?? */
-       printk(KERN_ERR "failed to find SAL entry point\n");
-}
-
-extern int platform_intr_list[];
-static int shub_1_1_found;
-
-/*
- * sn_check_for_wars
- *
- * Set flag for enabling shub specific wars
- */
-
-static inline int is_shub_1_1(int nasid)
-{
-       unsigned long id;
-       int rev;
-
-       if (is_shub2())
-               return 0;
-       id = REMOTE_HUB_L(nasid, SH1_SHUB_ID);
-       rev = (id & SH1_SHUB_ID_REVISION_MASK) >> SH1_SHUB_ID_REVISION_SHFT;
-       return rev <= 2;
-}
-
-static void sn_check_for_wars(void)
-{
-       int cnode;
-
-       if (is_shub2()) {
-               /* none yet */
-       } else {
-               for_each_online_node(cnode) {
-                       if (is_shub_1_1(cnodeid_to_nasid(cnode)))
-                               shub_1_1_found = 1;
-               }
-       }
-}
-
-/*
- * Scan the EFI PCDP table (if it exists) for an acceptable VGA console
- * output device.  If one exists, pick it and set sn_legacy_{io,mem} to
- * reflect the bus offsets needed to address it.
- *
- * Since pcdp support in SN is not supported in the 2.4 kernel (or at least
- * the one lbs is based on) just declare the needed structs here.
- *
- * Reference spec http://www.dig64.org/specifications/DIG64_PCDPv20.pdf
- *
- * Returns 0 if no acceptable vga is found, !0 otherwise.
- *
- * Note:  This stuff is duped here because Altix requires the PCDP to
- * locate a usable VGA device due to lack of proper ACPI support.  Structures
- * could be used from drivers/firmware/pcdp.h, but it was decided that moving
- * this file to a more public location just for Altix use was undesirable.
- */
-
-struct hcdp_uart_desc {
-       u8      pad[45];
-};
-
-struct pcdp {
-       u8      signature[4];   /* should be 'HCDP' */
-       u32     length;
-       u8      rev;            /* should be >=3 for pcdp, <3 for hcdp */
-       u8      sum;
-       u8      oem_id[6];
-       u64     oem_tableid;
-       u32     oem_rev;
-       u32     creator_id;
-       u32     creator_rev;
-       u32     num_type0;
-       struct hcdp_uart_desc uart[0];  /* num_type0 of these */
-       /* pcdp descriptors follow */
-}  __attribute__((packed));
-
-struct pcdp_device_desc {
-       u8      type;
-       u8      primary;
-       u16     length;
-       u16     index;
-       /* interconnect specific structure follows */
-       /* device specific structure follows that */
-}  __attribute__((packed));
-
-struct pcdp_interface_pci {
-       u8      type;           /* 1 == pci */
-       u8      reserved;
-       u16     length;
-       u8      segment;
-       u8      bus;
-       u8      dev;
-       u8      fun;
-       u16     devid;
-       u16     vendid;
-       u32     acpi_interrupt;
-       u64     mmio_tra;
-       u64     ioport_tra;
-       u8      flags;
-       u8      translation;
-}  __attribute__((packed));
-
-struct pcdp_vga_device {
-       u8      num_eas_desc;
-       /* ACPI Extended Address Space Desc follows */
-}  __attribute__((packed));
-
-/* from pcdp_device_desc.primary */
-#define PCDP_PRIMARY_CONSOLE   0x01
-
-/* from pcdp_device_desc.type */
-#define PCDP_CONSOLE_INOUT     0x0
-#define PCDP_CONSOLE_DEBUG     0x1
-#define PCDP_CONSOLE_OUT       0x2
-#define PCDP_CONSOLE_IN                0x3
-#define PCDP_CONSOLE_TYPE_VGA  0x8
-
-#define PCDP_CONSOLE_VGA       (PCDP_CONSOLE_TYPE_VGA | PCDP_CONSOLE_OUT)
-
-/* from pcdp_interface_pci.type */
-#define PCDP_IF_PCI            1
-
-/* from pcdp_interface_pci.translation */
-#define PCDP_PCI_TRANS_IOPORT  0x02
-#define PCDP_PCI_TRANS_MMIO    0x01
-
-#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
-static void
-sn_scan_pcdp(void)
-{
-       u8 *bp;
-       struct pcdp *pcdp;
-       struct pcdp_device_desc device;
-       struct pcdp_interface_pci if_pci;
-       extern struct efi efi;
-
-       if (efi.hcdp == EFI_INVALID_TABLE_ADDR)
-               return;         /* no hcdp/pcdp table */
-
-       pcdp = __va(efi.hcdp);
-
-       if (pcdp->rev < 3)
-               return;         /* only support PCDP (rev >= 3) */
-
-       for (bp = (u8 *)&pcdp->uart[pcdp->num_type0];
-            bp < (u8 *)pcdp + pcdp->length;
-            bp += device.length) {
-               memcpy(&device, bp, sizeof(device));
-               if (! (device.primary & PCDP_PRIMARY_CONSOLE))
-                       continue;       /* not primary console */
-
-               if (device.type != PCDP_CONSOLE_VGA)
-                       continue;       /* not VGA descriptor */
-
-               memcpy(&if_pci, bp+sizeof(device), sizeof(if_pci));
-               if (if_pci.type != PCDP_IF_PCI)
-                       continue;       /* not PCI interconnect */
-
-               if (if_pci.translation & PCDP_PCI_TRANS_IOPORT)
-                       vga_console_iobase = if_pci.ioport_tra;
-
-               if (if_pci.translation & PCDP_PCI_TRANS_MMIO)
-                       vga_console_membase =
-                               if_pci.mmio_tra | __IA64_UNCACHED_OFFSET;
-
-               break; /* once we find the primary, we're done */
-       }
-}
-#endif
-
-static unsigned long sn2_rtc_initial;
-
-/**
- * sn_setup - SN platform setup routine
- * @cmdline_p: kernel command line
- *
- * Handles platform setup for SN machines.  This includes determining
- * the RTC frequency (via a SAL call), initializing secondary CPUs, and
- * setting up per-node data areas.  The console is also initialized here.
- */
-void __init sn_setup(char **cmdline_p)
-{
-       long status, ticks_per_sec, drift;
-       u32 version = sn_sal_rev();
-       extern void sn_cpu_init(void);
-
-       sn2_rtc_initial = rtc_time();
-       ia64_sn_plat_set_error_handling_features();     // obsolete
-       ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV);
-       ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES);
-       /*
-        * Note: The calls to notify the PROM of ACPI and PCI Segment
-        *       support must be done prior to acpi_load_tables(), as
-        *       an ACPI capable PROM will rebuild the DSDT as result
-        *       of the call.
-        */
-       ia64_sn_set_os_feature(OSF_PCISEGMENT_ENABLE);
-       ia64_sn_set_os_feature(OSF_ACPI_ENABLE);
-
-       /* Load the new DSDT and SSDT tables into the global table list. */
-       acpi_table_init();
-
-#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE)
-       /*
-        * Handle SN vga console.
-        *
-        * SN systems do not have enough ACPI table information
-        * being passed from prom to identify VGA adapters and the legacy
-        * addresses to access them.  Until that is done, SN systems rely
-        * on the PCDP table to identify the primary VGA console if one
-        * exists.
-        *
-        * However, kernel PCDP support is optional, and even if it is built
-        * into the kernel, it will not be used if the boot cmdline contains
-        * console= directives.
-        *
-        * So, to work around this mess, we duplicate some of the PCDP code
-        * here so that the primary VGA console (as defined by PCDP) will
-        * work on SN systems even if a different console (e.g. serial) is
-        * selected on the boot line (or CONFIG_EFI_PCDP is off).
-        */
-
-       if (! vga_console_membase)
-               sn_scan_pcdp();
-
-       /*
-        *      Setup legacy IO space.
-        *      vga_console_iobase maps to PCI IO Space address 0 on the
-        *      bus containing the VGA console.
-        */
-       if (vga_console_iobase) {
-               io_space[0].mmio_base =
-                       (unsigned long) ioremap(vga_console_iobase, 0);
-               io_space[0].sparse = 0;
-       }
-
-       if (vga_console_membase) {
-               /* usable vga ... make tty0 the preferred default console */
-               if (!strstr(*cmdline_p, "console="))
-                       add_preferred_console("tty", 0, NULL);
-       } else {
-               printk(KERN_DEBUG "SGI: Disabling VGA console\n");
-               if (!strstr(*cmdline_p, "console="))
-                       add_preferred_console("ttySG", 0, NULL);
-#ifdef CONFIG_DUMMY_CONSOLE
-               conswitchp = &dummy_con;
-#else
-               conswitchp = NULL;
-#endif                         /* CONFIG_DUMMY_CONSOLE */
-       }
-#endif                         /* def(CONFIG_VT) && def(CONFIG_VGA_CONSOLE) */
-
-       MAX_DMA_ADDRESS = PAGE_OFFSET + MAX_PHYS_MEMORY;
-
-       /*
-        * Build the tables for managing cnodes.
-        */
-       build_cnode_tables();
-
-       status =
-           ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec,
-                              &drift);
-       if (status != 0 || ticks_per_sec < 100000) {
-               printk(KERN_WARNING
-                      "unable to determine platform RTC clock frequency, guessing.\n");
-               /* PROM gives wrong value for clock freq. so guess */
-               sn_rtc_cycles_per_second = 1000000000000UL / 30000UL;
-       } else
-               sn_rtc_cycles_per_second = ticks_per_sec;
-
-       platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR;
-
-       printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF);
-
-       /*
-        * we set the default root device to /dev/hda
-        * to make simulation easy
-        */
-       ROOT_DEV = Root_HDA1;
-
-       /*
-        * Create the PDAs and NODEPDAs for all the cpus.
-        */
-       sn_init_pdas(cmdline_p);
-
-       ia64_mark_idle = &snidle;
-
-       /*
-        * For the bootcpu, we do this here. All other cpus will make the
-        * call as part of cpu_init in slave cpu initialization.
-        */
-       sn_cpu_init();
-
-#ifdef CONFIG_SMP
-       init_smp_config();
-#endif
-       screen_info = sn_screen_info;
-
-       sn_timer_init();
-
-       /*
-        * set pm_power_off to a SAL call to allow
-        * sn machines to power off. The SAL call can be replaced
-        * by an ACPI interface call when ACPI is fully implemented
-        * for sn.
-        */
-       pm_power_off = ia64_sn_power_down;
-       current->thread.flags |= IA64_THREAD_MIGRATION;
-}
-
-/**
- * sn_init_pdas - setup node data areas
- *
- * One time setup for Node Data Area.  Called by sn_setup().
- */
-static void __init sn_init_pdas(char **cmdline_p)
-{
-       cnodeid_t cnode;
-
-       /*
-        * Allocate & initialize the nodepda for each node.
-        */
-       for_each_online_node(cnode) {
-               nodepdaindr[cnode] =
-                   memblock_alloc_node(sizeof(nodepda_t), SMP_CACHE_BYTES,
-                                       cnode);
-               if (!nodepdaindr[cnode])
-                       panic("%s: Failed to allocate %lu bytes align=0x%x nid=%d\n",
-                             __func__, sizeof(nodepda_t), SMP_CACHE_BYTES,
-                             cnode);
-               memset(nodepdaindr[cnode]->phys_cpuid, -1,
-                   sizeof(nodepdaindr[cnode]->phys_cpuid));
-               spin_lock_init(&nodepdaindr[cnode]->ptc_lock);
-       }
-
-       /*
-        * Allocate & initialize nodepda for TIOs.  For now, put them on node 0.
-        */
-       for (cnode = num_online_nodes(); cnode < num_cnodes; cnode++) {
-               nodepdaindr[cnode] =
-                   memblock_alloc_node(sizeof(nodepda_t), SMP_CACHE_BYTES, 0);
-               if (!nodepdaindr[cnode])
-                       panic("%s: Failed to allocate %lu bytes align=0x%x nid=%d\n",
-                             __func__, sizeof(nodepda_t), SMP_CACHE_BYTES,
-                             cnode);
-       }
-
-
-       /*
-        * Now copy the array of nodepda pointers to each nodepda.
-        */
-       for (cnode = 0; cnode < num_cnodes; cnode++)
-               memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr,
-                      sizeof(nodepdaindr));
-
-       /*
-        * Set up IO related platform-dependent nodepda fields.
-        * The following routine actually sets up the hubinfo struct
-        * in nodepda.
-        */
-       for_each_online_node(cnode) {
-               bte_init_node(nodepdaindr[cnode], cnode);
-       }
-
-       /*
-        * Initialize the per node hubdev.  This includes IO Nodes and
-        * headless/memless nodes.
-        */
-       for (cnode = 0; cnode < num_cnodes; cnode++) {
-               hubdev_init_node(nodepdaindr[cnode], cnode);
-       }
-}
-
-/**
- * sn_cpu_init - initialize per-cpu data areas
- * @cpuid: cpuid of the caller
- *
- * Called during cpu initialization on each cpu as it starts.
- * Currently, initializes the per-cpu data area for SNIA.
- * Also sets up a few fields in the nodepda.  Also known as
- * platform_cpu_init() by the ia64 machvec code.
- */
-void sn_cpu_init(void)
-{
-       int cpuid;
-       int cpuphyid;
-       int nasid;
-       int subnode;
-       int slice;
-       int cnode;
-       int i;
-       static int wars_have_been_checked, set_cpu0_number;
-
-       cpuid = smp_processor_id();
-       if (cpuid == 0 && IS_MEDUSA()) {
-               if (ia64_sn_is_fake_prom())
-                       sn_prom_type = 2;
-               else
-                       sn_prom_type = 1;
-               printk(KERN_INFO "Running on medusa with %s PROM\n",
-                      (sn_prom_type == 1) ? "real" : "fake");
-       }
-
-       memset(pda, 0, sizeof(*pda));
-       if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2,
-                               &sn_hub_info->nasid_bitmask,
-                               &sn_hub_info->nasid_shift,
-                               &sn_system_size, &sn_sharing_domain_size,
-                               &sn_partition_id, &sn_coherency_id,
-                               &sn_region_size))
-               BUG();
-       sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2;
-
-       /*
-        * Don't check status. The SAL call is not supported on all PROMs
-        * but a failure is harmless.
-        * Architecturally, cpu_init is always called twice on cpu 0. We
-        * should set cpu_number on cpu 0 once.
-        */
-       if (cpuid == 0) {
-               if (!set_cpu0_number) {
-                       (void) ia64_sn_set_cpu_number(cpuid);
-                       set_cpu0_number = 1;
-               }
-       } else
-               (void) ia64_sn_set_cpu_number(cpuid);
-
-       /*
-        * The boot cpu makes this call again after platform initialization is
-        * complete.
-        */
-       if (nodepdaindr[0] == NULL)
-               return;
-
-       for (i = 0; i < MAX_PROM_FEATURE_SETS; i++)
-               if (ia64_sn_get_prom_feature_set(i, &sn_prom_features[i]) != 0)
-                       break;
-
-       cpuphyid = get_sapicid();
-
-       if (ia64_sn_get_sapic_info(cpuphyid, &nasid, &subnode, &slice))
-               BUG();
-
-       for (i=0; i < MAX_NUMNODES; i++) {
-               if (nodepdaindr[i]) {
-                       nodepdaindr[i]->phys_cpuid[cpuid].nasid = nasid;
-                       nodepdaindr[i]->phys_cpuid[cpuid].slice = slice;
-                       nodepdaindr[i]->phys_cpuid[cpuid].subnode = subnode;
-               }
-       }
-
-       cnode = nasid_to_cnodeid(nasid);
-
-       __this_cpu_write(__sn_nodepda, nodepdaindr[cnode]);
-
-       pda->led_address =
-           (typeof(pda->led_address)) (LED0 + (slice << LED_CPU_SHIFT));
-       pda->led_state = LED_ALWAYS_SET;
-       pda->hb_count = HZ / 2;
-       pda->hb_state = 0;
-       pda->idle_flag = 0;
-
-       if (cpuid != 0) {
-               /* copy cpu 0's sn_cnodeid_to_nasid table to this cpu's */
-               memcpy(sn_cnodeid_to_nasid,
-                      (&per_cpu(__sn_cnodeid_to_nasid, 0)),
-                      sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid)));
-       }
-
-       /*
-        * Check for WARs.
-        * Only needs to be done once, on BSP.
-        * Has to be done after loop above, because it uses this cpu's
-        * sn_cnodeid_to_nasid table which was just initialized if this
-        * isn't cpu 0.
-        * Has to be done before assignment below.
-        */
-       if (!wars_have_been_checked) {
-               sn_check_for_wars();
-               wars_have_been_checked = 1;
-       }
-       sn_hub_info->shub_1_1_found = shub_1_1_found;
-
-       /*
-        * Set up addresses of PIO/MEM write status registers.
-        */
-       {
-               u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0};
-               u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_2,
-                       SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_3};
-               u64 *pio;
-               pio = is_shub1() ? pio1 : pio2;
-               pda->pio_write_status_addr =
-                  (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid, pio[slice]);
-               pda->pio_write_status_val = is_shub1() ? SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK : 0;
-       }
-
-       /*
-        * WAR addresses for SHUB 1.x.
-        */
-       if (local_node_data->active_cpu_count++ == 0 && is_shub1()) {
-               int buddy_nasid;
-               buddy_nasid =
-                   cnodeid_to_nasid(numa_node_id() ==
-                                    num_online_nodes() - 1 ? 0 : numa_node_id() + 1);
-               pda->pio_shub_war_cam_addr =
-                   (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid,
-                                                             SH1_PI_CAM_CONTROL);
-       }
-}
-
-/*
- * Build tables for converting between NASIDs and cnodes.
- */
-static inline int __init board_needs_cnode(int type)
-{
-       return (type == KLTYPE_SNIA || type == KLTYPE_TIO);
-}
-
-void __init build_cnode_tables(void)
-{
-       int nasid;
-       int node;
-       lboard_t *brd;
-
-       memset(physical_node_map, -1, sizeof(physical_node_map));
-       memset(sn_cnodeid_to_nasid, -1,
-                       sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid)));
-
-       /*
-        * First populate the tables with C/M bricks. This ensures that
-        * cnode == node for all C & M bricks.
-        */
-       for_each_online_node(node) {
-               nasid = pxm_to_nasid(node_to_pxm(node));
-               sn_cnodeid_to_nasid[node] = nasid;
-               physical_node_map[nasid] = node;
-       }
-
-       /*
-        * num_cnodes is total number of C/M/TIO bricks. Because of the 256 node
-        * limit on the number of nodes, we can't use the generic node numbers 
-        * for this. Note that num_cnodes is incremented below as TIOs or
-        * headless/memoryless nodes are discovered.
-        */
-       num_cnodes = num_online_nodes();
-
-       /* fakeprom does not support klgraph */
-       if (IS_RUNNING_ON_FAKE_PROM())
-               return;
-
-       /* Find TIOs & headless/memoryless nodes and add them to the tables */
-       for_each_online_node(node) {
-               kl_config_hdr_t *klgraph_header;
-               nasid = cnodeid_to_nasid(node);
-               klgraph_header = ia64_sn_get_klconfig_addr(nasid);
-               BUG_ON(klgraph_header == NULL);
-               brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info);
-               while (brd) {
-                       if (board_needs_cnode(brd->brd_type) && physical_node_map[brd->brd_nasid] < 0) {
-                               sn_cnodeid_to_nasid[num_cnodes] = brd->brd_nasid;
-                               physical_node_map[brd->brd_nasid] = num_cnodes++;
-                       }
-                       brd = find_lboard_next(brd);
-               }
-       }
-}
-
-int
-nasid_slice_to_cpuid(int nasid, int slice)
-{
-       long cpu;
-
-       for (cpu = 0; cpu < nr_cpu_ids; cpu++)
-               if (cpuid_to_nasid(cpu) == nasid &&
-                                       cpuid_to_slice(cpu) == slice)
-                       return cpu;
-
-       return -1;
-}
-
-int sn_prom_feature_available(int id)
-{
-       if (id >= BITS_PER_LONG * MAX_PROM_FEATURE_SETS)
-               return 0;
-       return test_bit(id, sn_prom_features);
-}
-
-void
-sn_kernel_launch_event(void)
-{
-       /* ignore status until we understand possible failure, if any*/
-       if (ia64_sn_kernel_launch_event())
-               printk(KERN_ERR "KEXEC is not supported in this PROM, Please update the PROM.\n");
-}
-EXPORT_SYMBOL(sn_prom_feature_available);
-
diff --git a/arch/ia64/sn/kernel/sn2/Makefile b/arch/ia64/sn/kernel/sn2/Makefile
deleted file mode 100644 (file)
index 170bde4..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-# arch/ia64/sn/kernel/sn2/Makefile
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
-#
-# sn2 specific kernel files
-#
-
-obj-y += cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \
-        prominfo_proc.o timer.o timer_interrupt.o sn_hwperf.o
diff --git a/arch/ia64/sn/kernel/sn2/cache.c b/arch/ia64/sn/kernel/sn2/cache.c
deleted file mode 100644 (file)
index 2862cb3..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- * 
- * Copyright (C) 2001-2003, 2006 Silicon Graphics, Inc. All rights reserved.
- *
- */
-#include <linux/module.h>
-#include <asm/pgalloc.h>
-#include <asm/sn/arch.h>
-
-/**
- * sn_flush_all_caches - flush a range of address from all caches (incl. L4)
- * @flush_addr: identity mapped region 7 address to start flushing
- * @bytes: number of bytes to flush
- *
- * Flush a range of addresses from all caches including L4. 
- * All addresses fully or partially contained within 
- * @flush_addr to @flush_addr + @bytes are flushed
- * from all caches.
- */
-void
-sn_flush_all_caches(long flush_addr, long bytes)
-{
-       unsigned long addr = flush_addr;
-
-       /* SHub1 requires a cached address */
-       if (is_shub1() && (addr & RGN_BITS) == RGN_BASE(RGN_UNCACHED))
-               addr = (addr - RGN_BASE(RGN_UNCACHED)) + RGN_BASE(RGN_KERNEL);
-
-       flush_icache_range(addr, addr + bytes);
-       /*
-        * The last call may have returned before the caches
-        * were actually flushed, so we call it again to make
-        * sure.
-        */
-       flush_icache_range(addr, addr + bytes);
-       mb();
-}
-EXPORT_SYMBOL(sn_flush_all_caches);
diff --git a/arch/ia64/sn/kernel/sn2/io.c b/arch/ia64/sn/kernel/sn2/io.c
deleted file mode 100644 (file)
index a12c058..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2003 Silicon Graphics, Inc. All rights reserved.
- *
- * The generic kernel requires function pointers to these routines, so
- * we wrap the inlines from asm/ia64/sn/sn2/io.h here.
- */
-
-#include <asm/sn/io.h>
-
-#ifdef CONFIG_IA64_GENERIC
-
-#undef __sn_inb
-#undef __sn_inw
-#undef __sn_inl
-#undef __sn_outb
-#undef __sn_outw
-#undef __sn_outl
-#undef __sn_readb
-#undef __sn_readw
-#undef __sn_readl
-#undef __sn_readq
-#undef __sn_readb_relaxed
-#undef __sn_readw_relaxed
-#undef __sn_readl_relaxed
-#undef __sn_readq_relaxed
-
-unsigned int __sn_inb(unsigned long port)
-{
-       return ___sn_inb(port);
-}
-
-unsigned int __sn_inw(unsigned long port)
-{
-       return ___sn_inw(port);
-}
-
-unsigned int __sn_inl(unsigned long port)
-{
-       return ___sn_inl(port);
-}
-
-void __sn_outb(unsigned char val, unsigned long port)
-{
-       ___sn_outb(val, port);
-}
-
-void __sn_outw(unsigned short val, unsigned long port)
-{
-       ___sn_outw(val, port);
-}
-
-void __sn_outl(unsigned int val, unsigned long port)
-{
-       ___sn_outl(val, port);
-}
-
-unsigned char __sn_readb(void __iomem *addr)
-{
-       return ___sn_readb(addr);
-}
-
-unsigned short __sn_readw(void __iomem *addr)
-{
-       return ___sn_readw(addr);
-}
-
-unsigned int __sn_readl(void __iomem *addr)
-{
-       return ___sn_readl(addr);
-}
-
-unsigned long __sn_readq(void __iomem *addr)
-{
-       return ___sn_readq(addr);
-}
-
-unsigned char __sn_readb_relaxed(void __iomem *addr)
-{
-       return ___sn_readb_relaxed(addr);
-}
-
-unsigned short __sn_readw_relaxed(void __iomem *addr)
-{
-       return ___sn_readw_relaxed(addr);
-}
-
-unsigned int __sn_readl_relaxed(void __iomem *addr)
-{
-       return ___sn_readl_relaxed(addr);
-}
-
-unsigned long __sn_readq_relaxed(void __iomem *addr)
-{
-       return ___sn_readq_relaxed(addr);
-}
-
-#endif
diff --git a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c
deleted file mode 100644 (file)
index e15457b..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1999,2001-2004, 2006 Silicon Graphics, Inc.  All Rights Reserved.
- *
- * Module to export the system's Firmware Interface Tables, including
- * PROM revision numbers and banners, in /proc
- */
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/nodemask.h>
-#include <asm/io.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/addrs.h>
-
-MODULE_DESCRIPTION("PROM version reporting for /proc");
-MODULE_AUTHOR("Chad Talbott");
-MODULE_LICENSE("GPL");
-
-/* Standard Intel FIT entry types */
-#define FIT_ENTRY_FIT_HEADER   0x00    /* FIT header entry */
-#define FIT_ENTRY_PAL_B                0x01    /* PAL_B entry */
-/* Entries 0x02 through 0x0D reserved by Intel */
-#define FIT_ENTRY_PAL_A_PROC   0x0E    /* Processor-specific PAL_A entry */
-#define FIT_ENTRY_PAL_A                0x0F    /* PAL_A entry, same as... */
-#define FIT_ENTRY_PAL_A_GEN    0x0F    /* ...Generic PAL_A entry */
-#define FIT_ENTRY_UNUSED       0x7F    /* Unused (reserved by Intel?) */
-/* OEM-defined entries range from 0x10 to 0x7E. */
-#define FIT_ENTRY_SAL_A                0x10    /* SAL_A entry */
-#define FIT_ENTRY_SAL_B                0x11    /* SAL_B entry */
-#define FIT_ENTRY_SALRUNTIME   0x12    /* SAL runtime entry */
-#define FIT_ENTRY_EFI          0x1F    /* EFI entry */
-#define FIT_ENTRY_FPSWA                0x20    /* embedded fpswa entry */
-#define FIT_ENTRY_VMLINUX      0x21    /* embedded vmlinux entry */
-
-#define FIT_MAJOR_SHIFT        (32 + 8)
-#define FIT_MAJOR_MASK ((1 << 8) - 1)
-#define FIT_MINOR_SHIFT        32
-#define FIT_MINOR_MASK ((1 << 8) - 1)
-
-#define FIT_MAJOR(q)   \
-       ((unsigned) ((q) >> FIT_MAJOR_SHIFT) & FIT_MAJOR_MASK)
-#define FIT_MINOR(q)   \
-       ((unsigned) ((q) >> FIT_MINOR_SHIFT) & FIT_MINOR_MASK)
-
-#define FIT_TYPE_SHIFT (32 + 16)
-#define FIT_TYPE_MASK  ((1 << 7) - 1)
-
-#define FIT_TYPE(q)    \
-       ((unsigned) ((q) >> FIT_TYPE_SHIFT) & FIT_TYPE_MASK)
-
-struct fit_type_map_t {
-       unsigned char type;
-       const char *name;
-};
-
-static const struct fit_type_map_t fit_entry_types[] = {
-       {FIT_ENTRY_FIT_HEADER, "FIT Header"},
-       {FIT_ENTRY_PAL_A_GEN, "Generic PAL_A"},
-       {FIT_ENTRY_PAL_A_PROC, "Processor-specific PAL_A"},
-       {FIT_ENTRY_PAL_A, "PAL_A"},
-       {FIT_ENTRY_PAL_B, "PAL_B"},
-       {FIT_ENTRY_SAL_A, "SAL_A"},
-       {FIT_ENTRY_SAL_B, "SAL_B"},
-       {FIT_ENTRY_SALRUNTIME, "SAL runtime"},
-       {FIT_ENTRY_EFI, "EFI"},
-       {FIT_ENTRY_VMLINUX, "Embedded Linux"},
-       {FIT_ENTRY_FPSWA, "Embedded FPSWA"},
-       {FIT_ENTRY_UNUSED, "Unused"},
-       {0xff, "Error"},
-};
-
-static const char *fit_type_name(unsigned char type)
-{
-       struct fit_type_map_t const *mapp;
-
-       for (mapp = fit_entry_types; mapp->type != 0xff; mapp++)
-               if (type == mapp->type)
-                       return mapp->name;
-
-       if ((type > FIT_ENTRY_PAL_A) && (type < FIT_ENTRY_UNUSED))
-               return "OEM type";
-       if ((type > FIT_ENTRY_PAL_B) && (type < FIT_ENTRY_PAL_A))
-               return "Reserved";
-
-       return "Unknown type";
-}
-
-static int
-get_fit_entry(unsigned long nasid, int index, unsigned long *fentry,
-             char *banner, int banlen)
-{
-       return ia64_sn_get_fit_compt(nasid, index, fentry, banner, banlen);
-}
-
-
-/*
- * These two routines display the FIT table for each node.
- */
-static void dump_fit_entry(struct seq_file *m, unsigned long *fentry)
-{
-       unsigned type;
-
-       type = FIT_TYPE(fentry[1]);
-       seq_printf(m, "%02x %-25s %x.%02x %016lx %u\n",
-                  type,
-                  fit_type_name(type),
-                  FIT_MAJOR(fentry[1]), FIT_MINOR(fentry[1]),
-                  fentry[0],
-                  /* mult by sixteen to get size in bytes */
-                  (unsigned)(fentry[1] & 0xffffff) * 16);
-}
-
-
-/*
- * We assume that the fit table will be small enough that we can print
- * the whole thing into one page.  (This is true for our default 16kB
- * pages -- each entry is about 60 chars wide when printed.)  I read
- * somewhere that the maximum size of the FIT is 128 entries, so we're
- * OK except for 4kB pages (and no one is going to do that on SN
- * anyway).
- */
-static int proc_fit_show(struct seq_file *m, void *v)
-{
-       unsigned long nasid = (unsigned long)m->private;
-       unsigned long fentry[2];
-       int index;
-
-       for (index=0;;index++) {
-               BUG_ON(index * 60 > PAGE_SIZE);
-               if (get_fit_entry(nasid, index, fentry, NULL, 0))
-                       break;
-               dump_fit_entry(m, fentry);
-       }
-       return 0;
-}
-
-static int proc_version_show(struct seq_file *m, void *v)
-{
-       unsigned long nasid = (unsigned long)m->private;
-       unsigned long fentry[2];
-       char banner[128];
-       int index;
-
-       for (index = 0; ; index++) {
-               if (get_fit_entry(nasid, index, fentry, banner,
-                                 sizeof(banner)))
-                       return 0;
-               if (FIT_TYPE(fentry[1]) == FIT_ENTRY_SAL_A)
-                       break;
-       }
-
-       seq_printf(m, "%x.%02x\n", FIT_MAJOR(fentry[1]), FIT_MINOR(fentry[1]));
-
-       if (banner[0])
-               seq_printf(m, "%s\n", banner);
-       return 0;
-}
-
-/* module entry points */
-int __init prominfo_init(void);
-void __exit prominfo_exit(void);
-
-module_init(prominfo_init);
-module_exit(prominfo_exit);
-
-#define NODE_NAME_LEN 11
-
-int __init prominfo_init(void)
-{
-       struct proc_dir_entry *sgi_prominfo_entry;
-       cnodeid_t cnodeid;
-
-       if (!ia64_platform_is("sn2"))
-               return 0;
-
-       sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL);
-       if (!sgi_prominfo_entry)
-               return -ENOMEM;
-
-       for_each_online_node(cnodeid) {
-               struct proc_dir_entry *dir;
-               unsigned long nasid;
-               char name[NODE_NAME_LEN];
-
-               sprintf(name, "node%d", cnodeid);
-               dir = proc_mkdir(name, sgi_prominfo_entry);
-               if (!dir)
-                       continue;
-               nasid = cnodeid_to_nasid(cnodeid);
-               proc_create_single_data("fit", 0, dir, proc_fit_show, 
-                               (void *)nasid);
-               proc_create_single_data("version", 0, dir, proc_version_show,
-                               (void *)nasid);
-       }
-       return 0;
-}
-
-void __exit prominfo_exit(void)
-{
-       remove_proc_subtree("sgi_prominfo", NULL);
-}
diff --git a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S
deleted file mode 100644 (file)
index bebbcc4..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <asm/types.h>
-#include <asm/sn/shub_mmr.h>
-
-#define DEADLOCKBIT    SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT
-#define WRITECOUNTMASK SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK
-#define ALIAS_OFFSET   8
-
-
-       .global sn2_ptc_deadlock_recovery_core
-       .proc   sn2_ptc_deadlock_recovery_core
-
-sn2_ptc_deadlock_recovery_core:
-       .regstk 6,0,0,0
-
-       ptc0     = in0
-       data0    = in1
-       ptc1     = in2
-       data1    = in3
-       piowc    = in4
-       zeroval  = in5
-       piowcphy = r30
-       psrsave  = r2
-       scr1     = r16
-       scr2     = r17
-       mask     = r18
-
-
-       extr.u  piowcphy=piowc,0,61;;   // Convert piowc to uncached physical address
-       dep     piowcphy=-1,piowcphy,63,1
-       movl    mask=WRITECOUNTMASK
-       mov     r8=r0
-
-1:
-       cmp.ne  p8,p9=r0,ptc1           // Test for shub type (ptc1 non-null on shub1)
-                                       // p8 = 1 if shub1, p9 = 1 if shub2
-
-       add     scr2=ALIAS_OFFSET,piowc // Address of WRITE_STATUS alias register 
-       mov     scr1=7;;                // Clear DEADLOCK, WRITE_ERROR, MULTI_WRITE_ERROR
-(p8)   st8.rel [scr2]=scr1;;
-(p9)   ld8.acq scr1=[scr2];;
-
-5:     ld8.acq scr1=[piowc];;          // Wait for PIOs to complete.
-       hint    @pause
-       and     scr2=scr1,mask;;        // mask of writecount bits
-       cmp.ne  p6,p0=zeroval,scr2
-(p6)   br.cond.sptk 5b
-       
-
-
-       ////////////// BEGIN PHYSICAL MODE ////////////////////
-       mov psrsave=psr                 // Disable IC (no PMIs)
-       rsm psr.i | psr.dt | psr.ic;;
-       srlz.i;;
-
-       st8.rel [ptc0]=data0            // Write PTC0 & wait for completion.
-
-5:     ld8.acq scr1=[piowcphy];;       // Wait for PIOs to complete.
-       hint    @pause
-       and     scr2=scr1,mask;;        // mask of writecount bits
-       cmp.ne  p6,p0=zeroval,scr2
-(p6)   br.cond.sptk 5b;;
-
-       tbit.nz p8,p7=scr1,DEADLOCKBIT;;// Test for DEADLOCK
-(p7)   cmp.ne p7,p0=r0,ptc1;;          // Test for non-null ptc1
-       
-(p7)   st8.rel [ptc1]=data1;;          // Now write PTC1.
-
-5:     ld8.acq scr1=[piowcphy];;       // Wait for PIOs to complete.
-       hint    @pause
-       and     scr2=scr1,mask;;        // mask of writecount bits
-       cmp.ne  p6,p0=zeroval,scr2
-(p6)   br.cond.sptk 5b
-       
-       tbit.nz p8,p0=scr1,DEADLOCKBIT;;// Test for DEADLOCK
-
-       mov psr.l=psrsave;;             // Reenable IC
-       srlz.i;;
-       ////////////// END   PHYSICAL MODE ////////////////////
-
-(p8)   add     r8=1,r8
-(p8)   br.cond.spnt 1b;;               // Repeat if DEADLOCK occurred.
-
-       br.ret.sptk     rp
-       .endp sn2_ptc_deadlock_recovery_core
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
deleted file mode 100644 (file)
index b510f4f..0000000
+++ /dev/null
@@ -1,577 +0,0 @@
-/*
- * SN2 Platform specific SMP Support
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/threads.h>
-#include <linux/sched.h>
-#include <linux/mm_types.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mmzone.h>
-#include <linux/module.h>
-#include <linux/bitops.h>
-#include <linux/nodemask.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-#include <asm/processor.h>
-#include <asm/irq.h>
-#include <asm/sal.h>
-#include <asm/delay.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/tlb.h>
-#include <asm/numa.h>
-#include <asm/hw_irq.h>
-#include <asm/current.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/shub_mmr.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/rw_mmr.h>
-#include <asm/sn/sn_feature_sets.h>
-
-DEFINE_PER_CPU(struct ptc_stats, ptcstats);
-DECLARE_PER_CPU(struct ptc_stats, ptcstats);
-
-static  __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock);
-
-/* 0 = old algorithm (no IPI flushes), 1 = ipi deadlock flush, 2 = ipi instead of SHUB ptc, >2 = always ipi */
-static int sn2_flush_opt = 0;
-
-extern unsigned long
-sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long,
-                              volatile unsigned long *, unsigned long,
-                              volatile unsigned long *, unsigned long);
-void
-sn2_ptc_deadlock_recovery(nodemask_t, short, short, int,
-                         volatile unsigned long *, unsigned long,
-                         volatile unsigned long *, unsigned long);
-
-/*
- * Note: some is the following is captured here to make degugging easier
- * (the macros make more sense if you see the debug patch - not posted)
- */
-#define sn2_ptctest    0
-#define local_node_uses_ptc_ga(sh1)    ((sh1) ? 1 : 0)
-#define max_active_pio(sh1)            ((sh1) ? 32 : 7)
-#define reset_max_active_on_deadlock() 1
-#define PTC_LOCK(sh1)                  ((sh1) ? &sn2_global_ptc_lock : &sn_nodepda->ptc_lock)
-
-struct ptc_stats {
-       unsigned long ptc_l;
-       unsigned long change_rid;
-       unsigned long shub_ptc_flushes;
-       unsigned long nodes_flushed;
-       unsigned long deadlocks;
-       unsigned long deadlocks2;
-       unsigned long lock_itc_clocks;
-       unsigned long shub_itc_clocks;
-       unsigned long shub_itc_clocks_max;
-       unsigned long shub_ptc_flushes_not_my_mm;
-       unsigned long shub_ipi_flushes;
-       unsigned long shub_ipi_flushes_itc_clocks;
-};
-
-#define sn2_ptctest    0
-
-static inline unsigned long wait_piowc(void)
-{
-       volatile unsigned long *piows;
-       unsigned long zeroval, ws;
-
-       piows = pda->pio_write_status_addr;
-       zeroval = pda->pio_write_status_val;
-       do {
-               cpu_relax();
-       } while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval);
-       return (ws & SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK) != 0;
-}
-
-/**
- * sn_migrate - SN-specific task migration actions
- * @task: Task being migrated to new CPU
- *
- * SN2 PIO writes from separate CPUs are not guaranteed to arrive in order.
- * Context switching user threads which have memory-mapped MMIO may cause
- * PIOs to issue from separate CPUs, thus the PIO writes must be drained
- * from the previous CPU's Shub before execution resumes on the new CPU.
- */
-void sn_migrate(struct task_struct *task)
-{
-       pda_t *last_pda = pdacpu(task_thread_info(task)->last_cpu);
-       volatile unsigned long *adr = last_pda->pio_write_status_addr;
-       unsigned long val = last_pda->pio_write_status_val;
-
-       /* Drain PIO writes from old CPU's Shub */
-       while (unlikely((*adr & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK)
-                       != val))
-               cpu_relax();
-}
-
-static void
-sn2_ipi_flush_all_tlb(struct mm_struct *mm)
-{
-       unsigned long itc;
-
-       itc = ia64_get_itc();
-       smp_flush_tlb_cpumask(*mm_cpumask(mm));
-       itc = ia64_get_itc() - itc;
-       __this_cpu_add(ptcstats.shub_ipi_flushes_itc_clocks, itc);
-       __this_cpu_inc(ptcstats.shub_ipi_flushes);
-}
-
-/**
- * sn2_global_tlb_purge - globally purge translation cache of virtual address range
- * @mm: mm_struct containing virtual address range
- * @start: start of virtual address range
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Purges the translation caches of all processors of the given virtual address
- * range.
- *
- * Note:
- *     - cpu_vm_mask is a bit mask that indicates which cpus have loaded the context.
- *     - cpu_vm_mask is converted into a nodemask of the nodes containing the
- *       cpus in cpu_vm_mask.
- *     - if only one bit is set in cpu_vm_mask & it is the current cpu & the
- *       process is purging its own virtual address range, then only the
- *       local TLB needs to be flushed. This flushing can be done using
- *       ptc.l. This is the common case & avoids the global spinlock.
- *     - if multiple cpus have loaded the context, then flushing has to be
- *       done with ptc.g/MMRs under protection of the global ptc_lock.
- */
-
-void
-sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start,
-                    unsigned long end, unsigned long nbits)
-{
-       int i, ibegin, shub1, cnode, mynasid, cpu, lcpu = 0, nasid;
-       int mymm = (mm == current->active_mm && mm == current->mm);
-       int use_cpu_ptcga;
-       volatile unsigned long *ptc0, *ptc1;
-       unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr = 0;
-       short nix;
-       nodemask_t nodes_flushed;
-       int active, max_active, deadlock, flush_opt = sn2_flush_opt;
-
-       if (flush_opt > 2) {
-               sn2_ipi_flush_all_tlb(mm);
-               return;
-       }
-
-       nodes_clear(nodes_flushed);
-       i = 0;
-
-       for_each_cpu(cpu, mm_cpumask(mm)) {
-               cnode = cpu_to_node(cpu);
-               node_set(cnode, nodes_flushed);
-               lcpu = cpu;
-               i++;
-       }
-
-       if (i == 0)
-               return;
-
-       preempt_disable();
-
-       if (likely(i == 1 && lcpu == smp_processor_id() && mymm)) {
-               do {
-                       ia64_ptcl(start, nbits << 2);
-                       start += (1UL << nbits);
-               } while (start < end);
-               ia64_srlz_i();
-               __this_cpu_inc(ptcstats.ptc_l);
-               preempt_enable();
-               return;
-       }
-
-       if (atomic_read(&mm->mm_users) == 1 && mymm) {
-               flush_tlb_mm(mm);
-               __this_cpu_inc(ptcstats.change_rid);
-               preempt_enable();
-               return;
-       }
-
-       if (flush_opt == 2) {
-               sn2_ipi_flush_all_tlb(mm);
-               preempt_enable();
-               return;
-       }
-
-       itc = ia64_get_itc();
-       nix = nodes_weight(nodes_flushed);
-
-       rr_value = (mm->context << 3) | REGION_NUMBER(start);
-
-       shub1 = is_shub1();
-       if (shub1) {
-               data0 = (1UL << SH1_PTC_0_A_SHFT) |
-                       (nbits << SH1_PTC_0_PS_SHFT) |
-                       (rr_value << SH1_PTC_0_RID_SHFT) |
-                       (1UL << SH1_PTC_0_START_SHFT);
-               ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_0);
-               ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_1);
-       } else {
-               data0 = (1UL << SH2_PTC_A_SHFT) |
-                       (nbits << SH2_PTC_PS_SHFT) |
-                       (1UL << SH2_PTC_START_SHFT);
-               ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH2_PTC + 
-                       (rr_value << SH2_PTC_RID_SHFT));
-               ptc1 = NULL;
-       }
-       
-
-       mynasid = get_nasid();
-       use_cpu_ptcga = local_node_uses_ptc_ga(shub1);
-       max_active = max_active_pio(shub1);
-
-       itc = ia64_get_itc();
-       spin_lock_irqsave(PTC_LOCK(shub1), flags);
-       itc2 = ia64_get_itc();
-
-       __this_cpu_add(ptcstats.lock_itc_clocks, itc2 - itc);
-       __this_cpu_inc(ptcstats.shub_ptc_flushes);
-       __this_cpu_add(ptcstats.nodes_flushed, nix);
-       if (!mymm)
-                __this_cpu_inc(ptcstats.shub_ptc_flushes_not_my_mm);
-
-       if (use_cpu_ptcga && !mymm) {
-               old_rr = ia64_get_rr(start);
-               ia64_set_rr(start, (old_rr & 0xff) | (rr_value << 8));
-               ia64_srlz_d();
-       }
-
-       wait_piowc();
-       do {
-               if (shub1)
-                       data1 = start | (1UL << SH1_PTC_1_START_SHFT);
-               else
-                       data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK);
-               deadlock = 0;
-               active = 0;
-               ibegin = 0;
-               i = 0;
-               for_each_node_mask(cnode, nodes_flushed) {
-                       nasid = cnodeid_to_nasid(cnode);
-                       if (use_cpu_ptcga && unlikely(nasid == mynasid)) {
-                               ia64_ptcga(start, nbits << 2);
-                               ia64_srlz_i();
-                       } else {
-                               ptc0 = CHANGE_NASID(nasid, ptc0);
-                               if (ptc1)
-                                       ptc1 = CHANGE_NASID(nasid, ptc1);
-                               pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, data1);
-                               active++;
-                       }
-                       if (active >= max_active || i == (nix - 1)) {
-                               if ((deadlock = wait_piowc())) {
-                                       if (flush_opt == 1)
-                                               goto done;
-                                       sn2_ptc_deadlock_recovery(nodes_flushed, ibegin, i, mynasid, ptc0, data0, ptc1, data1);
-                                       if (reset_max_active_on_deadlock())
-                                               max_active = 1;
-                               }
-                               active = 0;
-                               ibegin = i + 1;
-                       }
-                       i++;
-               }
-               start += (1UL << nbits);
-       } while (start < end);
-
-done:
-       itc2 = ia64_get_itc() - itc2;
-       __this_cpu_add(ptcstats.shub_itc_clocks, itc2);
-       if (itc2 > __this_cpu_read(ptcstats.shub_itc_clocks_max))
-               __this_cpu_write(ptcstats.shub_itc_clocks_max, itc2);
-
-       if (old_rr) {
-               ia64_set_rr(start, old_rr);
-               ia64_srlz_d();
-       }
-
-       spin_unlock_irqrestore(PTC_LOCK(shub1), flags);
-
-       if (flush_opt == 1 && deadlock) {
-               __this_cpu_inc(ptcstats.deadlocks);
-               sn2_ipi_flush_all_tlb(mm);
-       }
-
-       preempt_enable();
-}
-
-/*
- * sn2_ptc_deadlock_recovery
- *
- * Recover from PTC deadlocks conditions. Recovery requires stepping thru each 
- * TLB flush transaction.  The recovery sequence is somewhat tricky & is
- * coded in assembly language.
- */
-
-void
-sn2_ptc_deadlock_recovery(nodemask_t nodes, short ib, short ie, int mynasid,
-                         volatile unsigned long *ptc0, unsigned long data0,
-                         volatile unsigned long *ptc1, unsigned long data1)
-{
-       short nasid, i;
-       int cnode;
-       unsigned long *piows, zeroval, n;
-
-       __this_cpu_inc(ptcstats.deadlocks);
-
-       piows = (unsigned long *) pda->pio_write_status_addr;
-       zeroval = pda->pio_write_status_val;
-
-       i = 0;
-       for_each_node_mask(cnode, nodes) {
-               if (i < ib)
-                       goto next;
-
-               if (i > ie)
-                       break;
-
-               nasid = cnodeid_to_nasid(cnode);
-               if (local_node_uses_ptc_ga(is_shub1()) && nasid == mynasid)
-                       goto next;
-
-               ptc0 = CHANGE_NASID(nasid, ptc0);
-               if (ptc1)
-                       ptc1 = CHANGE_NASID(nasid, ptc1);
-
-               n = sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval);
-               __this_cpu_add(ptcstats.deadlocks2, n);
-next:
-               i++;
-       }
-
-}
-
-/**
- * sn_send_IPI_phys - send an IPI to a Nasid and slice
- * @nasid: nasid to receive the interrupt (may be outside partition)
- * @physid: physical cpuid to receive the interrupt.
- * @vector: command to send
- * @delivery_mode: delivery mechanism
- *
- * Sends an IPI (interprocessor interrupt) to the processor specified by
- * @physid
- *
- * @delivery_mode can be one of the following
- *
- * %IA64_IPI_DM_INT - pend an interrupt
- * %IA64_IPI_DM_PMI - pend a PMI
- * %IA64_IPI_DM_NMI - pend an NMI
- * %IA64_IPI_DM_INIT - pend an INIT interrupt
- */
-void sn_send_IPI_phys(int nasid, long physid, int vector, int delivery_mode)
-{
-       long val;
-       unsigned long flags = 0;
-       volatile long *p;
-
-       p = (long *)GLOBAL_MMR_PHYS_ADDR(nasid, SH_IPI_INT);
-       val = (1UL << SH_IPI_INT_SEND_SHFT) |
-           (physid << SH_IPI_INT_PID_SHFT) |
-           ((long)delivery_mode << SH_IPI_INT_TYPE_SHFT) |
-           ((long)vector << SH_IPI_INT_IDX_SHFT) |
-           (0x000feeUL << SH_IPI_INT_BASE_SHFT);
-
-       mb();
-       if (enable_shub_wars_1_1()) {
-               spin_lock_irqsave(&sn2_global_ptc_lock, flags);
-       }
-       pio_phys_write_mmr(p, val);
-       if (enable_shub_wars_1_1()) {
-               wait_piowc();
-               spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
-       }
-
-}
-
-EXPORT_SYMBOL(sn_send_IPI_phys);
-
-/**
- * sn2_send_IPI - send an IPI to a processor
- * @cpuid: target of the IPI
- * @vector: command to send
- * @delivery_mode: delivery mechanism
- * @redirect: redirect the IPI?
- *
- * Sends an IPI (InterProcessor Interrupt) to the processor specified by
- * @cpuid.  @vector specifies the command to send, while @delivery_mode can 
- * be one of the following
- *
- * %IA64_IPI_DM_INT - pend an interrupt
- * %IA64_IPI_DM_PMI - pend a PMI
- * %IA64_IPI_DM_NMI - pend an NMI
- * %IA64_IPI_DM_INIT - pend an INIT interrupt
- */
-void sn2_send_IPI(int cpuid, int vector, int delivery_mode, int redirect)
-{
-       long physid;
-       int nasid;
-
-       physid = cpu_physical_id(cpuid);
-       nasid = cpuid_to_nasid(cpuid);
-
-       /* the following is used only when starting cpus at boot time */
-       if (unlikely(nasid == -1))
-               ia64_sn_get_sapic_info(physid, &nasid, NULL, NULL);
-
-       sn_send_IPI_phys(nasid, physid, vector, delivery_mode);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-/**
- * sn_cpu_disable_allowed - Determine if a CPU can be disabled.
- * @cpu - CPU that is requested to be disabled.
- *
- * CPU disable is only allowed on SHub2 systems running with a PROM
- * that supports CPU disable. It is not permitted to disable the boot processor.
- */
-bool sn_cpu_disable_allowed(int cpu)
-{
-       if (is_shub2() && sn_prom_feature_available(PRF_CPU_DISABLE_SUPPORT)) {
-               if (cpu != 0)
-                       return true;
-               else
-                       printk(KERN_WARNING
-                             "Disabling the boot processor is not allowed.\n");
-
-       } else
-               printk(KERN_WARNING
-                      "CPU disable is not supported on this system.\n");
-
-       return false;
-}
-#endif /* CONFIG_HOTPLUG_CPU */
-
-#ifdef CONFIG_PROC_FS
-
-#define PTC_BASENAME   "sgi_sn/ptc_statistics"
-
-static void *sn2_ptc_seq_start(struct seq_file *file, loff_t * offset)
-{
-       if (*offset < nr_cpu_ids)
-               return offset;
-       return NULL;
-}
-
-static void *sn2_ptc_seq_next(struct seq_file *file, void *data, loff_t * offset)
-{
-       (*offset)++;
-       if (*offset < nr_cpu_ids)
-               return offset;
-       return NULL;
-}
-
-static void sn2_ptc_seq_stop(struct seq_file *file, void *data)
-{
-}
-
-static int sn2_ptc_seq_show(struct seq_file *file, void *data)
-{
-       struct ptc_stats *stat;
-       int cpu;
-
-       cpu = *(loff_t *) data;
-
-       if (!cpu) {
-               seq_printf(file,
-                          "# cpu ptc_l newrid ptc_flushes nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max not_my_mm deadlock2 ipi_fluches ipi_nsec\n");
-               seq_printf(file, "# ptctest %d, flushopt %d\n", sn2_ptctest, sn2_flush_opt);
-       }
-
-       if (cpu < nr_cpu_ids && cpu_online(cpu)) {
-               stat = &per_cpu(ptcstats, cpu);
-               seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l,
-                               stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed,
-                               stat->deadlocks,
-                               1000 * stat->lock_itc_clocks / per_cpu(ia64_cpu_info, cpu).cyc_per_usec,
-                               1000 * stat->shub_itc_clocks / per_cpu(ia64_cpu_info, cpu).cyc_per_usec,
-                               1000 * stat->shub_itc_clocks_max / per_cpu(ia64_cpu_info, cpu).cyc_per_usec,
-                               stat->shub_ptc_flushes_not_my_mm,
-                               stat->deadlocks2,
-                               stat->shub_ipi_flushes,
-                               1000 * stat->shub_ipi_flushes_itc_clocks / per_cpu(ia64_cpu_info, cpu).cyc_per_usec);
-       }
-       return 0;
-}
-
-static ssize_t sn2_ptc_proc_write(struct file *file, const char __user *user, size_t count, loff_t *data)
-{
-       int cpu;
-       char optstr[64];
-
-       if (count == 0 || count > sizeof(optstr))
-               return -EINVAL;
-       if (copy_from_user(optstr, user, count))
-               return -EFAULT;
-       optstr[count - 1] = '\0';
-       sn2_flush_opt = simple_strtoul(optstr, NULL, 0);
-
-       for_each_online_cpu(cpu)
-               memset(&per_cpu(ptcstats, cpu), 0, sizeof(struct ptc_stats));
-
-       return count;
-}
-
-static const struct seq_operations sn2_ptc_seq_ops = {
-       .start = sn2_ptc_seq_start,
-       .next = sn2_ptc_seq_next,
-       .stop = sn2_ptc_seq_stop,
-       .show = sn2_ptc_seq_show
-};
-
-static int sn2_ptc_proc_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &sn2_ptc_seq_ops);
-}
-
-static const struct file_operations proc_sn2_ptc_operations = {
-       .open = sn2_ptc_proc_open,
-       .read = seq_read,
-       .write = sn2_ptc_proc_write,
-       .llseek = seq_lseek,
-       .release = seq_release,
-};
-
-static struct proc_dir_entry *proc_sn2_ptc;
-
-static int __init sn2_ptc_init(void)
-{
-       if (!ia64_platform_is("sn2"))
-               return 0;
-
-       proc_sn2_ptc = proc_create(PTC_BASENAME, 0444,
-                                  NULL, &proc_sn2_ptc_operations);
-       if (!proc_sn2_ptc) {
-               printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME);
-               return -EINVAL;
-       }
-       spin_lock_init(&sn2_global_ptc_lock);
-       return 0;
-}
-
-static void __exit sn2_ptc_exit(void)
-{
-       remove_proc_entry(PTC_BASENAME, NULL);
-}
-
-module_init(sn2_ptc_init);
-module_exit(sn2_ptc_exit);
-#endif /* CONFIG_PROC_FS */
-
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c
deleted file mode 100644 (file)
index 55febd6..0000000
+++ /dev/null
@@ -1,1004 +0,0 @@
-/* 
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved.
- *
- * SGI Altix topology and hardware performance monitoring API.
- * Mark Goodwin <markgw@sgi.com>. 
- *
- * Creates /proc/sgi_sn/sn_topology (read-only) to export
- * info about Altix nodes, routers, CPUs and NumaLink
- * interconnection/topology.
- *
- * Also creates a dynamic misc device named "sn_hwperf"
- * that supports an ioctl interface to call down into SAL
- * to discover hw objects, topology and to read/write
- * memory mapped registers, e.g. for performance monitoring.
- * The "sn_hwperf" device is registered only after the procfs
- * file is first opened, i.e. only if/when it's needed. 
- *
- * This API is used by SGI Performance Co-Pilot and other
- * tools, see http://oss.sgi.com/projects/pcp
- */
-
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <linux/vmalloc.h>
-#include <linux/seq_file.h>
-#include <linux/miscdevice.h>
-#include <linux/utsname.h>
-#include <linux/cpumask.h>
-#include <linux/nodemask.h>
-#include <linux/smp.h>
-#include <linux/mutex.h>
-
-#include <asm/processor.h>
-#include <asm/topology.h>
-#include <linux/uaccess.h>
-#include <asm/sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/module.h>
-#include <asm/sn/geo.h>
-#include <asm/sn/sn2/sn_hwperf.h>
-#include <asm/sn/addrs.h>
-
-static void *sn_hwperf_salheap = NULL;
-static int sn_hwperf_obj_cnt = 0;
-static nasid_t sn_hwperf_master_nasid = INVALID_NASID;
-static int sn_hwperf_init(void);
-static DEFINE_MUTEX(sn_hwperf_init_mutex);
-
-#define cnode_possible(n)      ((n) < num_cnodes)
-
-static int sn_hwperf_enum_objects(int *nobj, struct sn_hwperf_object_info **ret)
-{
-       int e;
-       u64 sz;
-       struct sn_hwperf_object_info *objbuf = NULL;
-
-       if ((e = sn_hwperf_init()) < 0) {
-               printk(KERN_ERR "sn_hwperf_init failed: err %d\n", e);
-               goto out;
-       }
-
-       sz = sn_hwperf_obj_cnt * sizeof(struct sn_hwperf_object_info);
-       objbuf = vmalloc(sz);
-       if (objbuf == NULL) {
-               printk("sn_hwperf_enum_objects: vmalloc(%d) failed\n", (int)sz);
-               e = -ENOMEM;
-               goto out;
-       }
-
-       e = ia64_sn_hwperf_op(sn_hwperf_master_nasid, SN_HWPERF_ENUM_OBJECTS,
-               0, sz, (u64) objbuf, 0, 0, NULL);
-       if (e != SN_HWPERF_OP_OK) {
-               e = -EINVAL;
-               vfree(objbuf);
-       }
-
-out:
-       *nobj = sn_hwperf_obj_cnt;
-       *ret = objbuf;
-       return e;
-}
-
-static int sn_hwperf_location_to_bpos(char *location,
-       int *rack, int *bay, int *slot, int *slab)
-{
-       char type;
-
-       /* first scan for an old style geoid string */
-       if (sscanf(location, "%03d%c%02d#%d",
-               rack, &type, bay, slab) == 4)
-               *slot = 0; 
-       else /* scan for a new bladed geoid string */
-       if (sscanf(location, "%03d%c%02d^%02d#%d",
-               rack, &type, bay, slot, slab) != 5)
-               return -1; 
-       /* success */
-       return 0;
-}
-
-static int sn_hwperf_geoid_to_cnode(char *location)
-{
-       int cnode;
-       geoid_t geoid;
-       moduleid_t module_id;
-       int rack, bay, slot, slab;
-       int this_rack, this_bay, this_slot, this_slab;
-
-       if (sn_hwperf_location_to_bpos(location, &rack, &bay, &slot, &slab))
-               return -1;
-
-       /*
-        * FIXME: replace with cleaner for_each_XXX macro which addresses
-        * both compute and IO nodes once ACPI3.0 is available.
-        */
-       for (cnode = 0; cnode < num_cnodes; cnode++) {
-               geoid = cnodeid_get_geoid(cnode);
-               module_id = geo_module(geoid);
-               this_rack = MODULE_GET_RACK(module_id);
-               this_bay = MODULE_GET_BPOS(module_id);
-               this_slot = geo_slot(geoid);
-               this_slab = geo_slab(geoid);
-               if (rack == this_rack && bay == this_bay &&
-                       slot == this_slot && slab == this_slab) {
-                       break;
-               }
-       }
-
-       return cnode_possible(cnode) ? cnode : -1;
-}
-
-static int sn_hwperf_obj_to_cnode(struct sn_hwperf_object_info * obj)
-{
-       if (!SN_HWPERF_IS_NODE(obj) && !SN_HWPERF_IS_IONODE(obj))
-               BUG();
-       if (SN_HWPERF_FOREIGN(obj))
-               return -1;
-       return sn_hwperf_geoid_to_cnode(obj->location);
-}
-
-static int sn_hwperf_generic_ordinal(struct sn_hwperf_object_info *obj,
-                               struct sn_hwperf_object_info *objs)
-{
-       int ordinal;
-       struct sn_hwperf_object_info *p;
-
-       for (ordinal=0, p=objs; p != obj; p++) {
-               if (SN_HWPERF_FOREIGN(p))
-                       continue;
-               if (SN_HWPERF_SAME_OBJTYPE(p, obj))
-                       ordinal++;
-       }
-
-       return ordinal;
-}
-
-static const char *slabname_node =     "node"; /* SHub asic */
-static const char *slabname_ionode =   "ionode"; /* TIO asic */
-static const char *slabname_router =   "router"; /* NL3R or NL4R */
-static const char *slabname_other =    "other"; /* unknown asic */
-
-static const char *sn_hwperf_get_slabname(struct sn_hwperf_object_info *obj,
-                       struct sn_hwperf_object_info *objs, int *ordinal)
-{
-       int isnode;
-       const char *slabname = slabname_other;
-
-       if ((isnode = SN_HWPERF_IS_NODE(obj)) || SN_HWPERF_IS_IONODE(obj)) {
-               slabname = isnode ? slabname_node : slabname_ionode;
-               *ordinal = sn_hwperf_obj_to_cnode(obj);
-       }
-       else {
-               *ordinal = sn_hwperf_generic_ordinal(obj, objs);
-               if (SN_HWPERF_IS_ROUTER(obj))
-                       slabname = slabname_router;
-       }
-
-       return slabname;
-}
-
-static void print_pci_topology(struct seq_file *s)
-{
-       char *p;
-       size_t sz;
-       int e;
-
-       for (sz = PAGE_SIZE; sz < 16 * PAGE_SIZE; sz += PAGE_SIZE) {
-               if (!(p = kmalloc(sz, GFP_KERNEL)))
-                       break;
-               e = ia64_sn_ioif_get_pci_topology(__pa(p), sz);
-               if (e == SALRET_OK)
-                       seq_puts(s, p);
-               kfree(p);
-               if (e == SALRET_OK || e == SALRET_NOT_IMPLEMENTED)
-                       break;
-       }
-}
-
-static inline int sn_hwperf_has_cpus(cnodeid_t node)
-{
-       return node < MAX_NUMNODES && node_online(node) && nr_cpus_node(node);
-}
-
-static inline int sn_hwperf_has_mem(cnodeid_t node)
-{
-       return node < MAX_NUMNODES && node_online(node) && NODE_DATA(node)->node_present_pages;
-}
-
-static struct sn_hwperf_object_info *
-sn_hwperf_findobj_id(struct sn_hwperf_object_info *objbuf,
-       int nobj, int id)
-{
-       int i;
-       struct sn_hwperf_object_info *p = objbuf;
-
-       for (i=0; i < nobj; i++, p++) {
-               if (p->id == id)
-                       return p;
-       }
-
-       return NULL;
-
-}
-
-static int sn_hwperf_get_nearest_node_objdata(struct sn_hwperf_object_info *objbuf,
-       int nobj, cnodeid_t node, cnodeid_t *near_mem_node, cnodeid_t *near_cpu_node)
-{
-       int e;
-       struct sn_hwperf_object_info *nodeobj = NULL;
-       struct sn_hwperf_object_info *op;
-       struct sn_hwperf_object_info *dest;
-       struct sn_hwperf_object_info *router;
-       struct sn_hwperf_port_info ptdata[16];
-       int sz, i, j;
-       cnodeid_t c;
-       int found_mem = 0;
-       int found_cpu = 0;
-
-       if (!cnode_possible(node))
-               return -EINVAL;
-
-       if (sn_hwperf_has_cpus(node)) {
-               if (near_cpu_node)
-                       *near_cpu_node = node;
-               found_cpu++;
-       }
-
-       if (sn_hwperf_has_mem(node)) {
-               if (near_mem_node)
-                       *near_mem_node = node;
-               found_mem++;
-       }
-
-       if (found_cpu && found_mem)
-               return 0; /* trivially successful */
-
-       /* find the argument node object */
-       for (i=0, op=objbuf; i < nobj; i++, op++) {
-               if (!SN_HWPERF_IS_NODE(op) && !SN_HWPERF_IS_IONODE(op))
-                       continue;
-               if (node == sn_hwperf_obj_to_cnode(op)) {
-                       nodeobj = op;
-                       break;
-               }
-       }
-       if (!nodeobj) {
-               e = -ENOENT;
-               goto err;
-       }
-
-       /* get it's interconnect topology */
-       sz = op->ports * sizeof(struct sn_hwperf_port_info);
-       BUG_ON(sz > sizeof(ptdata));
-       e = ia64_sn_hwperf_op(sn_hwperf_master_nasid,
-                             SN_HWPERF_ENUM_PORTS, nodeobj->id, sz,
-                             (u64)&ptdata, 0, 0, NULL);
-       if (e != SN_HWPERF_OP_OK) {
-               e = -EINVAL;
-               goto err;
-       }
-
-       /* find nearest node with cpus and nearest memory */
-       for (router=NULL, j=0; j < op->ports; j++) {
-               dest = sn_hwperf_findobj_id(objbuf, nobj, ptdata[j].conn_id);
-               if (dest && SN_HWPERF_IS_ROUTER(dest))
-                       router = dest;
-               if (!dest || SN_HWPERF_FOREIGN(dest) ||
-                   !SN_HWPERF_IS_NODE(dest) || SN_HWPERF_IS_IONODE(dest)) {
-                       continue;
-               }
-               c = sn_hwperf_obj_to_cnode(dest);
-               if (!found_cpu && sn_hwperf_has_cpus(c)) {
-                       if (near_cpu_node)
-                               *near_cpu_node = c;
-                       found_cpu++;
-               }
-               if (!found_mem && sn_hwperf_has_mem(c)) {
-                       if (near_mem_node)
-                               *near_mem_node = c;
-                       found_mem++;
-               }
-       }
-
-       if (router && (!found_cpu || !found_mem)) {
-               /* search for a node connected to the same router */
-               sz = router->ports * sizeof(struct sn_hwperf_port_info);
-               BUG_ON(sz > sizeof(ptdata));
-               e = ia64_sn_hwperf_op(sn_hwperf_master_nasid,
-                                     SN_HWPERF_ENUM_PORTS, router->id, sz,
-                                     (u64)&ptdata, 0, 0, NULL);
-               if (e != SN_HWPERF_OP_OK) {
-                       e = -EINVAL;
-                       goto err;
-               }
-               for (j=0; j < router->ports; j++) {
-                       dest = sn_hwperf_findobj_id(objbuf, nobj,
-                               ptdata[j].conn_id);
-                       if (!dest || dest->id == node ||
-                           SN_HWPERF_FOREIGN(dest) ||
-                           !SN_HWPERF_IS_NODE(dest) ||
-                           SN_HWPERF_IS_IONODE(dest)) {
-                               continue;
-                       }
-                       c = sn_hwperf_obj_to_cnode(dest);
-                       if (!found_cpu && sn_hwperf_has_cpus(c)) {
-                               if (near_cpu_node)
-                                       *near_cpu_node = c;
-                               found_cpu++;
-                       }
-                       if (!found_mem && sn_hwperf_has_mem(c)) {
-                               if (near_mem_node)
-                                       *near_mem_node = c;
-                               found_mem++;
-                       }
-                       if (found_cpu && found_mem)
-                               break;
-               }
-       }
-
-       if (!found_cpu || !found_mem) {
-               /* resort to _any_ node with CPUs and memory */
-               for (i=0, op=objbuf; i < nobj; i++, op++) {
-                       if (SN_HWPERF_FOREIGN(op) ||
-                           SN_HWPERF_IS_IONODE(op) ||
-                           !SN_HWPERF_IS_NODE(op)) {
-                               continue;
-                       }
-                       c = sn_hwperf_obj_to_cnode(op);
-                       if (!found_cpu && sn_hwperf_has_cpus(c)) {
-                               if (near_cpu_node)
-                                       *near_cpu_node = c;
-                               found_cpu++;
-                       }
-                       if (!found_mem && sn_hwperf_has_mem(c)) {
-                               if (near_mem_node)
-                                       *near_mem_node = c;
-                               found_mem++;
-                       }
-                       if (found_cpu && found_mem)
-                               break;
-               }
-       }
-
-       if (!found_cpu || !found_mem)
-               e = -ENODATA;
-
-err:
-       return e;
-}
-
-
-static int sn_topology_show(struct seq_file *s, void *d)
-{
-       int sz;
-       int pt;
-       int e = 0;
-       int i;
-       int j;
-       const char *slabname;
-       int ordinal;
-       char slice;
-       struct cpuinfo_ia64 *c;
-       struct sn_hwperf_port_info *ptdata;
-       struct sn_hwperf_object_info *p;
-       struct sn_hwperf_object_info *obj = d;  /* this object */
-       struct sn_hwperf_object_info *objs = s->private; /* all objects */
-       u8 shubtype;
-       u8 system_size;
-       u8 sharing_size;
-       u8 partid;
-       u8 coher;
-       u8 nasid_shift;
-       u8 region_size;
-       u16 nasid_mask;
-       int nasid_msb;
-
-       if (obj == objs) {
-               seq_printf(s, "# sn_topology version 2\n");
-               seq_printf(s, "# objtype ordinal location partition"
-                       " [attribute value [, ...]]\n");
-
-               if (ia64_sn_get_sn_info(0,
-                       &shubtype, &nasid_mask, &nasid_shift, &system_size,
-                       &sharing_size, &partid, &coher, &region_size))
-                       BUG();
-               for (nasid_msb=63; nasid_msb > 0; nasid_msb--) {
-                       if (((u64)nasid_mask << nasid_shift) & (1ULL << nasid_msb))
-                               break;
-               }
-               seq_printf(s, "partition %u %s local "
-                       "shubtype %s, "
-                       "nasid_mask 0x%016llx, "
-                       "nasid_bits %d:%d, "
-                       "system_size %d, "
-                       "sharing_size %d, "
-                       "coherency_domain %d, "
-                       "region_size %d\n",
-
-                       partid, utsname()->nodename,
-                       shubtype ? "shub2" : "shub1", 
-                       (u64)nasid_mask << nasid_shift, nasid_msb, nasid_shift,
-                       system_size, sharing_size, coher, region_size);
-
-               print_pci_topology(s);
-       }
-
-       if (SN_HWPERF_FOREIGN(obj)) {
-               /* private in another partition: not interesting */
-               return 0;
-       }
-
-       for (i = 0; i < SN_HWPERF_MAXSTRING && obj->name[i]; i++) {
-               if (obj->name[i] == ' ')
-                       obj->name[i] = '_';
-       }
-
-       slabname = sn_hwperf_get_slabname(obj, objs, &ordinal);
-       seq_printf(s, "%s %d %s %s asic %s", slabname, ordinal, obj->location,
-               obj->sn_hwp_this_part ? "local" : "shared", obj->name);
-
-       if (ordinal < 0 || (!SN_HWPERF_IS_NODE(obj) && !SN_HWPERF_IS_IONODE(obj)))
-               seq_putc(s, '\n');
-       else {
-               cnodeid_t near_mem = -1;
-               cnodeid_t near_cpu = -1;
-
-               seq_printf(s, ", nasid 0x%x", cnodeid_to_nasid(ordinal));
-
-               if (sn_hwperf_get_nearest_node_objdata(objs, sn_hwperf_obj_cnt,
-                       ordinal, &near_mem, &near_cpu) == 0) {
-                       seq_printf(s, ", near_mem_nodeid %d, near_cpu_nodeid %d",
-                               near_mem, near_cpu);
-               }
-
-               if (!SN_HWPERF_IS_IONODE(obj)) {
-                       for_each_online_node(i) {
-                               seq_printf(s, i ? ":%d" : ", dist %d",
-                                       node_distance(ordinal, i));
-                       }
-               }
-
-               seq_putc(s, '\n');
-
-               /*
-                * CPUs on this node, if any
-                */
-               if (!SN_HWPERF_IS_IONODE(obj)) {
-                       for_each_cpu_and(i, cpu_online_mask,
-                                        cpumask_of_node(ordinal)) {
-                               slice = 'a' + cpuid_to_slice(i);
-                               c = cpu_data(i);
-                               seq_printf(s, "cpu %d %s%c local"
-                                          " freq %luMHz, arch ia64",
-                                          i, obj->location, slice,
-                                          c->proc_freq / 1000000);
-                               for_each_online_cpu(j) {
-                                       seq_printf(s, j ? ":%d" : ", dist %d",
-                                                  node_distance(
-                                                       cpu_to_node(i),
-                                                       cpu_to_node(j)));
-                               }
-                               seq_putc(s, '\n');
-                       }
-               }
-       }
-
-       if (obj->ports) {
-               /*
-                * numalink ports
-                */
-               sz = obj->ports * sizeof(struct sn_hwperf_port_info);
-               if ((ptdata = kmalloc(sz, GFP_KERNEL)) == NULL)
-                       return -ENOMEM;
-               e = ia64_sn_hwperf_op(sn_hwperf_master_nasid,
-                                     SN_HWPERF_ENUM_PORTS, obj->id, sz,
-                                     (u64) ptdata, 0, 0, NULL);
-               if (e != SN_HWPERF_OP_OK)
-                       return -EINVAL;
-               for (ordinal=0, p=objs; p != obj; p++) {
-                       if (!SN_HWPERF_FOREIGN(p))
-                               ordinal += p->ports;
-               }
-               for (pt = 0; pt < obj->ports; pt++) {
-                       for (p = objs, i = 0; i < sn_hwperf_obj_cnt; i++, p++) {
-                               if (ptdata[pt].conn_id == p->id) {
-                                       break;
-                               }
-                       }
-                       seq_printf(s, "numalink %d %s-%d",
-                           ordinal+pt, obj->location, ptdata[pt].port);
-
-                       if (i >= sn_hwperf_obj_cnt) {
-                               /* no connection */
-                               seq_puts(s, " local endpoint disconnected"
-                                           ", protocol unknown\n");
-                               continue;
-                       }
-
-                       if (obj->sn_hwp_this_part && p->sn_hwp_this_part)
-                               /* both ends local to this partition */
-                               seq_puts(s, " local");
-                       else if (SN_HWPERF_FOREIGN(p))
-                               /* both ends of the link in foreign partition */
-                               seq_puts(s, " foreign");
-                       else
-                               /* link straddles a partition */
-                               seq_puts(s, " shared");
-
-                       /*
-                        * Unlikely, but strictly should query the LLP config
-                        * registers because an NL4R can be configured to run
-                        * NL3 protocol, even when not talking to an NL3 router.
-                        * Ditto for node-node.
-                        */
-                       seq_printf(s, " endpoint %s-%d, protocol %s\n",
-                               p->location, ptdata[pt].conn_port,
-                               (SN_HWPERF_IS_NL3ROUTER(obj) ||
-                               SN_HWPERF_IS_NL3ROUTER(p)) ?  "LLP3" : "LLP4");
-               }
-               kfree(ptdata);
-       }
-
-       return 0;
-}
-
-static void *sn_topology_start(struct seq_file *s, loff_t * pos)
-{
-       struct sn_hwperf_object_info *objs = s->private;
-
-       if (*pos < sn_hwperf_obj_cnt)
-               return (void *)(objs + *pos);
-
-       return NULL;
-}
-
-static void *sn_topology_next(struct seq_file *s, void *v, loff_t * pos)
-{
-       ++*pos;
-       return sn_topology_start(s, pos);
-}
-
-static void sn_topology_stop(struct seq_file *m, void *v)
-{
-       return;
-}
-
-/*
- * /proc/sgi_sn/sn_topology, read-only using seq_file
- */
-static const struct seq_operations sn_topology_seq_ops = {
-       .start = sn_topology_start,
-       .next = sn_topology_next,
-       .stop = sn_topology_stop,
-       .show = sn_topology_show
-};
-
-struct sn_hwperf_op_info {
-       u64 op;
-       struct sn_hwperf_ioctl_args *a;
-       void *p;
-       int *v0;
-       int ret;
-};
-
-static void sn_hwperf_call_sal(void *info)
-{
-       struct sn_hwperf_op_info *op_info = info;
-       int r;
-
-       r = ia64_sn_hwperf_op(sn_hwperf_master_nasid, op_info->op,
-                     op_info->a->arg, op_info->a->sz,
-                     (u64) op_info->p, 0, 0, op_info->v0);
-       op_info->ret = r;
-}
-
-static long sn_hwperf_call_sal_work(void *info)
-{
-       sn_hwperf_call_sal(info);
-       return 0;
-}
-
-static int sn_hwperf_op_cpu(struct sn_hwperf_op_info *op_info)
-{
-       u32 cpu;
-       u32 use_ipi;
-       int r = 0;
-       
-       cpu = (op_info->a->arg & SN_HWPERF_ARG_CPU_MASK) >> 32;
-       use_ipi = op_info->a->arg & SN_HWPERF_ARG_USE_IPI_MASK;
-       op_info->a->arg &= SN_HWPERF_ARG_OBJID_MASK;
-
-       if (cpu != SN_HWPERF_ARG_ANY_CPU) {
-               if (cpu >= nr_cpu_ids || !cpu_online(cpu)) {
-                       r = -EINVAL;
-                       goto out;
-               }
-       }
-
-       if (cpu == SN_HWPERF_ARG_ANY_CPU) {
-               /* don't care which cpu */
-               sn_hwperf_call_sal(op_info);
-       } else if (cpu == get_cpu()) {
-               /* already on correct cpu */
-               sn_hwperf_call_sal(op_info);
-               put_cpu();
-       } else {
-               put_cpu();
-               if (use_ipi) {
-                       /* use an interprocessor interrupt to call SAL */
-                       smp_call_function_single(cpu, sn_hwperf_call_sal,
-                               op_info, 1);
-               } else {
-                       /* Call on the target CPU */
-                       work_on_cpu_safe(cpu, sn_hwperf_call_sal_work, op_info);
-               }
-       }
-       r = op_info->ret;
-
-out:
-       return r;
-}
-
-/* map SAL hwperf error code to system error code */
-static int sn_hwperf_map_err(int hwperf_err)
-{
-       int e;
-
-       switch(hwperf_err) {
-       case SN_HWPERF_OP_OK:
-               e = 0;
-               break;
-
-       case SN_HWPERF_OP_NOMEM:
-               e = -ENOMEM;
-               break;
-
-       case SN_HWPERF_OP_NO_PERM:
-               e = -EPERM;
-               break;
-
-       case SN_HWPERF_OP_IO_ERROR:
-               e = -EIO;
-               break;
-
-       case SN_HWPERF_OP_BUSY:
-               e = -EBUSY;
-               break;
-
-       case SN_HWPERF_OP_RECONFIGURE:
-               e = -EAGAIN;
-               break;
-
-       case SN_HWPERF_OP_INVAL:
-       default:
-               e = -EINVAL;
-               break;
-       }
-
-       return e;
-}
-
-/*
- * ioctl for "sn_hwperf" misc device
- */
-static long sn_hwperf_ioctl(struct file *fp, u32 op, unsigned long arg)
-{
-       struct sn_hwperf_ioctl_args a;
-       struct cpuinfo_ia64 *cdata;
-       struct sn_hwperf_object_info *objs;
-       struct sn_hwperf_object_info *cpuobj;
-       struct sn_hwperf_op_info op_info;
-       void *p = NULL;
-       int nobj;
-       char slice;
-       int node;
-       int r;
-       int v0;
-       int i;
-       int j;
-
-       /* only user requests are allowed here */
-       if ((op & SN_HWPERF_OP_MASK) < 10) {
-               r = -EINVAL;
-               goto error;
-       }
-       r = copy_from_user(&a, (const void __user *)arg,
-               sizeof(struct sn_hwperf_ioctl_args));
-       if (r != 0) {
-               r = -EFAULT;
-               goto error;
-       }
-
-       /*
-        * Allocate memory to hold a kernel copy of the user buffer. The
-        * buffer contents are either copied in or out (or both) of user
-        * space depending on the flags encoded in the requested operation.
-        */
-       if (a.ptr) {
-               p = vmalloc(a.sz);
-               if (!p) {
-                       r = -ENOMEM;
-                       goto error;
-               }
-       }
-
-       if (op & SN_HWPERF_OP_MEM_COPYIN) {
-               r = copy_from_user(p, (const void __user *)a.ptr, a.sz);
-               if (r != 0) {
-                       r = -EFAULT;
-                       goto error;
-               }
-       }
-
-       switch (op) {
-       case SN_HWPERF_GET_CPU_INFO:
-               if (a.sz == sizeof(u64)) {
-                       /* special case to get size needed */
-                       *(u64 *) p = (u64) num_online_cpus() *
-                               sizeof(struct sn_hwperf_object_info);
-               } else
-               if (a.sz < num_online_cpus() * sizeof(struct sn_hwperf_object_info)) {
-                       r = -ENOMEM;
-                       goto error;
-               } else
-               if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) {
-                       int cpuobj_index = 0;
-
-                       memset(p, 0, a.sz);
-                       for (i = 0; i < nobj; i++) {
-                               if (!SN_HWPERF_IS_NODE(objs + i))
-                                       continue;
-                               node = sn_hwperf_obj_to_cnode(objs + i);
-                               for_each_online_cpu(j) {
-                                       if (node != cpu_to_node(j))
-                                               continue;
-                                       cpuobj = (struct sn_hwperf_object_info *) p + cpuobj_index++;
-                                       slice = 'a' + cpuid_to_slice(j);
-                                       cdata = cpu_data(j);
-                                       cpuobj->id = j;
-                                       snprintf(cpuobj->name,
-                                                sizeof(cpuobj->name),
-                                                "CPU %luMHz %s",
-                                                cdata->proc_freq / 1000000,
-                                                cdata->vendor);
-                                       snprintf(cpuobj->location,
-                                                sizeof(cpuobj->location),
-                                                "%s%c", objs[i].location,
-                                                slice);
-                               }
-                       }
-
-                       vfree(objs);
-               }
-               break;
-
-       case SN_HWPERF_GET_NODE_NASID:
-               if (a.sz != sizeof(u64) ||
-                  (node = a.arg) < 0 || !cnode_possible(node)) {
-                       r = -EINVAL;
-                       goto error;
-               }
-               *(u64 *)p = (u64)cnodeid_to_nasid(node);
-               break;
-
-       case SN_HWPERF_GET_OBJ_NODE:
-               i = a.arg;
-               if (a.sz != sizeof(u64) || i < 0) {
-                       r = -EINVAL;
-                       goto error;
-               }
-               if ((r = sn_hwperf_enum_objects(&nobj, &objs)) == 0) {
-                       if (i >= nobj) {
-                               r = -EINVAL;
-                               vfree(objs);
-                               goto error;
-                       }
-                       if (objs[i].id != a.arg) {
-                               for (i = 0; i < nobj; i++) {
-                                       if (objs[i].id == a.arg)
-                                               break;
-                               }
-                       }
-                       if (i == nobj) {
-                               r = -EINVAL;
-                               vfree(objs);
-                               goto error;
-                       }
-
-                       if (!SN_HWPERF_IS_NODE(objs + i) &&
-                           !SN_HWPERF_IS_IONODE(objs + i)) {
-                               r = -ENOENT;
-                               vfree(objs);
-                               goto error;
-                       }
-
-                       *(u64 *)p = (u64)sn_hwperf_obj_to_cnode(objs + i);
-                       vfree(objs);
-               }
-               break;
-
-       case SN_HWPERF_GET_MMRS:
-       case SN_HWPERF_SET_MMRS:
-       case SN_HWPERF_OBJECT_DISTANCE:
-               op_info.p = p;
-               op_info.a = &a;
-               op_info.v0 = &v0;
-               op_info.op = op;
-               r = sn_hwperf_op_cpu(&op_info);
-               if (r) {
-                       r = sn_hwperf_map_err(r);
-                       a.v0 = v0;
-                       goto error;
-               }
-               break;
-
-       default:
-               /* all other ops are a direct SAL call */
-               r = ia64_sn_hwperf_op(sn_hwperf_master_nasid, op,
-                             a.arg, a.sz, (u64) p, 0, 0, &v0);
-               if (r) {
-                       r = sn_hwperf_map_err(r);
-                       goto error;
-               }
-               a.v0 = v0;
-               break;
-       }
-
-       if (op & SN_HWPERF_OP_MEM_COPYOUT) {
-               r = copy_to_user((void __user *)a.ptr, p, a.sz);
-               if (r != 0) {
-                       r = -EFAULT;
-                       goto error;
-               }
-       }
-
-error:
-       vfree(p);
-
-       return r;
-}
-
-static const struct file_operations sn_hwperf_fops = {
-       .unlocked_ioctl = sn_hwperf_ioctl,
-       .llseek = noop_llseek,
-};
-
-static struct miscdevice sn_hwperf_dev = {
-       MISC_DYNAMIC_MINOR,
-       "sn_hwperf",
-       &sn_hwperf_fops
-};
-
-static int sn_hwperf_init(void)
-{
-       u64 v;
-       int salr;
-       int e = 0;
-
-       /* single threaded, once-only initialization */
-       mutex_lock(&sn_hwperf_init_mutex);
-
-       if (sn_hwperf_salheap) {
-               mutex_unlock(&sn_hwperf_init_mutex);
-               return e;
-       }
-
-       /*
-        * The PROM code needs a fixed reference node. For convenience the
-        * same node as the console I/O is used.
-        */
-       sn_hwperf_master_nasid = (nasid_t) ia64_sn_get_console_nasid();
-
-       /*
-        * Request the needed size and install the PROM scratch area.
-        * The PROM keeps various tracking bits in this memory area.
-        */
-       salr = ia64_sn_hwperf_op(sn_hwperf_master_nasid,
-                                (u64) SN_HWPERF_GET_HEAPSIZE, 0,
-                                (u64) sizeof(u64), (u64) &v, 0, 0, NULL);
-       if (salr != SN_HWPERF_OP_OK) {
-               e = -EINVAL;
-               goto out;
-       }
-
-       if ((sn_hwperf_salheap = vmalloc(v)) == NULL) {
-               e = -ENOMEM;
-               goto out;
-       }
-       salr = ia64_sn_hwperf_op(sn_hwperf_master_nasid,
-                                SN_HWPERF_INSTALL_HEAP, 0, v,
-                                (u64) sn_hwperf_salheap, 0, 0, NULL);
-       if (salr != SN_HWPERF_OP_OK) {
-               e = -EINVAL;
-               goto out;
-       }
-
-       salr = ia64_sn_hwperf_op(sn_hwperf_master_nasid,
-                                SN_HWPERF_OBJECT_COUNT, 0,
-                                sizeof(u64), (u64) &v, 0, 0, NULL);
-       if (salr != SN_HWPERF_OP_OK) {
-               e = -EINVAL;
-               goto out;
-       }
-       sn_hwperf_obj_cnt = (int)v;
-
-out:
-       if (e < 0 && sn_hwperf_salheap) {
-               vfree(sn_hwperf_salheap);
-               sn_hwperf_salheap = NULL;
-               sn_hwperf_obj_cnt = 0;
-       }
-       mutex_unlock(&sn_hwperf_init_mutex);
-       return e;
-}
-
-int sn_topology_open(struct inode *inode, struct file *file)
-{
-       int e;
-       struct seq_file *seq;
-       struct sn_hwperf_object_info *objbuf;
-       int nobj;
-
-       if ((e = sn_hwperf_enum_objects(&nobj, &objbuf)) == 0) {
-               e = seq_open(file, &sn_topology_seq_ops);
-               seq = file->private_data;
-               seq->private = objbuf;
-       }
-
-       return e;
-}
-
-int sn_topology_release(struct inode *inode, struct file *file)
-{
-       struct seq_file *seq = file->private_data;
-
-       vfree(seq->private);
-       return seq_release(inode, file);
-}
-
-int sn_hwperf_get_nearest_node(cnodeid_t node,
-       cnodeid_t *near_mem_node, cnodeid_t *near_cpu_node)
-{
-       int e;
-       int nobj;
-       struct sn_hwperf_object_info *objbuf;
-
-       if ((e = sn_hwperf_enum_objects(&nobj, &objbuf)) == 0) {
-               e = sn_hwperf_get_nearest_node_objdata(objbuf, nobj,
-                       node, near_mem_node, near_cpu_node);
-               vfree(objbuf);
-       }
-
-       return e;
-}
-
-static int sn_hwperf_misc_register_init(void)
-{
-       int e;
-
-       if (!ia64_platform_is("sn2"))
-               return 0;
-
-       sn_hwperf_init();
-
-       /*
-        * Register a dynamic misc device for hwperf ioctls. Platforms
-        * supporting hotplug will create /dev/sn_hwperf, else user
-        * can to look up the minor number in /proc/misc.
-        */
-       if ((e = misc_register(&sn_hwperf_dev)) != 0) {
-               printk(KERN_ERR "sn_hwperf_misc_register_init: failed to "
-               "register misc device for \"%s\"\n", sn_hwperf_dev.name);
-       }
-
-       return e;
-}
-
-device_initcall(sn_hwperf_misc_register_init); /* after misc_init() */
-EXPORT_SYMBOL(sn_hwperf_get_nearest_node);
diff --git a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
deleted file mode 100644 (file)
index c2a4d84..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifdef CONFIG_PROC_FS
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-#include <linux/uaccess.h>
-#include <asm/sn/sn_sal.h>
-
-static int partition_id_show(struct seq_file *s, void *p)
-{
-       seq_printf(s, "%d\n", sn_partition_id);
-       return 0;
-}
-
-static int system_serial_number_show(struct seq_file *s, void *p)
-{
-       seq_printf(s, "%s\n", sn_system_serial_number());
-       return 0;
-}
-
-static int licenseID_show(struct seq_file *s, void *p)
-{
-       seq_printf(s, "0x%llx\n", sn_partition_serial_number_val());
-       return 0;
-}
-
-static int coherence_id_show(struct seq_file *s, void *p)
-{
-       seq_printf(s, "%d\n", partition_coherence_id());
-
-       return 0;
-}
-
-/* /proc/sgi_sn/sn_topology uses seq_file, see sn_hwperf.c */
-extern int sn_topology_open(struct inode *, struct file *);
-extern int sn_topology_release(struct inode *, struct file *);
-
-static const struct file_operations proc_sn_topo_fops = {
-       .open           = sn_topology_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = sn_topology_release,
-};
-
-void register_sn_procfs(void)
-{
-       static struct proc_dir_entry *sgi_proc_dir = NULL;
-
-       BUG_ON(sgi_proc_dir != NULL);
-       if (!(sgi_proc_dir = proc_mkdir("sgi_sn", NULL)))
-               return;
-
-       proc_create_single("partition_id", 0444, sgi_proc_dir,
-                       partition_id_show);
-       proc_create_single("system_serial_number", 0444, sgi_proc_dir,
-                       system_serial_number_show);
-       proc_create_single("licenseID", 0444, sgi_proc_dir, licenseID_show);
-       proc_create_single("coherence_id", 0444, sgi_proc_dir,
-                       coherence_id_show);
-       proc_create("sn_topology", 0444, sgi_proc_dir, &proc_sn_topo_fops);
-}
-
-#endif /* CONFIG_PROC_FS */
diff --git a/arch/ia64/sn/kernel/sn2/timer.c b/arch/ia64/sn/kernel/sn2/timer.c
deleted file mode 100644 (file)
index 3009d9d..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * linux/arch/ia64/sn/kernel/sn2/timer.c
- *
- * Copyright (C) 2003 Silicon Graphics, Inc.
- * Copyright (C) 2003 Hewlett-Packard Co
- *     David Mosberger <davidm@hpl.hp.com>: updated for new timer-interpolation infrastructure
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/time.h>
-#include <linux/interrupt.h>
-#include <linux/clocksource.h>
-
-#include <asm/hw_irq.h>
-#include <asm/timex.h>
-
-#include <asm/sn/leds.h>
-#include <asm/sn/shub_mmr.h>
-#include <asm/sn/clksupport.h>
-
-extern unsigned long sn_rtc_cycles_per_second;
-
-static u64 read_sn2(struct clocksource *cs)
-{
-       return (u64)readq(RTC_COUNTER_ADDR);
-}
-
-static struct clocksource clocksource_sn2 = {
-        .name           = "sn2_rtc",
-        .rating         = 450,
-        .read           = read_sn2,
-        .mask           = (1LL << 55) - 1,
-        .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-/*
- * sn udelay uses the RTC instead of the ITC because the ITC is not
- * synchronized across all CPUs, and the thread may migrate to another CPU
- * if preemption is enabled.
- */
-static void
-ia64_sn_udelay (unsigned long usecs)
-{
-       unsigned long start = rtc_time();
-       unsigned long end = start +
-                       usecs * sn_rtc_cycles_per_second / 1000000;
-
-       while (time_before((unsigned long)rtc_time(), end))
-               cpu_relax();
-}
-
-void __init sn_timer_init(void)
-{
-       clocksource_sn2.archdata.fsys_mmio = RTC_COUNTER_ADDR;
-       clocksource_register_hz(&clocksource_sn2, sn_rtc_cycles_per_second);
-
-       ia64_udelay = &ia64_sn_udelay;
-}
diff --git a/arch/ia64/sn/kernel/sn2/timer_interrupt.c b/arch/ia64/sn/kernel/sn2/timer_interrupt.c
deleted file mode 100644 (file)
index 103d6ea..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *
- *
- * Copyright (c) 2005, 2006 Silicon Graphics, Inc.  All Rights Reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/interrupt.h>
-#include <asm/sn/pda.h>
-#include <asm/sn/leds.h>
-
-extern void sn_lb_int_war_check(void);
-extern irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-
-#define SN_LB_INT_WAR_INTERVAL 100
-
-void sn_timer_interrupt(int irq, void *dev_id)
-{
-       /* LED blinking */
-       if (!pda->hb_count--) {
-               pda->hb_count = HZ / 2;
-               set_led_bits(pda->hb_state ^=
-                            LED_CPU_HEARTBEAT, LED_CPU_HEARTBEAT);
-       }
-
-       if (is_shub1()) {
-               if (enable_shub_wars_1_1()) {
-                       /* Bugfix code for SHUB 1.1 */
-                       if (pda->pio_shub_war_cam_addr)
-                               *pda->pio_shub_war_cam_addr = 0x8000000000000010UL;
-               }
-               if (pda->sn_lb_int_war_ticks == 0)
-                       sn_lb_int_war_check();
-               pda->sn_lb_int_war_ticks++;
-               if (pda->sn_lb_int_war_ticks >= SN_LB_INT_WAR_INTERVAL)
-                       pda->sn_lb_int_war_ticks = 0;
-       }
-}
diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c
deleted file mode 100644 (file)
index 32d0380..0000000
+++ /dev/null
@@ -1,569 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2005 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/proc_fs.h>
-#include <linux/capability.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/uaccess.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/io.h>
-#include <asm/sn/types.h>
-#include <asm/sn/shubio.h>
-#include <asm/sn/tiocx.h>
-#include <asm/sn/l1.h>
-#include <asm/sn/module.h>
-#include "tio.h"
-#include "xtalk/xwidgetdev.h"
-#include "xtalk/hubdev.h"
-
-#define CX_DEV_NONE 0
-#define DEVICE_NAME "tiocx"
-#define WIDGET_ID 0
-#define TIOCX_DEBUG 0
-
-#if TIOCX_DEBUG
-#define DBG(fmt...)    printk(KERN_ALERT fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-struct device_attribute dev_attr_cxdev_control;
-
-/**
- * tiocx_match - Try to match driver id list with device.
- * @dev: device pointer
- * @drv: driver pointer
- *
- * Returns 1 if match, 0 otherwise.
- */
-static int tiocx_match(struct device *dev, struct device_driver *drv)
-{
-       struct cx_dev *cx_dev = to_cx_dev(dev);
-       struct cx_drv *cx_drv = to_cx_driver(drv);
-       const struct cx_device_id *ids = cx_drv->id_table;
-
-       if (!ids)
-               return 0;
-
-       while (ids->part_num) {
-               if (ids->part_num == cx_dev->cx_id.part_num)
-                       return 1;
-               ids++;
-       }
-       return 0;
-
-}
-
-static int tiocx_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
-       return -ENODEV;
-}
-
-static void tiocx_bus_release(struct device *dev)
-{
-       kfree(to_cx_dev(dev));
-}
-
-/**
- * cx_device_match - Find cx_device in the id table.
- * @ids: id table from driver
- * @cx_device: part/mfg id for the device
- *
- */
-static const struct cx_device_id *cx_device_match(const struct cx_device_id
-                                                 *ids,
-                                                 struct cx_dev *cx_device)
-{
-       /*
-        * NOTES: We may want to check for CX_ANY_ID too.
-        *        Do we want to match against nasid too?
-        *        CX_DEV_NONE == 0, if the driver tries to register for
-        *        part/mfg == 0 we should return no-match (NULL) here.
-        */
-       while (ids->part_num && ids->mfg_num) {
-               if (ids->part_num == cx_device->cx_id.part_num &&
-                   ids->mfg_num == cx_device->cx_id.mfg_num)
-                       return ids;
-               ids++;
-       }
-
-       return NULL;
-}
-
-/**
- * cx_device_probe - Look for matching device.
- *                     Call driver probe routine if found.
- * @cx_driver: driver table (cx_drv struct) from driver
- * @cx_device: part/mfg id for the device
- */
-static int cx_device_probe(struct device *dev)
-{
-       const struct cx_device_id *id;
-       struct cx_drv *cx_drv = to_cx_driver(dev->driver);
-       struct cx_dev *cx_dev = to_cx_dev(dev);
-       int error = 0;
-
-       if (!cx_dev->driver && cx_drv->probe) {
-               id = cx_device_match(cx_drv->id_table, cx_dev);
-               if (id) {
-                       if ((error = cx_drv->probe(cx_dev, id)) < 0)
-                               return error;
-                       else
-                               cx_dev->driver = cx_drv;
-               }
-       }
-
-       return error;
-}
-
-/**
- * cx_driver_remove - Remove driver from device struct.
- * @dev: device
- */
-static int cx_driver_remove(struct device *dev)
-{
-       struct cx_dev *cx_dev = to_cx_dev(dev);
-       struct cx_drv *cx_drv = cx_dev->driver;
-       if (cx_drv->remove)
-               cx_drv->remove(cx_dev);
-       cx_dev->driver = NULL;
-       return 0;
-}
-
-struct bus_type tiocx_bus_type = {
-       .name = "tiocx",
-       .match = tiocx_match,
-       .uevent = tiocx_uevent,
-       .probe = cx_device_probe,
-       .remove = cx_driver_remove,
-};
-
-/**
- * cx_driver_register - Register the driver.
- * @cx_driver: driver table (cx_drv struct) from driver
- * 
- * Called from the driver init routine to register a driver.
- * The cx_drv struct contains the driver name, a pointer to
- * a table of part/mfg numbers and a pointer to the driver's
- * probe/attach routine.
- */
-int cx_driver_register(struct cx_drv *cx_driver)
-{
-       cx_driver->driver.name = cx_driver->name;
-       cx_driver->driver.bus = &tiocx_bus_type;
-
-       return driver_register(&cx_driver->driver);
-}
-
-/**
- * cx_driver_unregister - Unregister the driver.
- * @cx_driver: driver table (cx_drv struct) from driver
- */
-int cx_driver_unregister(struct cx_drv *cx_driver)
-{
-       driver_unregister(&cx_driver->driver);
-       return 0;
-}
-
-/**
- * cx_device_register - Register a device.
- * @nasid: device's nasid
- * @part_num: device's part number
- * @mfg_num: device's manufacturer number
- * @hubdev: hub info associated with this device
- * @bt: board type of the device
- *
- */
-int
-cx_device_register(nasid_t nasid, int part_num, int mfg_num,
-                  struct hubdev_info *hubdev, int bt)
-{
-       struct cx_dev *cx_dev;
-       int r;
-
-       cx_dev = kzalloc(sizeof(struct cx_dev), GFP_KERNEL);
-       DBG("cx_dev= 0x%p\n", cx_dev);
-       if (cx_dev == NULL)
-               return -ENOMEM;
-
-       cx_dev->cx_id.part_num = part_num;
-       cx_dev->cx_id.mfg_num = mfg_num;
-       cx_dev->cx_id.nasid = nasid;
-       cx_dev->hubdev = hubdev;
-       cx_dev->bt = bt;
-
-       cx_dev->dev.parent = NULL;
-       cx_dev->dev.bus = &tiocx_bus_type;
-       cx_dev->dev.release = tiocx_bus_release;
-       dev_set_name(&cx_dev->dev, "%d", cx_dev->cx_id.nasid);
-       r = device_register(&cx_dev->dev);
-       if (r) {
-               kfree(cx_dev);
-               return r;
-       }
-       get_device(&cx_dev->dev);
-
-       device_create_file(&cx_dev->dev, &dev_attr_cxdev_control);
-
-       return 0;
-}
-
-/**
- * cx_device_unregister - Unregister a device.
- * @cx_dev: part/mfg id for the device
- */
-int cx_device_unregister(struct cx_dev *cx_dev)
-{
-       put_device(&cx_dev->dev);
-       device_unregister(&cx_dev->dev);
-       return 0;
-}
-
-/**
- * cx_device_reload - Reload the device.
- * @nasid: device's nasid
- * @part_num: device's part number
- * @mfg_num: device's manufacturer number
- *
- * Remove the device associated with 'nasid' from device list and then
- * call device-register with the given part/mfg numbers.
- */
-static int cx_device_reload(struct cx_dev *cx_dev)
-{
-       cx_device_unregister(cx_dev);
-       return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num,
-                                 cx_dev->cx_id.mfg_num, cx_dev->hubdev,
-                                 cx_dev->bt);
-}
-
-static inline u64 tiocx_intr_alloc(nasid_t nasid, int widget,
-                                       u64 sn_irq_info,
-                                       int req_irq, nasid_t req_nasid,
-                                       int req_slice)
-{
-       struct ia64_sal_retval rv;
-       rv.status = 0;
-       rv.v0 = 0;
-
-       ia64_sal_oemcall_nolock(&rv, SN_SAL_IOIF_INTERRUPT,
-                               SAL_INTR_ALLOC, nasid,
-                               widget, sn_irq_info, req_irq,
-                               req_nasid, req_slice);
-       return rv.status;
-}
-
-static inline void tiocx_intr_free(nasid_t nasid, int widget,
-                                  struct sn_irq_info *sn_irq_info)
-{
-       struct ia64_sal_retval rv;
-       rv.status = 0;
-       rv.v0 = 0;
-
-       ia64_sal_oemcall_nolock(&rv, SN_SAL_IOIF_INTERRUPT,
-                               SAL_INTR_FREE, nasid,
-                               widget, sn_irq_info->irq_irq,
-                               sn_irq_info->irq_cookie, 0, 0);
-}
-
-struct sn_irq_info *tiocx_irq_alloc(nasid_t nasid, int widget, int irq,
-                                   nasid_t req_nasid, int slice)
-{
-       struct sn_irq_info *sn_irq_info;
-       int status;
-       int sn_irq_size = sizeof(struct sn_irq_info);
-
-       if ((nasid & 1) == 0)
-               return NULL;
-
-       sn_irq_info = kzalloc(sn_irq_size, GFP_KERNEL);
-       if (sn_irq_info == NULL)
-               return NULL;
-
-       status = tiocx_intr_alloc(nasid, widget, __pa(sn_irq_info), irq,
-                                 req_nasid, slice);
-       if (status) {
-               kfree(sn_irq_info);
-               return NULL;
-       } else {
-               return sn_irq_info;
-       }
-}
-
-void tiocx_irq_free(struct sn_irq_info *sn_irq_info)
-{
-       u64 bridge = (u64) sn_irq_info->irq_bridge;
-       nasid_t nasid = NASID_GET(bridge);
-       int widget;
-
-       if (nasid & 1) {
-               widget = TIO_SWIN_WIDGETNUM(bridge);
-               tiocx_intr_free(nasid, widget, sn_irq_info);
-               kfree(sn_irq_info);
-       }
-}
-
-u64 tiocx_dma_addr(u64 addr)
-{
-       return PHYS_TO_TIODMA(addr);
-}
-
-u64 tiocx_swin_base(int nasid)
-{
-       return TIO_SWIN_BASE(nasid, TIOCX_CORELET);
-}
-
-EXPORT_SYMBOL(cx_driver_register);
-EXPORT_SYMBOL(cx_driver_unregister);
-EXPORT_SYMBOL(cx_device_register);
-EXPORT_SYMBOL(cx_device_unregister);
-EXPORT_SYMBOL(tiocx_irq_alloc);
-EXPORT_SYMBOL(tiocx_irq_free);
-EXPORT_SYMBOL(tiocx_bus_type);
-EXPORT_SYMBOL(tiocx_dma_addr);
-EXPORT_SYMBOL(tiocx_swin_base);
-
-static void tio_conveyor_set(nasid_t nasid, int enable_flag)
-{
-       u64 ice_frz;
-       u64 disable_cb = (1ull << 61);
-
-       if (!(nasid & 1))
-               return;
-
-       ice_frz = REMOTE_HUB_L(nasid, TIO_ICE_FRZ_CFG);
-       if (enable_flag) {
-               if (!(ice_frz & disable_cb))    /* already enabled */
-                       return;
-               ice_frz &= ~disable_cb;
-       } else {
-               if (ice_frz & disable_cb)       /* already disabled */
-                       return;
-               ice_frz |= disable_cb;
-       }
-       DBG(KERN_ALERT "TIO_ICE_FRZ_CFG= 0x%lx\n", ice_frz);
-       REMOTE_HUB_S(nasid, TIO_ICE_FRZ_CFG, ice_frz);
-}
-
-#define tio_conveyor_enable(nasid) tio_conveyor_set(nasid, 1)
-#define tio_conveyor_disable(nasid) tio_conveyor_set(nasid, 0)
-
-static void tio_corelet_reset(nasid_t nasid, int corelet)
-{
-       if (!(nasid & 1))
-               return;
-
-       REMOTE_HUB_S(nasid, TIO_ICE_PMI_TX_CFG, 1 << corelet);
-       udelay(2000);
-       REMOTE_HUB_S(nasid, TIO_ICE_PMI_TX_CFG, 0);
-       udelay(2000);
-}
-
-static int is_fpga_tio(int nasid, int *bt)
-{
-       u16 uninitialized_var(ioboard_type);    /* GCC be quiet */
-       long rc;
-
-       rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard_type);
-       if (rc) {
-               printk(KERN_WARNING "ia64_sn_sysctl_ioboard_get failed: %ld\n",
-                      rc);
-               return 0;
-       }
-
-       switch (ioboard_type) {
-       case L1_BRICKTYPE_SA:
-       case L1_BRICKTYPE_ATHENA:
-       case L1_BOARDTYPE_DAYTONA:
-               *bt = ioboard_type;
-               return 1;
-       }
-
-       return 0;
-}
-
-static int bitstream_loaded(nasid_t nasid)
-{
-       u64 cx_credits;
-
-       cx_credits = REMOTE_HUB_L(nasid, TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3);
-       cx_credits &= TIO_ICE_PMI_TX_DYN_CREDIT_STAT_CB3_CREDIT_CNT_MASK;
-       DBG("cx_credits= 0x%lx\n", cx_credits);
-
-       return (cx_credits == 0xf) ? 1 : 0;
-}
-
-static int tiocx_reload(struct cx_dev *cx_dev)
-{
-       int part_num = CX_DEV_NONE;
-       int mfg_num = CX_DEV_NONE;
-       nasid_t nasid = cx_dev->cx_id.nasid;
-
-       if (bitstream_loaded(nasid)) {
-               u64 cx_id;
-               int rv;
-
-               rv = ia64_sn_sysctl_tio_clock_reset(nasid);
-               if (rv) {
-                       printk(KERN_ALERT "CX port JTAG reset failed.\n");
-               } else {
-                       cx_id = *(volatile u64 *)
-                               (TIO_SWIN_BASE(nasid, TIOCX_CORELET) +
-                                         WIDGET_ID);
-                       part_num = XWIDGET_PART_NUM(cx_id);
-                       mfg_num = XWIDGET_MFG_NUM(cx_id);
-                       DBG("part= 0x%x, mfg= 0x%x\n", part_num, mfg_num);
-                       /* just ignore it if it's a CE */
-                       if (part_num == TIO_CE_ASIC_PARTNUM)
-                               return 0;
-               }
-       }
-
-       cx_dev->cx_id.part_num = part_num;
-       cx_dev->cx_id.mfg_num = mfg_num;
-
-       /*
-        * Delete old device and register the new one.  It's ok if
-        * part_num/mfg_num == CX_DEV_NONE.  We want to register
-        * devices in the table even if a bitstream isn't loaded.
-        * That allows use to see that a bitstream isn't loaded via
-        * TIOCX_IOCTL_DEV_LIST.
-        */
-       return cx_device_reload(cx_dev);
-}
-
-static ssize_t show_cxdev_control(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct cx_dev *cx_dev = to_cx_dev(dev);
-
-       return sprintf(buf, "0x%x 0x%x 0x%x 0x%x\n",
-                      cx_dev->cx_id.nasid,
-                      cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num,
-                      cx_dev->bt);
-}
-
-static ssize_t store_cxdev_control(struct device *dev, struct device_attribute *attr, const char *buf,
-                                  size_t count)
-{
-       int n;
-       struct cx_dev *cx_dev = to_cx_dev(dev);
-
-       if (!capable(CAP_SYS_ADMIN))
-               return -EPERM;
-
-       if (count <= 0)
-               return 0;
-
-       n = simple_strtoul(buf, NULL, 0);
-
-       switch (n) {
-       case 1:
-               tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET);
-               tiocx_reload(cx_dev);
-               break;
-       case 2:
-               tiocx_reload(cx_dev);
-               break;
-       case 3:
-               tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET);
-               break;
-       default:
-               break;
-       }
-
-       return count;
-}
-
-DEVICE_ATTR(cxdev_control, 0644, show_cxdev_control, store_cxdev_control);
-
-static int __init tiocx_init(void)
-{
-       cnodeid_t cnodeid;
-       int found_tiocx_device = 0;
-       int err;
-
-       if (!ia64_platform_is("sn2"))
-               return 0;
-
-       err = bus_register(&tiocx_bus_type);
-       if (err)
-               return err;
-
-       for (cnodeid = 0; cnodeid < num_cnodes; cnodeid++) {
-               nasid_t nasid;
-               int bt;
-
-               nasid = cnodeid_to_nasid(cnodeid);
-
-               if ((nasid & 0x1) && is_fpga_tio(nasid, &bt)) {
-                       struct hubdev_info *hubdev;
-                       struct xwidget_info *widgetp;
-
-                       DBG("Found TIO at nasid 0x%x\n", nasid);
-
-                       hubdev =
-                           (struct hubdev_info *)(NODEPDA(cnodeid)->pdinfo);
-
-                       widgetp = &hubdev->hdi_xwidget_info[TIOCX_CORELET];
-
-                       /* The CE hangs off of the CX port but is not an FPGA */
-                       if (widgetp->xwi_hwid.part_num == TIO_CE_ASIC_PARTNUM)
-                               continue;
-
-                       tio_corelet_reset(nasid, TIOCX_CORELET);
-                       tio_conveyor_enable(nasid);
-
-                       if (cx_device_register
-                           (nasid, widgetp->xwi_hwid.part_num,
-                            widgetp->xwi_hwid.mfg_num, hubdev, bt) < 0)
-                               return -ENXIO;
-                       else
-                               found_tiocx_device++;
-               }
-       }
-
-       /* It's ok if we find zero devices. */
-       DBG("found_tiocx_device= %d\n", found_tiocx_device);
-
-       return 0;
-}
-
-static int cx_remove_device(struct device * dev, void * data)
-{
-       struct cx_dev *cx_dev = to_cx_dev(dev);
-       device_remove_file(dev, &dev_attr_cxdev_control);
-       cx_device_unregister(cx_dev);
-       return 0;
-}
-
-static void __exit tiocx_exit(void)
-{
-       DBG("tiocx_exit\n");
-
-       /*
-        * Unregister devices.
-        */
-       bus_for_each_dev(&tiocx_bus_type, NULL, NULL, cx_remove_device);
-       bus_unregister(&tiocx_bus_type);
-}
-
-fs_initcall(tiocx_init);
-module_exit(tiocx_exit);
-
-/************************************************************************
- * Module licensing and description
- ************************************************************************/
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Bruce Losure <blosure@sgi.com>");
-MODULE_DESCRIPTION("TIOCX module");
-MODULE_SUPPORTED_DEVICE(DEVICE_NAME);
diff --git a/arch/ia64/sn/pci/Makefile b/arch/ia64/sn/pci/Makefile
deleted file mode 100644 (file)
index 321576b..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 2000-2004 Silicon Graphics, Inc.  All Rights Reserved.
-#
-# Makefile for the sn pci general routines.
-
-obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
deleted file mode 100644 (file)
index b7d42e4..0000000
+++ /dev/null
@@ -1,446 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2000,2002-2005 Silicon Graphics, Inc. All rights reserved.
- *
- * Routines for PCI DMA mapping.  See Documentation/DMA-API.txt for
- * a description of how these routines should be used.
- */
-
-#include <linux/gfp.h>
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <asm/dma.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/sn_sal.h>
-
-#define SG_ENT_VIRT_ADDRESS(sg)        (sg_virt((sg)))
-#define SG_ENT_PHYS_ADDRESS(SG)        virt_to_phys(SG_ENT_VIRT_ADDRESS(SG))
-
-/**
- * sn_dma_supported - test a DMA mask
- * @dev: device to test
- * @mask: DMA mask to test
- *
- * Return whether the given PCI device DMA address mask can be supported
- * properly.  For example, if your device can only drive the low 24-bits
- * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
- * this function.  Of course, SN only supports devices that have 32 or more
- * address bits when using the PMU.
- */
-static int sn_dma_supported(struct device *dev, u64 mask)
-{
-       BUG_ON(!dev_is_pci(dev));
-
-       if (mask < 0x7fffffff)
-               return 0;
-       return 1;
-}
-
-/**
- * sn_dma_set_mask - set the DMA mask
- * @dev: device to set
- * @dma_mask: new mask
- *
- * Set @dev's DMA mask if the hw supports it.
- */
-int sn_dma_set_mask(struct device *dev, u64 dma_mask)
-{
-       BUG_ON(!dev_is_pci(dev));
-
-       if (!sn_dma_supported(dev, dma_mask))
-               return 0;
-
-       *dev->dma_mask = dma_mask;
-       return 1;
-}
-EXPORT_SYMBOL(sn_dma_set_mask);
-
-/**
- * sn_dma_alloc_coherent - allocate memory for coherent DMA
- * @dev: device to allocate for
- * @size: size of the region
- * @dma_handle: DMA (bus) address
- * @flags: memory allocation flags
- *
- * dma_alloc_coherent() returns a pointer to a memory region suitable for
- * coherent DMA traffic to/from a PCI device.  On SN platforms, this means
- * that @dma_handle will have the %PCIIO_DMA_CMD flag set.
- *
- * This interface is usually used for "command" streams (e.g. the command
- * queue for a SCSI controller).  See Documentation/DMA-API.txt for
- * more information.
- */
-static void *sn_dma_alloc_coherent(struct device *dev, size_t size,
-                                  dma_addr_t * dma_handle, gfp_t flags,
-                                  unsigned long attrs)
-{
-       void *cpuaddr;
-       unsigned long phys_addr;
-       int node;
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
-
-       BUG_ON(!dev_is_pci(dev));
-
-       /*
-        * Allocate the memory.
-        */
-       node = pcibus_to_node(pdev->bus);
-       if (likely(node >=0)) {
-               struct page *p = __alloc_pages_node(node,
-                                               flags, get_order(size));
-
-               if (likely(p))
-                       cpuaddr = page_address(p);
-               else
-                       return NULL;
-       } else
-               cpuaddr = (void *)__get_free_pages(flags, get_order(size));
-
-       if (unlikely(!cpuaddr))
-               return NULL;
-
-       memset(cpuaddr, 0x0, size);
-
-       /* physical addr. of the memory we just got */
-       phys_addr = __pa(cpuaddr);
-
-       /*
-        * 64 bit address translations should never fail.
-        * 32 bit translations can fail if there are insufficient mapping
-        * resources.
-        */
-
-       *dma_handle = provider->dma_map_consistent(pdev, phys_addr, size,
-                                                  SN_DMA_ADDR_PHYS);
-       if (!*dma_handle) {
-               printk(KERN_ERR "%s: out of ATEs\n", __func__);
-               free_pages((unsigned long)cpuaddr, get_order(size));
-               return NULL;
-       }
-
-       return cpuaddr;
-}
-
-/**
- * sn_pci_free_coherent - free memory associated with coherent DMAable region
- * @dev: device to free for
- * @size: size to free
- * @cpu_addr: kernel virtual address to free
- * @dma_handle: DMA address associated with this region
- *
- * Frees the memory allocated by dma_alloc_coherent(), potentially unmapping
- * any associated IOMMU mappings.
- */
-static void sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
-                                dma_addr_t dma_handle, unsigned long attrs)
-{
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
-
-       BUG_ON(!dev_is_pci(dev));
-
-       provider->dma_unmap(pdev, dma_handle, 0);
-       free_pages((unsigned long)cpu_addr, get_order(size));
-}
-
-/**
- * sn_dma_map_single_attrs - map a single page for DMA
- * @dev: device to map for
- * @cpu_addr: kernel virtual address of the region to map
- * @size: size of the region
- * @direction: DMA direction
- * @attrs: optional dma attributes
- *
- * Map the region pointed to by @cpu_addr for DMA and return the
- * DMA address.
- *
- * We map this to the one step pcibr_dmamap_trans interface rather than
- * the two step pcibr_dmamap_alloc/pcibr_dmamap_addr because we have
- * no way of saving the dmamap handle from the alloc to later free
- * (which is pretty much unacceptable).
- *
- * mappings with the DMA_ATTR_WRITE_BARRIER get mapped with
- * dma_map_consistent() so that writes force a flush of pending DMA.
- * (See "SGI Altix Architecture Considerations for Linux Device Drivers",
- * Document Number: 007-4763-001)
- *
- * TODO: simplify our interface;
- *       figure out how to save dmamap handle so can use two step.
- */
-static dma_addr_t sn_dma_map_page(struct device *dev, struct page *page,
-                                 unsigned long offset, size_t size,
-                                 enum dma_data_direction dir,
-                                 unsigned long attrs)
-{
-       void *cpu_addr = page_address(page) + offset;
-       dma_addr_t dma_addr;
-       unsigned long phys_addr;
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
-
-       BUG_ON(!dev_is_pci(dev));
-
-       phys_addr = __pa(cpu_addr);
-       if (attrs & DMA_ATTR_WRITE_BARRIER)
-               dma_addr = provider->dma_map_consistent(pdev, phys_addr,
-                                                       size, SN_DMA_ADDR_PHYS);
-       else
-               dma_addr = provider->dma_map(pdev, phys_addr, size,
-                                            SN_DMA_ADDR_PHYS);
-
-       if (!dma_addr) {
-               printk(KERN_ERR "%s: out of ATEs\n", __func__);
-               return DMA_MAPPING_ERROR;
-       }
-       return dma_addr;
-}
-
-/**
- * sn_dma_unmap_single_attrs - unamp a DMA mapped page
- * @dev: device to sync
- * @dma_addr: DMA address to sync
- * @size: size of region
- * @direction: DMA direction
- * @attrs: optional dma attributes
- *
- * This routine is supposed to sync the DMA region specified
- * by @dma_handle into the coherence domain.  On SN, we're always cache
- * coherent, so we just need to free any ATEs associated with this mapping.
- */
-static void sn_dma_unmap_page(struct device *dev, dma_addr_t dma_addr,
-                             size_t size, enum dma_data_direction dir,
-                             unsigned long attrs)
-{
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
-
-       BUG_ON(!dev_is_pci(dev));
-
-       provider->dma_unmap(pdev, dma_addr, dir);
-}
-
-/**
- * sn_dma_unmap_sg - unmap a DMA scatterlist
- * @dev: device to unmap
- * @sg: scatterlist to unmap
- * @nhwentries: number of scatterlist entries
- * @direction: DMA direction
- * @attrs: optional dma attributes
- *
- * Unmap a set of streaming mode DMA translations.
- */
-static void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
-                           int nhwentries, enum dma_data_direction dir,
-                           unsigned long attrs)
-{
-       int i;
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
-       struct scatterlist *sg;
-
-       BUG_ON(!dev_is_pci(dev));
-
-       for_each_sg(sgl, sg, nhwentries, i) {
-               provider->dma_unmap(pdev, sg->dma_address, dir);
-               sg->dma_address = (dma_addr_t) NULL;
-               sg->dma_length = 0;
-       }
-}
-
-/**
- * sn_dma_map_sg - map a scatterlist for DMA
- * @dev: device to map for
- * @sg: scatterlist to map
- * @nhwentries: number of entries
- * @direction: direction of the DMA transaction
- * @attrs: optional dma attributes
- *
- * mappings with the DMA_ATTR_WRITE_BARRIER get mapped with
- * dma_map_consistent() so that writes force a flush of pending DMA.
- * (See "SGI Altix Architecture Considerations for Linux Device Drivers",
- * Document Number: 007-4763-001)
- *
- * Maps each entry of @sg for DMA.
- */
-static int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl,
-                        int nhwentries, enum dma_data_direction dir,
-                        unsigned long attrs)
-{
-       unsigned long phys_addr;
-       struct scatterlist *saved_sg = sgl, *sg;
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
-       int i;
-
-       BUG_ON(!dev_is_pci(dev));
-
-       /*
-        * Setup a DMA address for each entry in the scatterlist.
-        */
-       for_each_sg(sgl, sg, nhwentries, i) {
-               dma_addr_t dma_addr;
-               phys_addr = SG_ENT_PHYS_ADDRESS(sg);
-               if (attrs & DMA_ATTR_WRITE_BARRIER)
-                       dma_addr = provider->dma_map_consistent(pdev,
-                                                               phys_addr,
-                                                               sg->length,
-                                                               SN_DMA_ADDR_PHYS);
-               else
-                       dma_addr = provider->dma_map(pdev, phys_addr,
-                                                    sg->length,
-                                                    SN_DMA_ADDR_PHYS);
-
-               sg->dma_address = dma_addr;
-               if (!sg->dma_address) {
-                       printk(KERN_ERR "%s: out of ATEs\n", __func__);
-
-                       /*
-                        * Free any successfully allocated entries.
-                        */
-                       if (i > 0)
-                               sn_dma_unmap_sg(dev, saved_sg, i, dir, attrs);
-                       return 0;
-               }
-
-               sg->dma_length = sg->length;
-       }
-
-       return nhwentries;
-}
-
-static u64 sn_dma_get_required_mask(struct device *dev)
-{
-       return DMA_BIT_MASK(64);
-}
-
-char *sn_pci_get_legacy_mem(struct pci_bus *bus)
-{
-       if (!SN_PCIBUS_BUSSOFT(bus))
-               return ERR_PTR(-ENODEV);
-
-       return (char *)(SN_PCIBUS_BUSSOFT(bus)->bs_legacy_mem | __IA64_UNCACHED_OFFSET);
-}
-
-int sn_pci_legacy_read(struct pci_bus *bus, u16 port, u32 *val, u8 size)
-{
-       unsigned long addr;
-       int ret;
-       struct ia64_sal_retval isrv;
-
-       /*
-        * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work
-        * around hw issues at the pci bus level.  SGI proms older than
-        * 4.10 don't implement this.
-        */
-
-       SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
-                pci_domain_nr(bus), bus->number,
-                0, /* io */
-                0, /* read */
-                port, size, __pa(val));
-
-       if (isrv.status == 0)
-               return size;
-
-       /*
-        * If the above failed, retry using the SAL_PROBE call which should
-        * be present in all proms (but which cannot work round PCI chipset
-        * bugs).  This code is retained for compatibility with old
-        * pre-4.10 proms, and should be removed at some point in the future.
-        */
-
-       if (!SN_PCIBUS_BUSSOFT(bus))
-               return -ENODEV;
-
-       addr = SN_PCIBUS_BUSSOFT(bus)->bs_legacy_io | __IA64_UNCACHED_OFFSET;
-       addr += port;
-
-       ret = ia64_sn_probe_mem(addr, (long)size, (void *)val);
-
-       if (ret == 2)
-               return -EINVAL;
-
-       if (ret == 1)
-               *val = -1;
-
-       return size;
-}
-
-int sn_pci_legacy_write(struct pci_bus *bus, u16 port, u32 val, u8 size)
-{
-       int ret = size;
-       unsigned long paddr;
-       unsigned long *addr;
-       struct ia64_sal_retval isrv;
-
-       /*
-        * First, try the SN_SAL_IOIF_PCI_SAFE SAL call which can work
-        * around hw issues at the pci bus level.  SGI proms older than
-        * 4.10 don't implement this.
-        */
-
-       SAL_CALL(isrv, SN_SAL_IOIF_PCI_SAFE,
-                pci_domain_nr(bus), bus->number,
-                0, /* io */
-                1, /* write */
-                port, size, __pa(&val));
-
-       if (isrv.status == 0)
-               return size;
-
-       /*
-        * If the above failed, retry using the SAL_PROBE call which should
-        * be present in all proms (but which cannot work round PCI chipset
-        * bugs).  This code is retained for compatibility with old
-        * pre-4.10 proms, and should be removed at some point in the future.
-        */
-
-       if (!SN_PCIBUS_BUSSOFT(bus)) {
-               ret = -ENODEV;
-               goto out;
-       }
-
-       /* Put the phys addr in uncached space */
-       paddr = SN_PCIBUS_BUSSOFT(bus)->bs_legacy_io | __IA64_UNCACHED_OFFSET;
-       paddr += port;
-       addr = (unsigned long *)paddr;
-
-       switch (size) {
-       case 1:
-               *(volatile u8 *)(addr) = (u8)(val);
-               break;
-       case 2:
-               *(volatile u16 *)(addr) = (u16)(val);
-               break;
-       case 4:
-               *(volatile u32 *)(addr) = (u32)(val);
-               break;
-       default:
-               ret = -EINVAL;
-               break;
-       }
- out:
-       return ret;
-}
-
-static struct dma_map_ops sn_dma_ops = {
-       .alloc                  = sn_dma_alloc_coherent,
-       .free                   = sn_dma_free_coherent,
-       .map_page               = sn_dma_map_page,
-       .unmap_page             = sn_dma_unmap_page,
-       .map_sg                 = sn_dma_map_sg,
-       .unmap_sg               = sn_dma_unmap_sg,
-       .dma_supported          = sn_dma_supported,
-       .get_required_mask      = sn_dma_get_required_mask,
-};
-
-void sn_dma_init(void)
-{
-       dma_ops = &sn_dma_ops;
-}
diff --git a/arch/ia64/sn/pci/pcibr/Makefile b/arch/ia64/sn/pci/pcibr/Makefile
deleted file mode 100644 (file)
index 712f6af..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License.  See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 2002-2004 Silicon Graphics, Inc.  All Rights Reserved.
-#
-# Makefile for the sn2 io routines.
-
-ccflags-y := -I $(srctree)/arch/ia64/sn/include
-
-obj-y                          +=  pcibr_dma.o pcibr_reg.o \
-                                   pcibr_ate.o pcibr_provider.o
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_ate.c b/arch/ia64/sn/pci/pcibr/pcibr_ate.c
deleted file mode 100644 (file)
index b67bb4c..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001-2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/pcibr_provider.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/pcidev.h>
-
-int pcibr_invalidate_ate;      /* by default don't invalidate ATE on free */
-
-/*
- * mark_ate: Mark the ate as either free or inuse.
- */
-static void mark_ate(struct ate_resource *ate_resource, int start, int number,
-                    u64 value)
-{
-       u64 *ate = ate_resource->ate;
-       int index;
-       int length = 0;
-
-       for (index = start; length < number; index++, length++)
-               ate[index] = value;
-}
-
-/*
- * find_free_ate:  Find the first free ate index starting from the given
- *                index for the desired consecutive count.
- */
-static int find_free_ate(struct ate_resource *ate_resource, int start,
-                        int count)
-{
-       u64 *ate = ate_resource->ate;
-       int index;
-       int start_free;
-
-       for (index = start; index < ate_resource->num_ate;) {
-               if (!ate[index]) {
-                       int i;
-                       int free;
-                       free = 0;
-                       start_free = index;     /* Found start free ate */
-                       for (i = start_free; i < ate_resource->num_ate; i++) {
-                               if (!ate[i]) {  /* This is free */
-                                       if (++free == count)
-                                               return start_free;
-                               } else {
-                                       index = i + 1;
-                                       break;
-                               }
-                       }
-                       if (i >= ate_resource->num_ate)
-                               return -1;
-               } else
-                       index++;        /* Try next ate */
-       }
-
-       return -1;
-}
-
-/*
- * free_ate_resource:  Free the requested number of ATEs.
- */
-static inline void free_ate_resource(struct ate_resource *ate_resource,
-                                    int start)
-{
-       mark_ate(ate_resource, start, ate_resource->ate[start], 0);
-       if ((ate_resource->lowest_free_index > start) ||
-           (ate_resource->lowest_free_index < 0))
-               ate_resource->lowest_free_index = start;
-}
-
-/*
- * alloc_ate_resource:  Allocate the requested number of ATEs.
- */
-static inline int alloc_ate_resource(struct ate_resource *ate_resource,
-                                    int ate_needed)
-{
-       int start_index;
-
-       /*
-        * Check for ate exhaustion.
-        */
-       if (ate_resource->lowest_free_index < 0)
-               return -1;
-
-       /*
-        * Find the required number of free consecutive ates.
-        */
-       start_index =
-           find_free_ate(ate_resource, ate_resource->lowest_free_index,
-                         ate_needed);
-       if (start_index >= 0)
-               mark_ate(ate_resource, start_index, ate_needed, ate_needed);
-
-       ate_resource->lowest_free_index =
-           find_free_ate(ate_resource, ate_resource->lowest_free_index, 1);
-
-       return start_index;
-}
-
-/*
- * Allocate "count" contiguous Bridge Address Translation Entries
- * on the specified bridge to be used for PCI to XTALK mappings.
- * Indices in rm map range from 1..num_entries.  Indices returned
- * to caller range from 0..num_entries-1.
- *
- * Return the start index on success, -1 on failure.
- */
-int pcibr_ate_alloc(struct pcibus_info *pcibus_info, int count)
-{
-       int status;
-       unsigned long flags;
-
-       spin_lock_irqsave(&pcibus_info->pbi_lock, flags);
-       status = alloc_ate_resource(&pcibus_info->pbi_int_ate_resource, count);
-       spin_unlock_irqrestore(&pcibus_info->pbi_lock, flags);
-
-       return status;
-}
-
-/*
- * Setup an Address Translation Entry as specified.  Use either the Bridge
- * internal maps or the external map RAM, as appropriate.
- */
-static inline u64 __iomem *pcibr_ate_addr(struct pcibus_info *pcibus_info,
-                                      int ate_index)
-{
-       if (ate_index < pcibus_info->pbi_int_ate_size) {
-               return pcireg_int_ate_addr(pcibus_info, ate_index);
-       }
-       panic("pcibr_ate_addr: invalid ate_index 0x%x", ate_index);
-}
-
-/*
- * Update the ate.
- */
-inline void
-ate_write(struct pcibus_info *pcibus_info, int ate_index, int count,
-         volatile u64 ate)
-{
-       while (count-- > 0) {
-               if (ate_index < pcibus_info->pbi_int_ate_size) {
-                       pcireg_int_ate_set(pcibus_info, ate_index, ate);
-               } else {
-                       panic("ate_write: invalid ate_index 0x%x", ate_index);
-               }
-               ate_index++;
-               ate += IOPGSIZE;
-       }
-
-       pcireg_tflush_get(pcibus_info); /* wait until Bridge PIO complete */
-}
-
-void pcibr_ate_free(struct pcibus_info *pcibus_info, int index)
-{
-
-       volatile u64 ate;
-       int count;
-       unsigned long flags;
-
-       if (pcibr_invalidate_ate) {
-               /* For debugging purposes, clear the valid bit in the ATE */
-               ate = *pcibr_ate_addr(pcibus_info, index);
-               count = pcibus_info->pbi_int_ate_resource.ate[index];
-               ate_write(pcibus_info, index, count, (ate & ~PCI32_ATE_V));
-       }
-
-       spin_lock_irqsave(&pcibus_info->pbi_lock, flags);
-       free_ate_resource(&pcibus_info->pbi_int_ate_resource, index);
-       spin_unlock_irqrestore(&pcibus_info->pbi_lock, flags);
-}
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_dma.c b/arch/ia64/sn/pci/pcibr/pcibr_dma.c
deleted file mode 100644 (file)
index 1e863b2..0000000
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001-2005 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/export.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/geo.h>
-#include <asm/sn/pcibr_provider.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/pic.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/tiocp.h>
-#include "tio.h"
-#include "xtalk/xwidgetdev.h"
-#include "xtalk/hubdev.h"
-
-extern int sn_ioif_inited;
-
-/* =====================================================================
- *    DMA MANAGEMENT
- *
- *      The Bridge ASIC provides three methods of doing DMA: via a "direct map"
- *      register available in 32-bit PCI space (which selects a contiguous 2G
- *     address space on some other widget), via "direct" addressing via 64-bit
- *      PCI space (all destination information comes from the PCI address,
- *      including transfer attributes), and via a "mapped" region that allows 
- *      a bunch of different small mappings to be established with the PMU.
- *
- *      For efficiency, we most prefer to use the 32bit direct mapping facility,
- *      since it requires no resource allocations. The advantage of using the
- *      PMU over the 64-bit direct is that single-cycle PCI addressing can be
- *      used; the advantage of using 64-bit direct over PMU addressing is that
- *      we do not have to allocate entries in the PMU.
- */
-
-static dma_addr_t
-pcibr_dmamap_ate32(struct pcidev_info *info,
-                  u64 paddr, size_t req_size, u64 flags, int dma_flags)
-{
-
-       struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info;
-       struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info->
-           pdi_pcibus_info;
-       u8 internal_device = (PCI_SLOT(pcidev_info->pdi_host_pcidev_info->
-                                           pdi_linux_pcidev->devfn)) - 1;
-       int ate_count;
-       int ate_index;
-       u64 ate_flags = flags | PCI32_ATE_V;
-       u64 ate;
-       u64 pci_addr;
-       u64 xio_addr;
-       u64 offset;
-
-       /* PIC in PCI-X mode does not supports 32bit PageMap mode */
-       if (IS_PIC_SOFT(pcibus_info) && IS_PCIX(pcibus_info)) {
-               return 0;
-       }
-
-       /* Calculate the number of ATEs needed. */
-       if (!(MINIMAL_ATE_FLAG(paddr, req_size))) {
-               ate_count = IOPG((IOPGSIZE - 1) /* worst case start offset */
-                                +req_size      /* max mapping bytes */
-                                - 1) + 1;      /* round UP */
-       } else {                /* assume requested target is page aligned */
-               ate_count = IOPG(req_size       /* max mapping bytes */
-                                - 1) + 1;      /* round UP */
-       }
-
-       /* Get the number of ATEs required. */
-       ate_index = pcibr_ate_alloc(pcibus_info, ate_count);
-       if (ate_index < 0)
-               return 0;
-
-       /* In PCI-X mode, Prefetch not supported */
-       if (IS_PCIX(pcibus_info))
-               ate_flags &= ~(PCI32_ATE_PREF);
-
-       if (SN_DMA_ADDRTYPE(dma_flags == SN_DMA_ADDR_PHYS))
-               xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) :
-                                                     PHYS_TO_TIODMA(paddr);
-       else
-               xio_addr = paddr;
-
-       offset = IOPGOFF(xio_addr);
-       ate = ate_flags | (xio_addr - offset);
-
-       /* If PIC, put the targetid in the ATE */
-       if (IS_PIC_SOFT(pcibus_info)) {
-               ate |= (pcibus_info->pbi_hub_xid << PIC_ATE_TARGETID_SHFT);
-       }
-
-       /*
-        * If we're mapping for MSI, set the MSI bit in the ATE.  If it's a
-        * TIOCP based pci bus, we also need to set the PIO bit in the ATE.
-        */
-       if (dma_flags & SN_DMA_MSI) {
-               ate |= PCI32_ATE_MSI;
-               if (IS_TIOCP_SOFT(pcibus_info))
-                       ate |= PCI32_ATE_PIO;
-       }
-
-       ate_write(pcibus_info, ate_index, ate_count, ate);
-
-       /*
-        * Set up the DMA mapped Address.
-        */
-       pci_addr = PCI32_MAPPED_BASE + offset + IOPGSIZE * ate_index;
-
-       /*
-        * If swap was set in device in pcibr_endian_set()
-        * we need to turn swapping on.
-        */
-       if (pcibus_info->pbi_devreg[internal_device] & PCIBR_DEV_SWAP_DIR)
-               ATE_SWAP_ON(pci_addr);
-
-
-       return pci_addr;
-}
-
-static dma_addr_t
-pcibr_dmatrans_direct64(struct pcidev_info * info, u64 paddr,
-                       u64 dma_attributes, int dma_flags)
-{
-       struct pcibus_info *pcibus_info = (struct pcibus_info *)
-           ((info->pdi_host_pcidev_info)->pdi_pcibus_info);
-       u64 pci_addr;
-
-       /* Translate to Crosstalk View of Physical Address */
-       if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS)
-               pci_addr = IS_PIC_SOFT(pcibus_info) ?
-                               PHYS_TO_DMA(paddr) :
-                               PHYS_TO_TIODMA(paddr);
-       else
-               pci_addr = paddr;
-       pci_addr |= dma_attributes;
-
-       /* Handle Bus mode */
-       if (IS_PCIX(pcibus_info))
-               pci_addr &= ~PCI64_ATTR_PREF;
-
-       /* Handle Bridge Chipset differences */
-       if (IS_PIC_SOFT(pcibus_info)) {
-               pci_addr |=
-                   ((u64) pcibus_info->
-                    pbi_hub_xid << PIC_PCI64_ATTR_TARG_SHFT);
-       } else
-               pci_addr |= (dma_flags & SN_DMA_MSI) ?
-                               TIOCP_PCI64_CMDTYPE_MSI :
-                               TIOCP_PCI64_CMDTYPE_MEM;
-
-       /* If PCI mode, func zero uses VCHAN0, every other func uses VCHAN1 */
-       if (!IS_PCIX(pcibus_info) && PCI_FUNC(info->pdi_linux_pcidev->devfn))
-               pci_addr |= PCI64_ATTR_VIRTUAL;
-
-       return pci_addr;
-}
-
-static dma_addr_t
-pcibr_dmatrans_direct32(struct pcidev_info * info,
-                       u64 paddr, size_t req_size, u64 flags, int dma_flags)
-{
-       struct pcidev_info *pcidev_info = info->pdi_host_pcidev_info;
-       struct pcibus_info *pcibus_info = (struct pcibus_info *)pcidev_info->
-           pdi_pcibus_info;
-       u64 xio_addr;
-
-       u64 xio_base;
-       u64 offset;
-       u64 endoff;
-
-       if (IS_PCIX(pcibus_info)) {
-               return 0;
-       }
-
-       if (dma_flags & SN_DMA_MSI)
-               return 0;
-
-       if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS)
-               xio_addr = IS_PIC_SOFT(pcibus_info) ? PHYS_TO_DMA(paddr) :
-                                                     PHYS_TO_TIODMA(paddr);
-       else
-               xio_addr = paddr;
-
-       xio_base = pcibus_info->pbi_dir_xbase;
-       offset = xio_addr - xio_base;
-       endoff = req_size + offset;
-       if ((req_size > (1ULL << 31)) ||        /* Too Big */
-           (xio_addr < xio_base) ||    /* Out of range for mappings */
-           (endoff > (1ULL << 31))) {  /* Too Big */
-               return 0;
-       }
-
-       return PCI32_DIRECT_BASE | offset;
-}
-
-/*
- * Wrapper routine for freeing DMA maps
- * DMA mappings for Direct 64 and 32 do not have any DMA maps.
- */
-void
-pcibr_dma_unmap(struct pci_dev *hwdev, dma_addr_t dma_handle, int direction)
-{
-       struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);
-       struct pcibus_info *pcibus_info =
-           (struct pcibus_info *)pcidev_info->pdi_pcibus_info;
-
-       if (IS_PCI32_MAPPED(dma_handle)) {
-               int ate_index;
-
-               ate_index =
-                   IOPG((ATE_SWAP_OFF(dma_handle) - PCI32_MAPPED_BASE));
-               pcibr_ate_free(pcibus_info, ate_index);
-       }
-}
-
-/*
- * On SN systems there is a race condition between a PIO read response and 
- * DMA's.  In rare cases, the read response may beat the DMA, causing the
- * driver to think that data in memory is complete and meaningful.  This code
- * eliminates that race.  This routine is called by the PIO read routines
- * after doing the read.  For PIC this routine then forces a fake interrupt
- * on another line, which is logically associated with the slot that the PIO
- * is addressed to.  It then spins while watching the memory location that
- * the interrupt is targeted to.  When the interrupt response arrives, we 
- * are sure that the DMA has landed in memory and it is safe for the driver
- * to proceed. For TIOCP use the Device(x) Write Request Buffer Flush 
- * Bridge register since it ensures the data has entered the coherence domain,
- * unlike the PIC Device(x) Write Request Buffer Flush register.
- */
-
-void sn_dma_flush(u64 addr)
-{
-       nasid_t nasid;
-       int is_tio;
-       int wid_num;
-       int i, j;
-       unsigned long flags;
-       u64 itte;
-       struct hubdev_info *hubinfo;
-       struct sn_flush_device_kernel *p;
-       struct sn_flush_device_common *common;
-       struct sn_flush_nasid_entry *flush_nasid_list;
-
-       if (!sn_ioif_inited)
-               return;
-
-       nasid = NASID_GET(addr);
-       if (-1 == nasid_to_cnodeid(nasid))
-               return;
-
-       hubinfo = (NODEPDA(nasid_to_cnodeid(nasid)))->pdinfo;
-
-       BUG_ON(!hubinfo);
-
-       flush_nasid_list = &hubinfo->hdi_flush_nasid_list;
-       if (flush_nasid_list->widget_p == NULL)
-               return;
-
-       is_tio = (nasid & 1);
-       if (is_tio) {
-               int itte_index;
-
-               if (TIO_HWIN(addr))
-                       itte_index = 0;
-               else if (TIO_BWIN_WINDOWNUM(addr))
-                       itte_index = TIO_BWIN_WINDOWNUM(addr);
-               else
-                       itte_index = -1;
-
-               if (itte_index >= 0) {
-                       itte = flush_nasid_list->iio_itte[itte_index];
-                       if (! TIO_ITTE_VALID(itte))
-                               return;
-                       wid_num = TIO_ITTE_WIDGET(itte);
-               } else
-                       wid_num = TIO_SWIN_WIDGETNUM(addr);
-       } else {
-               if (BWIN_WINDOWNUM(addr)) {
-                       itte = flush_nasid_list->iio_itte[BWIN_WINDOWNUM(addr)];
-                       wid_num = IIO_ITTE_WIDGET(itte);
-               } else
-                       wid_num = SWIN_WIDGETNUM(addr);
-       }
-       if (flush_nasid_list->widget_p[wid_num] == NULL)
-               return;
-       p = &flush_nasid_list->widget_p[wid_num][0];
-
-       /* find a matching BAR */
-       for (i = 0; i < DEV_PER_WIDGET; i++,p++) {
-               common = p->common;
-               for (j = 0; j < PCI_ROM_RESOURCE; j++) {
-                       if (common->sfdl_bar_list[j].start == 0)
-                               break;
-                       if (addr >= common->sfdl_bar_list[j].start
-                           && addr <= common->sfdl_bar_list[j].end)
-                               break;
-               }
-               if (j < PCI_ROM_RESOURCE && common->sfdl_bar_list[j].start != 0)
-                       break;
-       }
-
-       /* if no matching BAR, return without doing anything. */
-       if (i == DEV_PER_WIDGET)
-               return;
-
-       /*
-        * For TIOCP use the Device(x) Write Request Buffer Flush Bridge
-        * register since it ensures the data has entered the coherence
-        * domain, unlike PIC.
-        */
-       if (is_tio) {
-               /*
-                * Note:  devices behind TIOCE should never be matched in the
-                * above code, and so the following code is PIC/CP centric.
-                * If CE ever needs the sn_dma_flush mechanism, we will have
-                * to account for that here and in tioce_bus_fixup().
-                */
-               u32 tio_id = HUB_L(TIO_IOSPACE_ADDR(nasid, TIO_NODE_ID));
-               u32 revnum = XWIDGET_PART_REV_NUM(tio_id);
-
-               /* TIOCP BRINGUP WAR (PV907516): Don't write buffer flush reg */
-               if ((1 << XWIDGET_PART_REV_NUM_REV(revnum)) & PV907516) {
-                       return;
-               } else {
-                       pcireg_wrb_flush_get(common->sfdl_pcibus_info,
-                                            (common->sfdl_slot - 1));
-               }
-       } else {
-               spin_lock_irqsave(&p->sfdl_flush_lock, flags);
-               *common->sfdl_flush_addr = 0;
-
-               /* force an interrupt. */
-               *(volatile u32 *)(common->sfdl_force_int_addr) = 1;
-
-               /* wait for the interrupt to come back. */
-               while (*(common->sfdl_flush_addr) != 0x10f)
-                       cpu_relax();
-
-               /* okay, everything is synched up. */
-               spin_unlock_irqrestore(&p->sfdl_flush_lock, flags);
-       }
-       return;
-}
-
-/*
- * DMA interfaces.  Called from pci_dma.c routines.
- */
-
-dma_addr_t
-pcibr_dma_map(struct pci_dev * hwdev, unsigned long phys_addr, size_t size, int dma_flags)
-{
-       dma_addr_t dma_handle;
-       struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);
-
-       /* SN cannot support DMA addresses smaller than 32 bits. */
-       if (hwdev->dma_mask < 0x7fffffff) {
-               return 0;
-       }
-
-       if (hwdev->dma_mask == ~0UL) {
-               /*
-                * Handle the most common case: 64 bit cards.  This
-                * call should always succeed.
-                */
-
-               dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr,
-                                                    PCI64_ATTR_PREF, dma_flags);
-       } else {
-               /* Handle 32-63 bit cards via direct mapping */
-               dma_handle = pcibr_dmatrans_direct32(pcidev_info, phys_addr,
-                                                    size, 0, dma_flags);
-               if (!dma_handle) {
-                       /*
-                        * It is a 32 bit card and we cannot do direct mapping,
-                        * so we use an ATE.
-                        */
-
-                       dma_handle = pcibr_dmamap_ate32(pcidev_info, phys_addr,
-                                                       size, PCI32_ATE_PREF,
-                                                       dma_flags);
-               }
-       }
-
-       return dma_handle;
-}
-
-dma_addr_t
-pcibr_dma_map_consistent(struct pci_dev * hwdev, unsigned long phys_addr,
-                        size_t size, int dma_flags)
-{
-       dma_addr_t dma_handle;
-       struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(hwdev);
-
-       if (hwdev->dev.coherent_dma_mask == ~0UL) {
-               dma_handle = pcibr_dmatrans_direct64(pcidev_info, phys_addr,
-                                           PCI64_ATTR_BAR, dma_flags);
-       } else {
-               dma_handle = (dma_addr_t) pcibr_dmamap_ate32(pcidev_info,
-                                                   phys_addr, size,
-                                                   PCI32_ATE_BAR, dma_flags);
-       }
-
-       return dma_handle;
-}
-
-EXPORT_SYMBOL(sn_dma_flush);
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
deleted file mode 100644 (file)
index 7195df1..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001-2004, 2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/interrupt.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <linux/export.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/geo.h>
-#include <asm/sn/pcibr_provider.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/pic.h>
-#include <asm/sn/sn2/sn_hwperf.h>
-#include "xtalk/xwidgetdev.h"
-#include "xtalk/hubdev.h"
-
-int
-sal_pcibr_slot_enable(struct pcibus_info *soft, int device, void *resp,
-                      char **ssdt)
-{
-       struct ia64_sal_retval ret_stuff;
-       u64 busnum;
-       u64 segment;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       segment = soft->pbi_buscommon.bs_persist_segment;
-       busnum = soft->pbi_buscommon.bs_persist_busnum;
-       SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_ENABLE, segment,
-                       busnum, (u64) device, (u64) resp, (u64)ia64_tpa(ssdt),
-                       0, 0);
-
-       return (int)ret_stuff.v0;
-}
-
-int
-sal_pcibr_slot_disable(struct pcibus_info *soft, int device, int action,
-                      void *resp)
-{
-       struct ia64_sal_retval ret_stuff;
-       u64 busnum;
-       u64 segment;
-
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       segment = soft->pbi_buscommon.bs_persist_segment;
-       busnum = soft->pbi_buscommon.bs_persist_busnum;
-       SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_SLOT_DISABLE,
-                       segment, busnum, (u64) device, (u64) action,
-                       (u64) resp, 0, 0);
-
-       return (int)ret_stuff.v0;
-}
-
-static int sal_pcibr_error_interrupt(struct pcibus_info *soft)
-{
-       struct ia64_sal_retval ret_stuff;
-       u64 busnum;
-       int segment;
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       segment = soft->pbi_buscommon.bs_persist_segment;
-       busnum = soft->pbi_buscommon.bs_persist_busnum;
-       SAL_CALL_NOLOCK(ret_stuff,
-                       (u64) SN_SAL_IOIF_ERROR_INTERRUPT,
-                       (u64) segment, (u64) busnum, 0, 0, 0, 0, 0);
-
-       return (int)ret_stuff.v0;
-}
-
-u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus)
-{
-       long rc;
-       u16 uninitialized_var(ioboard);         /* GCC be quiet */
-       nasid_t nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base);
-
-       rc = ia64_sn_sysctl_ioboard_get(nasid, &ioboard);
-       if (rc) {
-               printk(KERN_WARNING "ia64_sn_sysctl_ioboard_get failed: %ld\n",
-                      rc);
-               return 0;
-       }
-
-       return ioboard;
-}
-
-/* 
- * PCI Bridge Error interrupt handler.  Gets invoked whenever a PCI 
- * bridge sends an error interrupt.
- */
-static irqreturn_t
-pcibr_error_intr_handler(int irq, void *arg)
-{
-       struct pcibus_info *soft = arg;
-
-       if (sal_pcibr_error_interrupt(soft) < 0)
-               panic("pcibr_error_intr_handler(): Fatal Bridge Error");
-
-       return IRQ_HANDLED;
-}
-
-void *
-pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
-{
-       int nasid, cnode, j;
-       struct hubdev_info *hubdev_info;
-       struct pcibus_info *soft;
-       struct sn_flush_device_kernel *sn_flush_device_kernel;
-       struct sn_flush_device_common *common;
-
-       if (! IS_PCI_BRIDGE_ASIC(prom_bussoft->bs_asic_type)) {
-               return NULL;
-       }
-
-       /*
-        * Allocate kernel bus soft and copy from prom.
-        */
-
-       soft = kmemdup(prom_bussoft, sizeof(struct pcibus_info), GFP_KERNEL);
-       if (!soft) {
-               return NULL;
-       }
-
-       soft->pbi_buscommon.bs_base = (unsigned long)
-               ioremap(REGION_OFFSET(soft->pbi_buscommon.bs_base),
-                       sizeof(struct pic));
-
-       spin_lock_init(&soft->pbi_lock);
-
-       /*
-        * register the bridge's error interrupt handler
-        */
-       if (request_irq(SGI_PCIASIC_ERROR, pcibr_error_intr_handler,
-                       IRQF_SHARED, "PCIBR error", (void *)(soft))) {
-               printk(KERN_WARNING
-                      "pcibr cannot allocate interrupt for error handler\n");
-       }
-       irq_set_handler(SGI_PCIASIC_ERROR, handle_level_irq);
-       sn_set_err_irq_affinity(SGI_PCIASIC_ERROR);
-
-       /* 
-        * Update the Bridge with the "kernel" pagesize 
-        */
-       if (PAGE_SIZE < 16384) {
-               pcireg_control_bit_clr(soft, PCIBR_CTRL_PAGE_SIZE);
-       } else {
-               pcireg_control_bit_set(soft, PCIBR_CTRL_PAGE_SIZE);
-       }
-
-       nasid = NASID_GET(soft->pbi_buscommon.bs_base);
-       cnode = nasid_to_cnodeid(nasid);
-       hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo);
-
-       if (hubdev_info->hdi_flush_nasid_list.widget_p) {
-               sn_flush_device_kernel = hubdev_info->hdi_flush_nasid_list.
-                   widget_p[(int)soft->pbi_buscommon.bs_xid];
-               if (sn_flush_device_kernel) {
-                       for (j = 0; j < DEV_PER_WIDGET;
-                            j++, sn_flush_device_kernel++) {
-                               common = sn_flush_device_kernel->common;
-                               if (common->sfdl_slot == -1)
-                                       continue;
-                               if ((common->sfdl_persistent_segment ==
-                                    soft->pbi_buscommon.bs_persist_segment) &&
-                                    (common->sfdl_persistent_busnum ==
-                                    soft->pbi_buscommon.bs_persist_busnum))
-                                       common->sfdl_pcibus_info =
-                                           soft;
-                       }
-               }
-       }
-
-       /* Setup the PMU ATE map */
-       soft->pbi_int_ate_resource.lowest_free_index = 0;
-       soft->pbi_int_ate_resource.ate =
-           kcalloc(soft->pbi_int_ate_size, sizeof(u64), GFP_KERNEL);
-
-       if (!soft->pbi_int_ate_resource.ate) {
-               kfree(soft);
-               return NULL;
-       }
-
-       return soft;
-}
-
-void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info)
-{
-       struct pcidev_info *pcidev_info;
-       struct pcibus_info *pcibus_info;
-       int bit = sn_irq_info->irq_int_bit;
-
-       if (! sn_irq_info->irq_bridge)
-               return;
-
-       pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
-       if (pcidev_info) {
-               pcibus_info =
-                   (struct pcibus_info *)pcidev_info->pdi_host_pcidev_info->
-                   pdi_pcibus_info;
-               pcireg_force_intr_set(pcibus_info, bit);
-       }
-}
-
-void pcibr_target_interrupt(struct sn_irq_info *sn_irq_info)
-{
-       struct pcidev_info *pcidev_info;
-       struct pcibus_info *pcibus_info;
-       int bit = sn_irq_info->irq_int_bit;
-       u64 xtalk_addr = sn_irq_info->irq_xtalkaddr;
-
-       pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
-       if (pcidev_info) {
-               pcibus_info =
-                   (struct pcibus_info *)pcidev_info->pdi_host_pcidev_info->
-                   pdi_pcibus_info;
-
-               /* Disable the device's IRQ   */
-               pcireg_intr_enable_bit_clr(pcibus_info, (1 << bit));
-
-               /* Change the device's IRQ    */
-               pcireg_intr_addr_addr_set(pcibus_info, bit, xtalk_addr);
-
-               /* Re-enable the device's IRQ */
-               pcireg_intr_enable_bit_set(pcibus_info, (1 << bit));
-
-               pcibr_force_interrupt(sn_irq_info);
-       }
-}
-
-/*
- * Provider entries for PIC/CP
- */
-
-struct sn_pcibus_provider pcibr_provider = {
-       .dma_map = pcibr_dma_map,
-       .dma_map_consistent = pcibr_dma_map_consistent,
-       .dma_unmap = pcibr_dma_unmap,
-       .bus_fixup = pcibr_bus_fixup,
-       .force_interrupt = pcibr_force_interrupt,
-       .target_interrupt = pcibr_target_interrupt
-};
-
-int
-pcibr_init_provider(void)
-{
-       sn_pci_provider[PCIIO_ASIC_TYPE_PIC] = &pcibr_provider;
-       sn_pci_provider[PCIIO_ASIC_TYPE_TIOCP] = &pcibr_provider;
-
-       return 0;
-}
-
-EXPORT_SYMBOL_GPL(sal_pcibr_slot_enable);
-EXPORT_SYMBOL_GPL(sal_pcibr_slot_disable);
-EXPORT_SYMBOL_GPL(sn_ioboard_to_pci_bus);
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_reg.c b/arch/ia64/sn/pci/pcibr/pcibr_reg.c
deleted file mode 100644 (file)
index 8b8bbd5..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/interrupt.h>
-#include <linux/types.h>
-#include <asm/sn/io.h>
-#include <asm/sn/pcibr_provider.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/pic.h>
-#include <asm/sn/tiocp.h>
-
-union br_ptr {
-       struct tiocp tio;
-       struct pic pic;
-};
-
-/*
- * Control Register Access -- Read/Write                            0000_0020
- */
-void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, u64 bits)
-{
-       union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
-
-       if (pcibus_info) {
-               switch (pcibus_info->pbi_bridge_type) {
-               case PCIBR_BRIDGETYPE_TIOCP:
-                       __sn_clrq_relaxed(&ptr->tio.cp_control, bits);
-                       break;
-               case PCIBR_BRIDGETYPE_PIC:
-                       __sn_clrq_relaxed(&ptr->pic.p_wid_control, bits);
-                       break;
-               default:
-                       panic
-                           ("pcireg_control_bit_clr: unknown bridgetype bridge 0x%p",
-                            ptr);
-               }
-       }
-}
-
-void pcireg_control_bit_set(struct pcibus_info *pcibus_info, u64 bits)
-{
-       union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
-
-       if (pcibus_info) {
-               switch (pcibus_info->pbi_bridge_type) {
-               case PCIBR_BRIDGETYPE_TIOCP:
-                       __sn_setq_relaxed(&ptr->tio.cp_control, bits);
-                       break;
-               case PCIBR_BRIDGETYPE_PIC:
-                       __sn_setq_relaxed(&ptr->pic.p_wid_control, bits);
-                       break;
-               default:
-                       panic
-                           ("pcireg_control_bit_set: unknown bridgetype bridge 0x%p",
-                            ptr);
-               }
-       }
-}
-
-/*
- * PCI/PCIX Target Flush Register Access -- Read Only              0000_0050
- */
-u64 pcireg_tflush_get(struct pcibus_info *pcibus_info)
-{
-       union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
-       u64 ret = 0;
-
-       if (pcibus_info) {
-               switch (pcibus_info->pbi_bridge_type) {
-               case PCIBR_BRIDGETYPE_TIOCP:
-                       ret = __sn_readq_relaxed(&ptr->tio.cp_tflush);
-                       break;
-               case PCIBR_BRIDGETYPE_PIC:
-                       ret = __sn_readq_relaxed(&ptr->pic.p_wid_tflush);
-                       break;
-               default:
-                       panic
-                           ("pcireg_tflush_get: unknown bridgetype bridge 0x%p",
-                            ptr);
-               }
-       }
-
-       /* Read of the Target Flush should always return zero */
-       if (ret != 0)
-               panic("pcireg_tflush_get:Target Flush failed\n");
-
-       return ret;
-}
-
-/*
- * Interrupt Status Register Access -- Read Only                   0000_0100
- */
-u64 pcireg_intr_status_get(struct pcibus_info * pcibus_info)
-{
-       union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
-       u64 ret = 0;
-
-       if (pcibus_info) {
-               switch (pcibus_info->pbi_bridge_type) {
-               case PCIBR_BRIDGETYPE_TIOCP:
-                       ret = __sn_readq_relaxed(&ptr->tio.cp_int_status);
-                       break;
-               case PCIBR_BRIDGETYPE_PIC:
-                       ret = __sn_readq_relaxed(&ptr->pic.p_int_status);
-                       break;
-               default:
-                       panic
-                           ("pcireg_intr_status_get: unknown bridgetype bridge 0x%p",
-                            ptr);
-               }
-       }
-       return ret;
-}
-
-/*
- * Interrupt Enable Register Access -- Read/Write                   0000_0108
- */
-void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, u64 bits)
-{
-       union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
-
-       if (pcibus_info) {
-               switch (pcibus_info->pbi_bridge_type) {
-               case PCIBR_BRIDGETYPE_TIOCP:
-                       __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits);
-                       break;
-               case PCIBR_BRIDGETYPE_PIC:
-                       __sn_clrq_relaxed(&ptr->pic.p_int_enable, bits);
-                       break;
-               default:
-                       panic
-                           ("pcireg_intr_enable_bit_clr: unknown bridgetype bridge 0x%p",
-                            ptr);
-               }
-       }
-}
-
-void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, u64 bits)
-{
-       union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
-
-       if (pcibus_info) {
-               switch (pcibus_info->pbi_bridge_type) {
-               case PCIBR_BRIDGETYPE_TIOCP:
-                       __sn_setq_relaxed(&ptr->tio.cp_int_enable, bits);
-                       break;
-               case PCIBR_BRIDGETYPE_PIC:
-                       __sn_setq_relaxed(&ptr->pic.p_int_enable, bits);
-                       break;
-               default:
-                       panic
-                           ("pcireg_intr_enable_bit_set: unknown bridgetype bridge 0x%p",
-                            ptr);
-               }
-       }
-}
-
-/*
- * Intr Host Address Register (int_addr) -- Read/Write  0000_0130 - 0000_0168
- */
-void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n,
-                              u64 addr)
-{
-       union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
-
-       if (pcibus_info) {
-               switch (pcibus_info->pbi_bridge_type) {
-               case PCIBR_BRIDGETYPE_TIOCP:
-                       __sn_clrq_relaxed(&ptr->tio.cp_int_addr[int_n],
-                           TIOCP_HOST_INTR_ADDR);
-                       __sn_setq_relaxed(&ptr->tio.cp_int_addr[int_n],
-                           (addr & TIOCP_HOST_INTR_ADDR));
-                       break;
-               case PCIBR_BRIDGETYPE_PIC:
-                       __sn_clrq_relaxed(&ptr->pic.p_int_addr[int_n],
-                           PIC_HOST_INTR_ADDR);
-                       __sn_setq_relaxed(&ptr->pic.p_int_addr[int_n],
-                           (addr & PIC_HOST_INTR_ADDR));
-                       break;
-               default:
-                       panic
-                           ("pcireg_intr_addr_addr_get: unknown bridgetype bridge 0x%p",
-                            ptr);
-               }
-       }
-}
-
-/*
- * Force Interrupt Register Access -- Write Only       0000_01C0 - 0000_01F8
- */
-void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n)
-{
-       union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
-
-       if (pcibus_info) {
-               switch (pcibus_info->pbi_bridge_type) {
-               case PCIBR_BRIDGETYPE_TIOCP:
-                       writeq(1, &ptr->tio.cp_force_pin[int_n]);
-                       break;
-               case PCIBR_BRIDGETYPE_PIC:
-                       writeq(1, &ptr->pic.p_force_pin[int_n]);
-                       break;
-               default:
-                       panic
-                           ("pcireg_force_intr_set: unknown bridgetype bridge 0x%p",
-                            ptr);
-               }
-       }
-}
-
-/*
- * Device(x) Write Buffer Flush Reg Access -- Read Only 0000_0240 - 0000_0258
- */
-u64 pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device)
-{
-       union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
-       u64 ret = 0;
-
-       if (pcibus_info) {
-               switch (pcibus_info->pbi_bridge_type) {
-               case PCIBR_BRIDGETYPE_TIOCP:
-                       ret =
-                           __sn_readq_relaxed(&ptr->tio.cp_wr_req_buf[device]);
-                       break;
-               case PCIBR_BRIDGETYPE_PIC:
-                       ret =
-                           __sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]);
-                       break;
-               default:
-                     panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", ptr);
-               }
-
-       }
-       /* Read of the Write Buffer Flush should always return zero */
-       return ret;
-}
-
-void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index,
-                       u64 val)
-{
-       union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
-
-       if (pcibus_info) {
-               switch (pcibus_info->pbi_bridge_type) {
-               case PCIBR_BRIDGETYPE_TIOCP:
-                       writeq(val, &ptr->tio.cp_int_ate_ram[ate_index]);
-                       break;
-               case PCIBR_BRIDGETYPE_PIC:
-                       writeq(val, &ptr->pic.p_int_ate_ram[ate_index]);
-                       break;
-               default:
-                       panic
-                           ("pcireg_int_ate_set: unknown bridgetype bridge 0x%p",
-                            ptr);
-               }
-       }
-}
-
-u64 __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index)
-{
-       union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
-       u64 __iomem *ret = NULL;
-
-       if (pcibus_info) {
-               switch (pcibus_info->pbi_bridge_type) {
-               case PCIBR_BRIDGETYPE_TIOCP:
-                       ret = &ptr->tio.cp_int_ate_ram[ate_index];
-                       break;
-               case PCIBR_BRIDGETYPE_PIC:
-                       ret = &ptr->pic.p_int_ate_ram[ate_index];
-                       break;
-               default:
-                       panic
-                           ("pcireg_int_ate_addr: unknown bridgetype bridge 0x%p",
-                            ptr);
-               }
-       }
-       return ret;
-}
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
deleted file mode 100644 (file)
index a70b11f..0000000
+++ /dev/null
@@ -1,677 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2003-2005 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/bitmap.h>
-#include <linux/slab.h>
-#include <linux/export.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/io.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/tioca_provider.h>
-
-u32 tioca_gart_found;
-EXPORT_SYMBOL(tioca_gart_found);       /* used by agp-sgi */
-
-LIST_HEAD(tioca_list);
-EXPORT_SYMBOL(tioca_list);     /* used by agp-sgi */
-
-static int tioca_gart_init(struct tioca_kernel *);
-
-/**
- * tioca_gart_init - Initialize SGI TIOCA GART
- * @tioca_common: ptr to common prom/kernel struct identifying the 
- *
- * If the indicated tioca has devices present, initialize its associated
- * GART MMR's and kernel memory.
- */
-static int
-tioca_gart_init(struct tioca_kernel *tioca_kern)
-{
-       u64 ap_reg;
-       u64 offset;
-       struct page *tmp;
-       struct tioca_common *tioca_common;
-       struct tioca __iomem *ca_base;
-
-       tioca_common = tioca_kern->ca_common;
-       ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
-
-       if (list_empty(tioca_kern->ca_devices))
-               return 0;
-
-       ap_reg = 0;
-
-       /*
-        * Validate aperature size
-        */
-
-       switch (CA_APERATURE_SIZE >> 20) {
-       case 4:
-               ap_reg |= (0x3ff << CA_GART_AP_SIZE_SHFT);      /* 4MB */
-               break;
-       case 8:
-               ap_reg |= (0x3fe << CA_GART_AP_SIZE_SHFT);      /* 8MB */
-               break;
-       case 16:
-               ap_reg |= (0x3fc << CA_GART_AP_SIZE_SHFT);      /* 16MB */
-               break;
-       case 32:
-               ap_reg |= (0x3f8 << CA_GART_AP_SIZE_SHFT);      /* 32 MB */
-               break;
-       case 64:
-               ap_reg |= (0x3f0 << CA_GART_AP_SIZE_SHFT);      /* 64 MB */
-               break;
-       case 128:
-               ap_reg |= (0x3e0 << CA_GART_AP_SIZE_SHFT);      /* 128 MB */
-               break;
-       case 256:
-               ap_reg |= (0x3c0 << CA_GART_AP_SIZE_SHFT);      /* 256 MB */
-               break;
-       case 512:
-               ap_reg |= (0x380 << CA_GART_AP_SIZE_SHFT);      /* 512 MB */
-               break;
-       case 1024:
-               ap_reg |= (0x300 << CA_GART_AP_SIZE_SHFT);      /* 1GB */
-               break;
-       case 2048:
-               ap_reg |= (0x200 << CA_GART_AP_SIZE_SHFT);      /* 2GB */
-               break;
-       case 4096:
-               ap_reg |= (0x000 << CA_GART_AP_SIZE_SHFT);      /* 4 GB */
-               break;
-       default:
-               printk(KERN_ERR "%s:  Invalid CA_APERATURE_SIZE "
-                      "0x%lx\n", __func__, (ulong) CA_APERATURE_SIZE);
-               return -1;
-       }
-
-       /*
-        * Set up other aperature parameters
-        */
-
-       if (PAGE_SIZE >= 16384) {
-               tioca_kern->ca_ap_pagesize = 16384;
-               ap_reg |= CA_GART_PAGE_SIZE;
-       } else {
-               tioca_kern->ca_ap_pagesize = 4096;
-       }
-
-       tioca_kern->ca_ap_size = CA_APERATURE_SIZE;
-       tioca_kern->ca_ap_bus_base = CA_APERATURE_BASE;
-       tioca_kern->ca_gart_entries =
-           tioca_kern->ca_ap_size / tioca_kern->ca_ap_pagesize;
-
-       ap_reg |= (CA_GART_AP_ENB_AGP | CA_GART_AP_ENB_PCI);
-       ap_reg |= tioca_kern->ca_ap_bus_base;
-
-       /*
-        * Allocate and set up the GART
-        */
-
-       tioca_kern->ca_gart_size = tioca_kern->ca_gart_entries * sizeof(u64);
-       tmp =
-           alloc_pages_node(tioca_kern->ca_closest_node,
-                            GFP_KERNEL | __GFP_ZERO,
-                            get_order(tioca_kern->ca_gart_size));
-
-       if (!tmp) {
-               printk(KERN_ERR "%s:  Could not allocate "
-                      "%llu bytes (order %d) for GART\n",
-                      __func__,
-                      tioca_kern->ca_gart_size,
-                      get_order(tioca_kern->ca_gart_size));
-               return -ENOMEM;
-       }
-
-       tioca_kern->ca_gart = page_address(tmp);
-       tioca_kern->ca_gart_coretalk_addr =
-           PHYS_TO_TIODMA(virt_to_phys(tioca_kern->ca_gart));
-
-       /*
-        * Compute PCI/AGP convenience fields 
-        */
-
-       offset = CA_PCI32_MAPPED_BASE - CA_APERATURE_BASE;
-       tioca_kern->ca_pciap_base = CA_PCI32_MAPPED_BASE;
-       tioca_kern->ca_pciap_size = CA_PCI32_MAPPED_SIZE;
-       tioca_kern->ca_pcigart_start = offset / tioca_kern->ca_ap_pagesize;
-       tioca_kern->ca_pcigart_base =
-           tioca_kern->ca_gart_coretalk_addr + offset;
-       tioca_kern->ca_pcigart =
-           &tioca_kern->ca_gart[tioca_kern->ca_pcigart_start];
-       tioca_kern->ca_pcigart_entries =
-           tioca_kern->ca_pciap_size / tioca_kern->ca_ap_pagesize;
-       tioca_kern->ca_pcigart_pagemap =
-           kzalloc(tioca_kern->ca_pcigart_entries / 8, GFP_KERNEL);
-       if (!tioca_kern->ca_pcigart_pagemap) {
-               free_pages((unsigned long)tioca_kern->ca_gart,
-                          get_order(tioca_kern->ca_gart_size));
-               return -1;
-       }
-
-       offset = CA_AGP_MAPPED_BASE - CA_APERATURE_BASE;
-       tioca_kern->ca_gfxap_base = CA_AGP_MAPPED_BASE;
-       tioca_kern->ca_gfxap_size = CA_AGP_MAPPED_SIZE;
-       tioca_kern->ca_gfxgart_start = offset / tioca_kern->ca_ap_pagesize;
-       tioca_kern->ca_gfxgart_base =
-           tioca_kern->ca_gart_coretalk_addr + offset;
-       tioca_kern->ca_gfxgart =
-           &tioca_kern->ca_gart[tioca_kern->ca_gfxgart_start];
-       tioca_kern->ca_gfxgart_entries =
-           tioca_kern->ca_gfxap_size / tioca_kern->ca_ap_pagesize;
-
-       /*
-        * various control settings:
-        *      use agp op-combining
-        *      use GET semantics to fetch memory
-        *      participate in coherency domain
-        *      DISABLE GART PREFETCHING due to hw bug tracked in SGI PV930029
-        */
-
-       __sn_setq_relaxed(&ca_base->ca_control1,
-                       CA_AGPDMA_OP_ENB_COMBDELAY);    /* PV895469 ? */
-       __sn_clrq_relaxed(&ca_base->ca_control2, CA_GART_MEM_PARAM);
-       __sn_setq_relaxed(&ca_base->ca_control2,
-                       (0x2ull << CA_GART_MEM_PARAM_SHFT));
-       tioca_kern->ca_gart_iscoherent = 1;
-       __sn_clrq_relaxed(&ca_base->ca_control2,
-                       (CA_GART_WR_PREFETCH_ENB | CA_GART_RD_PREFETCH_ENB));
-
-       /*
-        * Unmask GART fetch error interrupts.  Clear residual errors first.
-        */
-
-       writeq(CA_GART_FETCH_ERR, &ca_base->ca_int_status_alias);
-       writeq(CA_GART_FETCH_ERR, &ca_base->ca_mult_error_alias);
-       __sn_clrq_relaxed(&ca_base->ca_int_mask, CA_GART_FETCH_ERR);
-
-       /*
-        * Program the aperature and gart registers in TIOCA
-        */
-
-       writeq(ap_reg, &ca_base->ca_gart_aperature);
-       writeq(tioca_kern->ca_gart_coretalk_addr|1, &ca_base->ca_gart_ptr_table);
-
-       return 0;
-}
-
-/**
- * tioca_fastwrite_enable - enable AGP FW for a tioca and its functions
- * @tioca_kernel: structure representing the CA
- *
- * Given a CA, scan all attached functions making sure they all support
- * FastWrite.  If so, enable FastWrite for all functions and the CA itself.
- */
-
-void
-tioca_fastwrite_enable(struct tioca_kernel *tioca_kern)
-{
-       int cap_ptr;
-       u32 reg;
-       struct tioca __iomem *tioca_base;
-       struct pci_dev *pdev;
-       struct tioca_common *common;
-
-       common = tioca_kern->ca_common;
-
-       /*
-        * Scan all vga controllers on this bus making sure they all
-        * support FW.  If not, return.
-        */
-
-       list_for_each_entry(pdev, tioca_kern->ca_devices, bus_list) {
-               if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8))
-                       continue;
-
-               cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
-               if (!cap_ptr)
-                       return; /* no AGP CAP means no FW */
-
-               pci_read_config_dword(pdev, cap_ptr + PCI_AGP_STATUS, &reg);
-               if (!(reg & PCI_AGP_STATUS_FW))
-                       return; /* function doesn't support FW */
-       }
-
-       /*
-        * Set fw for all vga fn's
-        */
-
-       list_for_each_entry(pdev, tioca_kern->ca_devices, bus_list) {
-               if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8))
-                       continue;
-
-               cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
-               pci_read_config_dword(pdev, cap_ptr + PCI_AGP_COMMAND, &reg);
-               reg |= PCI_AGP_COMMAND_FW;
-               pci_write_config_dword(pdev, cap_ptr + PCI_AGP_COMMAND, reg);
-       }
-
-       /*
-        * Set ca's fw to match
-        */
-
-       tioca_base = (struct tioca __iomem*)common->ca_common.bs_base;
-       __sn_setq_relaxed(&tioca_base->ca_control1, CA_AGP_FW_ENABLE);
-}
-
-EXPORT_SYMBOL(tioca_fastwrite_enable); /* used by agp-sgi */
-
-/**
- * tioca_dma_d64 - create a DMA mapping using 64-bit direct mode
- * @paddr: system physical address
- *
- * Map @paddr into 64-bit CA bus space.  No device context is necessary.
- * Bits 53:0 come from the coretalk address.  We just need to mask in the
- * following optional bits of the 64-bit pci address:
- *
- * 63:60 - Coretalk Packet Type -  0x1 for Mem Get/Put (coherent)
- *                                 0x2 for PIO (non-coherent)
- *                                 We will always use 0x1
- * 55:55 - Swap bytes             Currently unused
- */
-static u64
-tioca_dma_d64(unsigned long paddr)
-{
-       dma_addr_t bus_addr;
-
-       bus_addr = PHYS_TO_TIODMA(paddr);
-
-       BUG_ON(!bus_addr);
-       BUG_ON(bus_addr >> 54);
-
-       /* Set upper nibble to Cache Coherent Memory op */
-       bus_addr |= (1UL << 60);
-
-       return bus_addr;
-}
-
-/**
- * tioca_dma_d48 - create a DMA mapping using 48-bit direct mode
- * @pdev: linux pci_dev representing the function
- * @paddr: system physical address
- *
- * Map @paddr into 64-bit bus space of the CA associated with @pcidev_info.
- *
- * The CA agp 48 bit direct address falls out as follows:
- *
- * When direct mapping AGP addresses, the 48 bit AGP address is
- * constructed as follows:
- *
- * [47:40] - Low 8 bits of the page Node ID extracted from coretalk
- *              address [47:40].  The upper 8 node bits are fixed
- *              and come from the xxx register bits [5:0]
- * [39:38] - Chiplet ID extracted from coretalk address [39:38]
- * [37:00] - node offset extracted from coretalk address [37:00]
- * 
- * Since the node id in general will be non-zero, and the chiplet id
- * will always be non-zero, it follows that the device must support
- * a dma mask of at least 0xffffffffff (40 bits) to target node 0
- * and in general should be 0xffffffffffff (48 bits) to target nodes
- * up to 255.  Nodes above 255 need the support of the xxx register,
- * and so a given CA can only directly target nodes in the range
- * xxx - xxx+255.
- */
-static u64
-tioca_dma_d48(struct pci_dev *pdev, u64 paddr)
-{
-       struct tioca_common *tioca_common;
-       struct tioca __iomem *ca_base;
-       u64 ct_addr;
-       dma_addr_t bus_addr;
-       u32 node_upper;
-       u64 agp_dma_extn;
-       struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev);
-
-       tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info;
-       ca_base = (struct tioca __iomem *)tioca_common->ca_common.bs_base;
-
-       ct_addr = PHYS_TO_TIODMA(paddr);
-       if (!ct_addr)
-               return 0;
-
-       bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffffUL);
-       node_upper = ct_addr >> 48;
-
-       if (node_upper > 64) {
-               printk(KERN_ERR "%s:  coretalk addr 0x%p node id out "
-                      "of range\n", __func__, (void *)ct_addr);
-               return 0;
-       }
-
-       agp_dma_extn = __sn_readq_relaxed(&ca_base->ca_agp_dma_addr_extn);
-       if (node_upper != (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT)) {
-               printk(KERN_ERR "%s:  coretalk upper node (%u) "
-                      "mismatch with ca_agp_dma_addr_extn (%llu)\n",
-                      __func__,
-                      node_upper, (agp_dma_extn >> CA_AGP_DMA_NODE_ID_SHFT));
-               return 0;
-       }
-
-       return bus_addr;
-}
-
-/**
- * tioca_dma_mapped - create a DMA mapping using a CA GART 
- * @pdev: linux pci_dev representing the function
- * @paddr: host physical address to map
- * @req_size: len (bytes) to map
- *
- * Map @paddr into CA address space using the GART mechanism.  The mapped
- * dma_addr_t is guaranteed to be contiguous in CA bus space.
- */
-static dma_addr_t
-tioca_dma_mapped(struct pci_dev *pdev, unsigned long paddr, size_t req_size)
-{
-       int ps, ps_shift, entry, entries, mapsize;
-       u64 xio_addr, end_xio_addr;
-       struct tioca_common *tioca_common;
-       struct tioca_kernel *tioca_kern;
-       dma_addr_t bus_addr = 0;
-       struct tioca_dmamap *ca_dmamap;
-       void *map;
-       unsigned long flags;
-       struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev);
-
-       tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info;
-       tioca_kern = (struct tioca_kernel *)tioca_common->ca_kernel_private;
-
-       xio_addr = PHYS_TO_TIODMA(paddr);
-       if (!xio_addr)
-               return 0;
-
-       spin_lock_irqsave(&tioca_kern->ca_lock, flags);
-
-       /*
-        * allocate a map struct
-        */
-
-       ca_dmamap = kzalloc(sizeof(struct tioca_dmamap), GFP_ATOMIC);
-       if (!ca_dmamap)
-               goto map_return;
-
-       /*
-        * Locate free entries that can hold req_size.  Account for
-        * unaligned start/length when allocating.
-        */
-
-       ps = tioca_kern->ca_ap_pagesize;        /* will be power of 2 */
-       ps_shift = ffs(ps) - 1;
-       end_xio_addr = xio_addr + req_size - 1;
-
-       entries = (end_xio_addr >> ps_shift) - (xio_addr >> ps_shift) + 1;
-
-       map = tioca_kern->ca_pcigart_pagemap;
-       mapsize = tioca_kern->ca_pcigart_entries;
-
-       entry = bitmap_find_next_zero_area(map, mapsize, 0, entries, 0);
-       if (entry >= mapsize) {
-               kfree(ca_dmamap);
-               goto map_return;
-       }
-
-       bitmap_set(map, entry, entries);
-
-       bus_addr = tioca_kern->ca_pciap_base + (entry * ps);
-
-       ca_dmamap->cad_dma_addr = bus_addr;
-       ca_dmamap->cad_gart_size = entries;
-       ca_dmamap->cad_gart_entry = entry;
-       list_add(&ca_dmamap->cad_list, &tioca_kern->ca_dmamaps);
-
-       if (xio_addr % ps) {
-               tioca_kern->ca_pcigart[entry] = tioca_paddr_to_gart(xio_addr);
-               bus_addr += xio_addr & (ps - 1);
-               xio_addr &= ~(ps - 1);
-               xio_addr += ps;
-               entry++;
-       }
-
-       while (xio_addr < end_xio_addr) {
-               tioca_kern->ca_pcigart[entry] = tioca_paddr_to_gart(xio_addr);
-               xio_addr += ps;
-               entry++;
-       }
-
-       tioca_tlbflush(tioca_kern);
-
-map_return:
-       spin_unlock_irqrestore(&tioca_kern->ca_lock, flags);
-       return bus_addr;
-}
-
-/**
- * tioca_dma_unmap - release CA mapping resources
- * @pdev: linux pci_dev representing the function
- * @bus_addr: bus address returned by an earlier tioca_dma_map
- * @dir: mapping direction (unused)
- *
- * Locate mapping resources associated with @bus_addr and release them.
- * For mappings created using the direct modes (64 or 48) there are no
- * resources to release.
- */
-static void
-tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
-{
-       int i, entry;
-       struct tioca_common *tioca_common;
-       struct tioca_kernel *tioca_kern;
-       struct tioca_dmamap *map;
-       struct pcidev_info *pcidev_info = SN_PCIDEV_INFO(pdev);
-       unsigned long flags;
-
-       tioca_common = (struct tioca_common *)pcidev_info->pdi_pcibus_info;
-       tioca_kern = (struct tioca_kernel *)tioca_common->ca_kernel_private;
-
-       /* return straight away if this isn't be a mapped address */
-
-       if (bus_addr < tioca_kern->ca_pciap_base ||
-           bus_addr >= (tioca_kern->ca_pciap_base + tioca_kern->ca_pciap_size))
-               return;
-
-       spin_lock_irqsave(&tioca_kern->ca_lock, flags);
-
-       list_for_each_entry(map, &tioca_kern->ca_dmamaps, cad_list)
-           if (map->cad_dma_addr == bus_addr)
-               break;
-
-       BUG_ON(map == NULL);
-
-       entry = map->cad_gart_entry;
-
-       for (i = 0; i < map->cad_gart_size; i++, entry++) {
-               clear_bit(entry, tioca_kern->ca_pcigart_pagemap);
-               tioca_kern->ca_pcigart[entry] = 0;
-       }
-       tioca_tlbflush(tioca_kern);
-
-       list_del(&map->cad_list);
-       spin_unlock_irqrestore(&tioca_kern->ca_lock, flags);
-       kfree(map);
-}
-
-/**
- * tioca_dma_map - map pages for PCI DMA
- * @pdev: linux pci_dev representing the function
- * @paddr: host physical address to map
- * @byte_count: bytes to map
- *
- * This is the main wrapper for mapping host physical pages to CA PCI space.
- * The mapping mode used is based on the devices dma_mask.  As a last resort
- * use the GART mapped mode.
- */
-static u64
-tioca_dma_map(struct pci_dev *pdev, unsigned long paddr, size_t byte_count, int dma_flags)
-{
-       u64 mapaddr;
-
-       /*
-        * Not supported for now ...
-        */
-       if (dma_flags & SN_DMA_MSI)
-               return 0;
-
-       /*
-        * If card is 64 or 48 bit addressable, use a direct mapping.  32
-        * bit direct is so restrictive w.r.t. where the memory resides that
-        * we don't use it even though CA has some support.
-        */
-
-       if (pdev->dma_mask == ~0UL)
-               mapaddr = tioca_dma_d64(paddr);
-       else if (pdev->dma_mask == 0xffffffffffffUL)
-               mapaddr = tioca_dma_d48(pdev, paddr);
-       else
-               mapaddr = 0;
-
-       /* Last resort ... use PCI portion of CA GART */
-
-       if (mapaddr == 0)
-               mapaddr = tioca_dma_mapped(pdev, paddr, byte_count);
-
-       return mapaddr;
-}
-
-/**
- * tioca_error_intr_handler - SGI TIO CA error interrupt handler
- * @irq: unused
- * @arg: pointer to tioca_common struct for the given CA
- *
- * Handle a CA error interrupt.  Simply a wrapper around a SAL call which
- * defers processing to the SGI prom.
- */
-static irqreturn_t
-tioca_error_intr_handler(int irq, void *arg)
-{
-       struct tioca_common *soft = arg;
-       struct ia64_sal_retval ret_stuff;
-       u64 segment;
-       u64 busnum;
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       segment = soft->ca_common.bs_persist_segment;
-       busnum = soft->ca_common.bs_persist_busnum;
-
-       SAL_CALL_NOLOCK(ret_stuff,
-                       (u64) SN_SAL_IOIF_ERROR_INTERRUPT,
-                       segment, busnum, 0, 0, 0, 0, 0);
-
-       return IRQ_HANDLED;
-}
-
-/**
- * tioca_bus_fixup - perform final PCI fixup for a TIO CA bus
- * @prom_bussoft: Common prom/kernel struct representing the bus
- *
- * Replicates the tioca_common pointed to by @prom_bussoft in kernel
- * space.  Allocates and initializes a kernel-only area for a given CA,
- * and sets up an irq for handling CA error interrupts.
- *
- * On successful setup, returns the kernel version of tioca_common back to
- * the caller.
- */
-static void *
-tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
-{
-       struct tioca_common *tioca_common;
-       struct tioca_kernel *tioca_kern;
-       struct pci_bus *bus;
-
-       /* sanity check prom rev */
-
-       if (is_shub1() && sn_sal_rev() < 0x0406) {
-               printk
-                   (KERN_ERR "%s:  SGI prom rev 4.06 or greater required "
-                    "for tioca support\n", __func__);
-               return NULL;
-       }
-
-       /*
-        * Allocate kernel bus soft and copy from prom.
-        */
-
-       tioca_common = kmemdup(prom_bussoft, sizeof(struct tioca_common),
-                              GFP_KERNEL);
-       if (!tioca_common)
-               return NULL;
-
-       tioca_common->ca_common.bs_base = (unsigned long)
-               ioremap(REGION_OFFSET(tioca_common->ca_common.bs_base),
-                       sizeof(struct tioca_common));
-
-       /* init kernel-private area */
-
-       tioca_kern = kzalloc(sizeof(struct tioca_kernel), GFP_KERNEL);
-       if (!tioca_kern) {
-               kfree(tioca_common);
-               return NULL;
-       }
-
-       tioca_kern->ca_common = tioca_common;
-       spin_lock_init(&tioca_kern->ca_lock);
-       INIT_LIST_HEAD(&tioca_kern->ca_dmamaps);
-       tioca_kern->ca_closest_node =
-           nasid_to_cnodeid(tioca_common->ca_closest_nasid);
-       tioca_common->ca_kernel_private = (u64) tioca_kern;
-
-       bus = pci_find_bus(tioca_common->ca_common.bs_persist_segment,
-               tioca_common->ca_common.bs_persist_busnum);
-       BUG_ON(!bus);
-       tioca_kern->ca_devices = &bus->devices;
-
-       /* init GART */
-
-       if (tioca_gart_init(tioca_kern) < 0) {
-               kfree(tioca_kern);
-               kfree(tioca_common);
-               return NULL;
-       }
-
-       tioca_gart_found++;
-       list_add(&tioca_kern->ca_list, &tioca_list);
-
-       if (request_irq(SGI_TIOCA_ERROR,
-                       tioca_error_intr_handler,
-                       IRQF_SHARED, "TIOCA error", (void *)tioca_common))
-               printk(KERN_WARNING
-                      "%s:  Unable to get irq %d.  "
-                      "Error interrupts won't be routed for TIOCA bus %d\n",
-                      __func__, SGI_TIOCA_ERROR,
-                      (int)tioca_common->ca_common.bs_persist_busnum);
-
-       irq_set_handler(SGI_TIOCA_ERROR, handle_level_irq);
-       sn_set_err_irq_affinity(SGI_TIOCA_ERROR);
-
-       /* Setup locality information */
-       controller->node = tioca_kern->ca_closest_node;
-       return tioca_common;
-}
-
-static struct sn_pcibus_provider tioca_pci_interfaces = {
-       .dma_map = tioca_dma_map,
-       .dma_map_consistent = tioca_dma_map,
-       .dma_unmap = tioca_dma_unmap,
-       .bus_fixup = tioca_bus_fixup,
-       .force_interrupt = NULL,
-       .target_interrupt = NULL
-};
-
-/**
- * tioca_init_provider - init SN PCI provider ops for TIO CA
- */
-int
-tioca_init_provider(void)
-{
-       sn_pci_provider[PCIIO_ASIC_TYPE_TIOCA] = &tioca_pci_interfaces;
-       return 0;
-}
diff --git a/arch/ia64/sn/pci/tioce_provider.c b/arch/ia64/sn/pci/tioce_provider.c
deleted file mode 100644 (file)
index 3bd9abc..0000000
+++ /dev/null
@@ -1,1062 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2003-2006 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/pci.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/io.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/tioce_provider.h>
-
-/*
- * 1/26/2006
- *
- * WAR for SGI PV 944642.  For revA TIOCE, need to use the following recipe
- * (taken from the above PV) before and after accessing tioce internal MMR's
- * to avoid tioce lockups.
- *
- * The recipe as taken from the PV:
- *
- *     if(mmr address < 0x45000) {
- *             if(mmr address == 0 or 0x80)
- *                     mmr wrt or read address 0xc0
- *             else if(mmr address == 0x148 or 0x200)
- *                     mmr wrt or read address 0x28
- *             else
- *                     mmr wrt or read address 0x158
- *
- *             do desired mmr access (rd or wrt)
- *
- *             if(mmr address == 0x100)
- *                     mmr wrt or read address 0x38
- *             mmr wrt or read address 0xb050
- *     } else
- *             do desired mmr access
- *
- * According to hw, we can use reads instead of writes to the above address
- *
- * Note this WAR can only to be used for accessing internal MMR's in the
- * TIOCE Coretalk Address Range 0x0 - 0x07ff_ffff.  This includes the
- * "Local CE Registers and Memories" and "PCI Compatible Config Space" address
- * spaces from table 2-1 of the "CE Programmer's Reference Overview" document.
- *
- * All registers defined in struct tioce will meet that criteria.
- */
-
-static inline void
-tioce_mmr_war_pre(struct tioce_kernel *kern, void __iomem *mmr_addr)
-{
-       u64 mmr_base;
-       u64 mmr_offset;
-
-       if (kern->ce_common->ce_rev != TIOCE_REV_A)
-               return;
-
-       mmr_base = kern->ce_common->ce_pcibus.bs_base;
-       mmr_offset = (unsigned long)mmr_addr - mmr_base;
-
-       if (mmr_offset < 0x45000) {
-               u64 mmr_war_offset;
-
-               if (mmr_offset == 0 || mmr_offset == 0x80)
-                       mmr_war_offset = 0xc0;
-               else if (mmr_offset == 0x148 || mmr_offset == 0x200)
-                       mmr_war_offset = 0x28;
-               else
-                       mmr_war_offset = 0x158;
-
-               readq_relaxed((void __iomem *)(mmr_base + mmr_war_offset));
-       }
-}
-
-static inline void
-tioce_mmr_war_post(struct tioce_kernel *kern, void __iomem *mmr_addr)
-{
-       u64 mmr_base;
-       u64 mmr_offset;
-
-       if (kern->ce_common->ce_rev != TIOCE_REV_A)
-               return;
-
-       mmr_base = kern->ce_common->ce_pcibus.bs_base;
-       mmr_offset = (unsigned long)mmr_addr - mmr_base;
-
-       if (mmr_offset < 0x45000) {
-               if (mmr_offset == 0x100)
-                       readq_relaxed((void __iomem *)(mmr_base + 0x38));
-               readq_relaxed((void __iomem *)(mmr_base + 0xb050));
-       }
-}
-
-/* load mmr contents into a variable */
-#define tioce_mmr_load(kern, mmrp, varp) do {\
-       tioce_mmr_war_pre(kern, mmrp); \
-       *(varp) = readq_relaxed(mmrp); \
-       tioce_mmr_war_post(kern, mmrp); \
-} while (0)
-
-/* store variable contents into mmr */
-#define tioce_mmr_store(kern, mmrp, varp) do {\
-       tioce_mmr_war_pre(kern, mmrp); \
-       writeq(*varp, mmrp); \
-       tioce_mmr_war_post(kern, mmrp); \
-} while (0)
-
-/* store immediate value into mmr */
-#define tioce_mmr_storei(kern, mmrp, val) do {\
-       tioce_mmr_war_pre(kern, mmrp); \
-       writeq(val, mmrp); \
-       tioce_mmr_war_post(kern, mmrp); \
-} while (0)
-
-/* set bits (immediate value) into mmr */
-#define tioce_mmr_seti(kern, mmrp, bits) do {\
-       u64 tmp; \
-       tioce_mmr_load(kern, mmrp, &tmp); \
-       tmp |= (bits); \
-       tioce_mmr_store(kern, mmrp, &tmp); \
-} while (0)
-
-/* clear bits (immediate value) into mmr */
-#define tioce_mmr_clri(kern, mmrp, bits) do { \
-       u64 tmp; \
-       tioce_mmr_load(kern, mmrp, &tmp); \
-       tmp &= ~(bits); \
-       tioce_mmr_store(kern, mmrp, &tmp); \
-} while (0)
-
-/**
- * Bus address ranges for the 5 flavors of TIOCE DMA
- */
-
-#define TIOCE_D64_MIN  0x8000000000000000UL
-#define TIOCE_D64_MAX  0xffffffffffffffffUL
-#define TIOCE_D64_ADDR(a)      ((a) >= TIOCE_D64_MIN)
-
-#define TIOCE_D32_MIN  0x0000000080000000UL
-#define TIOCE_D32_MAX  0x00000000ffffffffUL
-#define TIOCE_D32_ADDR(a)      ((a) >= TIOCE_D32_MIN && (a) <= TIOCE_D32_MAX)
-
-#define TIOCE_M32_MIN  0x0000000000000000UL
-#define TIOCE_M32_MAX  0x000000007fffffffUL
-#define TIOCE_M32_ADDR(a)      ((a) >= TIOCE_M32_MIN && (a) <= TIOCE_M32_MAX)
-
-#define TIOCE_M40_MIN  0x0000004000000000UL
-#define TIOCE_M40_MAX  0x0000007fffffffffUL
-#define TIOCE_M40_ADDR(a)      ((a) >= TIOCE_M40_MIN && (a) <= TIOCE_M40_MAX)
-
-#define TIOCE_M40S_MIN 0x0000008000000000UL
-#define TIOCE_M40S_MAX 0x000000ffffffffffUL
-#define TIOCE_M40S_ADDR(a)     ((a) >= TIOCE_M40S_MIN && (a) <= TIOCE_M40S_MAX)
-
-/*
- * ATE manipulation macros.
- */
-
-#define ATE_PAGESHIFT(ps)      (__ffs(ps))
-#define ATE_PAGEMASK(ps)       ((ps)-1)
-
-#define ATE_PAGE(x, ps) ((x) >> ATE_PAGESHIFT(ps))
-#define ATE_NPAGES(start, len, pagesize) \
-       (ATE_PAGE((start)+(len)-1, pagesize) - ATE_PAGE(start, pagesize) + 1)
-
-#define ATE_VALID(ate) ((ate) & (1UL << 63))
-#define ATE_MAKE(addr, ps, msi) \
-       (((addr) & ~ATE_PAGEMASK(ps)) | (1UL << 63) | ((msi)?(1UL << 62):0))
-
-/*
- * Flavors of ate-based mapping supported by tioce_alloc_map()
- */
-
-#define TIOCE_ATE_M32  1
-#define TIOCE_ATE_M40  2
-#define TIOCE_ATE_M40S 3
-
-#define KB(x)  ((u64)(x) << 10)
-#define MB(x)  ((u64)(x) << 20)
-#define GB(x)  ((u64)(x) << 30)
-
-/**
- * tioce_dma_d64 - create a DMA mapping using 64-bit direct mode
- * @ct_addr: system coretalk address
- *
- * Map @ct_addr into 64-bit CE bus space.  No device context is necessary
- * and no CE mapping are consumed.
- *
- * Bits 53:0 come from the coretalk address.  The remaining bits are set as
- * follows:
- *
- * 63    - must be 1 to indicate d64 mode to CE hardware
- * 62    - barrier bit ... controlled with tioce_dma_barrier()
- * 61    - msi bit ... specified through dma_flags
- * 60:54 - reserved, MBZ
- */
-static u64
-tioce_dma_d64(unsigned long ct_addr, int dma_flags)
-{
-       u64 bus_addr;
-
-       bus_addr = ct_addr | (1UL << 63);
-       if (dma_flags & SN_DMA_MSI)
-               bus_addr |= (1UL << 61);
-
-       return bus_addr;
-}
-
-/**
- * pcidev_to_tioce - return misc ce related pointers given a pci_dev
- * @pci_dev: pci device context
- * @base: ptr to store struct tioce_mmr * for the CE holding this device
- * @kernel: ptr to store struct tioce_kernel * for the CE holding this device
- * @port: ptr to store the CE port number that this device is on
- *
- * Return pointers to various CE-related structures for the CE upstream of
- * @pci_dev.
- */
-static inline void
-pcidev_to_tioce(struct pci_dev *pdev, struct tioce __iomem **base,
-               struct tioce_kernel **kernel, int *port)
-{
-       struct pcidev_info *pcidev_info;
-       struct tioce_common *ce_common;
-       struct tioce_kernel *ce_kernel;
-
-       pcidev_info = SN_PCIDEV_INFO(pdev);
-       ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
-       ce_kernel = (struct tioce_kernel *)ce_common->ce_kernel_private;
-
-       if (base)
-               *base = (struct tioce __iomem *)ce_common->ce_pcibus.bs_base;
-       if (kernel)
-               *kernel = ce_kernel;
-
-       /*
-        * we use port as a zero-based value internally, even though the
-        * documentation is 1-based.
-        */
-       if (port)
-               *port =
-                   (pdev->bus->number < ce_kernel->ce_port1_secondary) ? 0 : 1;
-}
-
-/**
- * tioce_alloc_map - Given a coretalk address, map it to pcie bus address
- * space using one of the various ATE-based address modes.
- * @ce_kern: tioce context
- * @type: map mode to use
- * @port: 0-based port that the requesting device is downstream of
- * @ct_addr: the coretalk address to map
- * @len: number of bytes to map
- *
- * Given the addressing type, set up various parameters that define the
- * ATE pool to use.  Search for a contiguous block of entries to cover the
- * length, and if enough resources exist, fill in the ATEs and construct a
- * tioce_dmamap struct to track the mapping.
- */
-static u64
-tioce_alloc_map(struct tioce_kernel *ce_kern, int type, int port,
-               u64 ct_addr, int len, int dma_flags)
-{
-       int i;
-       int j;
-       int first;
-       int last;
-       int entries;
-       int nates;
-       u64 pagesize;
-       int msi_capable, msi_wanted;
-       u64 *ate_shadow;
-       u64 __iomem *ate_reg;
-       u64 addr;
-       struct tioce __iomem *ce_mmr;
-       u64 bus_base;
-       struct tioce_dmamap *map;
-
-       ce_mmr = (struct tioce __iomem *)ce_kern->ce_common->ce_pcibus.bs_base;
-
-       switch (type) {
-       case TIOCE_ATE_M32:
-               /*
-                * The first 64 entries of the ate3240 pool are dedicated to
-                * super-page (TIOCE_ATE_M40S) mode.
-                */
-               first = 64;
-               entries = TIOCE_NUM_M3240_ATES - 64;
-               ate_shadow = ce_kern->ce_ate3240_shadow;
-               ate_reg = ce_mmr->ce_ure_ate3240;
-               pagesize = ce_kern->ce_ate3240_pagesize;
-               bus_base = TIOCE_M32_MIN;
-               msi_capable = 1;
-               break;
-       case TIOCE_ATE_M40:
-               first = 0;
-               entries = TIOCE_NUM_M40_ATES;
-               ate_shadow = ce_kern->ce_ate40_shadow;
-               ate_reg = ce_mmr->ce_ure_ate40;
-               pagesize = MB(64);
-               bus_base = TIOCE_M40_MIN;
-               msi_capable = 0;
-               break;
-       case TIOCE_ATE_M40S:
-               /*
-                * ate3240 entries 0-31 are dedicated to port1 super-page
-                * mappings.  ate3240 entries 32-63 are dedicated to port2.
-                */
-               first = port * 32;
-               entries = 32;
-               ate_shadow = ce_kern->ce_ate3240_shadow;
-               ate_reg = ce_mmr->ce_ure_ate3240;
-               pagesize = GB(16);
-               bus_base = TIOCE_M40S_MIN;
-               msi_capable = 0;
-               break;
-       default:
-               return 0;
-       }
-
-       msi_wanted = dma_flags & SN_DMA_MSI;
-       if (msi_wanted && !msi_capable)
-               return 0;
-
-       nates = ATE_NPAGES(ct_addr, len, pagesize);
-       if (nates > entries)
-               return 0;
-
-       last = first + entries - nates;
-       for (i = first; i <= last; i++) {
-               if (ATE_VALID(ate_shadow[i]))
-                       continue;
-
-               for (j = i; j < i + nates; j++)
-                       if (ATE_VALID(ate_shadow[j]))
-                               break;
-
-               if (j >= i + nates)
-                       break;
-       }
-
-       if (i > last)
-               return 0;
-
-       map = kzalloc(sizeof(struct tioce_dmamap), GFP_ATOMIC);
-       if (!map)
-               return 0;
-
-       addr = ct_addr;
-       for (j = 0; j < nates; j++) {
-               u64 ate;
-
-               ate = ATE_MAKE(addr, pagesize, msi_wanted);
-               ate_shadow[i + j] = ate;
-               tioce_mmr_storei(ce_kern, &ate_reg[i + j], ate);
-               addr += pagesize;
-       }
-
-       map->refcnt = 1;
-       map->nbytes = nates * pagesize;
-       map->ct_start = ct_addr & ~ATE_PAGEMASK(pagesize);
-       map->pci_start = bus_base + (i * pagesize);
-       map->ate_hw = &ate_reg[i];
-       map->ate_shadow = &ate_shadow[i];
-       map->ate_count = nates;
-
-       list_add(&map->ce_dmamap_list, &ce_kern->ce_dmamap_list);
-
-       return (map->pci_start + (ct_addr - map->ct_start));
-}
-
-/**
- * tioce_dma_d32 - create a DMA mapping using 32-bit direct mode
- * @pdev: linux pci_dev representing the function
- * @paddr: system physical address
- *
- * Map @paddr into 32-bit bus space of the CE associated with @pcidev_info.
- */
-static u64
-tioce_dma_d32(struct pci_dev *pdev, u64 ct_addr, int dma_flags)
-{
-       int dma_ok;
-       int port;
-       struct tioce __iomem *ce_mmr;
-       struct tioce_kernel *ce_kern;
-       u64 ct_upper;
-       u64 ct_lower;
-       dma_addr_t bus_addr;
-
-       if (dma_flags & SN_DMA_MSI)
-               return 0;
-
-       ct_upper = ct_addr & ~0x3fffffffUL;
-       ct_lower = ct_addr & 0x3fffffffUL;
-
-       pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port);
-
-       if (ce_kern->ce_port[port].dirmap_refcnt == 0) {
-               u64 tmp;
-
-               ce_kern->ce_port[port].dirmap_shadow = ct_upper;
-               tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_dir_map[port],
-                                ct_upper);
-               tmp = ce_mmr->ce_ure_dir_map[port];
-               dma_ok = 1;
-       } else
-               dma_ok = (ce_kern->ce_port[port].dirmap_shadow == ct_upper);
-
-       if (dma_ok) {
-               ce_kern->ce_port[port].dirmap_refcnt++;
-               bus_addr = TIOCE_D32_MIN + ct_lower;
-       } else
-               bus_addr = 0;
-
-       return bus_addr;
-}
-
-/**
- * tioce_dma_barrier - swizzle a TIOCE bus address to include or exclude
- * the barrier bit.
- * @bus_addr:  bus address to swizzle
- *
- * Given a TIOCE bus address, set the appropriate bit to indicate barrier
- * attributes.
- */
-static u64
-tioce_dma_barrier(u64 bus_addr, int on)
-{
-       u64 barrier_bit;
-
-       /* barrier not supported in M40/M40S mode */
-       if (TIOCE_M40_ADDR(bus_addr) || TIOCE_M40S_ADDR(bus_addr))
-               return bus_addr;
-
-       if (TIOCE_D64_ADDR(bus_addr))
-               barrier_bit = (1UL << 62);
-       else                    /* must be m32 or d32 */
-               barrier_bit = (1UL << 30);
-
-       return (on) ? (bus_addr | barrier_bit) : (bus_addr & ~barrier_bit);
-}
-
-/**
- * tioce_dma_unmap - release CE mapping resources
- * @pdev: linux pci_dev representing the function
- * @bus_addr: bus address returned by an earlier tioce_dma_map
- * @dir: mapping direction (unused)
- *
- * Locate mapping resources associated with @bus_addr and release them.
- * For mappings created using the direct modes there are no resources
- * to release.
- */
-void
-tioce_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir)
-{
-       int i;
-       int port;
-       struct tioce_kernel *ce_kern;
-       struct tioce __iomem *ce_mmr;
-       unsigned long flags;
-
-       bus_addr = tioce_dma_barrier(bus_addr, 0);
-       pcidev_to_tioce(pdev, &ce_mmr, &ce_kern, &port);
-
-       /* nothing to do for D64 */
-
-       if (TIOCE_D64_ADDR(bus_addr))
-               return;
-
-       spin_lock_irqsave(&ce_kern->ce_lock, flags);
-
-       if (TIOCE_D32_ADDR(bus_addr)) {
-               if (--ce_kern->ce_port[port].dirmap_refcnt == 0) {
-                       ce_kern->ce_port[port].dirmap_shadow = 0;
-                       tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_dir_map[port],
-                                        0);
-               }
-       } else {
-               struct tioce_dmamap *map;
-
-               list_for_each_entry(map, &ce_kern->ce_dmamap_list,
-                                   ce_dmamap_list) {
-                       u64 last;
-
-                       last = map->pci_start + map->nbytes - 1;
-                       if (bus_addr >= map->pci_start && bus_addr <= last)
-                               break;
-               }
-
-               if (&map->ce_dmamap_list == &ce_kern->ce_dmamap_list) {
-                       printk(KERN_WARNING
-                              "%s:  %s - no map found for bus_addr 0x%llx\n",
-                              __func__, pci_name(pdev), bus_addr);
-               } else if (--map->refcnt == 0) {
-                       for (i = 0; i < map->ate_count; i++) {
-                               map->ate_shadow[i] = 0;
-                               tioce_mmr_storei(ce_kern, &map->ate_hw[i], 0);
-                       }
-
-                       list_del(&map->ce_dmamap_list);
-                       kfree(map);
-               }
-       }
-
-       spin_unlock_irqrestore(&ce_kern->ce_lock, flags);
-}
-
-/**
- * tioce_do_dma_map - map pages for PCI DMA
- * @pdev: linux pci_dev representing the function
- * @paddr: host physical address to map
- * @byte_count: bytes to map
- *
- * This is the main wrapper for mapping host physical pages to CE PCI space.
- * The mapping mode used is based on the device's dma_mask.
- */
-static u64
-tioce_do_dma_map(struct pci_dev *pdev, u64 paddr, size_t byte_count,
-                int barrier, int dma_flags)
-{
-       unsigned long flags;
-       u64 ct_addr;
-       u64 mapaddr = 0;
-       struct tioce_kernel *ce_kern;
-       struct tioce_dmamap *map;
-       int port;
-       u64 dma_mask;
-
-       dma_mask = (barrier) ? pdev->dev.coherent_dma_mask : pdev->dma_mask;
-
-       /* cards must be able to address at least 31 bits */
-       if (dma_mask < 0x7fffffffUL)
-               return 0;
-
-       if (SN_DMA_ADDRTYPE(dma_flags) == SN_DMA_ADDR_PHYS)
-               ct_addr = PHYS_TO_TIODMA(paddr);
-       else
-               ct_addr = paddr;
-
-       /*
-        * If the device can generate 64 bit addresses, create a D64 map.
-        */
-       if (dma_mask == ~0UL) {
-               mapaddr = tioce_dma_d64(ct_addr, dma_flags);
-               if (mapaddr)
-                       goto dma_map_done;
-       }
-
-       pcidev_to_tioce(pdev, NULL, &ce_kern, &port);
-
-       spin_lock_irqsave(&ce_kern->ce_lock, flags);
-
-       /*
-        * D64 didn't work ... See if we have an existing map that covers
-        * this address range.  Must account for devices dma_mask here since
-        * an existing map might have been done in a mode using more pci
-        * address bits than this device can support.
-        */
-       list_for_each_entry(map, &ce_kern->ce_dmamap_list, ce_dmamap_list) {
-               u64 last;
-
-               last = map->ct_start + map->nbytes - 1;
-               if (ct_addr >= map->ct_start &&
-                   ct_addr + byte_count - 1 <= last &&
-                   map->pci_start <= dma_mask) {
-                       map->refcnt++;
-                       mapaddr = map->pci_start + (ct_addr - map->ct_start);
-                       break;
-               }
-       }
-
-       /*
-        * If we don't have a map yet, and the card can generate 40
-        * bit addresses, try the M40/M40S modes.  Note these modes do not
-        * support a barrier bit, so if we need a consistent map these
-        * won't work.
-        */
-       if (!mapaddr && !barrier && dma_mask >= 0xffffffffffUL) {
-               /*
-                * We have two options for 40-bit mappings:  16GB "super" ATEs
-                * and 64MB "regular" ATEs.  We'll try both if needed for a
-                * given mapping but which one we try first depends on the
-                * size.  For requests >64MB, prefer to use a super page with
-                * regular as the fallback. Otherwise, try in the reverse order.
-                */
-
-               if (byte_count > MB(64)) {
-                       mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40S,
-                                                 port, ct_addr, byte_count,
-                                                 dma_flags);
-                       if (!mapaddr)
-                               mapaddr =
-                                   tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1,
-                                                   ct_addr, byte_count,
-                                                   dma_flags);
-               } else {
-                       mapaddr = tioce_alloc_map(ce_kern, TIOCE_ATE_M40, -1,
-                                                 ct_addr, byte_count,
-                                                 dma_flags);
-                       if (!mapaddr)
-                               mapaddr =
-                                   tioce_alloc_map(ce_kern, TIOCE_ATE_M40S,
-                                                   port, ct_addr, byte_count,
-                                                   dma_flags);
-               }
-       }
-
-       /*
-        * 32-bit direct is the next mode to try
-        */
-       if (!mapaddr && dma_mask >= 0xffffffffUL)
-               mapaddr = tioce_dma_d32(pdev, ct_addr, dma_flags);
-
-       /*
-        * Last resort, try 32-bit ATE-based map.
-        */
-       if (!mapaddr)
-               mapaddr =
-                   tioce_alloc_map(ce_kern, TIOCE_ATE_M32, -1, ct_addr,
-                                   byte_count, dma_flags);
-
-       spin_unlock_irqrestore(&ce_kern->ce_lock, flags);
-
-dma_map_done:
-       if (mapaddr && barrier)
-               mapaddr = tioce_dma_barrier(mapaddr, 1);
-
-       return mapaddr;
-}
-
-/**
- * tioce_dma - standard pci dma map interface
- * @pdev: pci device requesting the map
- * @paddr: system physical address to map into pci space
- * @byte_count: # bytes to map
- *
- * Simply call tioce_do_dma_map() to create a map with the barrier bit clear
- * in the address.
- */
-static u64
-tioce_dma(struct pci_dev *pdev, unsigned long  paddr, size_t byte_count, int dma_flags)
-{
-       return tioce_do_dma_map(pdev, paddr, byte_count, 0, dma_flags);
-}
-
-/**
- * tioce_dma_consistent - consistent pci dma map interface
- * @pdev: pci device requesting the map
- * @paddr: system physical address to map into pci space
- * @byte_count: # bytes to map
- *
- * Simply call tioce_do_dma_map() to create a map with the barrier bit set
- * in the address.
- */
-static u64
-tioce_dma_consistent(struct pci_dev *pdev, unsigned long  paddr, size_t byte_count, int dma_flags)
-{
-       return tioce_do_dma_map(pdev, paddr, byte_count, 1, dma_flags);
-}
-
-/**
- * tioce_error_intr_handler - SGI TIO CE error interrupt handler
- * @irq: unused
- * @arg: pointer to tioce_common struct for the given CE
- *
- * Handle a CE error interrupt.  Simply a wrapper around a SAL call which
- * defers processing to the SGI prom.
- */
-static irqreturn_t
-tioce_error_intr_handler(int irq, void *arg)
-{
-       struct tioce_common *soft = arg;
-       struct ia64_sal_retval ret_stuff;
-       ret_stuff.status = 0;
-       ret_stuff.v0 = 0;
-
-       SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_ERROR_INTERRUPT,
-                       soft->ce_pcibus.bs_persist_segment,
-                       soft->ce_pcibus.bs_persist_busnum, 0, 0, 0, 0, 0);
-
-       if (ret_stuff.v0)
-               panic("tioce_error_intr_handler:  Fatal TIOCE error");
-
-       return IRQ_HANDLED;
-}
-
-/**
- * tioce_reserve_m32 - reserve M32 ATEs for the indicated address range
- * @tioce_kernel: TIOCE context to reserve ATEs for
- * @base: starting bus address to reserve
- * @limit: last bus address to reserve
- *
- * If base/limit falls within the range of bus space mapped through the
- * M32 space, reserve the resources corresponding to the range.
- */
-static void
-tioce_reserve_m32(struct tioce_kernel *ce_kern, u64 base, u64 limit)
-{
-       int ate_index, last_ate, ps;
-       struct tioce __iomem *ce_mmr;
-
-       ce_mmr = (struct tioce __iomem *)ce_kern->ce_common->ce_pcibus.bs_base;
-       ps = ce_kern->ce_ate3240_pagesize;
-       ate_index = ATE_PAGE(base, ps);
-       last_ate = ate_index + ATE_NPAGES(base, limit-base+1, ps) - 1;
-
-       if (ate_index < 64)
-               ate_index = 64;
-
-       if (last_ate >= TIOCE_NUM_M3240_ATES)
-               last_ate = TIOCE_NUM_M3240_ATES - 1;
-
-       while (ate_index <= last_ate) {
-               u64 ate;
-
-               ate = ATE_MAKE(0xdeadbeef, ps, 0);
-               ce_kern->ce_ate3240_shadow[ate_index] = ate;
-               tioce_mmr_storei(ce_kern, &ce_mmr->ce_ure_ate3240[ate_index],
-                                ate);
-               ate_index++;
-       }
-}
-
-/**
- * tioce_kern_init - init kernel structures related to a given TIOCE
- * @tioce_common: ptr to a cached tioce_common struct that originated in prom
- */
-static struct tioce_kernel *
-tioce_kern_init(struct tioce_common *tioce_common)
-{
-       int i;
-       int ps;
-       int dev;
-       u32 tmp;
-       unsigned int seg, bus;
-       struct tioce __iomem *tioce_mmr;
-       struct tioce_kernel *tioce_kern;
-
-       tioce_kern = kzalloc(sizeof(struct tioce_kernel), GFP_KERNEL);
-       if (!tioce_kern) {
-               return NULL;
-       }
-
-       tioce_kern->ce_common = tioce_common;
-       spin_lock_init(&tioce_kern->ce_lock);
-       INIT_LIST_HEAD(&tioce_kern->ce_dmamap_list);
-       tioce_common->ce_kernel_private = (u64) tioce_kern;
-
-       /*
-        * Determine the secondary bus number of the port2 logical PPB.
-        * This is used to decide whether a given pci device resides on
-        * port1 or port2.  Note:  We don't have enough plumbing set up
-        * here to use pci_read_config_xxx() so use raw_pci_read().
-        */
-
-       seg = tioce_common->ce_pcibus.bs_persist_segment;
-       bus = tioce_common->ce_pcibus.bs_persist_busnum;
-
-       raw_pci_read(seg, bus, PCI_DEVFN(2, 0), PCI_SECONDARY_BUS, 1,&tmp);
-       tioce_kern->ce_port1_secondary = (u8) tmp;
-
-       /*
-        * Set PMU pagesize to the largest size available, and zero out
-        * the ATEs.
-        */
-
-       tioce_mmr = (struct tioce __iomem *)tioce_common->ce_pcibus.bs_base;
-       tioce_mmr_clri(tioce_kern, &tioce_mmr->ce_ure_page_map,
-                      CE_URE_PAGESIZE_MASK);
-       tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_ure_page_map,
-                      CE_URE_256K_PAGESIZE);
-       ps = tioce_kern->ce_ate3240_pagesize = KB(256);
-
-       for (i = 0; i < TIOCE_NUM_M40_ATES; i++) {
-               tioce_kern->ce_ate40_shadow[i] = 0;
-               tioce_mmr_storei(tioce_kern, &tioce_mmr->ce_ure_ate40[i], 0);
-       }
-
-       for (i = 0; i < TIOCE_NUM_M3240_ATES; i++) {
-               tioce_kern->ce_ate3240_shadow[i] = 0;
-               tioce_mmr_storei(tioce_kern, &tioce_mmr->ce_ure_ate3240[i], 0);
-       }
-
-       /*
-        * Reserve ATEs corresponding to reserved address ranges.  These
-        * include:
-        *
-        *      Memory space covered by each PPB mem base/limit register
-        *      Memory space covered by each PPB prefetch base/limit register
-        *
-        * These bus ranges are for pio (downstream) traffic only, and so
-        * cannot be used for DMA.
-        */
-
-       for (dev = 1; dev <= 2; dev++) {
-               u64 base, limit;
-
-               /* mem base/limit */
-
-               raw_pci_read(seg, bus, PCI_DEVFN(dev, 0),
-                                 PCI_MEMORY_BASE, 2, &tmp);
-               base = (u64)tmp << 16;
-
-               raw_pci_read(seg, bus, PCI_DEVFN(dev, 0),
-                                 PCI_MEMORY_LIMIT, 2, &tmp);
-               limit = (u64)tmp << 16;
-               limit |= 0xfffffUL;
-
-               if (base < limit)
-                       tioce_reserve_m32(tioce_kern, base, limit);
-
-               /*
-                * prefetch mem base/limit.  The tioce ppb's have 64-bit
-                * decoders, so read the upper portions w/o checking the
-                * attributes.
-                */
-
-               raw_pci_read(seg, bus, PCI_DEVFN(dev, 0),
-                                 PCI_PREF_MEMORY_BASE, 2, &tmp);
-               base = ((u64)tmp & PCI_PREF_RANGE_MASK) << 16;
-
-               raw_pci_read(seg, bus, PCI_DEVFN(dev, 0),
-                                 PCI_PREF_BASE_UPPER32, 4, &tmp);
-               base |= (u64)tmp << 32;
-
-               raw_pci_read(seg, bus, PCI_DEVFN(dev, 0),
-                                 PCI_PREF_MEMORY_LIMIT, 2, &tmp);
-
-               limit = ((u64)tmp & PCI_PREF_RANGE_MASK) << 16;
-               limit |= 0xfffffUL;
-
-               raw_pci_read(seg, bus, PCI_DEVFN(dev, 0),
-                                 PCI_PREF_LIMIT_UPPER32, 4, &tmp);
-               limit |= (u64)tmp << 32;
-
-               if ((base < limit) && TIOCE_M32_ADDR(base))
-                       tioce_reserve_m32(tioce_kern, base, limit);
-       }
-
-       return tioce_kern;
-}
-
-/**
- * tioce_force_interrupt - implement altix force_interrupt() backend for CE
- * @sn_irq_info: sn asic irq that we need an interrupt generated for
- *
- * Given an sn_irq_info struct, set the proper bit in ce_adm_force_int to
- * force a secondary interrupt to be generated.  This is to work around an
- * asic issue where there is a small window of opportunity for a legacy device
- * interrupt to be lost.
- */
-static void
-tioce_force_interrupt(struct sn_irq_info *sn_irq_info)
-{
-       struct pcidev_info *pcidev_info;
-       struct tioce_common *ce_common;
-       struct tioce_kernel *ce_kern;
-       struct tioce __iomem *ce_mmr;
-       u64 force_int_val;
-
-       if (!sn_irq_info->irq_bridge)
-               return;
-
-       if (sn_irq_info->irq_bridge_type != PCIIO_ASIC_TYPE_TIOCE)
-               return;
-
-       pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
-       if (!pcidev_info)
-               return;
-
-       ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
-       ce_mmr = (struct tioce __iomem *)ce_common->ce_pcibus.bs_base;
-       ce_kern = (struct tioce_kernel *)ce_common->ce_kernel_private;
-
-       /*
-        * TIOCE Rev A workaround (PV 945826), force an interrupt by writing
-        * the TIO_INTx register directly (1/26/2006)
-        */
-       if (ce_common->ce_rev == TIOCE_REV_A) {
-               u64 int_bit_mask = (1ULL << sn_irq_info->irq_int_bit);
-               u64 status;
-
-               tioce_mmr_load(ce_kern, &ce_mmr->ce_adm_int_status, &status);
-               if (status & int_bit_mask) {
-                       u64 force_irq = (1 << 8) | sn_irq_info->irq_irq;
-                       u64 ctalk = sn_irq_info->irq_xtalkaddr;
-                       u64 nasid, offset;
-
-                       nasid = (ctalk & CTALK_NASID_MASK) >> CTALK_NASID_SHFT;
-                       offset = (ctalk & CTALK_NODE_OFFSET);
-                       HUB_S(TIO_IOSPACE_ADDR(nasid, offset), force_irq);
-               }
-
-               return;
-       }
-
-       /*
-        * irq_int_bit is originally set up by prom, and holds the interrupt
-        * bit shift (not mask) as defined by the bit definitions in the
-        * ce_adm_int mmr.  These shifts are not the same for the
-        * ce_adm_force_int register, so do an explicit mapping here to make
-        * things clearer.
-        */
-
-       switch (sn_irq_info->irq_int_bit) {
-       case CE_ADM_INT_PCIE_PORT1_DEV_A_SHFT:
-               force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT1_DEV_A_SHFT;
-               break;
-       case CE_ADM_INT_PCIE_PORT1_DEV_B_SHFT:
-               force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT1_DEV_B_SHFT;
-               break;
-       case CE_ADM_INT_PCIE_PORT1_DEV_C_SHFT:
-               force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT1_DEV_C_SHFT;
-               break;
-       case CE_ADM_INT_PCIE_PORT1_DEV_D_SHFT:
-               force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT1_DEV_D_SHFT;
-               break;
-       case CE_ADM_INT_PCIE_PORT2_DEV_A_SHFT:
-               force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT2_DEV_A_SHFT;
-               break;
-       case CE_ADM_INT_PCIE_PORT2_DEV_B_SHFT:
-               force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT2_DEV_B_SHFT;
-               break;
-       case CE_ADM_INT_PCIE_PORT2_DEV_C_SHFT:
-               force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT2_DEV_C_SHFT;
-               break;
-       case CE_ADM_INT_PCIE_PORT2_DEV_D_SHFT:
-               force_int_val = 1UL << CE_ADM_FORCE_INT_PCIE_PORT2_DEV_D_SHFT;
-               break;
-       default:
-               return;
-       }
-       tioce_mmr_storei(ce_kern, &ce_mmr->ce_adm_force_int, force_int_val);
-}
-
-/**
- * tioce_target_interrupt - implement set_irq_affinity for tioce resident
- * functions.  Note:  only applies to line interrupts, not MSI's.
- *
- * @sn_irq_info: SN IRQ context
- *
- * Given an sn_irq_info, set the associated CE device's interrupt destination
- * register.  Since the interrupt destination registers are on a per-ce-slot
- * basis, this will retarget line interrupts for all functions downstream of
- * the slot.
- */
-static void
-tioce_target_interrupt(struct sn_irq_info *sn_irq_info)
-{
-       struct pcidev_info *pcidev_info;
-       struct tioce_common *ce_common;
-       struct tioce_kernel *ce_kern;
-       struct tioce __iomem *ce_mmr;
-       int bit;
-       u64 vector;
-
-       pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo;
-       if (!pcidev_info)
-               return;
-
-       ce_common = (struct tioce_common *)pcidev_info->pdi_pcibus_info;
-       ce_mmr = (struct tioce __iomem *)ce_common->ce_pcibus.bs_base;
-       ce_kern = (struct tioce_kernel *)ce_common->ce_kernel_private;
-
-       bit = sn_irq_info->irq_int_bit;
-
-       tioce_mmr_seti(ce_kern, &ce_mmr->ce_adm_int_mask, (1UL << bit));
-       vector = (u64)sn_irq_info->irq_irq << INTR_VECTOR_SHFT;
-       vector |= sn_irq_info->irq_xtalkaddr;
-       tioce_mmr_storei(ce_kern, &ce_mmr->ce_adm_int_dest[bit], vector);
-       tioce_mmr_clri(ce_kern, &ce_mmr->ce_adm_int_mask, (1UL << bit));
-
-       tioce_force_interrupt(sn_irq_info);
-}
-
-/**
- * tioce_bus_fixup - perform final PCI fixup for a TIO CE bus
- * @prom_bussoft: Common prom/kernel struct representing the bus
- *
- * Replicates the tioce_common pointed to by @prom_bussoft in kernel
- * space.  Allocates and initializes a kernel-only area for a given CE,
- * and sets up an irq for handling CE error interrupts.
- *
- * On successful setup, returns the kernel version of tioce_common back to
- * the caller.
- */
-static void *
-tioce_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
-{
-       struct tioce_common *tioce_common;
-       struct tioce_kernel *tioce_kern;
-       struct tioce __iomem *tioce_mmr;
-
-       /*
-        * Allocate kernel bus soft and copy from prom.
-        */
-
-       tioce_common = kzalloc(sizeof(struct tioce_common), GFP_KERNEL);
-       if (!tioce_common)
-               return NULL;
-
-       memcpy(tioce_common, prom_bussoft, sizeof(struct tioce_common));
-       tioce_common->ce_pcibus.bs_base = (unsigned long)
-               ioremap(REGION_OFFSET(tioce_common->ce_pcibus.bs_base),
-                       sizeof(struct tioce_common));
-
-       tioce_kern = tioce_kern_init(tioce_common);
-       if (tioce_kern == NULL) {
-               kfree(tioce_common);
-               return NULL;
-       }
-
-       /*
-        * Clear out any transient errors before registering the error
-        * interrupt handler.
-        */
-
-       tioce_mmr = (struct tioce __iomem *)tioce_common->ce_pcibus.bs_base;
-       tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_int_status_alias, ~0ULL);
-       tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_adm_error_summary_alias,
-                      ~0ULL);
-       tioce_mmr_seti(tioce_kern, &tioce_mmr->ce_dre_comp_err_addr, 0ULL);
-
-       if (request_irq(SGI_PCIASIC_ERROR,
-                       tioce_error_intr_handler,
-                       IRQF_SHARED, "TIOCE error", (void *)tioce_common))
-               printk(KERN_WARNING
-                      "%s:  Unable to get irq %d.  "
-                      "Error interrupts won't be routed for "
-                      "TIOCE bus %04x:%02x\n",
-                      __func__, SGI_PCIASIC_ERROR,
-                      tioce_common->ce_pcibus.bs_persist_segment,
-                      tioce_common->ce_pcibus.bs_persist_busnum);
-
-       irq_set_handler(SGI_PCIASIC_ERROR, handle_level_irq);
-       sn_set_err_irq_affinity(SGI_PCIASIC_ERROR);
-       return tioce_common;
-}
-
-static struct sn_pcibus_provider tioce_pci_interfaces = {
-       .dma_map = tioce_dma,
-       .dma_map_consistent = tioce_dma_consistent,
-       .dma_unmap = tioce_dma_unmap,
-       .bus_fixup = tioce_bus_fixup,
-       .force_interrupt = tioce_force_interrupt,
-       .target_interrupt = tioce_target_interrupt
-};
-
-/**
- * tioce_init_provider - init SN PCI provider ops for TIO CE
- */
-int
-tioce_init_provider(void)
-{
-       sn_pci_provider[PCIIO_ASIC_TYPE_TIOCE] = &tioce_pci_interfaces;
-       return 0;
-}
index 124e441..2971965 100644 (file)
@@ -10,4 +10,3 @@
 ccflags-y := -Iarch/ia64/sn/include
 
 obj-y                          += setup.o
-obj-$(CONFIG_IA64_GENERIC)      += machvec.o
diff --git a/arch/ia64/uv/kernel/machvec.c b/arch/ia64/uv/kernel/machvec.c
deleted file mode 100644 (file)
index 50737a9..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#define MACHVEC_PLATFORM_NAME  uv
-#define MACHVEC_PLATFORM_HEADER        <asm/machvec_uv.h>
-#include <asm/machvec_init.h>
index f149065..bb02548 100644 (file)
@@ -8,25 +8,20 @@
  * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
  */
 
+#include <linux/acpi.h>
+#include <linux/efi.h>
 #include <linux/module.h>
 #include <linux/percpu.h>
-#include <asm/sn/simulator.h>
+#include <asm/uv/uv.h>
 #include <asm/uv/uv_mmrs.h>
 #include <asm/uv/uv_hub.h>
 
+bool ia64_is_uv;
+EXPORT_SYMBOL_GPL(ia64_is_uv);
+
 DEFINE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
 EXPORT_PER_CPU_SYMBOL_GPL(__uv_hub_info);
 
-#ifdef CONFIG_IA64_SGI_UV
-int sn_prom_type;
-long sn_partition_id;
-EXPORT_SYMBOL(sn_partition_id);
-long sn_coherency_id;
-EXPORT_SYMBOL_GPL(sn_coherency_id);
-long sn_region_size;
-EXPORT_SYMBOL(sn_region_size);
-#endif
-
 struct redir_addr {
        unsigned long redirect;
        unsigned long alias;
@@ -58,6 +53,34 @@ static __init void get_lowmem_redirect(unsigned long *base, unsigned long *size)
        BUG();
 }
 
+void __init uv_probe_system_type(void)
+{
+       struct acpi_table_rsdp *rsdp;
+       struct acpi_table_xsdt *xsdt;
+
+       if (efi.acpi20 == EFI_INVALID_TABLE_ADDR) {
+               pr_err("ACPI 2.0 RSDP not found.\n");
+               return;
+       }
+
+       rsdp = (struct acpi_table_rsdp *)__va(efi.acpi20);
+       if (strncmp(rsdp->signature, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)) {
+               pr_err("ACPI 2.0 RSDP signature incorrect.\n");
+               return;
+       }
+
+       xsdt = (struct acpi_table_xsdt *)__va(rsdp->xsdt_physical_address);
+       if (strncmp(xsdt->header.signature, ACPI_SIG_XSDT,
+                       sizeof(ACPI_SIG_XSDT) - 1)) {
+               pr_err("ACPI 2.0 XSDT signature incorrect.\n");
+               return;
+       }
+
+       if (!strcmp(xsdt->header.oem_id, "SGI") &&
+           !strcmp(xsdt->header.oem_table_id + 4, "UV"))
+               ia64_is_uv = true;
+}
+
 void __init uv_setup(char **cmdline_p)
 {
        union uvh_si_addr_map_config_u m_n_config;
@@ -66,30 +89,11 @@ void __init uv_setup(char **cmdline_p)
        int nid, cpu, m_val, n_val;
        unsigned long mmr_base, lowmem_redir_base, lowmem_redir_size;
 
-       if (IS_MEDUSA()) {
-               lowmem_redir_base = 0;
-               lowmem_redir_size = 0;
-               node_id.v = 0;
-               m_n_config.s.m_skt = 37;
-               m_n_config.s.n_skt = 0;
-               mmr_base = 0;
-#if 0
-               /* Need BIOS calls - TDB */
-               if (!ia64_sn_is_fake_prom())
-                       sn_prom_type = 1;
-               else
-#endif
-                       sn_prom_type = 2;
-               printk(KERN_INFO "Running on medusa with %s PROM\n",
-                                       (sn_prom_type == 1) ? "real" : "fake");
-       } else {
-               get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size);
-               node_id.v = uv_read_local_mmr(UVH_NODE_ID);
-               m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG);
-               mmr_base =
-                       uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) &
-                               ~UV_MMR_ENABLE;
-       }
+       get_lowmem_redirect(&lowmem_redir_base, &lowmem_redir_size);
+       node_id.v = uv_read_local_mmr(UVH_NODE_ID);
+       m_n_config.v = uv_read_local_mmr(UVH_SI_ADDR_MAP_CONFIG);
+       mmr_base = uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) &
+                       ~UV_MMR_ENABLE;
 
        m_val = m_n_config.s.m_skt;
        n_val = m_n_config.s.n_skt;
index 902255e..73bf5ea 100644 (file)
@@ -246,9 +246,9 @@ void __init config_atari(void)
        } else if (hwreg_present(tt_palette)) {
                ATARIHW_SET(TT_SHIFTER);
                pr_cont(" TT_SHIFTER");
-       } else if (hwreg_present(&shifter.bas_hi)) {
-               if (hwreg_present(&shifter.bas_lo) &&
-                   (shifter.bas_lo = 0x0aau, shifter.bas_lo == 0x0aau)) {
+       } else if (hwreg_present(&shifter_st.bas_hi)) {
+               if (hwreg_present(&shifter_st.bas_lo) &&
+                   (shifter_st.bas_lo = 0x0aau, shifter_st.bas_lo == 0x0aau)) {
                        ATARIHW_SET(EXTD_SHIFTER);
                        pr_cont(" EXTD_SHIFTER");
                } else {
index 04e0f21..9a33c1c 100644 (file)
@@ -125,6 +125,7 @@ CONFIG_NFT_XFRM=m
 CONFIG_NFT_SOCKET=m
 CONFIG_NFT_OSF=m
 CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NFT_FIB_NETDEV=m
@@ -250,9 +251,11 @@ CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_IP6_NF_TARGET_NPT=m
-CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
 CONFIG_NFT_BRIDGE_REJECT=m
 CONFIG_NF_LOG_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -330,7 +333,6 @@ CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
@@ -450,7 +452,6 @@ CONFIG_RTC_DRV_RP5C01=m
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_DAX=m
-# CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
@@ -573,6 +574,7 @@ CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_ADIANTUM=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_XXHASH=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -582,8 +584,10 @@ CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_SM3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
@@ -618,6 +622,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_WW_MUTEX_SELFTEST=m
 CONFIG_TEST_LIST_SORT=m
 CONFIG_TEST_SORT=m
+CONFIG_REED_SOLOMON_TEST=m
 CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
@@ -636,6 +641,7 @@ CONFIG_TEST_IDA=m
 CONFIG_TEST_VMALLOC=m
 CONFIG_TEST_USER_COPY=m
 CONFIG_TEST_BPF=m
+CONFIG_TEST_BLACKHOLE_DEV=m
 CONFIG_FIND_BIT_BENCHMARK=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_SYSCTL=m
@@ -644,4 +650,5 @@ CONFIG_TEST_STATIC_KEYS=m
 CONFIG_TEST_KMOD=m
 CONFIG_TEST_MEMCAT_P=m
 CONFIG_TEST_STACKINIT=m
+CONFIG_TEST_MEMINIT=m
 CONFIG_EARLY_PRINTK=y
index c6abbb5..7fdbc79 100644 (file)
@@ -121,6 +121,7 @@ CONFIG_NFT_XFRM=m
 CONFIG_NFT_SOCKET=m
 CONFIG_NFT_OSF=m
 CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NFT_FIB_NETDEV=m
@@ -246,9 +247,11 @@ CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_IP6_NF_TARGET_NPT=m
-CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
 CONFIG_NFT_BRIDGE_REJECT=m
 CONFIG_NF_LOG_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -315,7 +318,6 @@ CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
@@ -410,7 +412,6 @@ CONFIG_RTC_DRV_GENERIC=m
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_DAX=m
-# CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
@@ -533,6 +534,7 @@ CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_ADIANTUM=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_XXHASH=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -542,8 +544,10 @@ CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_SM3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
@@ -578,6 +582,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_WW_MUTEX_SELFTEST=m
 CONFIG_TEST_LIST_SORT=m
 CONFIG_TEST_SORT=m
+CONFIG_REED_SOLOMON_TEST=m
 CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
@@ -596,6 +601,7 @@ CONFIG_TEST_IDA=m
 CONFIG_TEST_VMALLOC=m
 CONFIG_TEST_USER_COPY=m
 CONFIG_TEST_BPF=m
+CONFIG_TEST_BLACKHOLE_DEV=m
 CONFIG_FIND_BIT_BENCHMARK=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_SYSCTL=m
@@ -604,4 +610,5 @@ CONFIG_TEST_STATIC_KEYS=m
 CONFIG_TEST_KMOD=m
 CONFIG_TEST_MEMCAT_P=m
 CONFIG_TEST_STACKINIT=m
+CONFIG_TEST_MEMINIT=m
 CONFIG_EARLY_PRINTK=y
index 06ae65b..f176340 100644 (file)
@@ -128,6 +128,7 @@ CONFIG_NFT_XFRM=m
 CONFIG_NFT_SOCKET=m
 CONFIG_NFT_OSF=m
 CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NFT_FIB_NETDEV=m
@@ -253,9 +254,11 @@ CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_IP6_NF_TARGET_NPT=m
-CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
 CONFIG_NFT_BRIDGE_REJECT=m
 CONFIG_NF_LOG_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -330,7 +333,6 @@ CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
@@ -432,7 +434,6 @@ CONFIG_RTC_DRV_GENERIC=m
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_DAX=m
-# CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
@@ -555,6 +556,7 @@ CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_ADIANTUM=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_XXHASH=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -564,8 +566,10 @@ CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_SM3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
@@ -600,6 +604,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_WW_MUTEX_SELFTEST=m
 CONFIG_TEST_LIST_SORT=m
 CONFIG_TEST_SORT=m
+CONFIG_REED_SOLOMON_TEST=m
 CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
@@ -618,6 +623,7 @@ CONFIG_TEST_IDA=m
 CONFIG_TEST_VMALLOC=m
 CONFIG_TEST_USER_COPY=m
 CONFIG_TEST_BPF=m
+CONFIG_TEST_BLACKHOLE_DEV=m
 CONFIG_FIND_BIT_BENCHMARK=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_SYSCTL=m
@@ -626,4 +632,5 @@ CONFIG_TEST_STATIC_KEYS=m
 CONFIG_TEST_KMOD=m
 CONFIG_TEST_MEMCAT_P=m
 CONFIG_TEST_STACKINIT=m
+CONFIG_TEST_MEMINIT=m
 CONFIG_EARLY_PRINTK=y
index 5616b94..91154d6 100644 (file)
@@ -118,6 +118,7 @@ CONFIG_NFT_XFRM=m
 CONFIG_NFT_SOCKET=m
 CONFIG_NFT_OSF=m
 CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NFT_FIB_NETDEV=m
@@ -243,9 +244,11 @@ CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_IP6_NF_TARGET_NPT=m
-CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
 CONFIG_NFT_BRIDGE_REJECT=m
 CONFIG_NF_LOG_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -312,7 +315,6 @@ CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
@@ -403,7 +405,6 @@ CONFIG_RTC_DRV_GENERIC=m
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_DAX=m
-# CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
@@ -526,6 +527,7 @@ CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_ADIANTUM=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_XXHASH=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -535,8 +537,10 @@ CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_SM3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
@@ -571,6 +575,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_WW_MUTEX_SELFTEST=m
 CONFIG_TEST_LIST_SORT=m
 CONFIG_TEST_SORT=m
+CONFIG_REED_SOLOMON_TEST=m
 CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
@@ -589,6 +594,7 @@ CONFIG_TEST_IDA=m
 CONFIG_TEST_VMALLOC=m
 CONFIG_TEST_USER_COPY=m
 CONFIG_TEST_BPF=m
+CONFIG_TEST_BLACKHOLE_DEV=m
 CONFIG_FIND_BIT_BENCHMARK=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_SYSCTL=m
@@ -597,4 +603,5 @@ CONFIG_TEST_STATIC_KEYS=m
 CONFIG_TEST_KMOD=m
 CONFIG_TEST_MEMCAT_P=m
 CONFIG_TEST_STACKINIT=m
+CONFIG_TEST_MEMINIT=m
 CONFIG_EARLY_PRINTK=y
index 1106521..c398c4a 100644 (file)
@@ -120,6 +120,7 @@ CONFIG_NFT_XFRM=m
 CONFIG_NFT_SOCKET=m
 CONFIG_NFT_OSF=m
 CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NFT_FIB_NETDEV=m
@@ -245,9 +246,11 @@ CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_IP6_NF_TARGET_NPT=m
-CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
 CONFIG_NFT_BRIDGE_REJECT=m
 CONFIG_NF_LOG_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -314,7 +317,6 @@ CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
@@ -412,7 +414,6 @@ CONFIG_RTC_DRV_GENERIC=m
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_DAX=m
-# CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
@@ -535,6 +536,7 @@ CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_ADIANTUM=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_XXHASH=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -544,8 +546,10 @@ CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_SM3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
@@ -580,6 +584,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_WW_MUTEX_SELFTEST=m
 CONFIG_TEST_LIST_SORT=m
 CONFIG_TEST_SORT=m
+CONFIG_REED_SOLOMON_TEST=m
 CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
@@ -598,6 +603,7 @@ CONFIG_TEST_IDA=m
 CONFIG_TEST_VMALLOC=m
 CONFIG_TEST_USER_COPY=m
 CONFIG_TEST_BPF=m
+CONFIG_TEST_BLACKHOLE_DEV=m
 CONFIG_FIND_BIT_BENCHMARK=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_SYSCTL=m
@@ -606,4 +612,5 @@ CONFIG_TEST_STATIC_KEYS=m
 CONFIG_TEST_KMOD=m
 CONFIG_TEST_MEMCAT_P=m
 CONFIG_TEST_STACKINIT=m
+CONFIG_TEST_MEMINIT=m
 CONFIG_EARLY_PRINTK=y
index 226c6c0..350d004 100644 (file)
@@ -119,6 +119,7 @@ CONFIG_NFT_XFRM=m
 CONFIG_NFT_SOCKET=m
 CONFIG_NFT_OSF=m
 CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NFT_FIB_NETDEV=m
@@ -244,9 +245,11 @@ CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_IP6_NF_TARGET_NPT=m
-CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
 CONFIG_NFT_BRIDGE_REJECT=m
 CONFIG_NF_LOG_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -321,7 +324,6 @@ CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
@@ -434,7 +436,6 @@ CONFIG_RTC_DRV_GENERIC=m
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_DAX=m
-# CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
@@ -557,6 +558,7 @@ CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_ADIANTUM=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_XXHASH=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -566,8 +568,10 @@ CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_SM3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
@@ -602,6 +606,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_WW_MUTEX_SELFTEST=m
 CONFIG_TEST_LIST_SORT=m
 CONFIG_TEST_SORT=m
+CONFIG_REED_SOLOMON_TEST=m
 CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
@@ -620,6 +625,7 @@ CONFIG_TEST_IDA=m
 CONFIG_TEST_VMALLOC=m
 CONFIG_TEST_USER_COPY=m
 CONFIG_TEST_BPF=m
+CONFIG_TEST_BLACKHOLE_DEV=m
 CONFIG_FIND_BIT_BENCHMARK=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_SYSCTL=m
@@ -628,4 +634,5 @@ CONFIG_TEST_STATIC_KEYS=m
 CONFIG_TEST_KMOD=m
 CONFIG_TEST_MEMCAT_P=m
 CONFIG_TEST_STACKINIT=m
+CONFIG_TEST_MEMINIT=m
 CONFIG_EARLY_PRINTK=y
index 39f6034..b838dd8 100644 (file)
@@ -139,6 +139,7 @@ CONFIG_NFT_XFRM=m
 CONFIG_NFT_SOCKET=m
 CONFIG_NFT_OSF=m
 CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NFT_FIB_NETDEV=m
@@ -264,9 +265,11 @@ CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_IP6_NF_TARGET_NPT=m
-CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
 CONFIG_NFT_BRIDGE_REJECT=m
 CONFIG_NF_LOG_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -354,7 +357,6 @@ CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
@@ -516,7 +518,6 @@ CONFIG_RTC_DRV_GENERIC=m
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_DAX=m
-# CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
@@ -639,6 +640,7 @@ CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_ADIANTUM=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_XXHASH=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -648,8 +650,10 @@ CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_SM3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
@@ -684,6 +688,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_WW_MUTEX_SELFTEST=m
 CONFIG_TEST_LIST_SORT=m
 CONFIG_TEST_SORT=m
+CONFIG_REED_SOLOMON_TEST=m
 CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
@@ -702,6 +707,7 @@ CONFIG_TEST_IDA=m
 CONFIG_TEST_VMALLOC=m
 CONFIG_TEST_USER_COPY=m
 CONFIG_TEST_BPF=m
+CONFIG_TEST_BLACKHOLE_DEV=m
 CONFIG_FIND_BIT_BENCHMARK=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_SYSCTL=m
@@ -710,4 +716,5 @@ CONFIG_TEST_STATIC_KEYS=m
 CONFIG_TEST_KMOD=m
 CONFIG_TEST_MEMCAT_P=m
 CONFIG_TEST_STACKINIT=m
+CONFIG_TEST_MEMINIT=m
 CONFIG_EARLY_PRINTK=y
index 175a607..3f8dd61 100644 (file)
@@ -117,6 +117,7 @@ CONFIG_NFT_XFRM=m
 CONFIG_NFT_SOCKET=m
 CONFIG_NFT_OSF=m
 CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NFT_FIB_NETDEV=m
@@ -242,9 +243,11 @@ CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_IP6_NF_TARGET_NPT=m
-CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
 CONFIG_NFT_BRIDGE_REJECT=m
 CONFIG_NF_LOG_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -311,7 +314,6 @@ CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
@@ -402,7 +404,6 @@ CONFIG_RTC_DRV_GENERIC=m
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_DAX=m
-# CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
@@ -525,6 +526,7 @@ CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_ADIANTUM=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_XXHASH=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -534,8 +536,10 @@ CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_SM3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
@@ -570,6 +574,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_WW_MUTEX_SELFTEST=m
 CONFIG_TEST_LIST_SORT=m
 CONFIG_TEST_SORT=m
+CONFIG_REED_SOLOMON_TEST=m
 CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
@@ -588,6 +593,7 @@ CONFIG_TEST_IDA=m
 CONFIG_TEST_VMALLOC=m
 CONFIG_TEST_USER_COPY=m
 CONFIG_TEST_BPF=m
+CONFIG_TEST_BLACKHOLE_DEV=m
 CONFIG_FIND_BIT_BENCHMARK=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_SYSCTL=m
@@ -596,4 +602,5 @@ CONFIG_TEST_STATIC_KEYS=m
 CONFIG_TEST_KMOD=m
 CONFIG_TEST_MEMCAT_P=m
 CONFIG_TEST_STACKINIT=m
+CONFIG_TEST_MEMINIT=m
 CONFIG_EARLY_PRINTK=y
index f41c34d..ae3b2d4 100644 (file)
@@ -118,6 +118,7 @@ CONFIG_NFT_XFRM=m
 CONFIG_NFT_SOCKET=m
 CONFIG_NFT_OSF=m
 CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NFT_FIB_NETDEV=m
@@ -243,9 +244,11 @@ CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_IP6_NF_TARGET_NPT=m
-CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
 CONFIG_NFT_BRIDGE_REJECT=m
 CONFIG_NF_LOG_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -312,7 +315,6 @@ CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
@@ -403,7 +405,6 @@ CONFIG_RTC_DRV_GENERIC=m
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_DAX=m
-# CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
@@ -526,6 +527,7 @@ CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_ADIANTUM=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_XXHASH=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -535,8 +537,10 @@ CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_SM3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
@@ -571,6 +575,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_WW_MUTEX_SELFTEST=m
 CONFIG_TEST_LIST_SORT=m
 CONFIG_TEST_SORT=m
+CONFIG_REED_SOLOMON_TEST=m
 CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
@@ -589,6 +594,7 @@ CONFIG_TEST_IDA=m
 CONFIG_TEST_VMALLOC=m
 CONFIG_TEST_USER_COPY=m
 CONFIG_TEST_BPF=m
+CONFIG_TEST_BLACKHOLE_DEV=m
 CONFIG_FIND_BIT_BENCHMARK=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_SYSCTL=m
@@ -597,4 +603,5 @@ CONFIG_TEST_STATIC_KEYS=m
 CONFIG_TEST_KMOD=m
 CONFIG_TEST_MEMCAT_P=m
 CONFIG_TEST_STACKINIT=m
+CONFIG_TEST_MEMINIT=m
 CONFIG_EARLY_PRINTK=y
index c9d2cb0..cd61ef1 100644 (file)
@@ -119,6 +119,7 @@ CONFIG_NFT_XFRM=m
 CONFIG_NFT_SOCKET=m
 CONFIG_NFT_OSF=m
 CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NFT_FIB_NETDEV=m
@@ -244,9 +245,11 @@ CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_IP6_NF_TARGET_NPT=m
-CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
 CONFIG_NFT_BRIDGE_REJECT=m
 CONFIG_NF_LOG_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -320,7 +323,6 @@ CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
@@ -421,7 +423,6 @@ CONFIG_RTC_DRV_GENERIC=m
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_DAX=m
-# CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
@@ -544,6 +545,7 @@ CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_ADIANTUM=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_XXHASH=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -553,8 +555,10 @@ CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_SM3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
@@ -589,6 +593,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_WW_MUTEX_SELFTEST=m
 CONFIG_TEST_LIST_SORT=m
 CONFIG_TEST_SORT=m
+CONFIG_REED_SOLOMON_TEST=m
 CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
@@ -607,6 +612,7 @@ CONFIG_TEST_IDA=m
 CONFIG_TEST_VMALLOC=m
 CONFIG_TEST_USER_COPY=m
 CONFIG_TEST_BPF=m
+CONFIG_TEST_BLACKHOLE_DEV=m
 CONFIG_FIND_BIT_BENCHMARK=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_SYSCTL=m
@@ -615,4 +621,5 @@ CONFIG_TEST_STATIC_KEYS=m
 CONFIG_TEST_KMOD=m
 CONFIG_TEST_MEMCAT_P=m
 CONFIG_TEST_STACKINIT=m
+CONFIG_TEST_MEMINIT=m
 CONFIG_EARLY_PRINTK=y
index 79a64fd..151f537 100644 (file)
@@ -115,6 +115,7 @@ CONFIG_NFT_XFRM=m
 CONFIG_NFT_SOCKET=m
 CONFIG_NFT_OSF=m
 CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NFT_FIB_NETDEV=m
@@ -240,9 +241,11 @@ CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_IP6_NF_TARGET_NPT=m
-CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
 CONFIG_NFT_BRIDGE_REJECT=m
 CONFIG_NF_LOG_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -309,7 +312,6 @@ CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
@@ -405,7 +407,6 @@ CONFIG_RTC_DRV_GENERIC=m
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_DAX=m
-# CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
@@ -528,6 +529,7 @@ CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_ADIANTUM=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_XXHASH=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -537,8 +539,10 @@ CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_SM3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
@@ -573,6 +577,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_WW_MUTEX_SELFTEST=m
 CONFIG_TEST_LIST_SORT=m
 CONFIG_TEST_SORT=m
+CONFIG_REED_SOLOMON_TEST=m
 CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
@@ -591,6 +596,7 @@ CONFIG_TEST_IDA=m
 CONFIG_TEST_VMALLOC=m
 CONFIG_TEST_USER_COPY=m
 CONFIG_TEST_BPF=m
+CONFIG_TEST_BLACKHOLE_DEV=m
 CONFIG_FIND_BIT_BENCHMARK=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_SYSCTL=m
@@ -599,3 +605,4 @@ CONFIG_TEST_STATIC_KEYS=m
 CONFIG_TEST_KMOD=m
 CONFIG_TEST_MEMCAT_P=m
 CONFIG_TEST_STACKINIT=m
+CONFIG_TEST_MEMINIT=m
index e3402a5..1dcb0ee 100644 (file)
@@ -115,6 +115,7 @@ CONFIG_NFT_XFRM=m
 CONFIG_NFT_SOCKET=m
 CONFIG_NFT_OSF=m
 CONFIG_NFT_TPROXY=m
+CONFIG_NFT_SYNPROXY=m
 CONFIG_NFT_DUP_NETDEV=m
 CONFIG_NFT_FWD_NETDEV=m
 CONFIG_NFT_FIB_NETDEV=m
@@ -240,9 +241,11 @@ CONFIG_IP6_NF_RAW=m
 CONFIG_IP6_NF_NAT=m
 CONFIG_IP6_NF_TARGET_MASQUERADE=m
 CONFIG_IP6_NF_TARGET_NPT=m
-CONFIG_NF_TABLES_BRIDGE=y
+CONFIG_NF_TABLES_BRIDGE=m
+CONFIG_NFT_BRIDGE_META=m
 CONFIG_NFT_BRIDGE_REJECT=m
 CONFIG_NF_LOG_BRIDGE=m
+CONFIG_NF_CONNTRACK_BRIDGE=m
 CONFIG_BRIDGE_NF_EBTABLES=m
 CONFIG_BRIDGE_EBT_BROUTE=m
 CONFIG_BRIDGE_EBT_T_FILTER=m
@@ -309,7 +312,6 @@ CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=m
-CONFIG_CHR_DEV_OSST=m
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
 CONFIG_CHR_DEV_SG=m
@@ -404,7 +406,6 @@ CONFIG_RTC_DRV_GENERIC=m
 # CONFIG_VIRTIO_MENU is not set
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_DAX=m
-# CONFIG_VALIDATE_FS_PARSER is not set
 CONFIG_EXT4_FS=y
 CONFIG_REISERFS_FS=m
 CONFIG_JFS_FS=m
@@ -527,6 +528,7 @@ CONFIG_CRYPTO_KEYWRAP=m
 CONFIG_CRYPTO_ADIANTUM=m
 CONFIG_CRYPTO_XCBC=m
 CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_XXHASH=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_RMD128=m
 CONFIG_CRYPTO_RMD160=m
@@ -536,8 +538,10 @@ CONFIG_CRYPTO_SHA3=m
 CONFIG_CRYPTO_SM3=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_AES_TI=m
 CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
 CONFIG_CRYPTO_BLOWFISH=m
 CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST5=m
@@ -572,6 +576,7 @@ CONFIG_MAGIC_SYSRQ=y
 CONFIG_WW_MUTEX_SELFTEST=m
 CONFIG_TEST_LIST_SORT=m
 CONFIG_TEST_SORT=m
+CONFIG_REED_SOLOMON_TEST=m
 CONFIG_ATOMIC64_SELFTEST=m
 CONFIG_ASYNC_RAID6_TEST=m
 CONFIG_TEST_HEXDUMP=m
@@ -590,6 +595,7 @@ CONFIG_TEST_IDA=m
 CONFIG_TEST_VMALLOC=m
 CONFIG_TEST_USER_COPY=m
 CONFIG_TEST_BPF=m
+CONFIG_TEST_BLACKHOLE_DEV=m
 CONFIG_FIND_BIT_BENCHMARK=m
 CONFIG_TEST_FIRMWARE=m
 CONFIG_TEST_SYSCTL=m
@@ -598,4 +604,5 @@ CONFIG_TEST_STATIC_KEYS=m
 CONFIG_TEST_KMOD=m
 CONFIG_TEST_MEMCAT_P=m
 CONFIG_TEST_STACKINIT=m
+CONFIG_TEST_MEMINIT=m
 CONFIG_EARLY_PRINTK=y
index 5330082..9a038a3 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <linux/types.h>
 #include <asm/bootinfo-atari.h>
-#include <asm/raw_io.h>
 #include <asm/kmap.h>
 
 extern u_long atari_mch_cookie;
@@ -132,14 +131,6 @@ extern struct atari_hw_present atari_hw_present;
  */
 
 
-#define atari_readb   raw_inb
-#define atari_writeb  raw_outb
-
-#define atari_inb_p   raw_inb
-#define atari_outb_p  raw_outb
-
-
-
 #include <linux/mm.h>
 #include <asm/cacheflush.h>
 
@@ -170,7 +161,7 @@ static inline void dma_cache_maintenance( unsigned long paddr,
 #define TT_HIGH 6
 
 #define SHF_BAS (0xffff8200)
-struct SHIFTER
+struct SHIFTER_ST
  {
        u_char pad1;
        u_char bas_hi;
@@ -187,7 +178,7 @@ struct SHIFTER
        u_char pad7;
        u_char bas_lo;
  };
-# define shifter ((*(volatile struct SHIFTER *)SHF_BAS))
+# define shifter_st ((*(volatile struct SHIFTER_ST *)SHF_BAS))
 
 #define SHF_FBAS (0xffff820e)
 struct SHIFTER_F030
index 6c03ca5..819f611 100644 (file)
 #include <asm-generic/iomap.h>
 
 #ifdef CONFIG_ATARI
-#include <asm/atarihw.h>
+#define atari_readb   raw_inb
+#define atari_writeb  raw_outb
+
+#define atari_inb_p   raw_inb
+#define atari_outb_p  raw_outb
 #endif
 
 
index aac7f04..421b6c9 100644 (file)
@@ -28,14 +28,8 @@ static inline void __iomem *ioremap(unsigned long physaddr, unsigned long size)
        return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
 }
 
-#define ioremap_nocache ioremap_nocache
-static inline void __iomem *ioremap_nocache(unsigned long physaddr,
-                                           unsigned long size)
-{
-       return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
-}
-
-#define ioremap_uc ioremap_nocache
+#define ioremap_nocache ioremap
+#define ioremap_uc ioremap
 #define ioremap_wt ioremap_wt
 static inline void __iomem *ioremap_wt(unsigned long physaddr,
                                       unsigned long size)
@@ -43,13 +37,6 @@ static inline void __iomem *ioremap_wt(unsigned long physaddr,
        return __ioremap(physaddr, size, IOMAP_WRITETHROUGH);
 }
 
-#define ioremap_fullcache ioremap_fullcache
-static inline void __iomem *ioremap_fullcache(unsigned long physaddr,
-                                             unsigned long size)
-{
-       return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
-}
-
 #define memset_io memset_io
 static inline void memset_io(volatile void __iomem *addr, unsigned char val,
                             int count)
index d9a08be..8a43bab 100644 (file)
@@ -4,6 +4,7 @@
 
 #include <linux/seq_file.h>
 #include <linux/interrupt.h>
+#include <linux/irq.h>
 
 #include <asm/bootinfo-mac.h>
 
@@ -82,11 +83,11 @@ struct mac_model
 #define MAC_EXP_PDS_NUBUS      3 /* Accepts PDS card and/or NuBus card(s) */
 #define MAC_EXP_PDS_COMM       4 /* Accepts PDS card or Comm Slot card */
 
-#define MAC_FLOPPY_IWM         0
-#define MAC_FLOPPY_SWIM_ADDR1  1
-#define MAC_FLOPPY_SWIM_ADDR2  2
-#define MAC_FLOPPY_SWIM_IOP    3
-#define MAC_FLOPPY_AV          4
+#define MAC_FLOPPY_UNSUPPORTED 0
+#define MAC_FLOPPY_SWIM_IOP    1
+#define MAC_FLOPPY_OLD         2
+#define MAC_FLOPPY_QUADRA      3
+#define MAC_FLOPPY_LC          4
 
 extern struct mac_model *macintosh_config;
 
index 205ac75..611f73b 100644 (file)
@@ -209,7 +209,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_IWM,
+               .floppy_type    = MAC_FLOPPY_UNSUPPORTED, /* IWM */
        },
 
        /*
@@ -224,7 +224,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_IWM,
+               .floppy_type    = MAC_FLOPPY_UNSUPPORTED, /* IWM */
        }, {
                .ident          = MAC_MODEL_IIX,
                .name           = "IIx",
@@ -233,7 +233,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_IICX,
                .name           = "IIcx",
@@ -242,7 +242,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_SE30,
                .name           = "SE/30",
@@ -251,7 +251,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        },
 
        /*
@@ -269,7 +269,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_IIFX,
                .name           = "IIfx",
@@ -278,7 +278,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_IIFX,
                .scc_type       = MAC_SCC_IOP,
                .expansion_type = MAC_EXP_PDS_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_IOP,
+               .floppy_type    = MAC_FLOPPY_SWIM_IOP, /* SWIM */
        }, {
                .ident          = MAC_MODEL_IISI,
                .name           = "IIsi",
@@ -287,7 +287,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_IIVI,
                .name           = "IIvi",
@@ -296,7 +296,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM */
        }, {
                .ident          = MAC_MODEL_IIVX,
                .name           = "IIvx",
@@ -305,7 +305,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM */
        },
 
        /*
@@ -319,7 +319,7 @@ static struct mac_model mac_data_table[] = {
                .via_type       = MAC_VIA_IICI,
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM */
        }, {
                .ident          = MAC_MODEL_CCL,
                .name           = "Color Classic",
@@ -328,7 +328,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_CCLII,
                .name           = "Color Classic II",
@@ -337,7 +337,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM 2 */
        },
 
        /*
@@ -352,7 +352,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM */
        }, {
                .ident          = MAC_MODEL_LCII,
                .name           = "LC II",
@@ -361,7 +361,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM */
        }, {
                .ident          = MAC_MODEL_LCIII,
                .name           = "LC III",
@@ -370,7 +370,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM 2 */
        },
 
        /*
@@ -391,7 +391,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_QUADRA,
                .scc_type       = MAC_SCC_QUADRA,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_Q605_ACC,
                .name           = "Quadra 605",
@@ -400,7 +400,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_QUADRA,
                .scc_type       = MAC_SCC_QUADRA,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_Q610,
                .name           = "Quadra 610",
@@ -410,7 +410,7 @@ static struct mac_model mac_data_table[] = {
                .scc_type       = MAC_SCC_QUADRA,
                .ether_type     = MAC_ETHER_SONIC,
                .expansion_type = MAC_EXP_PDS_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_Q630,
                .name           = "Quadra 630",
@@ -420,7 +420,7 @@ static struct mac_model mac_data_table[] = {
                .ide_type       = MAC_IDE_QUADRA,
                .scc_type       = MAC_SCC_QUADRA,
                .expansion_type = MAC_EXP_PDS_COMM,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_Q650,
                .name           = "Quadra 650",
@@ -430,7 +430,7 @@ static struct mac_model mac_data_table[] = {
                .scc_type       = MAC_SCC_QUADRA,
                .ether_type     = MAC_ETHER_SONIC,
                .expansion_type = MAC_EXP_PDS_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM 2 */
        },
        /* The Q700 does have a NS Sonic */
        {
@@ -442,7 +442,7 @@ static struct mac_model mac_data_table[] = {
                .scc_type       = MAC_SCC_QUADRA,
                .ether_type     = MAC_ETHER_SONIC,
                .expansion_type = MAC_EXP_PDS_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM */
        }, {
                .ident          = MAC_MODEL_Q800,
                .name           = "Quadra 800",
@@ -452,7 +452,7 @@ static struct mac_model mac_data_table[] = {
                .scc_type       = MAC_SCC_QUADRA,
                .ether_type     = MAC_ETHER_SONIC,
                .expansion_type = MAC_EXP_PDS_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_Q840,
                .name           = "Quadra 840AV",
@@ -462,7 +462,7 @@ static struct mac_model mac_data_table[] = {
                .scc_type       = MAC_SCC_PSC,
                .ether_type     = MAC_ETHER_MACE,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_AV,
+               .floppy_type    = MAC_FLOPPY_UNSUPPORTED, /* New Age */
        }, {
                .ident          = MAC_MODEL_Q900,
                .name           = "Quadra 900",
@@ -472,7 +472,7 @@ static struct mac_model mac_data_table[] = {
                .scc_type       = MAC_SCC_IOP,
                .ether_type     = MAC_ETHER_SONIC,
                .expansion_type = MAC_EXP_PDS_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_IOP,
+               .floppy_type    = MAC_FLOPPY_SWIM_IOP, /* SWIM */
        }, {
                .ident          = MAC_MODEL_Q950,
                .name           = "Quadra 950",
@@ -482,7 +482,7 @@ static struct mac_model mac_data_table[] = {
                .scc_type       = MAC_SCC_IOP,
                .ether_type     = MAC_ETHER_SONIC,
                .expansion_type = MAC_EXP_PDS_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_IOP,
+               .floppy_type    = MAC_FLOPPY_SWIM_IOP, /* SWIM */
        },
 
        /*
@@ -497,7 +497,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_P475,
                .name           = "Performa 475",
@@ -506,7 +506,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_QUADRA,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_P475F,
                .name           = "Performa 475",
@@ -515,7 +515,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_QUADRA,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_P520,
                .name           = "Performa 520",
@@ -524,7 +524,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_P550,
                .name           = "Performa 550",
@@ -533,7 +533,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM 2 */
        },
        /* These have the comm slot, and therefore possibly SONIC ethernet */
        {
@@ -544,7 +544,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_QUADRA,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS_COMM,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_P588,
                .name           = "Performa 588",
@@ -554,7 +554,7 @@ static struct mac_model mac_data_table[] = {
                .ide_type       = MAC_IDE_QUADRA,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_PDS_COMM,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_TV,
                .name           = "TV",
@@ -562,7 +562,7 @@ static struct mac_model mac_data_table[] = {
                .via_type       = MAC_VIA_IICI,
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_P600,
                .name           = "Performa 600",
@@ -571,7 +571,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_LC,
                .scc_type       = MAC_SCC_II,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_LC, /* SWIM */
        },
 
        /*
@@ -588,7 +588,7 @@ static struct mac_model mac_data_table[] = {
                .scc_type       = MAC_SCC_QUADRA,
                .ether_type     = MAC_ETHER_SONIC,
                .expansion_type = MAC_EXP_PDS_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_C650,
                .name           = "Centris 650",
@@ -598,7 +598,7 @@ static struct mac_model mac_data_table[] = {
                .scc_type       = MAC_SCC_QUADRA,
                .ether_type     = MAC_ETHER_SONIC,
                .expansion_type = MAC_EXP_PDS_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR1,
+               .floppy_type    = MAC_FLOPPY_QUADRA, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_C660,
                .name           = "Centris 660AV",
@@ -608,7 +608,7 @@ static struct mac_model mac_data_table[] = {
                .scc_type       = MAC_SCC_PSC,
                .ether_type     = MAC_ETHER_MACE,
                .expansion_type = MAC_EXP_PDS_NUBUS,
-               .floppy_type    = MAC_FLOPPY_AV,
+               .floppy_type    = MAC_FLOPPY_UNSUPPORTED, /* New Age */
        },
 
        /*
@@ -624,7 +624,7 @@ static struct mac_model mac_data_table[] = {
                .via_type       = MAC_VIA_QUADRA,
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_QUADRA,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB145,
                .name           = "PowerBook 145",
@@ -632,7 +632,7 @@ static struct mac_model mac_data_table[] = {
                .via_type       = MAC_VIA_QUADRA,
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_QUADRA,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB150,
                .name           = "PowerBook 150",
@@ -641,7 +641,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_OLD,
                .ide_type       = MAC_IDE_PB,
                .scc_type       = MAC_SCC_QUADRA,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB160,
                .name           = "PowerBook 160",
@@ -649,7 +649,7 @@ static struct mac_model mac_data_table[] = {
                .via_type       = MAC_VIA_QUADRA,
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_QUADRA,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB165,
                .name           = "PowerBook 165",
@@ -657,7 +657,7 @@ static struct mac_model mac_data_table[] = {
                .via_type       = MAC_VIA_QUADRA,
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_QUADRA,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB165C,
                .name           = "PowerBook 165c",
@@ -665,7 +665,7 @@ static struct mac_model mac_data_table[] = {
                .via_type       = MAC_VIA_QUADRA,
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_QUADRA,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB170,
                .name           = "PowerBook 170",
@@ -673,7 +673,7 @@ static struct mac_model mac_data_table[] = {
                .via_type       = MAC_VIA_QUADRA,
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_QUADRA,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB180,
                .name           = "PowerBook 180",
@@ -681,7 +681,7 @@ static struct mac_model mac_data_table[] = {
                .via_type       = MAC_VIA_QUADRA,
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_QUADRA,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB180C,
                .name           = "PowerBook 180c",
@@ -689,7 +689,7 @@ static struct mac_model mac_data_table[] = {
                .via_type       = MAC_VIA_QUADRA,
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_QUADRA,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB190,
                .name           = "PowerBook 190",
@@ -698,7 +698,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_OLD,
                .ide_type       = MAC_IDE_BABOON,
                .scc_type       = MAC_SCC_QUADRA,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM 2 */
        }, {
                .ident          = MAC_MODEL_PB520,
                .name           = "PowerBook 520",
@@ -707,7 +707,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_OLD,
                .scc_type       = MAC_SCC_QUADRA,
                .ether_type     = MAC_ETHER_SONIC,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM 2 */
        },
 
        /*
@@ -724,7 +724,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_DUO,
                .scc_type       = MAC_SCC_QUADRA,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB230,
                .name           = "PowerBook Duo 230",
@@ -733,7 +733,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_DUO,
                .scc_type       = MAC_SCC_QUADRA,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB250,
                .name           = "PowerBook Duo 250",
@@ -742,7 +742,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_DUO,
                .scc_type       = MAC_SCC_QUADRA,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB270C,
                .name           = "PowerBook Duo 270c",
@@ -751,7 +751,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_DUO,
                .scc_type       = MAC_SCC_QUADRA,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB280,
                .name           = "PowerBook Duo 280",
@@ -760,7 +760,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_DUO,
                .scc_type       = MAC_SCC_QUADRA,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        }, {
                .ident          = MAC_MODEL_PB280C,
                .name           = "PowerBook Duo 280c",
@@ -769,7 +769,7 @@ static struct mac_model mac_data_table[] = {
                .scsi_type      = MAC_SCSI_DUO,
                .scc_type       = MAC_SCC_QUADRA,
                .expansion_type = MAC_EXP_NUBUS,
-               .floppy_type    = MAC_FLOPPY_SWIM_ADDR2,
+               .floppy_type    = MAC_FLOPPY_OLD, /* SWIM */
        },
 
        /*
@@ -960,7 +960,7 @@ static const struct resource mac_scsi_ccl_rsrc[] __initconst = {
 
 int __init mac_platform_init(void)
 {
-       u8 *swim_base;
+       phys_addr_t swim_base = 0;
 
        if (!MACH_IS_MAC)
                return -ENODEV;
@@ -977,22 +977,22 @@ int __init mac_platform_init(void)
         */
 
        switch (macintosh_config->floppy_type) {
-       case MAC_FLOPPY_SWIM_ADDR1:
-               swim_base = (u8 *)(VIA1_BASE + 0x1E000);
+       case MAC_FLOPPY_QUADRA:
+               swim_base = 0x5001E000;
                break;
-       case MAC_FLOPPY_SWIM_ADDR2:
-               swim_base = (u8 *)(VIA1_BASE + 0x16000);
+       case MAC_FLOPPY_OLD:
+               swim_base = 0x50016000;
                break;
-       default:
-               swim_base = NULL;
+       case MAC_FLOPPY_LC:
+               swim_base = 0x50F16000;
                break;
        }
 
        if (swim_base) {
                struct resource swim_rsrc = {
                        .flags = IORESOURCE_MEM,
-                       .start = (resource_size_t)swim_base,
-                       .end   = (resource_size_t)swim_base + 0x1FFF,
+                       .start = swim_base,
+                       .end   = swim_base + 0x1FFF,
                };
 
                platform_device_register_simple("swim", -1, &swim_rsrc, 1);
index 6656602..f14ad05 100644 (file)
@@ -103,7 +103,6 @@ CONFIG_FW_LOADER=m
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
-CONFIG_SGI_IOC4=m
 CONFIG_EEPROM_LEGACY=y
 CONFIG_EEPROM_MAX6875=y
 CONFIG_IDE=y
index 572cab9..3708840 100644 (file)
@@ -46,7 +46,6 @@ CONFIG_CONNECTOR=y
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
 CONFIG_BLK_DEV_NBD=m
-CONFIG_SGI_IOC4=y
 CONFIG_RAID_ATTRS=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
index ae93a94..507ad91 100644 (file)
@@ -117,7 +117,6 @@ CONFIG_MTD_CFI_AMDSTD=y
 CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV_LOOP=m
 CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_SGI_IOC4=m
 CONFIG_SCSI=m
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=m
index 0f4b09f..8762e75 100644 (file)
@@ -198,7 +198,6 @@ CONFIG_BLK_DEV_SX8=m
 CONFIG_BLK_DEV_RAM=m
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_ATA_OVER_ETH=m
-CONFIG_SGI_IOC4=m
 CONFIG_RAID_ATTRS=m
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
index 6883ea4..bb0b1b2 100644 (file)
@@ -49,7 +49,6 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=9220
 CONFIG_CDROM_PKTCDVD=m
 CONFIG_ATA_OVER_ETH=m
-CONFIG_SGI_IOC4=m
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_IDETAPE=y
index fe61513..330b19f 100644 (file)
@@ -316,6 +316,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
                                regs->uregs[0] = -EINTR;
                                break;
                        }
+                       /* Else, fall through */
                case -ERESTARTNOINTR:
                        regs->uregs[0] = regs->orig_r0;
                        regs->ipc -= 4;
@@ -360,6 +361,7 @@ static void do_signal(struct pt_regs *regs)
                switch (regs->uregs[0]) {
                case -ERESTART_RESTARTBLOCK:
                        regs->uregs[15] = __NR_restart_syscall;
+                       /* Fall through */
                case -ERESTARTNOHAND:
                case -ERESTARTSYS:
                case -ERESTARTNOINTR:
index 6d732e4..2e757c7 100644 (file)
@@ -61,6 +61,8 @@ config PARISC
        select HAVE_KRETPROBES
        select HAVE_DYNAMIC_FTRACE if $(cc-option,-fpatchable-function-entry=1,1)
        select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE
+       select HAVE_KPROBES_ON_FTRACE
+       select HAVE_DYNAMIC_FTRACE_WITH_REGS
 
        help
          The PA-RISC microprocessor is designed by Hewlett-Packard and used
@@ -344,6 +346,29 @@ config NR_CPUS
        depends on SMP
        default "4"
 
+config KEXEC
+       bool "Kexec system call"
+       select KEXEC_CORE
+       help
+         kexec is a system call that implements the ability to shutdown your
+         current kernel, and to start another kernel.  It is like a reboot
+         but it is independent of the system firmware.   And like a reboot
+         you can start any kernel with it, not just Linux.
+
+         It is an ongoing process to be certain the hardware in a machine
+         shutdown, so do not be surprised if this code does not
+         initially work for you.
+
+config KEXEC_FILE
+       bool "kexec file based system call"
+       select KEXEC_CORE
+       select KEXEC_ELF
+       help
+         This enables the kexec_file_load() System call. This is
+         file based and takes file descriptors as system call argument
+         for kernel and initramfs as opposed to list of segments as
+         accepted by previous system call.
+
 endmenu
 
 
index 793d8ba..0ec54f4 100644 (file)
@@ -8,6 +8,7 @@
 #define ALT_COND_NO_ICACHE     0x04    /* if system has no i-cache  */
 #define ALT_COND_NO_SPLIT_TLB  0x08    /* if split_tlb == 0  */
 #define ALT_COND_NO_IOC_FDC    0x10    /* if I/O cache does not need flushes */
+#define ALT_COND_RUN_ON_QEMU   0x20    /* if running on QEMU */
 
 #define INSN_PxTLB     0x02            /* modify pdtlb, pitlb */
 #define INSN_NOP       0x08000240      /* nop */
@@ -21,7 +22,7 @@
 
 struct alt_instr {
        s32 orig_offset;        /* offset to original instructions */
-       u32 len;                /* end of original instructions */
+       s32 len;                /* end of original instructions */
        u32 cond;               /* see ALT_COND_XXX */
        u32 replacement;        /* replacement instruction or code */
 };
@@ -40,12 +41,20 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end,
 
 #else
 
+/* to replace one single instructions by a new instruction */
 #define ALTERNATIVE(from, to, cond, replacement)\
        .section .altinstructions, "aw" !       \
        .word (from - .), (to - from)/4 !       \
        .word cond, replacement         !       \
        .previous
 
+/* to replace multiple instructions by new code */
+#define ALTERNATIVE_CODE(from, num_instructions, cond, new_instr_ptr)\
+       .section .altinstructions, "aw" !       \
+       .word (from - .), -num_instructions !   \
+       .word cond, (new_instr_ptr - .) !       \
+       .previous
+
 #endif  /*  __ASSEMBLY__  */
 
 #endif /* __ASM_PARISC_ALTERNATIVE_H */
index 288da73..e480b2c 100644 (file)
@@ -30,6 +30,7 @@
 enum fixed_addresses {
        /* Support writing RO kernel text via kprobes, jump labels, etc. */
        FIX_TEXT_POKE0,
+       FIX_TEXT_KEXEC,
        FIX_BITMAP_COUNT
 };
 
index 958c0aa..a7cf0d0 100644 (file)
@@ -8,6 +8,7 @@ extern void mcount(void);
 #define MCOUNT_ADDR            ((unsigned long)mcount)
 #define MCOUNT_INSN_SIZE       4
 #define CC_USING_NOP_MCOUNT
+#define ARCH_SUPPORTS_FTRACE_OPS 1
 extern unsigned long sys_call_table[];
 
 extern unsigned long return_address(unsigned int);
diff --git a/arch/parisc/include/asm/kexec.h b/arch/parisc/include/asm/kexec.h
new file mode 100644 (file)
index 0000000..a99ea74
--- /dev/null
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_PARISC_KEXEC_H
+#define _ASM_PARISC_KEXEC_H
+
+#ifdef CONFIG_KEXEC
+
+/* Maximum physical address we can use pages from */
+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
+/* Maximum address we can reach in physical address mode */
+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
+/* Maximum address we can use for the control code buffer */
+#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)
+
+#define KEXEC_CONTROL_PAGE_SIZE        4096
+
+#define KEXEC_ARCH KEXEC_ARCH_PARISC
+#define ARCH_HAS_KIMAGE_ARCH
+
+#ifndef __ASSEMBLY__
+
+struct kimage_arch {
+       unsigned long initrd_start;
+       unsigned long initrd_end;
+       unsigned long cmdline;
+};
+
+static inline void crash_setup_regs(struct pt_regs *newregs,
+                                   struct pt_regs *oldregs)
+{
+       /* Dummy implementation for now */
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* CONFIG_KEXEC */
+
+#endif /* _ASM_PARISC_KEXEC_H */
index 19bb2e4..b388d81 100644 (file)
@@ -91,6 +91,7 @@ int pdc_sti_call(unsigned long func, unsigned long flags,
                  unsigned long inptr, unsigned long outputr,
                  unsigned long glob_cfg);
 
+int __pdc_cpu_rendezvous(void);
 static inline char * os_id_to_string(u16 os_id) {
        switch(os_id) {
        case OS_ID_NONE:        return "No OS";
index f6e1132..4a0c9db 100644 (file)
@@ -8,4 +8,19 @@ extern void * memset(void *, int, size_t);
 #define __HAVE_ARCH_MEMCPY
 void * memcpy(void * dest,const void *src,size_t count);
 
+#define __HAVE_ARCH_STRLEN
+extern size_t strlen(const char *s);
+
+#define __HAVE_ARCH_STRCPY
+extern char *strcpy(char *dest, const char *src);
+
+#define __HAVE_ARCH_STRNCPY
+extern char *strncpy(char *dest, const char *src, size_t count);
+
+#define __HAVE_ARCH_STRCAT
+extern char *strcat(char *dest, const char *src);
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *, int, size_t);
+
 #endif
index c232266..2663c8f 100644 (file)
@@ -37,3 +37,5 @@ obj-$(CONFIG_FUNCTION_GRAPH_TRACER)   += ftrace.o
 obj-$(CONFIG_JUMP_LABEL)               += jump_label.o
 obj-$(CONFIG_KGDB)                     += kgdb.o
 obj-$(CONFIG_KPROBES)                  += kprobes.o
+obj-$(CONFIG_KEXEC)                    += kexec.o relocate_kernel.o
+obj-$(CONFIG_KEXEC_FILE)               += kexec_file.o
index ca1f5ca..3c66d5c 100644 (file)
@@ -28,7 +28,8 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
 
        for (entry = start; entry < end; entry++, index++) {
 
-               u32 *from, len, cond, replacement;
+               u32 *from, cond, replacement;
+               s32 len;
 
                from = (u32 *)((ulong)&entry->orig_offset + entry->orig_offset);
                len = entry->len;
@@ -49,6 +50,8 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
                        continue;
                if ((cond & ALT_COND_NO_ICACHE) && (cache_info.ic_size != 0))
                        continue;
+               if ((cond & ALT_COND_RUN_ON_QEMU) && !running_on_qemu)
+                       continue;
 
                /*
                 * If the PDC_MODEL capabilities has Non-coherent IO-PDIR bit
@@ -74,11 +77,19 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
                if (replacement == INSN_NOP && len > 1)
                        replacement = 0xe8000002 + (len-2)*8; /* "b,n .+8" */
 
-               pr_debug("Do    %d: Cond 0x%x, Replace %02d instructions @ 0x%px with 0x%08x\n",
-                       index, cond, len, from, replacement);
-
-               /* Replace instruction */
-               *from = replacement;
+               pr_debug("ALTERNATIVE %3d: Cond %2x, Replace %2d instructions to 0x%08x @ 0x%px (%pS)\n",
+                       index, cond, len, replacement, from, from);
+
+               if (len < 0) {
+                       /* Replace multiple instruction by new code */
+                       u32 *source;
+                       len = -len;
+                       source = (u32 *)((ulong)&entry->replacement + entry->replacement);
+                       memcpy(from, source, 4 * len);
+               } else {
+                       /* Replace by one instruction */
+                       *from = replacement;
+               }
                applied++;
        }
 
index d9d3387..1d1d748 100644 (file)
@@ -1996,6 +1996,7 @@ _mcount:
         * calling mcount(), and 2 instructions for ftrace_stub().  That way we
         * have all on one L1 cacheline.
         */
+       ldi     0, %arg3
        b       ftrace_function_trampoline
        copy    %r3, %arg2      /* caller original %sp */
 ftrace_stub:
@@ -2048,6 +2049,7 @@ ftrace_caller:
        LDREG   0(%r3), %r25
        copy    %rp, %r26
        ldo     -8(%r25), %r25
+       ldi     0, %r23         /* no pt_regs */
        b,l     ftrace_function_trampoline, %rp
        copy    %r3, %r24
 
@@ -2075,6 +2077,103 @@ ftrace_caller:
 
 ENDPROC_CFI(ftrace_caller)
 
+#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS
+ENTRY_CFI(ftrace_regs_caller,caller,frame=FTRACE_FRAME_SIZE+PT_SZ_ALGN,
+       CALLS,SAVE_RP,SAVE_SP)
+ftrace_regs_caller:
+       .global ftrace_regs_caller
+
+       ldo     -FTRACE_FRAME_SIZE(%sp), %r1
+       STREG   %rp, -RP_OFFSET(%r1)
+
+       copy    %sp, %r1
+       ldo     PT_SZ_ALGN(%sp), %sp
+
+       STREG   %rp, PT_GR2(%r1)
+       STREG   %r3, PT_GR3(%r1)
+       STREG   %r4, PT_GR4(%r1)
+       STREG   %r5, PT_GR5(%r1)
+       STREG   %r6, PT_GR6(%r1)
+       STREG   %r7, PT_GR7(%r1)
+       STREG   %r8, PT_GR8(%r1)
+       STREG   %r9, PT_GR9(%r1)
+       STREG   %r10, PT_GR10(%r1)
+       STREG   %r11, PT_GR11(%r1)
+       STREG   %r12, PT_GR12(%r1)
+       STREG   %r13, PT_GR13(%r1)
+       STREG   %r14, PT_GR14(%r1)
+       STREG   %r15, PT_GR15(%r1)
+       STREG   %r16, PT_GR16(%r1)
+       STREG   %r17, PT_GR17(%r1)
+       STREG   %r18, PT_GR18(%r1)
+       STREG   %r19, PT_GR19(%r1)
+       STREG   %r20, PT_GR20(%r1)
+       STREG   %r21, PT_GR21(%r1)
+       STREG   %r22, PT_GR22(%r1)
+       STREG   %r23, PT_GR23(%r1)
+       STREG   %r24, PT_GR24(%r1)
+       STREG   %r25, PT_GR25(%r1)
+       STREG   %r26, PT_GR26(%r1)
+       STREG   %r27, PT_GR27(%r1)
+       STREG   %r28, PT_GR28(%r1)
+       STREG   %r29, PT_GR29(%r1)
+       STREG   %r30, PT_GR30(%r1)
+       STREG   %r31, PT_GR31(%r1)
+       mfctl   %cr11, %r26
+       STREG   %r26, PT_SAR(%r1)
+
+       copy    %rp, %r26
+       LDREG   -FTRACE_FRAME_SIZE-PT_SZ_ALGN(%sp), %r25
+       ldo     -8(%r25), %r25
+       copy    %r3, %arg2
+       b,l     ftrace_function_trampoline, %rp
+       copy    %r1, %arg3 /* struct pt_regs */
+
+       ldo     -PT_SZ_ALGN(%sp), %r1
+
+       LDREG   PT_SAR(%r1), %rp
+       mtctl   %rp, %cr11
+
+       LDREG   PT_GR2(%r1), %rp
+       LDREG   PT_GR3(%r1), %r3
+       LDREG   PT_GR4(%r1), %r4
+       LDREG   PT_GR5(%r1), %r5
+       LDREG   PT_GR6(%r1), %r6
+       LDREG   PT_GR7(%r1), %r7
+       LDREG   PT_GR8(%r1), %r8
+       LDREG   PT_GR9(%r1), %r9
+       LDREG   PT_GR10(%r1),%r10
+       LDREG   PT_GR11(%r1),%r11
+       LDREG   PT_GR12(%r1),%r12
+       LDREG   PT_GR13(%r1),%r13
+       LDREG   PT_GR14(%r1),%r14
+       LDREG   PT_GR15(%r1),%r15
+       LDREG   PT_GR16(%r1),%r16
+       LDREG   PT_GR17(%r1),%r17
+       LDREG   PT_GR18(%r1),%r18
+       LDREG   PT_GR19(%r1),%r19
+       LDREG   PT_GR20(%r1),%r20
+       LDREG   PT_GR21(%r1),%r21
+       LDREG   PT_GR22(%r1),%r22
+       LDREG   PT_GR23(%r1),%r23
+       LDREG   PT_GR24(%r1),%r24
+       LDREG   PT_GR25(%r1),%r25
+       LDREG   PT_GR26(%r1),%r26
+       LDREG   PT_GR27(%r1),%r27
+       LDREG   PT_GR28(%r1),%r28
+       LDREG   PT_GR29(%r1),%r29
+       LDREG   PT_GR30(%r1),%r30
+       LDREG   PT_GR31(%r1),%r31
+
+       ldo     -PT_SZ_ALGN(%sp), %sp
+       LDREGM  -FTRACE_FRAME_SIZE(%sp), %r1
+       /* Adjust return point to jump back to beginning of traced function */
+       ldo     -4(%r1), %r1
+       bv,n    (%r1)
+
+ENDPROC_CFI(ftrace_regs_caller)
+
+#endif
 #endif
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
index 58cc08e..1d976f2 100644 (file)
@@ -312,6 +312,19 @@ int pdc_chassis_disp(unsigned long disp)
 }
 
 /**
+ * pdc_cpu_rendenzvous - Stop currently executing CPU
+ * @retval: -1 on error, 0 on success
+ */
+int __pdc_cpu_rendezvous(void)
+{
+       if (is_pdc_pat())
+               return mem_pdc_call(PDC_PAT_CPU, PDC_PAT_CPU_RENDEZVOUS);
+       else
+               return mem_pdc_call(PDC_PROC, 1, 0);
+}
+
+
+/**
  * pdc_chassis_warn - Fetches chassis warnings
  * @retval: -1 on error, 0 on success
  */
index b6fb30f..b836fc6 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/init.h>
 #include <linux/ftrace.h>
 #include <linux/uaccess.h>
+#include <linux/kprobes.h>
+#include <linux/ptrace.h>
 
 #include <asm/assembly.h>
 #include <asm/sections.h>
@@ -48,17 +50,22 @@ static void __hot prepare_ftrace_return(unsigned long *parent,
 
 void notrace __hot ftrace_function_trampoline(unsigned long parent,
                                unsigned long self_addr,
-                               unsigned long org_sp_gr3)
+                               unsigned long org_sp_gr3,
+                               struct pt_regs *regs)
 {
 #ifndef CONFIG_DYNAMIC_FTRACE
        extern ftrace_func_t ftrace_trace_function;
 #endif
-       if (ftrace_trace_function != ftrace_stub)
-               ftrace_trace_function(self_addr, parent, NULL, NULL);
+       extern struct ftrace_ops *function_trace_op;
+
+       if (function_trace_op->flags & FTRACE_OPS_FL_ENABLED &&
+           ftrace_trace_function != ftrace_stub)
+               ftrace_trace_function(self_addr, parent,
+                               function_trace_op, regs);
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
        if (ftrace_graph_return != (trace_func_graph_ret_t) ftrace_stub ||
-               ftrace_graph_entry != ftrace_graph_entry_stub) {
+           ftrace_graph_entry != ftrace_graph_entry_stub) {
                unsigned long *parent_rp;
 
                /* calculate pointer to %rp in stack */
@@ -96,6 +103,12 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
        return 0;
 }
 
+int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr,
+                       unsigned long addr)
+{
+       return 0;
+}
+
 unsigned long ftrace_call_adjust(unsigned long addr)
 {
        return addr+(FTRACE_PATCHABLE_FUNCTION_SIZE-1)*4;
@@ -187,3 +200,46 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
        return 0;
 }
 #endif
+
+#ifdef CONFIG_KPROBES_ON_FTRACE
+void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+                          struct ftrace_ops *ops, struct pt_regs *regs)
+{
+       struct kprobe_ctlblk *kcb;
+       struct kprobe *p = get_kprobe((kprobe_opcode_t *)ip);
+
+       if (unlikely(!p) || kprobe_disabled(p))
+               return;
+
+       if (kprobe_running()) {
+               kprobes_inc_nmissed_count(p);
+               return;
+       }
+
+       __this_cpu_write(current_kprobe, p);
+
+       kcb = get_kprobe_ctlblk();
+       kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+
+       regs->iaoq[0] = ip;
+       regs->iaoq[1] = ip + 4;
+
+       if (!p->pre_handler || !p->pre_handler(p, regs)) {
+               regs->iaoq[0] = ip + 4;
+               regs->iaoq[1] = ip + 8;
+
+               if (unlikely(p->post_handler)) {
+                       kcb->kprobe_status = KPROBE_HIT_SSDONE;
+                       p->post_handler(p, regs, 0);
+               }
+       }
+       __this_cpu_write(current_kprobe, NULL);
+}
+NOKPROBE_SYMBOL(kprobe_ftrace_handler);
+
+int arch_prepare_kprobe_ftrace(struct kprobe *p)
+{
+       p->ainsn.insn = NULL;
+       return 0;
+}
+#endif
diff --git a/arch/parisc/kernel/kexec.c b/arch/parisc/kernel/kexec.c
new file mode 100644 (file)
index 0000000..5eb7f30
--- /dev/null
@@ -0,0 +1,112 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <asm/cacheflush.h>
+#include <asm/sections.h>
+
+extern void relocate_new_kernel(unsigned long head,
+                               unsigned long start,
+                               unsigned long phys);
+
+extern const unsigned int relocate_new_kernel_size;
+extern unsigned int kexec_initrd_start_offset;
+extern unsigned int kexec_initrd_end_offset;
+extern unsigned int kexec_cmdline_offset;
+extern unsigned int kexec_free_mem_offset;
+
+static void kexec_show_segment_info(const struct kimage *kimage,
+                                   unsigned long n)
+{
+       pr_debug("    segment[%lu]: %016lx - %016lx, 0x%lx bytes, %lu pages\n",
+                       n,
+                       kimage->segment[n].mem,
+                       kimage->segment[n].mem + kimage->segment[n].memsz,
+                       (unsigned long)kimage->segment[n].memsz,
+                       (unsigned long)kimage->segment[n].memsz /  PAGE_SIZE);
+}
+
+static void kexec_image_info(const struct kimage *kimage)
+{
+       unsigned long i;
+
+       pr_debug("kexec kimage info:\n");
+       pr_debug("  type:        %d\n", kimage->type);
+       pr_debug("  start:       %lx\n", kimage->start);
+       pr_debug("  head:        %lx\n", kimage->head);
+       pr_debug("  nr_segments: %lu\n", kimage->nr_segments);
+
+       for (i = 0; i < kimage->nr_segments; i++)
+               kexec_show_segment_info(kimage, i);
+
+#ifdef CONFIG_KEXEC_FILE
+       if (kimage->file_mode) {
+               pr_debug("cmdline: %.*s\n", (int)kimage->cmdline_buf_len,
+                        kimage->cmdline_buf);
+       }
+#endif
+}
+
+void machine_kexec_cleanup(struct kimage *kimage)
+{
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+}
+
+void machine_shutdown(void)
+{
+       smp_send_stop();
+       while (num_online_cpus() > 1) {
+               cpu_relax();
+               mdelay(1);
+       }
+}
+
+void machine_kexec(struct kimage *image)
+{
+#ifdef CONFIG_64BIT
+       Elf64_Fdesc desc;
+#endif
+       void (*reloc)(unsigned long head,
+                     unsigned long start,
+                     unsigned long phys);
+
+       unsigned long phys = page_to_phys(image->control_code_page);
+       void *virt = (void *)__fix_to_virt(FIX_TEXT_KEXEC);
+       struct kimage_arch *arch = &image->arch;
+
+       set_fixmap(FIX_TEXT_KEXEC, phys);
+
+       flush_cache_all();
+
+#ifdef CONFIG_64BIT
+       reloc = (void *)&desc;
+       desc.addr = (long long)virt;
+#else
+       reloc = (void *)virt;
+#endif
+
+       memcpy(virt, dereference_function_descriptor(relocate_new_kernel),
+               relocate_new_kernel_size);
+
+       *(unsigned long *)(virt + kexec_cmdline_offset) = arch->cmdline;
+       *(unsigned long *)(virt + kexec_initrd_start_offset) = arch->initrd_start;
+       *(unsigned long *)(virt + kexec_initrd_end_offset) = arch->initrd_end;
+       *(unsigned long *)(virt + kexec_free_mem_offset) = PAGE0->mem_free;
+
+       flush_cache_all();
+       flush_tlb_all();
+       local_irq_disable();
+
+       reloc(image->head & PAGE_MASK, image->start, phys);
+}
+
+int machine_kexec_prepare(struct kimage *image)
+{
+       kexec_image_info(image);
+       return 0;
+}
diff --git a/arch/parisc/kernel/kexec_file.c b/arch/parisc/kernel/kexec_file.c
new file mode 100644 (file)
index 0000000..8c53420
--- /dev/null
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Load ELF vmlinux file for the kexec_file_load syscall.
+ *
+ * Copyright (c) 2019 Sven Schnelle <svens@stackframe.org>
+ *
+ */
+#include <linux/elf.h>
+#include <linux/kexec.h>
+#include <linux/libfdt.h>
+#include <linux/module.h>
+#include <linux/of_fdt.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+static void *elf_load(struct kimage *image, char *kernel_buf,
+                       unsigned long kernel_len, char *initrd,
+                       unsigned long initrd_len, char *cmdline,
+                       unsigned long cmdline_len)
+{
+       int ret, i;
+       unsigned long kernel_load_addr;
+       struct elfhdr ehdr;
+       struct kexec_elf_info elf_info;
+       struct kexec_buf kbuf = { .image = image, .buf_min = 0,
+                                 .buf_max = -1UL, };
+
+       ret = kexec_build_elf_info(kernel_buf, kernel_len, &ehdr, &elf_info);
+       if (ret)
+               goto out;
+
+       ret = kexec_elf_load(image, &ehdr, &elf_info, &kbuf, &kernel_load_addr);
+       if (ret)
+               goto out;
+
+       image->start = __pa(elf_info.ehdr->e_entry);
+
+       for (i = 0; i < image->nr_segments; i++)
+               image->segment[i].mem = __pa(image->segment[i].mem);
+
+       pr_debug("Loaded the kernel at 0x%lx, entry at 0x%lx\n",
+                kernel_load_addr, image->start);
+
+       if (initrd != NULL) {
+               kbuf.buffer = initrd;
+               kbuf.bufsz = kbuf.memsz = initrd_len;
+               kbuf.buf_align = PAGE_SIZE;
+               kbuf.top_down = false;
+               kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+               ret = kexec_add_buffer(&kbuf);
+               if (ret)
+                       goto out;
+
+               pr_debug("Loaded initrd at 0x%lx\n", kbuf.mem);
+               image->arch.initrd_start = kbuf.mem;
+               image->arch.initrd_end = kbuf.mem + initrd_len;
+       }
+
+       if (cmdline != NULL) {
+               kbuf.buffer = cmdline;
+               kbuf.bufsz = kbuf.memsz = ALIGN(cmdline_len, 8);
+               kbuf.buf_align = PAGE_SIZE;
+               kbuf.top_down = false;
+               kbuf.buf_min = PAGE0->mem_free + PAGE_SIZE;
+               kbuf.buf_max = kernel_load_addr;
+               kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
+               ret = kexec_add_buffer(&kbuf);
+               if (ret)
+                       goto out;
+
+               pr_debug("Loaded cmdline at 0x%lx\n", kbuf.mem);
+               image->arch.cmdline = kbuf.mem;
+       }
+out:
+       return NULL;
+}
+
+const struct kexec_file_ops kexec_elf_ops = {
+       .probe = kexec_elf_probe,
+       .load = elf_load,
+};
+
+const struct kexec_file_ops * const kexec_file_loaders[] = {
+       &kexec_elf_ops,
+       NULL
+};
index 5d7f269..77ec518 100644 (file)
@@ -281,10 +281,6 @@ int __kprobes arch_trampoline_kprobe(struct kprobe *p)
 {
        return p->addr == trampoline_p.addr;
 }
-bool arch_kprobe_on_func_entry(unsigned long offset)
-{
-       return !offset;
-}
 
 int __init arch_init_kprobes(void)
 {
index df46b0e..fa092ed 100644 (file)
@@ -174,6 +174,15 @@ fdtdone:
 
 2:      bv             %r0(%r2)
        nop
+
+       /*
+        * When running in qemu, drop whole flush_tlb_all_local function and
+        * replace by one pdtlbe instruction, for which QEMU will drop all
+        * local TLB entries.
+        */
+3:     pdtlbe          %r0(%sr1,%r0)
+       bv,n            %r0(%r2)
+       ALTERNATIVE_CODE(flush_tlb_all_local, 2, ALT_COND_RUN_ON_QEMU, 3b)
 ENDPROC_CFI(flush_tlb_all_local)
 
        .import cache_info,data
index e8a6a75..8ed409e 100644 (file)
 
 #include <linux/string.h>
 EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(strcpy);
+EXPORT_SYMBOL(strncpy);
+EXPORT_SYMBOL(strcat);
 
 #include <linux/atomic.h>
 EXPORT_SYMBOL(__xchg8);
index bc41ca2..cf285b1 100644 (file)
 #define DBG_RES(x...)
 #endif
 
-/* To be used as: mdelay(pci_post_reset_delay);
- *
- * post_reset is the time the kernel should stall to prevent anyone from
- * accessing the PCI bus once #RESET is de-asserted. 
- * PCI spec somewhere says 1 second but with multi-PCI bus systems,
- * this makes the boot time much longer than necessary.
- * 20ms seems to work for all the HP PCI implementations to date.
- *
- * #define pci_post_reset_delay 50
- */
-
 struct pci_port_ops *pci_port __ro_after_init;
 struct pci_bios_ops *pci_bios __ro_after_init;
 
diff --git a/arch/parisc/kernel/relocate_kernel.S b/arch/parisc/kernel/relocate_kernel.S
new file mode 100644 (file)
index 0000000..2561e52
--- /dev/null
@@ -0,0 +1,149 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#include <linux/linkage.h>
+#include <linux/kexec.h>
+
+#include <asm/assembly.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <asm/psw.h>
+
+.level PA_ASM_LEVEL
+
+.macro kexec_param name
+.align 8
+ENTRY(kexec\()_\name)
+#ifdef CONFIG_64BIT
+       .dword 0
+#else
+       .word 0
+#endif
+
+ENTRY(kexec\()_\name\()_offset)
+       .word kexec\()_\name - relocate_new_kernel
+.endm
+
+.text
+
+/* args:
+ * r26 - kimage->head
+ * r25 - start address of kernel
+ * r24 - physical address of relocate code
+ */
+
+ENTRY_CFI(relocate_new_kernel)
+0:     copy    %arg1, %rp
+       /* disable I and Q bit, so we are allowed to execute RFI */
+       rsm PSW_SM_I, %r0
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+
+       rsm PSW_SM_Q, %r0
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+       nop
+
+       /*
+        * After return-from-interrupt, we want to run without Code/Data
+        * translation enabled just like on a normal boot.
+        */
+
+       /* calculate new physical execution address */
+       ldo     1f-0b(%arg2), %r1
+       mtctl   %r0, %cr17 /* IIASQ */
+       mtctl   %r0, %cr17 /* IIASQ */
+       mtctl   %r1, %cr18 /* IIAOQ */
+       ldo     4(%r1),%r1
+       mtctl   %r1, %cr18 /* IIAOQ */
+#ifdef CONFIG_64BIT
+       depdi,z 1, PSW_W_BIT, 1, %r1
+       mtctl   %r1, %cr22 /* IPSW */
+#else
+       mtctl   %r0, %cr22 /* IPSW */
+#endif
+       /* lets go... */
+       rfi
+1:     nop
+       nop
+
+.Lloop:
+       LDREG,ma        REG_SZ(%arg0), %r3
+       /* If crash kernel, no copy needed */
+       cmpib,COND(=),n 0,%r3,boot
+
+       bb,<,n          %r3, 31 - IND_DONE_BIT, boot
+       bb,>=,n         %r3, 31 - IND_INDIRECTION_BIT, .Lnotind
+       /* indirection, load and restart */
+       movb            %r3, %arg0, .Lloop
+       depi            0, 31, PAGE_SHIFT, %arg0
+
+.Lnotind:
+       bb,>=,n         %r3, 31 - IND_DESTINATION_BIT, .Lnotdest
+       b               .Lloop
+       copy            %r3, %r20
+
+.Lnotdest:
+       bb,>=           %r3, 31 - IND_SOURCE_BIT, .Lloop
+       depi            0, 31, PAGE_SHIFT, %r3
+       copy            %r3, %r21
+
+       /* copy page */
+       copy            %r0, %r18
+       zdepi           1, 31 - PAGE_SHIFT, 1, %r18
+       add             %r20, %r18, %r17
+
+       depi            0, 31, PAGE_SHIFT, %r20
+.Lcopy:
+       copy            %r20, %r12
+       LDREG,ma        REG_SZ(%r21), %r8
+       LDREG,ma        REG_SZ(%r21), %r9
+       LDREG,ma        REG_SZ(%r21), %r10
+       LDREG,ma        REG_SZ(%r21), %r11
+       STREG,ma        %r8, REG_SZ(%r20)
+       STREG,ma        %r9, REG_SZ(%r20)
+       STREG,ma        %r10, REG_SZ(%r20)
+       STREG,ma        %r11, REG_SZ(%r20)
+
+#ifndef CONFIG_64BIT
+       LDREG,ma        REG_SZ(%r21), %r8
+       LDREG,ma        REG_SZ(%r21), %r9
+       LDREG,ma        REG_SZ(%r21), %r10
+       LDREG,ma        REG_SZ(%r21), %r11
+       STREG,ma        %r8, REG_SZ(%r20)
+       STREG,ma        %r9, REG_SZ(%r20)
+       STREG,ma        %r10, REG_SZ(%r20)
+       STREG,ma        %r11, REG_SZ(%r20)
+#endif
+
+       fdc             %r0(%r12)
+       cmpb,COND(<<)   %r20,%r17,.Lcopy
+       fic             (%sr4, %r12)
+       b,n             .Lloop
+
+boot:
+       mtctl   %r0, %cr15
+
+       LDREG   kexec_free_mem-0b(%arg2), %arg0
+       LDREG   kexec_cmdline-0b(%arg2), %arg1
+       LDREG   kexec_initrd_end-0b(%arg2), %arg3
+       LDREG   kexec_initrd_start-0b(%arg2), %arg2
+       bv,n %r0(%rp)
+
+ENDPROC_CFI(relocate_new_kernel);
+
+ENTRY(relocate_new_kernel_size)
+       .word relocate_new_kernel_size - relocate_new_kernel
+
+kexec_param cmdline
+kexec_param initrd_start
+kexec_param initrd_end
+kexec_param free_mem
index cbd074b..e202c37 100644 (file)
@@ -109,6 +109,7 @@ halt_processor(void)
        /* REVISIT : does PM *know* this CPU isn't available? */
        set_cpu_online(smp_processor_id(), false);
        local_irq_disable();
+       __pdc_cpu_rendezvous();
        for (;;)
                ;
 }
index 670d137..285ff51 100644 (file)
 352    common  pkey_alloc              sys_pkey_alloc
 353    common  pkey_free               sys_pkey_free
 354    common  rseq                    sys_rseq
-# 355 through 402 are unassigned to sync up with generic numbers
+355    common  kexec_file_load         sys_kexec_file_load             sys_kexec_file_load
+# up to 402 is unassigned and reserved for arch specific syscalls
 403    32      clock_gettime64                 sys_clock_gettime               sys_clock_gettime
 404    32      clock_settime64                 sys_clock_settime               sys_clock_settime
 405    32      clock_adjtime64                 sys_clock_adjtime               sys_clock_adjtime
index 58dcf44..82fc011 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/bug.h>
 #include <linux/ratelimit.h>
 #include <linux/uaccess.h>
+#include <linux/kdebug.h>
 
 #include <asm/assembly.h>
 #include <asm/io.h>
@@ -414,6 +415,7 @@ void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long o
 {
        static DEFINE_SPINLOCK(terminate_lock);
 
+       (void)notify_die(DIE_OOPS, msg, regs, 0, code, SIGTRAP);
        bust_spinlocks(1);
 
        set_eiem(0);
index 7b19766..2d7a997 100644 (file)
@@ -3,7 +3,7 @@
 # Makefile for parisc-specific library files
 #
 
-lib-y  := lusercopy.o bitops.o checksum.o io.o memset.o memcpy.o \
-          ucmpdi2.o delay.o
+lib-y  := lusercopy.o bitops.o checksum.o io.o memcpy.o \
+          ucmpdi2.o delay.o string.o
 
 obj-y  := iomap.o
diff --git a/arch/parisc/lib/memset.c b/arch/parisc/lib/memset.c
deleted file mode 100644 (file)
index 1d7929b..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Copyright (C) 1991, 1997 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-/* Slight modifications for pa-risc linux - Paul Bame <bame@debian.org> */
-
-#include <linux/types.h>
-#include <asm/string.h>
-
-#define OPSIZ (BITS_PER_LONG/8)
-typedef unsigned long op_t;
-
-void *
-memset (void *dstpp, int sc, size_t len)
-{
-  unsigned int c = sc;
-  long int dstp = (long int) dstpp;
-
-  if (len >= 8)
-    {
-      size_t xlen;
-      op_t cccc;
-
-      cccc = (unsigned char) c;
-      cccc |= cccc << 8;
-      cccc |= cccc << 16;
-      if (OPSIZ > 4)
-       /* Do the shift in two steps to avoid warning if long has 32 bits.  */
-       cccc |= (cccc << 16) << 16;
-
-      /* There are at least some bytes to set.
-        No need to test for LEN == 0 in this alignment loop.  */
-      while (dstp % OPSIZ != 0)
-       {
-         ((unsigned char *) dstp)[0] = c;
-         dstp += 1;
-         len -= 1;
-       }
-
-      /* Write 8 `op_t' per iteration until less than 8 `op_t' remain.  */
-      xlen = len / (OPSIZ * 8);
-      while (xlen > 0)
-       {
-         ((op_t *) dstp)[0] = cccc;
-         ((op_t *) dstp)[1] = cccc;
-         ((op_t *) dstp)[2] = cccc;
-         ((op_t *) dstp)[3] = cccc;
-         ((op_t *) dstp)[4] = cccc;
-         ((op_t *) dstp)[5] = cccc;
-         ((op_t *) dstp)[6] = cccc;
-         ((op_t *) dstp)[7] = cccc;
-         dstp += 8 * OPSIZ;
-         xlen -= 1;
-       }
-      len %= OPSIZ * 8;
-
-      /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain.  */
-      xlen = len / OPSIZ;
-      while (xlen > 0)
-       {
-         ((op_t *) dstp)[0] = cccc;
-         dstp += OPSIZ;
-         xlen -= 1;
-       }
-      len %= OPSIZ;
-    }
-
-  /* Write the last few bytes.  */
-  while (len > 0)
-    {
-      ((unsigned char *) dstp)[0] = c;
-      dstp += 1;
-      len -= 1;
-    }
-
-  return dstpp;
-}
diff --git a/arch/parisc/lib/string.S b/arch/parisc/lib/string.S
new file mode 100644 (file)
index 0000000..4a64264
--- /dev/null
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *    PA-RISC assembly string functions
+ *
+ *    Copyright (C) 2019 Helge Deller <deller@gmx.de>
+ */
+
+#include <asm/assembly.h>
+#include <linux/linkage.h>
+
+       .section .text.hot
+       .level PA_ASM_LEVEL
+
+       t0 = r20
+       t1 = r21
+       t2 = r22
+
+ENTRY_CFI(strlen, frame=0,no_calls)
+       or,COND(<>) arg0,r0,ret0
+       b,l,n   .Lstrlen_null_ptr,r0
+       depwi   0,31,2,ret0
+       cmpb,COND(<>) arg0,ret0,.Lstrlen_not_aligned
+       ldw,ma  4(ret0),t0
+       cmpib,tr 0,r0,.Lstrlen_loop
+       uxor,nbz r0,t0,r0
+.Lstrlen_not_aligned:
+       uaddcm  arg0,ret0,t1
+       shladd  t1,3,r0,t1
+       mtsar   t1
+       depwi   -1,%sar,32,t0
+       uxor,nbz r0,t0,r0
+.Lstrlen_loop:
+       b,l,n   .Lstrlen_end_loop,r0
+       ldw,ma  4(ret0),t0
+       cmpib,tr 0,r0,.Lstrlen_loop
+       uxor,nbz r0,t0,r0
+.Lstrlen_end_loop:
+       extrw,u,<> t0,7,8,r0
+       addib,tr,n -3,ret0,.Lstrlen_out
+       extrw,u,<> t0,15,8,r0
+       addib,tr,n -2,ret0,.Lstrlen_out
+       extrw,u,<> t0,23,8,r0
+       addi    -1,ret0,ret0
+.Lstrlen_out:
+       bv r0(rp)
+       uaddcm ret0,arg0,ret0
+.Lstrlen_null_ptr:
+       bv,n r0(rp)
+ENDPROC_CFI(strlen)
+
+
+ENTRY_CFI(strcpy, frame=0,no_calls)
+       ldb     0(arg1),t0
+       stb     t0,0(arg0)
+       ldo     0(arg0),ret0
+       ldo     1(arg1),t1
+       cmpb,=  r0,t0,2f
+       ldo     1(arg0),t2
+1:     ldb     0(t1),arg1
+       stb     arg1,0(t2)
+       ldo     1(t1),t1
+       cmpb,<> r0,arg1,1b
+       ldo     1(t2),t2
+2:     bv,n    r0(rp)
+ENDPROC_CFI(strcpy)
+
+
+ENTRY_CFI(strncpy, frame=0,no_calls)
+       ldb     0(arg1),t0
+       stb     t0,0(arg0)
+       ldo     1(arg1),t1
+       ldo     0(arg0),ret0
+       cmpb,=  r0,t0,2f
+       ldo     1(arg0),arg1
+1:     ldo     -1(arg2),arg2
+       cmpb,COND(=),n r0,arg2,2f
+       ldb     0(t1),arg0
+       stb     arg0,0(arg1)
+       ldo     1(t1),t1
+       cmpb,<> r0,arg0,1b
+       ldo     1(arg1),arg1
+2:     bv,n    r0(rp)
+ENDPROC_CFI(strncpy)
+
+
+ENTRY_CFI(strcat, frame=0,no_calls)
+       ldb     0(arg0),t0
+       cmpb,=  t0,r0,2f
+       ldo     0(arg0),ret0
+       ldo     1(arg0),arg0
+1:     ldb     0(arg0),t1
+       cmpb,<>,n r0,t1,1b
+       ldo     1(arg0),arg0
+2:     ldb     0(arg1),t2
+       stb     t2,0(arg0)
+       ldo     1(arg0),arg0
+       ldb     0(arg1),t0
+       cmpb,<> r0,t0,2b
+       ldo     1(arg1),arg1
+       bv,n    r0(rp)
+ENDPROC_CFI(strcat)
+
+
+ENTRY_CFI(memset, frame=0,no_calls)
+       copy    arg0,ret0
+       cmpb,COND(=) r0,arg0,4f
+       copy    arg0,t2
+       cmpb,COND(=) r0,arg2,4f
+       ldo     -1(arg2),arg3
+       subi    -1,arg3,t0
+       subi    0,t0,t1
+       cmpiclr,COND(>=) 0,t1,arg2
+       ldo     -1(t1),arg2
+       extru arg2,31,2,arg0
+2:     stb     arg1,0(t2)
+       ldo     1(t2),t2
+       addib,>= -1,arg0,2b
+       ldo     -1(arg3),arg3
+       cmpiclr,COND(<=) 4,arg2,r0
+       b,l,n   4f,r0
+#ifdef CONFIG_64BIT
+       depd,*  r0,63,2,arg2
+#else
+       depw    r0,31,2,arg2
+#endif
+       ldo     1(t2),t2
+3:     stb     arg1,-1(t2)
+       stb     arg1,0(t2)
+       stb     arg1,1(t2)
+       stb     arg1,2(t2)
+       addib,COND(>) -4,arg2,3b
+       ldo     4(t2),t2
+4:     bv,n    r0(rp)
+ENDPROC_CFI(memset)
+
+       .end
index d8dcd88..891cd23 100644 (file)
@@ -511,6 +511,7 @@ config KEXEC_FILE
        select KEXEC_CORE
        select HAVE_IMA_KEXEC
        select BUILD_BIN2C
+       select KEXEC_ELF
        depends on PPC64
        depends on CRYPTO=y
        depends on CRYPTO_SHA256=y
index c345b79..403f7e1 100644 (file)
@@ -39,13 +39,11 @@ endif
 uname := $(shell uname -m)
 KBUILD_DEFCONFIG := $(if $(filter ppc%,$(uname)),$(uname),ppc64)_defconfig
 
-ifdef CONFIG_PPC64
 new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi)
 
 ifeq ($(new_nm),y)
 NM             := $(NM) --synthetic
 endif
-endif
 
 # BITS is used as extension for files which are available in a 32 bit
 # and a 64 bit version to simplify shared Makefiles.
diff --git a/arch/powerpc/include/asm/error-injection.h b/arch/powerpc/include/asm/error-injection.h
deleted file mode 100644 (file)
index 62fd247..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-
-#ifndef _ASM_ERROR_INJECTION_H
-#define _ASM_ERROR_INJECTION_H
-
-#include <linux/compiler.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-#include <asm-generic/error-injection.h>
-
-void override_function_with_return(struct pt_regs *regs);
-
-#endif /* _ASM_ERROR_INJECTION_H */
index 83cf7b8..3072fd6 100644 (file)
 #include <linux/slab.h>
 #include <linux/types.h>
 
-#define PURGATORY_STACK_SIZE   (16 * 1024)
-
-#define elf_addr_to_cpu        elf64_to_cpu
-
-#ifndef Elf_Rel
-#define Elf_Rel                Elf64_Rel
-#endif /* Elf_Rel */
-
-struct elf_info {
-       /*
-        * Where the ELF binary contents are kept.
-        * Memory managed by the user of the struct.
-        */
-       const char *buffer;
-
-       const struct elfhdr *ehdr;
-       const struct elf_phdr *proghdrs;
-       struct elf_shdr *sechdrs;
-};
-
-static inline bool elf_is_elf_file(const struct elfhdr *ehdr)
-{
-       return memcmp(ehdr->e_ident, ELFMAG, SELFMAG) == 0;
-}
-
-static uint64_t elf64_to_cpu(const struct elfhdr *ehdr, uint64_t value)
-{
-       if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
-               value = le64_to_cpu(value);
-       else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
-               value = be64_to_cpu(value);
-
-       return value;
-}
-
-static uint16_t elf16_to_cpu(const struct elfhdr *ehdr, uint16_t value)
-{
-       if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
-               value = le16_to_cpu(value);
-       else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
-               value = be16_to_cpu(value);
-
-       return value;
-}
-
-static uint32_t elf32_to_cpu(const struct elfhdr *ehdr, uint32_t value)
-{
-       if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
-               value = le32_to_cpu(value);
-       else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
-               value = be32_to_cpu(value);
-
-       return value;
-}
-
-/**
- * elf_is_ehdr_sane - check that it is safe to use the ELF header
- * @buf_len:   size of the buffer in which the ELF file is loaded.
- */
-static bool elf_is_ehdr_sane(const struct elfhdr *ehdr, size_t buf_len)
-{
-       if (ehdr->e_phnum > 0 && ehdr->e_phentsize != sizeof(struct elf_phdr)) {
-               pr_debug("Bad program header size.\n");
-               return false;
-       } else if (ehdr->e_shnum > 0 &&
-                  ehdr->e_shentsize != sizeof(struct elf_shdr)) {
-               pr_debug("Bad section header size.\n");
-               return false;
-       } else if (ehdr->e_ident[EI_VERSION] != EV_CURRENT ||
-                  ehdr->e_version != EV_CURRENT) {
-               pr_debug("Unknown ELF version.\n");
-               return false;
-       }
-
-       if (ehdr->e_phoff > 0 && ehdr->e_phnum > 0) {
-               size_t phdr_size;
-
-               /*
-                * e_phnum is at most 65535 so calculating the size of the
-                * program header cannot overflow.
-                */
-               phdr_size = sizeof(struct elf_phdr) * ehdr->e_phnum;
-
-               /* Sanity check the program header table location. */
-               if (ehdr->e_phoff + phdr_size < ehdr->e_phoff) {
-                       pr_debug("Program headers at invalid location.\n");
-                       return false;
-               } else if (ehdr->e_phoff + phdr_size > buf_len) {
-                       pr_debug("Program headers truncated.\n");
-                       return false;
-               }
-       }
-
-       if (ehdr->e_shoff > 0 && ehdr->e_shnum > 0) {
-               size_t shdr_size;
-
-               /*
-                * e_shnum is at most 65536 so calculating
-                * the size of the section header cannot overflow.
-                */
-               shdr_size = sizeof(struct elf_shdr) * ehdr->e_shnum;
-
-               /* Sanity check the section header table location. */
-               if (ehdr->e_shoff + shdr_size < ehdr->e_shoff) {
-                       pr_debug("Section headers at invalid location.\n");
-                       return false;
-               } else if (ehdr->e_shoff + shdr_size > buf_len) {
-                       pr_debug("Section headers truncated.\n");
-                       return false;
-               }
-       }
-
-       return true;
-}
-
-static int elf_read_ehdr(const char *buf, size_t len, struct elfhdr *ehdr)
-{
-       struct elfhdr *buf_ehdr;
-
-       if (len < sizeof(*buf_ehdr)) {
-               pr_debug("Buffer is too small to hold ELF header.\n");
-               return -ENOEXEC;
-       }
-
-       memset(ehdr, 0, sizeof(*ehdr));
-       memcpy(ehdr->e_ident, buf, sizeof(ehdr->e_ident));
-       if (!elf_is_elf_file(ehdr)) {
-               pr_debug("No ELF header magic.\n");
-               return -ENOEXEC;
-       }
-
-       if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) {
-               pr_debug("Not a supported ELF class.\n");
-               return -ENOEXEC;
-       } else  if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB &&
-               ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
-               pr_debug("Not a supported ELF data format.\n");
-               return -ENOEXEC;
-       }
-
-       buf_ehdr = (struct elfhdr *) buf;
-       if (elf16_to_cpu(ehdr, buf_ehdr->e_ehsize) != sizeof(*buf_ehdr)) {
-               pr_debug("Bad ELF header size.\n");
-               return -ENOEXEC;
-       }
-
-       ehdr->e_type      = elf16_to_cpu(ehdr, buf_ehdr->e_type);
-       ehdr->e_machine   = elf16_to_cpu(ehdr, buf_ehdr->e_machine);
-       ehdr->e_version   = elf32_to_cpu(ehdr, buf_ehdr->e_version);
-       ehdr->e_entry     = elf_addr_to_cpu(ehdr, buf_ehdr->e_entry);
-       ehdr->e_phoff     = elf_addr_to_cpu(ehdr, buf_ehdr->e_phoff);
-       ehdr->e_shoff     = elf_addr_to_cpu(ehdr, buf_ehdr->e_shoff);
-       ehdr->e_flags     = elf32_to_cpu(ehdr, buf_ehdr->e_flags);
-       ehdr->e_phentsize = elf16_to_cpu(ehdr, buf_ehdr->e_phentsize);
-       ehdr->e_phnum     = elf16_to_cpu(ehdr, buf_ehdr->e_phnum);
-       ehdr->e_shentsize = elf16_to_cpu(ehdr, buf_ehdr->e_shentsize);
-       ehdr->e_shnum     = elf16_to_cpu(ehdr, buf_ehdr->e_shnum);
-       ehdr->e_shstrndx  = elf16_to_cpu(ehdr, buf_ehdr->e_shstrndx);
-
-       return elf_is_ehdr_sane(ehdr, len) ? 0 : -ENOEXEC;
-}
-
-/**
- * elf_is_phdr_sane - check that it is safe to use the program header
- * @buf_len:   size of the buffer in which the ELF file is loaded.
- */
-static bool elf_is_phdr_sane(const struct elf_phdr *phdr, size_t buf_len)
-{
-
-       if (phdr->p_offset + phdr->p_filesz < phdr->p_offset) {
-               pr_debug("ELF segment location wraps around.\n");
-               return false;
-       } else if (phdr->p_offset + phdr->p_filesz > buf_len) {
-               pr_debug("ELF segment not in file.\n");
-               return false;
-       } else if (phdr->p_paddr + phdr->p_memsz < phdr->p_paddr) {
-               pr_debug("ELF segment address wraps around.\n");
-               return false;
-       }
-
-       return true;
-}
-
-static int elf_read_phdr(const char *buf, size_t len, struct elf_info *elf_info,
-                        int idx)
-{
-       /* Override the const in proghdrs, we are the ones doing the loading. */
-       struct elf_phdr *phdr = (struct elf_phdr *) &elf_info->proghdrs[idx];
-       const char *pbuf;
-       struct elf_phdr *buf_phdr;
-
-       pbuf = buf + elf_info->ehdr->e_phoff + (idx * sizeof(*buf_phdr));
-       buf_phdr = (struct elf_phdr *) pbuf;
-
-       phdr->p_type   = elf32_to_cpu(elf_info->ehdr, buf_phdr->p_type);
-       phdr->p_offset = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_offset);
-       phdr->p_paddr  = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_paddr);
-       phdr->p_vaddr  = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_vaddr);
-       phdr->p_flags  = elf32_to_cpu(elf_info->ehdr, buf_phdr->p_flags);
-
-       /*
-        * The following fields have a type equivalent to Elf_Addr
-        * both in 32 bit and 64 bit ELF.
-        */
-       phdr->p_filesz = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_filesz);
-       phdr->p_memsz  = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_memsz);
-       phdr->p_align  = elf_addr_to_cpu(elf_info->ehdr, buf_phdr->p_align);
-
-       return elf_is_phdr_sane(phdr, len) ? 0 : -ENOEXEC;
-}
-
-/**
- * elf_read_phdrs - read the program headers from the buffer
- *
- * This function assumes that the program header table was checked for sanity.
- * Use elf_is_ehdr_sane() if it wasn't.
- */
-static int elf_read_phdrs(const char *buf, size_t len,
-                         struct elf_info *elf_info)
-{
-       size_t phdr_size, i;
-       const struct elfhdr *ehdr = elf_info->ehdr;
-
-       /*
-        * e_phnum is at most 65535 so calculating the size of the
-        * program header cannot overflow.
-        */
-       phdr_size = sizeof(struct elf_phdr) * ehdr->e_phnum;
-
-       elf_info->proghdrs = kzalloc(phdr_size, GFP_KERNEL);
-       if (!elf_info->proghdrs)
-               return -ENOMEM;
-
-       for (i = 0; i < ehdr->e_phnum; i++) {
-               int ret;
-
-               ret = elf_read_phdr(buf, len, elf_info, i);
-               if (ret) {
-                       kfree(elf_info->proghdrs);
-                       elf_info->proghdrs = NULL;
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-/**
- * elf_is_shdr_sane - check that it is safe to use the section header
- * @buf_len:   size of the buffer in which the ELF file is loaded.
- */
-static bool elf_is_shdr_sane(const struct elf_shdr *shdr, size_t buf_len)
-{
-       bool size_ok;
-
-       /* SHT_NULL headers have undefined values, so we can't check them. */
-       if (shdr->sh_type == SHT_NULL)
-               return true;
-
-       /* Now verify sh_entsize */
-       switch (shdr->sh_type) {
-       case SHT_SYMTAB:
-               size_ok = shdr->sh_entsize == sizeof(Elf_Sym);
-               break;
-       case SHT_RELA:
-               size_ok = shdr->sh_entsize == sizeof(Elf_Rela);
-               break;
-       case SHT_DYNAMIC:
-               size_ok = shdr->sh_entsize == sizeof(Elf_Dyn);
-               break;
-       case SHT_REL:
-               size_ok = shdr->sh_entsize == sizeof(Elf_Rel);
-               break;
-       case SHT_NOTE:
-       case SHT_PROGBITS:
-       case SHT_HASH:
-       case SHT_NOBITS:
-       default:
-               /*
-                * This is a section whose entsize requirements
-                * I don't care about.  If I don't know about
-                * the section I can't care about it's entsize
-                * requirements.
-                */
-               size_ok = true;
-               break;
-       }
-
-       if (!size_ok) {
-               pr_debug("ELF section with wrong entry size.\n");
-               return false;
-       } else if (shdr->sh_addr + shdr->sh_size < shdr->sh_addr) {
-               pr_debug("ELF section address wraps around.\n");
-               return false;
-       }
-
-       if (shdr->sh_type != SHT_NOBITS) {
-               if (shdr->sh_offset + shdr->sh_size < shdr->sh_offset) {
-                       pr_debug("ELF section location wraps around.\n");
-                       return false;
-               } else if (shdr->sh_offset + shdr->sh_size > buf_len) {
-                       pr_debug("ELF section not in file.\n");
-                       return false;
-               }
-       }
-
-       return true;
-}
-
-static int elf_read_shdr(const char *buf, size_t len, struct elf_info *elf_info,
-                        int idx)
-{
-       struct elf_shdr *shdr = &elf_info->sechdrs[idx];
-       const struct elfhdr *ehdr = elf_info->ehdr;
-       const char *sbuf;
-       struct elf_shdr *buf_shdr;
-
-       sbuf = buf + ehdr->e_shoff + idx * sizeof(*buf_shdr);
-       buf_shdr = (struct elf_shdr *) sbuf;
-
-       shdr->sh_name      = elf32_to_cpu(ehdr, buf_shdr->sh_name);
-       shdr->sh_type      = elf32_to_cpu(ehdr, buf_shdr->sh_type);
-       shdr->sh_addr      = elf_addr_to_cpu(ehdr, buf_shdr->sh_addr);
-       shdr->sh_offset    = elf_addr_to_cpu(ehdr, buf_shdr->sh_offset);
-       shdr->sh_link      = elf32_to_cpu(ehdr, buf_shdr->sh_link);
-       shdr->sh_info      = elf32_to_cpu(ehdr, buf_shdr->sh_info);
-
-       /*
-        * The following fields have a type equivalent to Elf_Addr
-        * both in 32 bit and 64 bit ELF.
-        */
-       shdr->sh_flags     = elf_addr_to_cpu(ehdr, buf_shdr->sh_flags);
-       shdr->sh_size      = elf_addr_to_cpu(ehdr, buf_shdr->sh_size);
-       shdr->sh_addralign = elf_addr_to_cpu(ehdr, buf_shdr->sh_addralign);
-       shdr->sh_entsize   = elf_addr_to_cpu(ehdr, buf_shdr->sh_entsize);
-
-       return elf_is_shdr_sane(shdr, len) ? 0 : -ENOEXEC;
-}
-
-/**
- * elf_read_shdrs - read the section headers from the buffer
- *
- * This function assumes that the section header table was checked for sanity.
- * Use elf_is_ehdr_sane() if it wasn't.
- */
-static int elf_read_shdrs(const char *buf, size_t len,
-                         struct elf_info *elf_info)
-{
-       size_t shdr_size, i;
-
-       /*
-        * e_shnum is at most 65536 so calculating
-        * the size of the section header cannot overflow.
-        */
-       shdr_size = sizeof(struct elf_shdr) * elf_info->ehdr->e_shnum;
-
-       elf_info->sechdrs = kzalloc(shdr_size, GFP_KERNEL);
-       if (!elf_info->sechdrs)
-               return -ENOMEM;
-
-       for (i = 0; i < elf_info->ehdr->e_shnum; i++) {
-               int ret;
-
-               ret = elf_read_shdr(buf, len, elf_info, i);
-               if (ret) {
-                       kfree(elf_info->sechdrs);
-                       elf_info->sechdrs = NULL;
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-/**
- * elf_read_from_buffer - read ELF file and sets up ELF header and ELF info
- * @buf:       Buffer to read ELF file from.
- * @len:       Size of @buf.
- * @ehdr:      Pointer to existing struct which will be populated.
- * @elf_info:  Pointer to existing struct which will be populated.
- *
- * This function allows reading ELF files with different byte order than
- * the kernel, byte-swapping the fields as needed.
- *
- * Return:
- * On success returns 0, and the caller should call elf_free_info(elf_info) to
- * free the memory allocated for the section and program headers.
- */
-int elf_read_from_buffer(const char *buf, size_t len, struct elfhdr *ehdr,
-                        struct elf_info *elf_info)
-{
-       int ret;
-
-       ret = elf_read_ehdr(buf, len, ehdr);
-       if (ret)
-               return ret;
-
-       elf_info->buffer = buf;
-       elf_info->ehdr = ehdr;
-       if (ehdr->e_phoff > 0 && ehdr->e_phnum > 0) {
-               ret = elf_read_phdrs(buf, len, elf_info);
-               if (ret)
-                       return ret;
-       }
-       if (ehdr->e_shoff > 0 && ehdr->e_shnum > 0) {
-               ret = elf_read_shdrs(buf, len, elf_info);
-               if (ret) {
-                       kfree(elf_info->proghdrs);
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
-/**
- * elf_free_info - free memory allocated by elf_read_from_buffer
- */
-void elf_free_info(struct elf_info *elf_info)
-{
-       kfree(elf_info->proghdrs);
-       kfree(elf_info->sechdrs);
-       memset(elf_info, 0, sizeof(*elf_info));
-}
-/**
- * build_elf_exec_info - read ELF executable and check that we can use it
- */
-static int build_elf_exec_info(const char *buf, size_t len, struct elfhdr *ehdr,
-                              struct elf_info *elf_info)
-{
-       int i;
-       int ret;
-
-       ret = elf_read_from_buffer(buf, len, ehdr, elf_info);
-       if (ret)
-               return ret;
-
-       /* Big endian vmlinux has type ET_DYN. */
-       if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
-               pr_err("Not an ELF executable.\n");
-               goto error;
-       } else if (!elf_info->proghdrs) {
-               pr_err("No ELF program header.\n");
-               goto error;
-       }
-
-       for (i = 0; i < ehdr->e_phnum; i++) {
-               /*
-                * Kexec does not support loading interpreters.
-                * In addition this check keeps us from attempting
-                * to kexec ordinay executables.
-                */
-               if (elf_info->proghdrs[i].p_type == PT_INTERP) {
-                       pr_err("Requires an ELF interpreter.\n");
-                       goto error;
-               }
-       }
-
-       return 0;
-error:
-       elf_free_info(elf_info);
-       return -ENOEXEC;
-}
-
-static int elf64_probe(const char *buf, unsigned long len)
-{
-       struct elfhdr ehdr;
-       struct elf_info elf_info;
-       int ret;
-
-       ret = build_elf_exec_info(buf, len, &ehdr, &elf_info);
-       if (ret)
-               return ret;
-
-       elf_free_info(&elf_info);
-
-       return elf_check_arch(&ehdr) ? 0 : -ENOEXEC;
-}
-
-/**
- * elf_exec_load - load ELF executable image
- * @lowest_load_addr:  On return, will be the address where the first PT_LOAD
- *                     section will be loaded in memory.
- *
- * Return:
- * 0 on success, negative value on failure.
- */
-static int elf_exec_load(struct kimage *image, struct elfhdr *ehdr,
-                        struct elf_info *elf_info,
-                        unsigned long *lowest_load_addr)
-{
-       unsigned long base = 0, lowest_addr = UINT_MAX;
-       int ret;
-       size_t i;
-       struct kexec_buf kbuf = { .image = image, .buf_max = ppc64_rma_size,
-                                 .top_down = false };
-
-       /* Read in the PT_LOAD segments. */
-       for (i = 0; i < ehdr->e_phnum; i++) {
-               unsigned long load_addr;
-               size_t size;
-               const struct elf_phdr *phdr;
-
-               phdr = &elf_info->proghdrs[i];
-               if (phdr->p_type != PT_LOAD)
-                       continue;
-
-               size = phdr->p_filesz;
-               if (size > phdr->p_memsz)
-                       size = phdr->p_memsz;
-
-               kbuf.buffer = (void *) elf_info->buffer + phdr->p_offset;
-               kbuf.bufsz = size;
-               kbuf.memsz = phdr->p_memsz;
-               kbuf.buf_align = phdr->p_align;
-               kbuf.buf_min = phdr->p_paddr + base;
-               kbuf.mem = KEXEC_BUF_MEM_UNKNOWN;
-               ret = kexec_add_buffer(&kbuf);
-               if (ret)
-                       goto out;
-               load_addr = kbuf.mem;
-
-               if (load_addr < lowest_addr)
-                       lowest_addr = load_addr;
-       }
-
-       /* Update entry point to reflect new load address. */
-       ehdr->e_entry += base;
-
-       *lowest_load_addr = lowest_addr;
-       ret = 0;
- out:
-       return ret;
-}
-
 static void *elf64_load(struct kimage *image, char *kernel_buf,
                        unsigned long kernel_len, char *initrd,
                        unsigned long initrd_len, char *cmdline,
@@ -570,18 +35,18 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
        void *fdt;
        const void *slave_code;
        struct elfhdr ehdr;
-       struct elf_info elf_info;
+       struct kexec_elf_info elf_info;
        struct kexec_buf kbuf = { .image = image, .buf_min = 0,
                                  .buf_max = ppc64_rma_size };
        struct kexec_buf pbuf = { .image = image, .buf_min = 0,
                                  .buf_max = ppc64_rma_size, .top_down = true,
                                  .mem = KEXEC_BUF_MEM_UNKNOWN };
 
-       ret = build_elf_exec_info(kernel_buf, kernel_len, &ehdr, &elf_info);
+       ret = kexec_build_elf_info(kernel_buf, kernel_len, &ehdr, &elf_info);
        if (ret)
                goto out;
 
-       ret = elf_exec_load(image, &ehdr, &elf_info, &kernel_load_addr);
+       ret = kexec_elf_load(image, &ehdr, &elf_info, &kbuf, &kernel_load_addr);
        if (ret)
                goto out;
 
@@ -648,13 +113,13 @@ static void *elf64_load(struct kimage *image, char *kernel_buf,
                pr_err("Error setting up the purgatory.\n");
 
 out:
-       elf_free_info(&elf_info);
+       kexec_free_elf_info(&elf_info);
 
        /* Make kimage_file_post_load_cleanup free the fdt buffer for us. */
        return ret ? ERR_PTR(ret) : fdt;
 }
 
 const struct kexec_file_ops kexec_elf64_ops = {
-       .probe = elf64_probe,
+       .probe = kexec_elf_probe,
        .load = elf64_load,
 };
index 8fc4de0..7a84c9f 100644 (file)
@@ -101,21 +101,8 @@ static void check_if_tm_restore_required(struct task_struct *tsk)
        }
 }
 
-static bool tm_active_with_fp(struct task_struct *tsk)
-{
-       return MSR_TM_ACTIVE(tsk->thread.regs->msr) &&
-               (tsk->thread.ckpt_regs.msr & MSR_FP);
-}
-
-static bool tm_active_with_altivec(struct task_struct *tsk)
-{
-       return MSR_TM_ACTIVE(tsk->thread.regs->msr) &&
-               (tsk->thread.ckpt_regs.msr & MSR_VEC);
-}
 #else
 static inline void check_if_tm_restore_required(struct task_struct *tsk) { }
-static inline bool tm_active_with_fp(struct task_struct *tsk) { return false; }
-static inline bool tm_active_with_altivec(struct task_struct *tsk) { return false; }
 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
 
 bool strict_msr_control;
@@ -252,7 +239,7 @@ EXPORT_SYMBOL(enable_kernel_fp);
 
 static int restore_fp(struct task_struct *tsk)
 {
-       if (tsk->thread.load_fp || tm_active_with_fp(tsk)) {
+       if (tsk->thread.load_fp) {
                load_fp_state(&current->thread.fp_state);
                current->thread.load_fp++;
                return 1;
@@ -334,8 +321,7 @@ EXPORT_SYMBOL_GPL(flush_altivec_to_thread);
 
 static int restore_altivec(struct task_struct *tsk)
 {
-       if (cpu_has_feature(CPU_FTR_ALTIVEC) &&
-               (tsk->thread.load_vec || tm_active_with_altivec(tsk))) {
+       if (cpu_has_feature(CPU_FTR_ALTIVEC) && (tsk->thread.load_vec)) {
                load_vr_state(&tsk->thread.vr_state);
                tsk->thread.used_vr = 1;
                tsk->thread.load_vec++;
@@ -497,13 +483,14 @@ void giveup_all(struct task_struct *tsk)
        if (!tsk->thread.regs)
                return;
 
+       check_if_tm_restore_required(tsk);
+
        usermsr = tsk->thread.regs->msr;
 
        if ((usermsr & msr_all_available) == 0)
                return;
 
        msr_check_and_set(msr_all_available);
-       check_if_tm_restore_required(tsk);
 
        WARN_ON((usermsr & MSR_VSX) && !((usermsr & MSR_FP) && (usermsr & MSR_VEC)));
 
index e99a147..c4b606f 100644 (file)
@@ -660,8 +660,10 @@ long kvmppc_h_put_tce_indirect(struct kvm_vcpu *vcpu,
                }
                tce = be64_to_cpu(tce);
 
-               if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua))
-                       return H_PARAMETER;
+               if (kvmppc_tce_to_ua(vcpu->kvm, tce, &ua)) {
+                       ret = H_PARAMETER;
+                       goto unlock_exit;
+               }
 
                list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
                        ret = kvmppc_tce_iommu_map(vcpu->kvm, stt,
index f50bbee..b4f20f1 100644 (file)
@@ -556,8 +556,10 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu,
                unsigned long tce = be64_to_cpu(((u64 *)tces)[i]);
 
                ua = 0;
-               if (kvmppc_rm_tce_to_ua(vcpu->kvm, tce, &ua, NULL))
-                       return H_PARAMETER;
+               if (kvmppc_rm_tce_to_ua(vcpu->kvm, tce, &ua, NULL)) {
+                       ret = H_PARAMETER;
+                       goto unlock_exit;
+               }
 
                list_for_each_entry_lockless(stit, &stt->iommu_tables, next) {
                        ret = kvmppc_rm_tce_iommu_map(vcpu->kvm, stt,
index d4acf6f..bf60983 100644 (file)
@@ -630,7 +630,6 @@ static void early_init_this_mmu(void)
 #ifdef CONFIG_PPC_FSL_BOOK3E
        if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
                unsigned int num_cams;
-               int __maybe_unused cpu = smp_processor_id();
                bool map = true;
 
                /* use a quarter of the TLBCAM for bolted linear map */
diff --git a/arch/riscv/Kbuild b/arch/riscv/Kbuild
new file mode 100644 (file)
index 0000000..d1d0aa7
--- /dev/null
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-y += kernel/ mm/ net/
index 59a4727..1211543 100644 (file)
@@ -35,6 +35,8 @@ config RISCV
        select HAVE_DMA_CONTIGUOUS
        select HAVE_FUTEX_CMPXCHG if FUTEX
        select HAVE_PERF_EVENTS
+       select HAVE_PERF_REGS
+       select HAVE_PERF_USER_STACK_DUMP
        select HAVE_SYSCALL_TRACEPOINTS
        select IRQ_DOMAIN
        select SPARSE_IRQ
@@ -48,12 +50,14 @@ config RISCV
        select PCI_MSI if PCI
        select RISCV_TIMER
        select GENERIC_IRQ_MULTI_HANDLER
+       select GENERIC_ARCH_TOPOLOGY if SMP
        select ARCH_HAS_PTE_SPECIAL
        select ARCH_HAS_MMIOWB
        select HAVE_EBPF_JIT if 64BIT
        select EDAC_SUPPORT
        select ARCH_HAS_GIGANTIC_PAGE
        select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
+       select SPARSEMEM_STATIC if 32BIT
 
 config MMU
        def_bool y
@@ -62,12 +66,32 @@ config ZONE_DMA32
        bool
        default y if 64BIT
 
+config VA_BITS
+       int
+       default 32 if 32BIT
+       default 39 if 64BIT
+
+config PA_BITS
+       int
+       default 34 if 32BIT
+       default 56 if 64BIT
+
 config PAGE_OFFSET
        hex
        default 0xC0000000 if 32BIT && MAXPHYSMEM_2GB
        default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB
        default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB
 
+config ARCH_FLATMEM_ENABLE
+       def_bool y
+
+config ARCH_SPARSEMEM_ENABLE
+       def_bool y
+       select SPARSEMEM_VMEMMAP_ENABLE
+
+config ARCH_SELECT_MEMORY_MODEL
+       def_bool ARCH_SPARSEMEM_ENABLE
+
 config ARCH_WANT_GENERAL_HUGETLB
        def_bool y
 
index 7a117be..4f0a3d2 100644 (file)
@@ -54,6 +54,9 @@ endif
 ifeq ($(CONFIG_MODULE_SECTIONS),y)
        KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/riscv/kernel/module.lds
 endif
+ifeq ($(CONFIG_PERF_EVENTS),y)
+        KBUILD_CFLAGS += -fno-omit-frame-pointer
+endif
 
 KBUILD_CFLAGS_MODULE += $(call cc-option,-mno-relax)
 
@@ -72,7 +75,7 @@ KBUILD_IMAGE  := $(boot)/Image.gz
 
 head-y := arch/riscv/kernel/head.o
 
-core-y += arch/riscv/kernel/ arch/riscv/mm/ arch/riscv/net/
+core-y += arch/riscv/
 
 libs-y += arch/riscv/lib/
 
index 9c66033..161f28d 100644 (file)
@@ -30,10 +30,6 @@ enum fixed_addresses {
        __end_of_fixed_addresses
 };
 
-#define FIXADDR_SIZE           (__end_of_fixed_addresses * PAGE_SIZE)
-#define FIXADDR_TOP            (VMALLOC_START)
-#define FIXADDR_START          (FIXADDR_TOP - FIXADDR_SIZE)
-
 #define FIXMAP_PAGE_IO         PAGE_KERNEL
 
 #define __early_set_fixmap     __set_fixmap
index ef28e10..344db52 100644 (file)
@@ -3,7 +3,8 @@
 #ifndef __ASM_IMAGE_H
 #define __ASM_IMAGE_H
 
-#define RISCV_IMAGE_MAGIC      "RISCV"
+#define RISCV_IMAGE_MAGIC      "RISCV\0\0\0"
+#define RISCV_IMAGE_MAGIC2     "RSC\x05"
 
 #define RISCV_IMAGE_FLAG_BE_SHIFT      0
 #define RISCV_IMAGE_FLAG_BE_MASK       0x1
@@ -23,7 +24,7 @@
 #define __HEAD_FLAGS           (__HEAD_FLAG(BE))
 
 #define RISCV_HEADER_VERSION_MAJOR 0
-#define RISCV_HEADER_VERSION_MINOR 1
+#define RISCV_HEADER_VERSION_MINOR 2
 
 #define RISCV_HEADER_VERSION (RISCV_HEADER_VERSION_MAJOR << 16 | \
                              RISCV_HEADER_VERSION_MINOR)
@@ -39,9 +40,8 @@
  * @version:           version
  * @res1:              reserved
  * @res2:              reserved
- * @magic:             Magic number
- * @res3:              reserved (will be used for additional RISC-V specific
- *                     header)
+ * @magic:             Magic number (RISC-V specific; deprecated)
+ * @magic2:            Magic number 2 (to match the ARM64 'magic' field pos)
  * @res4:              reserved (will be used for PE COFF offset)
  *
  * The intention is for this header format to be shared between multiple
@@ -58,7 +58,7 @@ struct riscv_image_header {
        u32 res1;
        u64 res2;
        u64 magic;
-       u32 res3;
+       u32 magic2;
        u32 res4;
 };
 #endif /* __ASSEMBLY__ */
index 707e00a..3db261c 100644 (file)
@@ -110,8 +110,10 @@ extern unsigned long min_low_pfn;
 #define page_to_bus(page)      (page_to_phys(page))
 #define phys_to_page(paddr)    (pfn_to_page(phys_to_pfn(paddr)))
 
+#ifdef CONFIG_FLATMEM
 #define pfn_valid(pfn) \
        (((pfn) >= pfn_base) && (((pfn)-pfn_base) < max_mapnr))
+#endif
 
 #define ARCH_PFN_OFFSET                (pfn_base)
 
index a364aba..80905b2 100644 (file)
@@ -84,6 +84,19 @@ extern pgd_t swapper_pg_dir[];
 #define __S111 PAGE_SHARED_EXEC
 
 /*
+ * Roughly size the vmemmap space to be large enough to fit enough
+ * struct pages to map half the virtual address space. Then
+ * position vmemmap directly below the VMALLOC region.
+ */
+#define VMEMMAP_SHIFT \
+       (CONFIG_VA_BITS - PAGE_SHIFT - 1 + STRUCT_PAGE_MAX_SHIFT)
+#define VMEMMAP_SIZE   BIT(VMEMMAP_SHIFT)
+#define VMEMMAP_END    (VMALLOC_START - 1)
+#define VMEMMAP_START  (VMALLOC_START - VMEMMAP_SIZE)
+
+#define vmemmap                ((struct page *)VMEMMAP_START)
+
+/*
  * ZERO_PAGE is a global shared page that is always zero,
  * used for zero-mapped memory areas, etc.
  */
@@ -420,14 +433,22 @@ static inline void pgtable_cache_init(void)
 #define VMALLOC_END      (PAGE_OFFSET - 1)
 #define VMALLOC_START    (PAGE_OFFSET - VMALLOC_SIZE)
 
+#define FIXADDR_TOP      VMALLOC_START
+#ifdef CONFIG_64BIT
+#define FIXADDR_SIZE     PMD_SIZE
+#else
+#define FIXADDR_SIZE     PGDIR_SIZE
+#endif
+#define FIXADDR_START    (FIXADDR_TOP - FIXADDR_SIZE)
+
 /*
- * Task size is 0x4000000000 for RV64 or 0xb800000 for RV32.
+ * Task size is 0x4000000000 for RV64 or 0x9fc00000 for RV32.
  * Note that PGDIR_SIZE must evenly divide TASK_SIZE.
  */
 #ifdef CONFIG_64BIT
 #define TASK_SIZE (PGDIR_SIZE * PTRS_PER_PGD / 2)
 #else
-#define TASK_SIZE VMALLOC_START
+#define TASK_SIZE FIXADDR_START
 #endif
 
 #include <asm-generic/pgtable.h>
index c6ed4d6..a83451d 100644 (file)
@@ -61,11 +61,5 @@ static inline unsigned long cpuid_to_hartid_map(int cpu)
        return boot_cpu_hartid;
 }
 
-static inline void riscv_cpuid_to_hartid_mask(const struct cpumask *in,
-                                             struct cpumask *out)
-{
-       cpumask_set_cpu(cpuid_to_hartid_map(0), out);
-}
-
 #endif /* CONFIG_SMP */
 #endif /* _ASM_RISCV_SMP_H */
diff --git a/arch/riscv/include/asm/sparsemem.h b/arch/riscv/include/asm/sparsemem.h
new file mode 100644 (file)
index 0000000..b58ba2d
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __ASM_SPARSEMEM_H
+#define __ASM_SPARSEMEM_H
+
+#ifdef CONFIG_SPARSEMEM
+#define MAX_PHYSMEM_BITS       CONFIG_PA_BITS
+#define SECTION_SIZE_BITS      27
+#endif /* CONFIG_SPARSEMEM */
+
+#endif /* __ASM_SPARSEMEM_H */
index 6a703ec..c7ef131 100644 (file)
@@ -6,43 +6,41 @@
 #ifndef _ASM_RISCV_TIMEX_H
 #define _ASM_RISCV_TIMEX_H
 
-#include <asm/param.h>
+#include <asm/csr.h>
 
 typedef unsigned long cycles_t;
 
-static inline cycles_t get_cycles_inline(void)
+static inline cycles_t get_cycles(void)
 {
-       cycles_t n;
-
-       __asm__ __volatile__ (
-               "rdtime %0"
-               : "=r" (n));
-       return n;
+       return csr_read(CSR_TIME);
 }
-#define get_cycles get_cycles_inline
+#define get_cycles get_cycles
 
 #ifdef CONFIG_64BIT
-static inline uint64_t get_cycles64(void)
+static inline u64 get_cycles64(void)
+{
+       return get_cycles();
+}
+#else /* CONFIG_64BIT */
+static inline u32 get_cycles_hi(void)
 {
-        return get_cycles();
+       return csr_read(CSR_TIMEH);
 }
-#else
-static inline uint64_t get_cycles64(void)
+
+static inline u64 get_cycles64(void)
 {
-       u32 lo, hi, tmp;
-       __asm__ __volatile__ (
-               "1:\n"
-               "rdtimeh %0\n"
-               "rdtime %1\n"
-               "rdtimeh %2\n"
-               "bne %0, %2, 1b"
-               : "=&r" (hi), "=&r" (lo), "=&r" (tmp));
+       u32 hi, lo;
+
+       do {
+               hi = get_cycles_hi();
+               lo = get_cycles();
+       } while (hi != get_cycles_hi());
+
        return ((u64)hi << 32) | lo;
 }
-#endif
+#endif /* CONFIG_64BIT */
 
 #define ARCH_HAS_READ_CURRENT_TIMER
-
 static inline int read_current_timer(unsigned long *timer_val)
 {
        *timer_val = get_cycles();
index 4d9bbe8..37ae4e3 100644 (file)
@@ -25,8 +25,13 @@ static inline void local_flush_tlb_page(unsigned long addr)
        __asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory");
 }
 
-#ifndef CONFIG_SMP
-
+#ifdef CONFIG_SMP
+void flush_tlb_all(void);
+void flush_tlb_mm(struct mm_struct *mm);
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
+void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+                    unsigned long end);
+#else /* CONFIG_SMP */
 #define flush_tlb_all() local_flush_tlb_all()
 #define flush_tlb_page(vma, addr) local_flush_tlb_page(addr)
 
@@ -37,35 +42,6 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
 }
 
 #define flush_tlb_mm(mm) flush_tlb_all()
-
-#else /* CONFIG_SMP */
-
-#include <asm/sbi.h>
-
-static inline void remote_sfence_vma(struct cpumask *cmask, unsigned long start,
-                                    unsigned long size)
-{
-       struct cpumask hmask;
-
-       cpumask_clear(&hmask);
-       riscv_cpuid_to_hartid_mask(cmask, &hmask);
-       sbi_remote_sfence_vma(hmask.bits, start, size);
-}
-
-#define flush_tlb_all() sbi_remote_sfence_vma(NULL, 0, -1)
-
-#define flush_tlb_range(vma, start, end) \
-       remote_sfence_vma(mm_cpumask((vma)->vm_mm), start, (end) - (start))
-
-static inline void flush_tlb_page(struct vm_area_struct *vma,
-                                 unsigned long addr)
-{
-       flush_tlb_range(vma, addr, addr + PAGE_SIZE);
-}
-
-#define flush_tlb_mm(mm)                               \
-       remote_sfence_vma(mm_cpumask(mm), 0, -1)
-
 #endif /* CONFIG_SMP */
 
 /* Flush a range of kernel pages */
diff --git a/arch/riscv/include/uapi/asm/perf_regs.h b/arch/riscv/include/uapi/asm/perf_regs.h
new file mode 100644 (file)
index 0000000..196f964
--- /dev/null
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#ifndef _ASM_RISCV_PERF_REGS_H
+#define _ASM_RISCV_PERF_REGS_H
+
+enum perf_event_riscv_regs {
+       PERF_REG_RISCV_PC,
+       PERF_REG_RISCV_RA,
+       PERF_REG_RISCV_SP,
+       PERF_REG_RISCV_GP,
+       PERF_REG_RISCV_TP,
+       PERF_REG_RISCV_T0,
+       PERF_REG_RISCV_T1,
+       PERF_REG_RISCV_T2,
+       PERF_REG_RISCV_S0,
+       PERF_REG_RISCV_S1,
+       PERF_REG_RISCV_A0,
+       PERF_REG_RISCV_A1,
+       PERF_REG_RISCV_A2,
+       PERF_REG_RISCV_A3,
+       PERF_REG_RISCV_A4,
+       PERF_REG_RISCV_A5,
+       PERF_REG_RISCV_A6,
+       PERF_REG_RISCV_A7,
+       PERF_REG_RISCV_S2,
+       PERF_REG_RISCV_S3,
+       PERF_REG_RISCV_S4,
+       PERF_REG_RISCV_S5,
+       PERF_REG_RISCV_S6,
+       PERF_REG_RISCV_S7,
+       PERF_REG_RISCV_S8,
+       PERF_REG_RISCV_S9,
+       PERF_REG_RISCV_S10,
+       PERF_REG_RISCV_S11,
+       PERF_REG_RISCV_T3,
+       PERF_REG_RISCV_T4,
+       PERF_REG_RISCV_T5,
+       PERF_REG_RISCV_T6,
+       PERF_REG_RISCV_MAX,
+};
+#endif /* _ASM_RISCV_PERF_REGS_H */
index 2420d37..696020f 100644 (file)
@@ -38,6 +38,8 @@ obj-$(CONFIG_MODULE_SECTIONS) += module-sections.o
 obj-$(CONFIG_FUNCTION_TRACER)  += mcount.o ftrace.o
 obj-$(CONFIG_DYNAMIC_FTRACE)   += mcount-dyn.o
 
-obj-$(CONFIG_PERF_EVENTS)      += perf_event.o
+obj-$(CONFIG_PERF_EVENTS)      += perf_event.o
+obj-$(CONFIG_PERF_EVENTS)      += perf_callchain.o
+obj-$(CONFIG_HAVE_PERF_REGS)   += perf_regs.o
 
 clean:
index bc7a56e..74ccfd4 100644 (file)
@@ -167,7 +167,7 @@ ENTRY(handle_exception)
        tail do_IRQ
 1:
        /* Exceptions run with interrupts enabled */
-       csrs sstatus, SR_SIE
+       csrs CSR_SSTATUS, SR_SIE
 
        /* Handle syscalls */
        li t0, EXC_SYSCALL
@@ -222,7 +222,7 @@ ret_from_syscall:
 
 ret_from_exception:
        REG_L s0, PT_SSTATUS(sp)
-       csrc sstatus, SR_SIE
+       csrc CSR_SSTATUS, SR_SIE
        andi s0, s0, SR_SPP
        bnez s0, resume_kernel
 
@@ -265,7 +265,7 @@ work_pending:
        bnez s1, work_resched
 work_notifysig:
        /* Handle pending signals and notify-resume requests */
-       csrs sstatus, SR_SIE /* Enable interrupts for do_notify_resume() */
+       csrs CSR_SSTATUS, SR_SIE /* Enable interrupts for do_notify_resume() */
        move a0, sp /* pt_regs */
        move a1, s0 /* current_thread_info->flags */
        tail do_notify_resume
index 1defb06..631d315 100644 (file)
@@ -23,7 +23,7 @@ ENTRY(__fstate_save)
        li  a2,  TASK_THREAD_F0
        add a0, a0, a2
        li t1, SR_FS
-       csrs sstatus, t1
+       csrs CSR_SSTATUS, t1
        frcsr t0
        fsd f0,  TASK_THREAD_F0_F0(a0)
        fsd f1,  TASK_THREAD_F1_F0(a0)
@@ -58,7 +58,7 @@ ENTRY(__fstate_save)
        fsd f30, TASK_THREAD_F30_F0(a0)
        fsd f31, TASK_THREAD_F31_F0(a0)
        sw t0, TASK_THREAD_FCSR_F0(a0)
-       csrc sstatus, t1
+       csrc CSR_SSTATUS, t1
        ret
 ENDPROC(__fstate_save)
 
@@ -67,7 +67,7 @@ ENTRY(__fstate_restore)
        add a0, a0, a2
        li t1, SR_FS
        lw t0, TASK_THREAD_FCSR_F0(a0)
-       csrs sstatus, t1
+       csrs CSR_SSTATUS, t1
        fld f0,  TASK_THREAD_F0_F0(a0)
        fld f1,  TASK_THREAD_F1_F0(a0)
        fld f2,  TASK_THREAD_F2_F0(a0)
@@ -101,6 +101,6 @@ ENTRY(__fstate_restore)
        fld f30, TASK_THREAD_F30_F0(a0)
        fld f31, TASK_THREAD_F31_F0(a0)
        fscsr t0
-       csrc sstatus, t1
+       csrc CSR_SSTATUS, t1
        ret
 ENDPROC(__fstate_restore)
index 0f1ba17..15a9189 100644 (file)
@@ -39,9 +39,9 @@ ENTRY(_start)
        .word RISCV_HEADER_VERSION
        .word 0
        .dword 0
-       .asciz RISCV_IMAGE_MAGIC
-       .word 0
+       .ascii RISCV_IMAGE_MAGIC
        .balign 4
+       .ascii RISCV_IMAGE_MAGIC2
        .word 0
 
 .global _start_kernel
@@ -61,7 +61,7 @@ _start_kernel:
         * floating point in kernel space
         */
        li t0, SR_FS
-       csrc sstatus, t0
+       csrc CSR_SSTATUS, t0
 
        /* Pick one hart to run the main boot sequence */
        la a3, hart_lottery
diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c
new file mode 100644 (file)
index 0000000..8d2804f
--- /dev/null
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#include <linux/perf_event.h>
+#include <linux/uaccess.h>
+
+/* Kernel callchain */
+struct stackframe {
+       unsigned long fp;
+       unsigned long ra;
+};
+
+/*
+ * Get the return address for a single stackframe and return a pointer to the
+ * next frame tail.
+ */
+static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry,
+                                   unsigned long fp, unsigned long reg_ra)
+{
+       struct stackframe buftail;
+       unsigned long ra = 0;
+       unsigned long *user_frame_tail =
+                       (unsigned long *)(fp - sizeof(struct stackframe));
+
+       /* Check accessibility of one struct frame_tail beyond */
+       if (!access_ok(user_frame_tail, sizeof(buftail)))
+               return 0;
+       if (__copy_from_user_inatomic(&buftail, user_frame_tail,
+                                     sizeof(buftail)))
+               return 0;
+
+       if (reg_ra != 0)
+               ra = reg_ra;
+       else
+               ra = buftail.ra;
+
+       fp = buftail.fp;
+       if (ra != 0)
+               perf_callchain_store(entry, ra);
+       else
+               return 0;
+
+       return fp;
+}
+
+/*
+ * This will be called when the target is in user mode
+ * This function will only be called when we use
+ * "PERF_SAMPLE_CALLCHAIN" in
+ * kernel/events/core.c:perf_prepare_sample()
+ *
+ * How to trigger perf_callchain_[user/kernel] :
+ * $ perf record -e cpu-clock --call-graph fp ./program
+ * $ perf report --call-graph
+ *
+ * On RISC-V platform, the program being sampled and the C library
+ * need to be compiled with -fno-omit-frame-pointer, otherwise
+ * the user stack will not contain function frame.
+ */
+void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
+                        struct pt_regs *regs)
+{
+       unsigned long fp = 0;
+
+       /* RISC-V does not support perf in guest mode. */
+       if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
+               return;
+
+       fp = regs->s0;
+       perf_callchain_store(entry, regs->sepc);
+
+       fp = user_backtrace(entry, fp, regs->ra);
+       while (fp && !(fp & 0x3) && entry->nr < entry->max_stack)
+               fp = user_backtrace(entry, fp, 0);
+}
+
+bool fill_callchain(unsigned long pc, void *entry)
+{
+       return perf_callchain_store(entry, pc);
+}
+
+void notrace walk_stackframe(struct task_struct *task,
+       struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg);
+void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
+                          struct pt_regs *regs)
+{
+       /* RISC-V does not support perf in guest mode. */
+       if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+               pr_warn("RISC-V does not support perf in guest mode!");
+               return;
+       }
+
+       walk_stackframe(NULL, regs, fill_callchain, entry);
+}
diff --git a/arch/riscv/kernel/perf_regs.c b/arch/riscv/kernel/perf_regs.c
new file mode 100644 (file)
index 0000000..04a38fb
--- /dev/null
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/perf_event.h>
+#include <linux/bug.h>
+#include <asm/perf_regs.h>
+#include <asm/ptrace.h>
+
+u64 perf_reg_value(struct pt_regs *regs, int idx)
+{
+       if (WARN_ON_ONCE((u32)idx >= PERF_REG_RISCV_MAX))
+               return 0;
+
+       return ((unsigned long *)regs)[idx];
+}
+
+#define REG_RESERVED (~((1ULL << PERF_REG_RISCV_MAX) - 1))
+
+int perf_reg_validate(u64 mask)
+{
+       if (!mask || mask & REG_RESERVED)
+               return -EINVAL;
+
+       return 0;
+}
+
+u64 perf_reg_abi(struct task_struct *task)
+{
+#if __riscv_xlen == 64
+       return PERF_SAMPLE_REGS_ABI_64;
+#else
+       return PERF_SAMPLE_REGS_ABI_32;
+#endif
+}
+
+void perf_get_regs_user(struct perf_regs *regs_user,
+                       struct pt_regs *regs,
+                       struct pt_regs *regs_user_copy)
+{
+       regs_user->regs = task_pt_regs(current);
+       regs_user->abi = perf_reg_abi(current);
+}
index 5a98345..3836760 100644 (file)
@@ -56,6 +56,7 @@ void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out)
 {
        int cpu;
 
+       cpumask_clear(out);
        for_each_cpu(cpu, in)
                cpumask_set_cpu(cpuid_to_hartid_map(cpu), out);
 }
@@ -78,13 +79,42 @@ static void ipi_stop(void)
                wait_for_interrupt();
 }
 
+static void send_ipi_mask(const struct cpumask *mask, enum ipi_message_type op)
+{
+       struct cpumask hartid_mask;
+       int cpu;
+
+       smp_mb__before_atomic();
+       for_each_cpu(cpu, mask)
+               set_bit(op, &ipi_data[cpu].bits);
+       smp_mb__after_atomic();
+
+       riscv_cpuid_to_hartid_mask(mask, &hartid_mask);
+       sbi_send_ipi(cpumask_bits(&hartid_mask));
+}
+
+static void send_ipi_single(int cpu, enum ipi_message_type op)
+{
+       int hartid = cpuid_to_hartid_map(cpu);
+
+       smp_mb__before_atomic();
+       set_bit(op, &ipi_data[cpu].bits);
+       smp_mb__after_atomic();
+
+       sbi_send_ipi(cpumask_bits(cpumask_of(hartid)));
+}
+
+static inline void clear_ipi(void)
+{
+       csr_clear(CSR_SIP, SIE_SSIE);
+}
+
 void riscv_software_interrupt(void)
 {
        unsigned long *pending_ipis = &ipi_data[smp_processor_id()].bits;
        unsigned long *stats = ipi_data[smp_processor_id()].stats;
 
-       /* Clear pending IPI */
-       csr_clear(CSR_SIP, SIE_SSIE);
+       clear_ipi();
 
        while (true) {
                unsigned long ops;
@@ -118,23 +148,6 @@ void riscv_software_interrupt(void)
        }
 }
 
-static void
-send_ipi_message(const struct cpumask *to_whom, enum ipi_message_type operation)
-{
-       int cpuid, hartid;
-       struct cpumask hartid_mask;
-
-       cpumask_clear(&hartid_mask);
-       mb();
-       for_each_cpu(cpuid, to_whom) {
-               set_bit(operation, &ipi_data[cpuid].bits);
-               hartid = cpuid_to_hartid_map(cpuid);
-               cpumask_set_cpu(hartid, &hartid_mask);
-       }
-       mb();
-       sbi_send_ipi(cpumask_bits(&hartid_mask));
-}
-
 static const char * const ipi_names[] = {
        [IPI_RESCHEDULE]        = "Rescheduling interrupts",
        [IPI_CALL_FUNC]         = "Function call interrupts",
@@ -156,12 +169,12 @@ void show_ipi_stats(struct seq_file *p, int prec)
 
 void arch_send_call_function_ipi_mask(struct cpumask *mask)
 {
-       send_ipi_message(mask, IPI_CALL_FUNC);
+       send_ipi_mask(mask, IPI_CALL_FUNC);
 }
 
 void arch_send_call_function_single_ipi(int cpu)
 {
-       send_ipi_message(cpumask_of(cpu), IPI_CALL_FUNC);
+       send_ipi_single(cpu, IPI_CALL_FUNC);
 }
 
 void smp_send_stop(void)
@@ -176,7 +189,7 @@ void smp_send_stop(void)
 
                if (system_state <= SYSTEM_RUNNING)
                        pr_crit("SMP: stopping secondary CPUs\n");
-               send_ipi_message(&mask, IPI_CPU_STOP);
+               send_ipi_mask(&mask, IPI_CPU_STOP);
        }
 
        /* Wait up to one second for other CPUs to stop */
@@ -191,6 +204,5 @@ void smp_send_stop(void)
 
 void smp_send_reschedule(int cpu)
 {
-       send_ipi_message(cpumask_of(cpu), IPI_RESCHEDULE);
+       send_ipi_single(cpu, IPI_RESCHEDULE);
 }
-
index 7462a44..18ae6da 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright (C) 2017 SiFive
  */
 
+#include <linux/arch_topology.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -35,6 +36,7 @@ static DECLARE_COMPLETION(cpu_running);
 
 void __init smp_prepare_boot_cpu(void)
 {
+       init_cpu_topology();
 }
 
 void __init smp_prepare_cpus(unsigned int max_cpus)
@@ -138,6 +140,7 @@ asmlinkage void __init smp_callin(void)
 
        trap_init();
        notify_cpu_starting(smp_processor_id());
+       update_siblings_masks(smp_processor_id());
        set_cpu_online(smp_processor_id(), 1);
        /*
         * Remote TLB flushes are ignored while the CPU is offline, so emit
index f156427..0940681 100644 (file)
@@ -19,8 +19,8 @@ struct stackframe {
        unsigned long ra;
 };
 
-static void notrace walk_stackframe(struct task_struct *task,
-       struct pt_regs *regs, bool (*fn)(unsigned long, void *), void *arg)
+void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs,
+                            bool (*fn)(unsigned long, void *), void *arg)
 {
        unsigned long fp, sp, pc;
 
index 399e6f0..ed2696c 100644 (file)
@@ -18,7 +18,7 @@ ENTRY(__asm_copy_from_user)
 
        /* Enable access to user memory */
        li t6, SR_SUM
-       csrs sstatus, t6
+       csrs CSR_SSTATUS, t6
 
        add a3, a1, a2
        /* Use word-oriented copy only if low-order bits match */
@@ -47,7 +47,7 @@ ENTRY(__asm_copy_from_user)
 
 3:
        /* Disable access to user memory */
-       csrc sstatus, t6
+       csrc CSR_SSTATUS, t6
        li a0, 0
        ret
 4: /* Edge case: unalignment */
@@ -72,7 +72,7 @@ ENTRY(__clear_user)
 
        /* Enable access to user memory */
        li t6, SR_SUM
-       csrs sstatus, t6
+       csrs CSR_SSTATUS, t6
 
        add a3, a0, a1
        addi t0, a0, SZREG-1
@@ -94,7 +94,7 @@ ENTRY(__clear_user)
 
 3:
        /* Disable access to user memory */
-       csrc sstatus, t6
+       csrc CSR_SSTATUS, t6
        li a0, 0
        ret
 4: /* Edge case: unalignment */
@@ -114,11 +114,11 @@ ENDPROC(__clear_user)
        /* Fixup code for __copy_user(10) and __clear_user(11) */
 10:
        /* Disable access to user memory */
-       csrs sstatus, t6
+       csrs CSR_SSTATUS, t6
        mv a0, a2
        ret
 11:
-       csrs sstatus, t6
+       csrs CSR_SSTATUS, t6
        mv a0, a1
        ret
        .previous
index 74055e1..9d9a173 100644 (file)
@@ -13,4 +13,7 @@ obj-y += cacheflush.o
 obj-y += context.o
 obj-y += sifive_l2_cache.o
 
+ifeq ($(CONFIG_MMU),y)
+obj-$(CONFIG_SMP) += tlbflush.o
+endif
 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
index 9ebcff8..3f15938 100644 (file)
@@ -47,7 +47,6 @@ void flush_icache_mm(struct mm_struct *mm, bool local)
        cpumask_andnot(&others, mm_cpumask(mm), cpumask_of(cpu));
        local |= cpumask_empty(&others);
        if (mm != current->active_mm || !local) {
-               cpumask_clear(&hmask);
                riscv_cpuid_to_hartid_mask(&others, &hmask);
                sbi_remote_fence_i(hmask.bits);
        } else {
index 89ceb3c..beeb5d7 100644 (file)
@@ -57,12 +57,7 @@ void switch_mm(struct mm_struct *prev, struct mm_struct *next,
        cpumask_clear_cpu(cpu, mm_cpumask(prev));
        cpumask_set_cpu(cpu, mm_cpumask(next));
 
-       /*
-        * Use the old spbtr name instead of using the current satp
-        * name to support binutils 2.29 which doesn't know about the
-        * privileged ISA 1.10 yet.
-        */
-       csr_write(sptbr, virt_to_pfn(next->pgd) | SATP_MODE);
+       csr_write(CSR_SATP, virt_to_pfn(next->pgd) | SATP_MODE);
        local_flush_tlb_all();
 
        flush_icache_deferred(next);
index 42bf939..f0ba713 100644 (file)
@@ -435,13 +435,23 @@ static void __init setup_vm_final(void)
        clear_fixmap(FIX_PMD);
 
        /* Move to swapper page table */
-       csr_write(sptbr, PFN_DOWN(__pa(swapper_pg_dir)) | SATP_MODE);
+       csr_write(CSR_SATP, PFN_DOWN(__pa(swapper_pg_dir)) | SATP_MODE);
        local_flush_tlb_all();
 }
 
 void __init paging_init(void)
 {
        setup_vm_final();
+       memblocks_present();
+       sparse_init();
        setup_zero_page();
        zone_sizes_init();
 }
+
+#ifdef CONFIG_SPARSEMEM
+int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node,
+                              struct vmem_altmap *altmap)
+{
+       return vmemmap_populate_basepages(start, end, node);
+}
+#endif
diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
new file mode 100644 (file)
index 0000000..24cd33d
--- /dev/null
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <asm/sbi.h>
+
+void flush_tlb_all(void)
+{
+       sbi_remote_sfence_vma(NULL, 0, -1);
+}
+
+static void __sbi_tlb_flush_range(struct cpumask *cmask, unsigned long start,
+                                 unsigned long size)
+{
+       struct cpumask hmask;
+
+       riscv_cpuid_to_hartid_mask(cmask, &hmask);
+       sbi_remote_sfence_vma(hmask.bits, start, size);
+}
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+       __sbi_tlb_flush_range(mm_cpumask(mm), 0, -1);
+}
+
+void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
+{
+       __sbi_tlb_flush_range(mm_cpumask(vma->vm_mm), addr, PAGE_SIZE);
+}
+
+void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+                    unsigned long end)
+{
+       __sbi_tlb_flush_range(mm_cpumask(vma->vm_mm), start, end - start);
+}
index b5fd6e8..d1ccc16 100644 (file)
@@ -1961,6 +1961,16 @@ int s390int_to_s390irq(struct kvm_s390_interrupt *s390int,
        case KVM_S390_MCHK:
                irq->u.mchk.mcic = s390int->parm64;
                break;
+       case KVM_S390_INT_PFAULT_INIT:
+               irq->u.ext.ext_params = s390int->parm;
+               irq->u.ext.ext_params2 = s390int->parm64;
+               break;
+       case KVM_S390_RESTART:
+       case KVM_S390_INT_CLOCK_COMP:
+       case KVM_S390_INT_CPU_TIMER:
+               break;
+       default:
+               return -EINVAL;
        }
        return 0;
 }
index f329dcb..39cff07 100644 (file)
@@ -1018,6 +1018,8 @@ static int kvm_s390_vm_start_migration(struct kvm *kvm)
        /* mark all the pages in active slots as dirty */
        for (slotnr = 0; slotnr < slots->used_slots; slotnr++) {
                ms = slots->memslots + slotnr;
+               if (!ms->dirty_bitmap)
+                       return -EINVAL;
                /*
                 * The second half of the bitmap is only used on x86,
                 * and would be wasted otherwise, so we put it to good
@@ -4323,7 +4325,7 @@ long kvm_arch_vcpu_async_ioctl(struct file *filp,
        }
        case KVM_S390_INTERRUPT: {
                struct kvm_s390_interrupt s390int;
-               struct kvm_s390_irq s390irq;
+               struct kvm_s390_irq s390irq = {};
 
                if (copy_from_user(&s390int, argp, sizeof(s390int)))
                        return -EFAULT;
index e636728..955eb35 100644 (file)
@@ -863,7 +863,7 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
                break;
        case BPF_ALU64 | BPF_NEG: /* dst = -dst */
                /* lcgr %dst,%dst */
-               EMIT4(0xb9130000, dst_reg, dst_reg);
+               EMIT4(0xb9030000, dst_reg, dst_reg);
                break;
        /*
         * BPF_FROM_BE/LE
@@ -1049,8 +1049,8 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
                /* llgf %w1,map.max_entries(%b2) */
                EMIT6_DISP_LH(0xe3000000, 0x0016, REG_W1, REG_0, BPF_REG_2,
                              offsetof(struct bpf_array, map.max_entries));
-               /* clgrj %b3,%w1,0xa,label0: if %b3 >= %w1 goto out */
-               EMIT6_PCREL_LABEL(0xec000000, 0x0065, BPF_REG_3,
+               /* clrj %b3,%w1,0xa,label0: if (u32)%b3 >= (u32)%w1 goto out */
+               EMIT6_PCREL_LABEL(0xec000000, 0x0077, BPF_REG_3,
                                  REG_W1, 0, 0xa);
 
                /*
@@ -1076,8 +1076,10 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp, int i
                 *         goto out;
                 */
 
-               /* sllg %r1,%b3,3: %r1 = index * 8 */
-               EMIT6_DISP_LH(0xeb000000, 0x000d, REG_1, BPF_REG_3, REG_0, 3);
+               /* llgfr %r1,%b3: %r1 = (u32) index */
+               EMIT4(0xb9160000, REG_1, BPF_REG_3);
+               /* sllg %r1,%r1,3: %r1 *= 8 */
+               EMIT6_DISP_LH(0xeb000000, 0x000d, REG_1, REG_1, REG_0, 3);
                /* lg %r1,prog(%b2,%r1) */
                EMIT6_DISP_LH(0xe3000000, 0x0004, REG_1, BPF_REG_2,
                              REG_1, offsetof(struct bpf_array, ptrs));
index ccc8892..9f41a6f 100644 (file)
@@ -336,25 +336,28 @@ SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second
 {
        long err;
 
+       if (!IS_ENABLED(CONFIG_SYSVIPC))
+               return -ENOSYS;
+
        /* No need for backward compatibility. We can start fresh... */
        if (call <= SEMTIMEDOP) {
                switch (call) {
                case SEMOP:
-                       err = sys_semtimedop(first, ptr,
-                                            (unsigned int)second, NULL);
+                       err = ksys_semtimedop(first, ptr,
+                                             (unsigned int)second, NULL);
                        goto out;
                case SEMTIMEDOP:
-                       err = sys_semtimedop(first, ptr, (unsigned int)second,
+                       err = ksys_semtimedop(first, ptr, (unsigned int)second,
                                (const struct __kernel_timespec __user *)
-                                            (unsigned long) fifth);
+                                             (unsigned long) fifth);
                        goto out;
                case SEMGET:
-                       err = sys_semget(first, (int)second, (int)third);
+                       err = ksys_semget(first, (int)second, (int)third);
                        goto out;
                case SEMCTL: {
-                       err = sys_semctl(first, second,
-                                        (int)third | IPC_64,
-                                        (unsigned long) ptr);
+                       err = ksys_old_semctl(first, second,
+                                             (int)third | IPC_64,
+                                             (unsigned long) ptr);
                        goto out;
                }
                default:
@@ -365,18 +368,18 @@ SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second
        if (call <= MSGCTL) {
                switch (call) {
                case MSGSND:
-                       err = sys_msgsnd(first, ptr, (size_t)second,
+                       err = ksys_msgsnd(first, ptr, (size_t)second,
                                         (int)third);
                        goto out;
                case MSGRCV:
-                       err = sys_msgrcv(first, ptr, (size_t)second, fifth,
+                       err = ksys_msgrcv(first, ptr, (size_t)second, fifth,
                                         (int)third);
                        goto out;
                case MSGGET:
-                       err = sys_msgget((key_t)first, (int)second);
+                       err = ksys_msgget((key_t)first, (int)second);
                        goto out;
                case MSGCTL:
-                       err = sys_msgctl(first, (int)second | IPC_64, ptr);
+                       err = ksys_old_msgctl(first, (int)second | IPC_64, ptr);
                        goto out;
                default:
                        err = -ENOSYS;
@@ -396,13 +399,13 @@ SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second
                        goto out;
                }
                case SHMDT:
-                       err = sys_shmdt(ptr);
+                       err = ksys_shmdt(ptr);
                        goto out;
                case SHMGET:
-                       err = sys_shmget(first, (size_t)second, (int)third);
+                       err = ksys_shmget(first, (size_t)second, (int)third);
                        goto out;
                case SHMCTL:
-                       err = sys_shmctl(first, (int)second | IPC_64, ptr);
+                       err = ksys_old_shmctl(first, (int)second | IPC_64, ptr);
                        goto out;
                default:
                        err = -ENOSYS;
index d112982..c014ae3 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/kallsyms.h>
 #include <linux/proc_fs.h>
 #include <linux/syscore_ops.h>
-#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 
index 56e748a..94df086 100644 (file)
@@ -38,6 +38,7 @@ REALMODE_CFLAGS       := $(M16_CFLAGS) -g -Os -DDISABLE_BRANCH_PROFILING \
 
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -ffreestanding)
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -fno-stack-protector)
+REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), -Wno-address-of-packed-member)
 REALMODE_CFLAGS += $(call __cc-option, $(CC), $(REALMODE_CFLAGS), $(cc_stack_align4))
 export REALMODE_CFLAGS
 
index 2faddeb..c886269 100644 (file)
@@ -72,7 +72,7 @@ static unsigned long find_trampoline_placement(void)
 
        /* Find the first usable memory region under bios_start. */
        for (i = boot_params->e820_entries - 1; i >= 0; i--) {
-               unsigned long new;
+               unsigned long new = bios_start;
 
                entry = &boot_params->e820_table[i];
 
index 62f317c..5b35b7e 100644 (file)
@@ -661,10 +661,17 @@ fail:
 
        throttle = perf_event_overflow(event, &data, &regs);
 out:
-       if (throttle)
+       if (throttle) {
                perf_ibs_stop(event, 0);
-       else
-               perf_ibs_enable_event(perf_ibs, hwc, period >> 4);
+       } else {
+               period >>= 4;
+
+               if ((ibs_caps & IBS_CAPS_RDWROPCNT) &&
+                   (*config & IBS_OP_CNT_CTL))
+                       period |= *config & IBS_OP_CUR_CNT_RAND;
+
+               perf_ibs_enable_event(perf_ibs, hwc, period);
+       }
 
        perf_event_update_userpage(event);
 
index 648260b..e4c2cb6 100644 (file)
@@ -3572,6 +3572,11 @@ static u64 bdw_limit_period(struct perf_event *event, u64 left)
        return left;
 }
 
+static u64 nhm_limit_period(struct perf_event *event, u64 left)
+{
+       return max(left, 32ULL);
+}
+
 PMU_FORMAT_ATTR(event, "config:0-7"    );
 PMU_FORMAT_ATTR(umask, "config:8-15"   );
 PMU_FORMAT_ATTR(edge,  "config:18"     );
@@ -4606,6 +4611,7 @@ __init int intel_pmu_init(void)
                x86_pmu.pebs_constraints = intel_nehalem_pebs_event_constraints;
                x86_pmu.enable_all = intel_pmu_nhm_enable_all;
                x86_pmu.extra_regs = intel_nehalem_extra_regs;
+               x86_pmu.limit_period = nhm_limit_period;
 
                mem_attr = nhm_mem_events_attrs;
 
index e65d7fe..5208ba4 100644 (file)
@@ -37,12 +37,14 @@ static inline int fill_gva_list(u64 gva_list[], int offset,
                 * Lower 12 bits encode the number of additional
                 * pages to flush (in addition to the 'cur' page).
                 */
-               if (diff >= HV_TLB_FLUSH_UNIT)
+               if (diff >= HV_TLB_FLUSH_UNIT) {
                        gva_list[gva_n] |= ~PAGE_MASK;
-               else if (diff)
+                       cur += HV_TLB_FLUSH_UNIT;
+               }  else if (diff) {
                        gva_list[gva_n] |= (diff - 1) >> PAGE_SHIFT;
+                       cur = end;
+               }
 
-               cur += HV_TLB_FLUSH_UNIT;
                gva_n++;
 
        } while (cur < end);
index 9e5f3c7..981fe92 100644 (file)
@@ -70,6 +70,7 @@ static void sanitize_boot_params(struct boot_params *boot_params)
                        BOOT_PARAM_PRESERVE(eddbuf_entries),
                        BOOT_PARAM_PRESERVE(edd_mbr_sig_buf_entries),
                        BOOT_PARAM_PRESERVE(edd_mbr_sig_buffer),
+                       BOOT_PARAM_PRESERVE(secure_boot),
                        BOOT_PARAM_PRESERVE(hdr),
                        BOOT_PARAM_PRESERVE(e820_table),
                        BOOT_PARAM_PRESERVE(eddbuf),
diff --git a/arch/x86/include/asm/error-injection.h b/arch/x86/include/asm/error-injection.h
deleted file mode 100644 (file)
index 47b7a12..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _ASM_ERROR_INJECTION_H
-#define _ASM_ERROR_INJECTION_H
-
-#include <linux/compiler.h>
-#include <linux/linkage.h>
-#include <asm/ptrace.h>
-#include <asm-generic/error-injection.h>
-
-asmlinkage void just_return_func(void);
-void override_function_with_return(struct pt_regs *regs);
-
-#endif /* _ASM_ERROR_INJECTION_H */
index 287f1f7..c38a666 100644 (file)
@@ -16,7 +16,6 @@
 #define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
 
 #ifndef __ASSEMBLY__
-extern void mcount(void);
 extern atomic_t modifying_ftrace_code;
 extern void __fentry__(void);
 
index baedab8..b91623d 100644 (file)
@@ -4,7 +4,6 @@
 
 extern int force_iommu, no_iommu;
 extern int iommu_detected;
-extern int iommu_pass_through;
 
 /* 10 seconds */
 #define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
index 74e88e5..bdc16b0 100644 (file)
@@ -335,6 +335,7 @@ struct kvm_mmu_page {
        int root_count;          /* Currently serving as active root */
        unsigned int unsync_children;
        struct kvm_rmap_head parent_ptes; /* rmap pointers to parent sptes */
+       unsigned long mmu_valid_gen;
        DECLARE_BITMAP(unsync_child_bitmap, 512);
 
 #ifdef CONFIG_X86_32
@@ -856,6 +857,7 @@ struct kvm_arch {
        unsigned long n_requested_mmu_pages;
        unsigned long n_max_mmu_pages;
        unsigned int indirect_shadow_pages;
+       unsigned long mmu_valid_gen;
        struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES];
        /*
         * Hash table of struct kvm_mmu_page.
index 1392d5e..ee26e92 100644 (file)
@@ -252,16 +252,20 @@ struct pebs_lbr {
 #define IBSCTL_LVT_OFFSET_VALID                (1ULL<<8)
 #define IBSCTL_LVT_OFFSET_MASK         0x0F
 
-/* ibs fetch bits/masks */
+/* IBS fetch bits/masks */
 #define IBS_FETCH_RAND_EN      (1ULL<<57)
 #define IBS_FETCH_VAL          (1ULL<<49)
 #define IBS_FETCH_ENABLE       (1ULL<<48)
 #define IBS_FETCH_CNT          0xFFFF0000ULL
 #define IBS_FETCH_MAX_CNT      0x0000FFFFULL
 
-/* ibs op bits/masks */
-/* lower 4 bits of the current count are ignored: */
-#define IBS_OP_CUR_CNT         (0xFFFF0ULL<<32)
+/*
+ * IBS op bits/masks
+ * The lower 7 bits of the current count are random bits
+ * preloaded by hardware and ignored in software
+ */
+#define IBS_OP_CUR_CNT         (0xFFF80ULL<<32)
+#define IBS_OP_CUR_CNT_RAND    (0x0007FULL<<32)
 #define IBS_OP_CNT_CTL         (1ULL<<19)
 #define IBS_OP_VAL             (1ULL<<18)
 #define IBS_OP_ENABLE          (1ULL<<17)
index 9c44353..35c225e 100644 (file)
@@ -444,8 +444,10 @@ __pu_label:                                                        \
 ({                                                                     \
        int __gu_err;                                                   \
        __inttype(*(ptr)) __gu_val;                                     \
+       __typeof__(ptr) __gu_ptr = (ptr);                               \
+       __typeof__(size) __gu_size = (size);                            \
        __uaccess_begin_nospec();                                       \
-       __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT);    \
+       __get_user_size(__gu_val, __gu_ptr, __gu_size, __gu_err, -EFAULT);      \
        __uaccess_end();                                                \
        (x) = (__force __typeof__(*(ptr)))__gu_val;                     \
        __builtin_expect(__gu_err, 0);                                  \
index d63e63b..251c795 100644 (file)
@@ -21,6 +21,7 @@
 #define PCI_DEVICE_ID_AMD_17H_DF_F4    0x1464
 #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F4 0x15ec
 #define PCI_DEVICE_ID_AMD_17H_M30H_DF_F4 0x1494
+#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F4 0x1444
 
 /* Protect the PCI config register pairs used for SMN and DF indirect access. */
 static DEFINE_MUTEX(smn_mutex);
@@ -50,6 +51,7 @@ const struct pci_device_id amd_nb_misc_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
        {}
 };
 EXPORT_SYMBOL_GPL(amd_nb_misc_ids);
@@ -63,6 +65,7 @@ static const struct pci_device_id amd_nb_link_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_DF_F4) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F4) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F4) },
+       { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F4) },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) },
        {}
 };
index aa5495d..08fb79f 100644 (file)
@@ -834,6 +834,10 @@ bool __init apic_needs_pit(void)
        if (!boot_cpu_has(X86_FEATURE_APIC))
                return true;
 
+       /* Virt guests may lack ARAT, but still have DEADLINE */
+       if (!boot_cpu_has(X86_FEATURE_ARAT))
+               return true;
+
        /* Deadline timer is based on TSC so no further PIT action required */
        if (boot_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER))
                return false;
index afee386..caedd8d 100644 (file)
@@ -38,32 +38,12 @@ static int bigsmp_early_logical_apicid(int cpu)
        return early_per_cpu(x86_cpu_to_apicid, cpu);
 }
 
-static inline unsigned long calculate_ldr(int cpu)
-{
-       unsigned long val, id;
-
-       val = apic_read(APIC_LDR) & ~APIC_LDR_MASK;
-       id = per_cpu(x86_bios_cpu_apicid, cpu);
-       val |= SET_APIC_LOGICAL_ID(id);
-
-       return val;
-}
-
 /*
- * Set up the logical destination ID.
- *
- * Intel recommends to set DFR, LDR and TPR before enabling
- * an APIC.  See e.g. "AP-388 82489DX User's Manual" (Intel
- * document number 292116).  So here it goes...
+ * bigsmp enables physical destination mode
+ * and doesn't use LDR and DFR
  */
 static void bigsmp_init_apic_ldr(void)
 {
-       unsigned long val;
-       int cpu = smp_processor_id();
-
-       apic_write(APIC_DFR, APIC_DFR_FLAT);
-       val = calculate_ldr(cpu);
-       apic_write(APIC_LDR, val);
 }
 
 static void bigsmp_setup_apic_routing(void)
index c7bb6c6..d6af97f 100644 (file)
@@ -2438,7 +2438,13 @@ unsigned int arch_dynirq_lower_bound(unsigned int from)
         * dmar_alloc_hwirq() may be called before setup_IO_APIC(), so use
         * gsi_top if ioapic_dynirq_base hasn't been initialized yet.
         */
-       return ioapic_initialized ? ioapic_dynirq_base : gsi_top;
+       if (!ioapic_initialized)
+               return gsi_top;
+       /*
+        * For DT enabled machines ioapic_dynirq_base is irrelevant and not
+        * updated. So simply return @from if ioapic_dynirq_base == 0.
+        */
+       return ioapic_dynirq_base ? : from;
 }
 
 #ifdef CONFIG_X86_32
index 210f1f5..87bcdc6 100644 (file)
@@ -107,11 +107,11 @@ static struct severity {
         */
        MCESEV(
                AO, "Action optional: memory scrubbing error",
-               SER, MASK(MCI_STATUS_OVER|MCI_UC_AR|MCACOD_SCRUBMSK, MCI_STATUS_UC|MCACOD_SCRUB)
+               SER, MASK(MCI_UC_AR|MCACOD_SCRUBMSK, MCI_STATUS_UC|MCACOD_SCRUB)
                ),
        MCESEV(
                AO, "Action optional: last level cache writeback error",
-               SER, MASK(MCI_STATUS_OVER|MCI_UC_AR|MCACOD, MCI_STATUS_UC|MCACOD_L3WB)
+               SER, MASK(MCI_UC_AR|MCACOD, MCI_STATUS_UC|MCACOD_L3WB)
                ),
 
        /* ignore OVER for UCNA */
index f62b498..fa4352d 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <linux/dma-direct.h>
 #include <linux/dma-debug.h>
+#include <linux/iommu.h>
 #include <linux/dmar.h>
 #include <linux/export.h>
 #include <linux/memblock.h>
@@ -34,21 +35,6 @@ int no_iommu __read_mostly;
 /* Set this to 1 if there is a HW IOMMU in the system */
 int iommu_detected __read_mostly = 0;
 
-/*
- * This variable becomes 1 if iommu=pt is passed on the kernel command line.
- * If this variable is 1, IOMMU implementations do no DMA translation for
- * devices and allow every device to access to whole physical memory. This is
- * useful if a user wants to use an IOMMU only for KVM device assignment to
- * guests and not for driver dma translation.
- * It is also possible to disable by default in kernel config, and enable with
- * iommu=nopt at boot time.
- */
-#ifdef CONFIG_IOMMU_DEFAULT_PASSTHROUGH
-int iommu_pass_through __read_mostly = 1;
-#else
-int iommu_pass_through __read_mostly;
-#endif
-
 extern struct iommu_table_entry __iommu_table[], __iommu_table_end[];
 
 void __init pci_iommu_alloc(void)
@@ -120,9 +106,9 @@ static __init int iommu_setup(char *p)
                        swiotlb = 1;
 #endif
                if (!strncmp(p, "pt", 2))
-                       iommu_pass_through = 1;
+                       iommu_set_default_passthrough(true);
                if (!strncmp(p, "nopt", 4))
-                       iommu_pass_through = 0;
+                       iommu_set_default_translated(true);
 
                gart_parse_options(p);
 
index d8359eb..8cd745e 100644 (file)
@@ -508,9 +508,12 @@ struct uprobe_xol_ops {
        void    (*abort)(struct arch_uprobe *, struct pt_regs *);
 };
 
-static inline int sizeof_long(void)
+static inline int sizeof_long(struct pt_regs *regs)
 {
-       return in_ia32_syscall() ? 4 : 8;
+       /*
+        * Check registers for mode as in_xxx_syscall() does not apply here.
+        */
+       return user_64bit_mode(regs) ? 8 : 4;
 }
 
 static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs)
@@ -521,9 +524,9 @@ static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs)
 
 static int emulate_push_stack(struct pt_regs *regs, unsigned long val)
 {
-       unsigned long new_sp = regs->sp - sizeof_long();
+       unsigned long new_sp = regs->sp - sizeof_long(regs);
 
-       if (copy_to_user((void __user *)new_sp, &val, sizeof_long()))
+       if (copy_to_user((void __user *)new_sp, &val, sizeof_long(regs)))
                return -EFAULT;
 
        regs->sp = new_sp;
@@ -556,7 +559,7 @@ static int default_post_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs
                long correction = utask->vaddr - utask->xol_vaddr;
                regs->ip += correction;
        } else if (auprobe->defparam.fixups & UPROBE_FIX_CALL) {
-               regs->sp += sizeof_long(); /* Pop incorrect return address */
+               regs->sp += sizeof_long(regs); /* Pop incorrect return address */
                if (emulate_push_stack(regs, utask->vaddr + auprobe->defparam.ilen))
                        return -ERESTART;
        }
@@ -675,7 +678,7 @@ static int branch_post_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs)
         * "call" insn was executed out-of-line. Just restore ->sp and restart.
         * We could also restore ->ip and try to call branch_emulate_op() again.
         */
-       regs->sp += sizeof_long();
+       regs->sp += sizeof_long(regs);
        return -ERESTART;
 }
 
@@ -1056,7 +1059,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
 unsigned long
 arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs *regs)
 {
-       int rasize = sizeof_long(), nleft;
+       int rasize = sizeof_long(regs), nleft;
        unsigned long orig_ret_vaddr = 0; /* clear high bits for 32-bit apps */
 
        if (copy_from_user(&orig_ret_vaddr, (void __user *)regs->sp, rasize))
index c10a8b1..fff790a 100644 (file)
@@ -1781,7 +1781,7 @@ int kvm_vm_ioctl_hv_eventfd(struct kvm *kvm, struct kvm_hyperv_eventfd *args)
 int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
                                struct kvm_cpuid_entry2 __user *entries)
 {
-       uint16_t evmcs_ver = kvm_x86_ops->nested_get_evmcs_version(vcpu);
+       uint16_t evmcs_ver = 0;
        struct kvm_cpuid_entry2 cpuid_entries[] = {
                { .function = HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS },
                { .function = HYPERV_CPUID_INTERFACE },
@@ -1793,6 +1793,9 @@ int kvm_vcpu_ioctl_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
        };
        int i, nent = ARRAY_SIZE(cpuid_entries);
 
+       if (kvm_x86_ops->nested_get_evmcs_version)
+               evmcs_ver = kvm_x86_ops->nested_get_evmcs_version(vcpu);
+
        /* Skip NESTED_FEATURES if eVMCS is not supported */
        if (!evmcs_ver)
                --nent;
index 218b277..a63964e 100644 (file)
@@ -2095,6 +2095,12 @@ static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu, int direct
        if (!direct)
                sp->gfns = mmu_memory_cache_alloc(&vcpu->arch.mmu_page_cache);
        set_page_private(virt_to_page(sp->spt), (unsigned long)sp);
+
+       /*
+        * active_mmu_pages must be a FIFO list, as kvm_zap_obsolete_pages()
+        * depends on valid pages being added to the head of the list.  See
+        * comments in kvm_zap_obsolete_pages().
+        */
        list_add(&sp->link, &vcpu->kvm->arch.active_mmu_pages);
        kvm_mod_used_mmu_pages(vcpu->kvm, +1);
        return sp;
@@ -2244,7 +2250,7 @@ static void kvm_mmu_commit_zap_page(struct kvm *kvm,
 #define for_each_valid_sp(_kvm, _sp, _gfn)                             \
        hlist_for_each_entry(_sp,                                       \
          &(_kvm)->arch.mmu_page_hash[kvm_page_table_hashfn(_gfn)], hash_link) \
-               if ((_sp)->role.invalid) {    \
+               if (is_obsolete_sp((_kvm), (_sp)) || (_sp)->role.invalid) {    \
                } else
 
 #define for_each_gfn_indirect_valid_sp(_kvm, _sp, _gfn)                        \
@@ -2301,6 +2307,11 @@ static void kvm_mmu_audit(struct kvm_vcpu *vcpu, int point) { }
 static void mmu_audit_disable(void) { }
 #endif
 
+static bool is_obsolete_sp(struct kvm *kvm, struct kvm_mmu_page *sp)
+{
+       return unlikely(sp->mmu_valid_gen != kvm->arch.mmu_valid_gen);
+}
+
 static bool kvm_sync_page(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
                         struct list_head *invalid_list)
 {
@@ -2525,6 +2536,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
                if (level > PT_PAGE_TABLE_LEVEL && need_sync)
                        flush |= kvm_sync_pages(vcpu, gfn, &invalid_list);
        }
+       sp->mmu_valid_gen = vcpu->kvm->arch.mmu_valid_gen;
        clear_page(sp->spt);
        trace_kvm_mmu_get_page(sp, true);
 
@@ -4233,6 +4245,13 @@ static bool fast_cr3_switch(struct kvm_vcpu *vcpu, gpa_t new_cr3,
                        return false;
 
                if (cached_root_available(vcpu, new_cr3, new_role)) {
+                       /*
+                        * It is possible that the cached previous root page is
+                        * obsolete because of a change in the MMU generation
+                        * number. However, changing the generation number is
+                        * accompanied by KVM_REQ_MMU_RELOAD, which will free
+                        * the root set here and allocate a new one.
+                        */
                        kvm_make_request(KVM_REQ_LOAD_CR3, vcpu);
                        if (!skip_tlb_flush) {
                                kvm_make_request(KVM_REQ_MMU_SYNC, vcpu);
@@ -5649,11 +5668,89 @@ int kvm_mmu_create(struct kvm_vcpu *vcpu)
        return alloc_mmu_pages(vcpu);
 }
 
+
+static void kvm_zap_obsolete_pages(struct kvm *kvm)
+{
+       struct kvm_mmu_page *sp, *node;
+       LIST_HEAD(invalid_list);
+       int ign;
+
+restart:
+       list_for_each_entry_safe_reverse(sp, node,
+             &kvm->arch.active_mmu_pages, link) {
+               /*
+                * No obsolete valid page exists before a newly created page
+                * since active_mmu_pages is a FIFO list.
+                */
+               if (!is_obsolete_sp(kvm, sp))
+                       break;
+
+               /*
+                * Do not repeatedly zap a root page to avoid unnecessary
+                * KVM_REQ_MMU_RELOAD, otherwise we may not be able to
+                * progress:
+                *    vcpu 0                        vcpu 1
+                *                         call vcpu_enter_guest():
+                *                            1): handle KVM_REQ_MMU_RELOAD
+                *                                and require mmu-lock to
+                *                                load mmu
+                * repeat:
+                *    1): zap root page and
+                *        send KVM_REQ_MMU_RELOAD
+                *
+                *    2): if (cond_resched_lock(mmu-lock))
+                *
+                *                            2): hold mmu-lock and load mmu
+                *
+                *                            3): see KVM_REQ_MMU_RELOAD bit
+                *                                on vcpu->requests is set
+                *                                then return 1 to call
+                *                                vcpu_enter_guest() again.
+                *            goto repeat;
+                *
+                * Since we are reversely walking the list and the invalid
+                * list will be moved to the head, skip the invalid page
+                * can help us to avoid the infinity list walking.
+                */
+               if (sp->role.invalid)
+                       continue;
+
+               if (need_resched() || spin_needbreak(&kvm->mmu_lock)) {
+                       kvm_mmu_commit_zap_page(kvm, &invalid_list);
+                       cond_resched_lock(&kvm->mmu_lock);
+                       goto restart;
+               }
+
+               if (__kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list, &ign))
+                       goto restart;
+       }
+
+       kvm_mmu_commit_zap_page(kvm, &invalid_list);
+}
+
+/*
+ * Fast invalidate all shadow pages and use lock-break technique
+ * to zap obsolete pages.
+ *
+ * It's required when memslot is being deleted or VM is being
+ * destroyed, in these cases, we should ensure that KVM MMU does
+ * not use any resource of the being-deleted slot or all slots
+ * after calling the function.
+ */
+static void kvm_mmu_zap_all_fast(struct kvm *kvm)
+{
+       spin_lock(&kvm->mmu_lock);
+       kvm->arch.mmu_valid_gen++;
+
+       kvm_zap_obsolete_pages(kvm);
+       spin_unlock(&kvm->mmu_lock);
+}
+
 static void kvm_mmu_invalidate_zap_pages_in_memslot(struct kvm *kvm,
                        struct kvm_memory_slot *slot,
                        struct kvm_page_track_notifier_node *node)
 {
-       kvm_mmu_zap_all(kvm);
+       kvm_mmu_zap_all_fast(kvm);
 }
 
 void kvm_mmu_init_vm(struct kvm *kvm)
index e3d3b21..e036807 100644 (file)
@@ -7128,12 +7128,6 @@ failed:
        return ret;
 }
 
-static uint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu)
-{
-       /* Not supported */
-       return 0;
-}
-
 static int nested_enable_evmcs(struct kvm_vcpu *vcpu,
                                   uint16_t *vmcs_version)
 {
@@ -7332,7 +7326,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
        .mem_enc_unreg_region = svm_unregister_enc_region,
 
        .nested_enable_evmcs = nested_enable_evmcs,
-       .nested_get_evmcs_version = nested_get_evmcs_version,
+       .nested_get_evmcs_version = NULL,
 
        .need_emulation_on_page_fault = svm_need_emulation_on_page_fault,
 };
index ced9fba..a3cba32 100644 (file)
@@ -4540,6 +4540,7 @@ static int handle_vmread(struct kvm_vcpu *vcpu)
        int len;
        gva_t gva = 0;
        struct vmcs12 *vmcs12;
+       struct x86_exception e;
        short offset;
 
        if (!nested_vmx_check_permission(vcpu))
@@ -4588,7 +4589,8 @@ static int handle_vmread(struct kvm_vcpu *vcpu)
                                vmx_instruction_info, true, len, &gva))
                        return 1;
                /* _system ok, nested_vmx_check_permission has verified cpl=0 */
-               kvm_write_guest_virt_system(vcpu, gva, &field_value, len, NULL);
+               if (kvm_write_guest_virt_system(vcpu, gva, &field_value, len, &e))
+                       kvm_inject_page_fault(vcpu, &e);
        }
 
        return nested_vmx_succeed(vcpu);
index 42ed3fa..c030c96 100644 (file)
@@ -7797,6 +7797,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
        .set_nested_state = NULL,
        .get_vmcs12_pages = NULL,
        .nested_enable_evmcs = NULL,
+       .nested_get_evmcs_version = NULL,
        .need_emulation_on_page_fault = vmx_need_emulation_on_page_fault,
 };
 
index 93b0bd4..91602d3 100644 (file)
@@ -5312,6 +5312,13 @@ int kvm_write_guest_virt_system(struct kvm_vcpu *vcpu, gva_t addr, void *val,
        /* kvm_write_guest_virt_system can pull in tons of pages. */
        vcpu->arch.l1tf_flush_l1d = true;
 
+       /*
+        * FIXME: this should call handle_emulation_failure if X86EMUL_IO_NEEDED
+        * is returned, but our callers are not ready for that and they blindly
+        * call kvm_inject_page_fault.  Ensure that they at least do not leak
+        * uninitialized kernel stack memory into cr2 and error code.
+        */
+       memset(exception, 0, sizeof(*exception));
        return kvm_write_guest_virt_helper(addr, val, bytes, vcpu,
                                           PFERR_WRITE_MASK, exception);
 }
@@ -6594,12 +6601,13 @@ restart:
                unsigned long rflags = kvm_x86_ops->get_rflags(vcpu);
                toggle_interruptibility(vcpu, ctxt->interruptibility);
                vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
-               kvm_rip_write(vcpu, ctxt->eip);
-               if (r == EMULATE_DONE && ctxt->tf)
-                       kvm_vcpu_do_singlestep(vcpu, &r);
                if (!ctxt->have_exception ||
-                   exception_type(ctxt->exception.vector) == EXCPT_TRAP)
+                   exception_type(ctxt->exception.vector) == EXCPT_TRAP) {
+                       kvm_rip_write(vcpu, ctxt->eip);
+                       if (r == EMULATE_DONE && ctxt->tf)
+                               kvm_vcpu_do_singlestep(vcpu, &r);
                        __kvm_set_rflags(vcpu, ctxt->eflags);
+               }
 
                /*
                 * For STI, interrupts are shadowed; so KVM_REQ_EVENT will
index 6a9a77a..e14e95e 100644 (file)
@@ -516,7 +516,7 @@ static inline void check_conflict(int warnlvl, pgprot_t prot, pgprotval_t val,
  */
 static inline pgprot_t static_protections(pgprot_t prot, unsigned long start,
                                          unsigned long pfn, unsigned long npg,
-                                         int warnlvl)
+                                         unsigned long lpsize, int warnlvl)
 {
        pgprotval_t forbidden, res;
        unsigned long end;
@@ -535,9 +535,17 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long start,
        check_conflict(warnlvl, prot, res, start, end, pfn, "Text NX");
        forbidden = res;
 
-       res = protect_kernel_text_ro(start, end);
-       check_conflict(warnlvl, prot, res, start, end, pfn, "Text RO");
-       forbidden |= res;
+       /*
+        * Special case to preserve a large page. If the change spawns the
+        * full large page mapping then there is no point to split it
+        * up. Happens with ftrace and is going to be removed once ftrace
+        * switched to text_poke().
+        */
+       if (lpsize != (npg * PAGE_SIZE) || (start & (lpsize - 1))) {
+               res = protect_kernel_text_ro(start, end);
+               check_conflict(warnlvl, prot, res, start, end, pfn, "Text RO");
+               forbidden |= res;
+       }
 
        /* Check the PFN directly */
        res = protect_pci_bios(pfn, pfn + npg - 1);
@@ -819,7 +827,7 @@ static int __should_split_large_page(pte_t *kpte, unsigned long address,
         * extra conditional required here.
         */
        chk_prot = static_protections(old_prot, lpaddr, old_pfn, numpages,
-                                     CPA_CONFLICT);
+                                     psize, CPA_CONFLICT);
 
        if (WARN_ON_ONCE(pgprot_val(chk_prot) != pgprot_val(old_prot))) {
                /*
@@ -855,7 +863,7 @@ static int __should_split_large_page(pte_t *kpte, unsigned long address,
         * protection requirement in the large page.
         */
        new_prot = static_protections(req_prot, lpaddr, old_pfn, numpages,
-                                     CPA_DETECT);
+                                     psize, CPA_DETECT);
 
        /*
         * If there is a conflict, split the large page.
@@ -906,7 +914,8 @@ static void split_set_pte(struct cpa_data *cpa, pte_t *pte, unsigned long pfn,
        if (!cpa->force_static_prot)
                goto set;
 
-       prot = static_protections(ref_prot, address, pfn, npg, CPA_PROTECT);
+       /* Hand in lpsize = 0 to enforce the protection mechanism */
+       prot = static_protections(ref_prot, address, pfn, npg, 0, CPA_PROTECT);
 
        if (pgprot_val(prot) == pgprot_val(ref_prot))
                goto set;
@@ -1503,7 +1512,8 @@ repeat:
                pgprot_val(new_prot) |= pgprot_val(cpa->mask_set);
 
                cpa_inc_4k_install();
-               new_prot = static_protections(new_prot, address, pfn, 1,
+               /* Hand in lpsize = 0 to enforce the protection mechanism */
+               new_prot = static_protections(new_prot, address, pfn, 1, 0,
                                              CPA_PROTECT);
 
                new_prot = pgprot_clear_protnone_bits(new_prot);
index 8901a1f..10fb42d 100644 (file)
@@ -18,37 +18,40 @@ targets += purgatory.ro
 KASAN_SANITIZE := n
 KCOV_INSTRUMENT := n
 
+# These are adjustments to the compiler flags used for objects that
+# make up the standalone purgatory.ro
+
+PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel
+PURGATORY_CFLAGS := -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss
+
 # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
 # in turn leaves some undefined symbols like __fentry__ in purgatory and not
 # sure how to relocate those.
 ifdef CONFIG_FUNCTION_TRACER
-CFLAGS_REMOVE_sha256.o         += $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_purgatory.o      += $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_string.o         += $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_kexec-purgatory.o        += $(CC_FLAGS_FTRACE)
+PURGATORY_CFLAGS_REMOVE                += $(CC_FLAGS_FTRACE)
 endif
 
 ifdef CONFIG_STACKPROTECTOR
-CFLAGS_REMOVE_sha256.o         += -fstack-protector
-CFLAGS_REMOVE_purgatory.o      += -fstack-protector
-CFLAGS_REMOVE_string.o         += -fstack-protector
-CFLAGS_REMOVE_kexec-purgatory.o        += -fstack-protector
+PURGATORY_CFLAGS_REMOVE                += -fstack-protector
 endif
 
 ifdef CONFIG_STACKPROTECTOR_STRONG
-CFLAGS_REMOVE_sha256.o         += -fstack-protector-strong
-CFLAGS_REMOVE_purgatory.o      += -fstack-protector-strong
-CFLAGS_REMOVE_string.o         += -fstack-protector-strong
-CFLAGS_REMOVE_kexec-purgatory.o        += -fstack-protector-strong
+PURGATORY_CFLAGS_REMOVE                += -fstack-protector-strong
 endif
 
 ifdef CONFIG_RETPOLINE
-CFLAGS_REMOVE_sha256.o         += $(RETPOLINE_CFLAGS)
-CFLAGS_REMOVE_purgatory.o      += $(RETPOLINE_CFLAGS)
-CFLAGS_REMOVE_string.o         += $(RETPOLINE_CFLAGS)
-CFLAGS_REMOVE_kexec-purgatory.o        += $(RETPOLINE_CFLAGS)
+PURGATORY_CFLAGS_REMOVE                += $(RETPOLINE_CFLAGS)
 endif
 
+CFLAGS_REMOVE_purgatory.o      += $(PURGATORY_CFLAGS_REMOVE)
+CFLAGS_purgatory.o             += $(PURGATORY_CFLAGS)
+
+CFLAGS_REMOVE_sha256.o         += $(PURGATORY_CFLAGS_REMOVE)
+CFLAGS_sha256.o                        += $(PURGATORY_CFLAGS)
+
+CFLAGS_REMOVE_string.o         += $(PURGATORY_CFLAGS_REMOVE)
+CFLAGS_string.o                        += $(PURGATORY_CFLAGS)
+
 $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
                $(call if_changed,ld)
 
index 61cf4ea..477d63d 100644 (file)
@@ -30,8 +30,6 @@ source "drivers/block/Kconfig"
 
 source "drivers/nvme/Kconfig"
 
-# misc before ide - BLK_DEV_SGIIOC4 depends on SGI_IOC4
-
 source "drivers/misc/Kconfig"
 
 source "drivers/ide/Kconfig"
index 6d37564..05be8c7 100644 (file)
@@ -132,7 +132,6 @@ obj-y                               += mmc/
 obj-$(CONFIG_MEMSTICK)         += memstick/
 obj-$(CONFIG_NEW_LEDS)         += leds/
 obj-$(CONFIG_INFINIBAND)       += infiniband/
-obj-$(CONFIG_SGI_SN)           += sn/
 obj-y                          += firmware/
 obj-$(CONFIG_CRYPTO)           += crypto/
 obj-$(CONFIG_SUPERH)           += sh/
index 5f61589..ebe1e9e 100644 (file)
@@ -323,7 +323,7 @@ config ACPI_NUMA
        bool "NUMA support"
        depends on NUMA
        depends on (X86 || IA64 || ARM64)
-       default y if IA64_GENERIC || IA64_SGI_SN2 || ARM64
+       default y if IA64 || ARM64
 
 config ACPI_CUSTOM_DSDT_FILE
        string "Custom DSDT Table file to include"
index 8569b79..5a7551d 100644 (file)
@@ -1256,12 +1256,12 @@ static int  __init arm_smmu_v3_set_proximity(struct device *dev,
 
        smmu = (struct acpi_iort_smmu_v3 *)node->node_data;
        if (smmu->flags & ACPI_IORT_SMMU_V3_PXM_VALID) {
-               int node = acpi_map_pxm_to_node(smmu->pxm);
+               int dev_node = acpi_map_pxm_to_node(smmu->pxm);
 
-               if (node != NUMA_NO_NODE && !node_online(node))
+               if (dev_node != NUMA_NO_NODE && !node_online(dev_node))
                        return -EINVAL;
 
-               set_dev_node(dev, node);
+               set_dev_node(dev, dev_node);
                pr_info("SMMU-v3[%llx] Mapped to Proximity domain %d\n",
                        smmu->base_address,
                        smmu->pxm);
index 1e7ac0b..f31544d 100644 (file)
@@ -541,6 +541,44 @@ static int find_acpi_cpu_topology_tag(unsigned int cpu, int level, int flag)
 }
 
 /**
+ * check_acpi_cpu_flag() - Determine if CPU node has a flag set
+ * @cpu: Kernel logical CPU number
+ * @rev: The minimum PPTT revision defining the flag
+ * @flag: The flag itself
+ *
+ * Check the node representing a CPU for a given flag.
+ *
+ * Return: -ENOENT if the PPTT doesn't exist, the CPU cannot be found or
+ *        the table revision isn't new enough.
+ *        1, any passed flag set
+ *        0, flag unset
+ */
+static int check_acpi_cpu_flag(unsigned int cpu, int rev, u32 flag)
+{
+       struct acpi_table_header *table;
+       acpi_status status;
+       u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+       struct acpi_pptt_processor *cpu_node = NULL;
+       int ret = -ENOENT;
+
+       status = acpi_get_table(ACPI_SIG_PPTT, 0, &table);
+       if (ACPI_FAILURE(status)) {
+               acpi_pptt_warn_missing();
+               return ret;
+       }
+
+       if (table->revision >= rev)
+               cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
+
+       if (cpu_node)
+               ret = (cpu_node->flags & flag) != 0;
+
+       acpi_put_table(table);
+
+       return ret;
+}
+
+/**
  * acpi_find_last_cache_level() - Determines the number of cache levels for a PE
  * @cpu: Kernel logical CPU number
  *
@@ -605,6 +643,20 @@ int cache_setup_acpi(unsigned int cpu)
 }
 
 /**
+ * acpi_pptt_cpu_is_thread() - Determine if CPU is a thread
+ * @cpu: Kernel logical CPU number
+ *
+ * Return: 1, a thread
+ *         0, not a thread
+ *         -ENOENT ,if the PPTT doesn't exist, the CPU cannot be found or
+ *         the table revision isn't new enough.
+ */
+int acpi_pptt_cpu_is_thread(unsigned int cpu)
+{
+       return check_acpi_cpu_flag(cpu, 2, ACPI_PPTT_ACPI_PROCESSOR_IS_THREAD);
+}
+
+/**
  * find_acpi_cpu_topology() - Determine a unique topology value for a given CPU
  * @cpu: Kernel logical CPU number
  * @level: The topological level for which we would like a unique ID
@@ -664,7 +716,6 @@ int find_acpi_cpu_cache_topology(unsigned int cpu, int level)
        return ret;
 }
 
-
 /**
  * find_acpi_cpu_topology_package() - Determine a unique CPU package value
  * @cpu: Kernel logical CPU number
index 2e2efa5..8c37294 100644 (file)
@@ -200,7 +200,7 @@ config ATM_NICSTAR_USE_SUNI
          make the card work).
 
 config ATM_NICSTAR_USE_IDT77105
-       bool "Use IDT77015 PHY driver (25Mbps)"
+       bool "Use IDT77105 PHY driver (25Mbps)"
        depends on ATM_NICSTAR
        help
          Support for the PHYsical layer chip in ForeRunner LE25 cards. In
index dc40449..28b92e3 100644 (file)
@@ -202,7 +202,7 @@ config GENERIC_ARCH_TOPOLOGY
        help
          Enable support for architectures common topology code: e.g., parsing
          CPU capacity information from DT, usage of such information for
-         appropriate scaling, sysfs interface for changing capacity values at
+         appropriate scaling, sysfs interface for reading capacity values at
          runtime.
 
 endmenu
index 63c1e76..b54d241 100644 (file)
 #include <linux/string.h>
 #include <linux/sched/topology.h>
 #include <linux/cpuset.h>
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/percpu.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
 
 DEFINE_PER_CPU(unsigned long, freq_scale) = SCHED_CAPACITY_SCALE;
 
@@ -241,3 +246,296 @@ static void parsing_done_workfn(struct work_struct *work)
 #else
 core_initcall(free_raw_capacity);
 #endif
+
+#if defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
+static int __init get_cpu_for_node(struct device_node *node)
+{
+       struct device_node *cpu_node;
+       int cpu;
+
+       cpu_node = of_parse_phandle(node, "cpu", 0);
+       if (!cpu_node)
+               return -1;
+
+       cpu = of_cpu_node_to_id(cpu_node);
+       if (cpu >= 0)
+               topology_parse_cpu_capacity(cpu_node, cpu);
+       else
+               pr_crit("Unable to find CPU node for %pOF\n", cpu_node);
+
+       of_node_put(cpu_node);
+       return cpu;
+}
+
+static int __init parse_core(struct device_node *core, int package_id,
+                            int core_id)
+{
+       char name[10];
+       bool leaf = true;
+       int i = 0;
+       int cpu;
+       struct device_node *t;
+
+       do {
+               snprintf(name, sizeof(name), "thread%d", i);
+               t = of_get_child_by_name(core, name);
+               if (t) {
+                       leaf = false;
+                       cpu = get_cpu_for_node(t);
+                       if (cpu >= 0) {
+                               cpu_topology[cpu].package_id = package_id;
+                               cpu_topology[cpu].core_id = core_id;
+                               cpu_topology[cpu].thread_id = i;
+                       } else {
+                               pr_err("%pOF: Can't get CPU for thread\n",
+                                      t);
+                               of_node_put(t);
+                               return -EINVAL;
+                       }
+                       of_node_put(t);
+               }
+               i++;
+       } while (t);
+
+       cpu = get_cpu_for_node(core);
+       if (cpu >= 0) {
+               if (!leaf) {
+                       pr_err("%pOF: Core has both threads and CPU\n",
+                              core);
+                       return -EINVAL;
+               }
+
+               cpu_topology[cpu].package_id = package_id;
+               cpu_topology[cpu].core_id = core_id;
+       } else if (leaf) {
+               pr_err("%pOF: Can't get CPU for leaf core\n", core);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int __init parse_cluster(struct device_node *cluster, int depth)
+{
+       char name[10];
+       bool leaf = true;
+       bool has_cores = false;
+       struct device_node *c;
+       static int package_id __initdata;
+       int core_id = 0;
+       int i, ret;
+
+       /*
+        * First check for child clusters; we currently ignore any
+        * information about the nesting of clusters and present the
+        * scheduler with a flat list of them.
+        */
+       i = 0;
+       do {
+               snprintf(name, sizeof(name), "cluster%d", i);
+               c = of_get_child_by_name(cluster, name);
+               if (c) {
+                       leaf = false;
+                       ret = parse_cluster(c, depth + 1);
+                       of_node_put(c);
+                       if (ret != 0)
+                               return ret;
+               }
+               i++;
+       } while (c);
+
+       /* Now check for cores */
+       i = 0;
+       do {
+               snprintf(name, sizeof(name), "core%d", i);
+               c = of_get_child_by_name(cluster, name);
+               if (c) {
+                       has_cores = true;
+
+                       if (depth == 0) {
+                               pr_err("%pOF: cpu-map children should be clusters\n",
+                                      c);
+                               of_node_put(c);
+                               return -EINVAL;
+                       }
+
+                       if (leaf) {
+                               ret = parse_core(c, package_id, core_id++);
+                       } else {
+                               pr_err("%pOF: Non-leaf cluster with core %s\n",
+                                      cluster, name);
+                               ret = -EINVAL;
+                       }
+
+                       of_node_put(c);
+                       if (ret != 0)
+                               return ret;
+               }
+               i++;
+       } while (c);
+
+       if (leaf && !has_cores)
+               pr_warn("%pOF: empty cluster\n", cluster);
+
+       if (leaf)
+               package_id++;
+
+       return 0;
+}
+
+static int __init parse_dt_topology(void)
+{
+       struct device_node *cn, *map;
+       int ret = 0;
+       int cpu;
+
+       cn = of_find_node_by_path("/cpus");
+       if (!cn) {
+               pr_err("No CPU information found in DT\n");
+               return 0;
+       }
+
+       /*
+        * When topology is provided cpu-map is essentially a root
+        * cluster with restricted subnodes.
+        */
+       map = of_get_child_by_name(cn, "cpu-map");
+       if (!map)
+               goto out;
+
+       ret = parse_cluster(map, 0);
+       if (ret != 0)
+               goto out_map;
+
+       topology_normalize_cpu_scale();
+
+       /*
+        * Check that all cores are in the topology; the SMP code will
+        * only mark cores described in the DT as possible.
+        */
+       for_each_possible_cpu(cpu)
+               if (cpu_topology[cpu].package_id == -1)
+                       ret = -EINVAL;
+
+out_map:
+       of_node_put(map);
+out:
+       of_node_put(cn);
+       return ret;
+}
+#endif
+
+/*
+ * cpu topology table
+ */
+struct cpu_topology cpu_topology[NR_CPUS];
+EXPORT_SYMBOL_GPL(cpu_topology);
+
+const struct cpumask *cpu_coregroup_mask(int cpu)
+{
+       const cpumask_t *core_mask = cpumask_of_node(cpu_to_node(cpu));
+
+       /* Find the smaller of NUMA, core or LLC siblings */
+       if (cpumask_subset(&cpu_topology[cpu].core_sibling, core_mask)) {
+               /* not numa in package, lets use the package siblings */
+               core_mask = &cpu_topology[cpu].core_sibling;
+       }
+       if (cpu_topology[cpu].llc_id != -1) {
+               if (cpumask_subset(&cpu_topology[cpu].llc_sibling, core_mask))
+                       core_mask = &cpu_topology[cpu].llc_sibling;
+       }
+
+       return core_mask;
+}
+
+void update_siblings_masks(unsigned int cpuid)
+{
+       struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
+       int cpu;
+
+       /* update core and thread sibling masks */
+       for_each_online_cpu(cpu) {
+               cpu_topo = &cpu_topology[cpu];
+
+               if (cpuid_topo->llc_id == cpu_topo->llc_id) {
+                       cpumask_set_cpu(cpu, &cpuid_topo->llc_sibling);
+                       cpumask_set_cpu(cpuid, &cpu_topo->llc_sibling);
+               }
+
+               if (cpuid_topo->package_id != cpu_topo->package_id)
+                       continue;
+
+               cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
+               cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
+
+               if (cpuid_topo->core_id != cpu_topo->core_id)
+                       continue;
+
+               cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
+               cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
+       }
+}
+
+static void clear_cpu_topology(int cpu)
+{
+       struct cpu_topology *cpu_topo = &cpu_topology[cpu];
+
+       cpumask_clear(&cpu_topo->llc_sibling);
+       cpumask_set_cpu(cpu, &cpu_topo->llc_sibling);
+
+       cpumask_clear(&cpu_topo->core_sibling);
+       cpumask_set_cpu(cpu, &cpu_topo->core_sibling);
+       cpumask_clear(&cpu_topo->thread_sibling);
+       cpumask_set_cpu(cpu, &cpu_topo->thread_sibling);
+}
+
+void __init reset_cpu_topology(void)
+{
+       unsigned int cpu;
+
+       for_each_possible_cpu(cpu) {
+               struct cpu_topology *cpu_topo = &cpu_topology[cpu];
+
+               cpu_topo->thread_id = -1;
+               cpu_topo->core_id = -1;
+               cpu_topo->package_id = -1;
+               cpu_topo->llc_id = -1;
+
+               clear_cpu_topology(cpu);
+       }
+}
+
+void remove_cpu_topology(unsigned int cpu)
+{
+       int sibling;
+
+       for_each_cpu(sibling, topology_core_cpumask(cpu))
+               cpumask_clear_cpu(cpu, topology_core_cpumask(sibling));
+       for_each_cpu(sibling, topology_sibling_cpumask(cpu))
+               cpumask_clear_cpu(cpu, topology_sibling_cpumask(sibling));
+       for_each_cpu(sibling, topology_llc_cpumask(cpu))
+               cpumask_clear_cpu(cpu, topology_llc_cpumask(sibling));
+
+       clear_cpu_topology(cpu);
+}
+
+__weak int __init parse_acpi_topology(void)
+{
+       return 0;
+}
+
+#if defined(CONFIG_ARM64) || defined(CONFIG_RISCV)
+void __init init_cpu_topology(void)
+{
+       reset_cpu_topology();
+
+       /*
+        * Discard anything that was parsed if we hit an error so we
+        * don't use partial information.
+        */
+       if (parse_acpi_topology())
+               reset_cpu_topology();
+       else if (of_have_populated_dt() && parse_dt_topology())
+               reset_cpu_topology();
+}
+#endif
index e5e1b3a..e72843f 100644 (file)
@@ -588,14 +588,6 @@ void regmap_debugfs_init(struct regmap *map, const char *name)
        }
 
        map->debugfs = debugfs_create_dir(name, regmap_debugfs_root);
-       if (!map->debugfs) {
-               dev_warn(map->dev,
-                        "Failed to create %s debugfs directory\n", name);
-
-               kfree(map->debugfs_name);
-               map->debugfs_name = NULL;
-               return;
-       }
 
        debugfs_create_file("name", 0400, map->debugfs,
                            map, &regmap_name_fops);
@@ -672,10 +664,6 @@ void regmap_debugfs_initcall(void)
        struct regmap_debugfs_node *node, *tmp;
 
        regmap_debugfs_root = debugfs_create_dir("regmap", NULL);
-       if (!regmap_debugfs_root) {
-               pr_warn("regmap: Failed to create debugfs root\n");
-               return;
-       }
 
        mutex_lock(&regmap_debugfs_early_lock);
        list_for_each_entry_safe(node, tmp, &regmap_debugfs_early_list, link) {
index c9dc70c..3d64c93 100644 (file)
@@ -370,7 +370,6 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
                if (ret < 0) {
                        dev_err(map->dev, "IRQ thread failed to resume: %d\n",
                                ret);
-                       pm_runtime_put(map->dev);
                        goto exit;
                }
        }
@@ -425,8 +424,6 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
                                        dev_err(map->dev,
                                                "Failed to read IRQ status %d\n",
                                                ret);
-                                       if (chip->runtime_pm)
-                                               pm_runtime_put(map->dev);
                                        goto exit;
                                }
                        }
@@ -478,8 +475,6 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
                                dev_err(map->dev,
                                        "Failed to read IRQ status: %d\n",
                                        ret);
-                               if (chip->runtime_pm)
-                                       pm_runtime_put(map->dev);
                                goto exit;
                        }
                }
@@ -513,10 +508,10 @@ static irqreturn_t regmap_irq_thread(int irq, void *d)
                }
        }
 
+exit:
        if (chip->runtime_pm)
                pm_runtime_put(map->dev);
 
-exit:
        if (chip->handle_post_irq)
                chip->handle_post_irq(chip->irq_drv_data);
 
index 10b280f..7c0c5ca 100644 (file)
@@ -33,6 +33,7 @@ static struct bus_type soc_bus_type = {
 
 static DEVICE_ATTR(machine,  S_IRUGO, soc_info_get,  NULL);
 static DEVICE_ATTR(family,   S_IRUGO, soc_info_get,  NULL);
+static DEVICE_ATTR(serial_number, S_IRUGO, soc_info_get,  NULL);
 static DEVICE_ATTR(soc_id,   S_IRUGO, soc_info_get,  NULL);
 static DEVICE_ATTR(revision, S_IRUGO, soc_info_get,  NULL);
 
@@ -57,6 +58,9 @@ static umode_t soc_attribute_mode(struct kobject *kobj,
        if ((attr == &dev_attr_revision.attr)
            && (soc_dev->attr->revision != NULL))
                return attr->mode;
+       if ((attr == &dev_attr_serial_number.attr)
+           && (soc_dev->attr->serial_number != NULL))
+               return attr->mode;
        if ((attr == &dev_attr_soc_id.attr)
            && (soc_dev->attr->soc_id != NULL))
                return attr->mode;
@@ -77,6 +81,8 @@ static ssize_t soc_info_get(struct device *dev,
                return sprintf(buf, "%s\n", soc_dev->attr->family);
        if (attr == &dev_attr_revision)
                return sprintf(buf, "%s\n", soc_dev->attr->revision);
+       if (attr == &dev_attr_serial_number)
+               return sprintf(buf, "%s\n", soc_dev->attr->serial_number);
        if (attr == &dev_attr_soc_id)
                return sprintf(buf, "%s\n", soc_dev->attr->soc_id);
 
@@ -87,6 +93,7 @@ static ssize_t soc_info_get(struct device *dev,
 static struct attribute *soc_attr[] = {
        &dev_attr_machine.attr,
        &dev_attr_family.attr,
+       &dev_attr_serial_number.attr,
        &dev_attr_soc_id.attr,
        &dev_attr_revision.attr,
        NULL,
@@ -157,6 +164,7 @@ out2:
 out1:
        return ERR_PTR(ret);
 }
+EXPORT_SYMBOL_GPL(soc_device_register);
 
 /* Ensure soc_dev->attr is freed prior to calling soc_device_unregister. */
 void soc_device_unregister(struct soc_device *soc_dev)
@@ -166,6 +174,7 @@ void soc_device_unregister(struct soc_device *soc_dev)
        device_unregister(&soc_dev->dev);
        early_soc_dev_attr = NULL;
 }
+EXPORT_SYMBOL_GPL(soc_device_unregister);
 
 static int __init soc_bus_register(void)
 {
index 3327192..c8fb886 100644 (file)
@@ -3038,6 +3038,17 @@ again:
                }
                return true;
        case RBD_OBJ_READ_PARENT:
+               /*
+                * The parent image is read only up to the overlap -- zero-fill
+                * from the overlap to the end of the request.
+                */
+               if (!*result) {
+                       u32 obj_overlap = rbd_obj_img_extents_bytes(obj_req);
+
+                       if (obj_overlap < obj_req->ex.oe_len)
+                               rbd_obj_zero_range(obj_req, obj_overlap,
+                                           obj_req->ex.oe_len - obj_overlap);
+               }
                return true;
        default:
                BUG();
index a0e8453..1fa58c0 100644 (file)
@@ -337,7 +337,7 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
 
        usb_free_urb(urb);
 
-       return 0;
+       return err;
 }
 
 static int bpa10x_set_diag(struct hci_dev *hdev, bool enable)
index 5cf0734..ba41490 100644 (file)
@@ -384,6 +384,9 @@ static const struct usb_device_id blacklist_table[] = {
        { USB_DEVICE(0x13d3, 0x3526), .driver_info = BTUSB_REALTEK },
        { USB_DEVICE(0x0b05, 0x185c), .driver_info = BTUSB_REALTEK },
 
+       /* Additional Realtek 8822CE Bluetooth devices */
+       { USB_DEVICE(0x04ca, 0x4005), .driver_info = BTUSB_REALTEK },
+
        /* Silicon Wave based devices */
        { USB_DEVICE(0x0c10, 0x0000), .driver_info = BTUSB_SWAVE },
 
@@ -1170,10 +1173,6 @@ static int btusb_open(struct hci_dev *hdev)
        }
 
        data->intf->needs_remote_wakeup = 1;
-       /* device specific wakeup source enabled and required for USB
-        * remote wakeup while host is suspended
-        */
-       device_wakeup_enable(&data->udev->dev);
 
        if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags))
                goto done;
@@ -1238,7 +1237,6 @@ static int btusb_close(struct hci_dev *hdev)
                goto failed;
 
        data->intf->needs_remote_wakeup = 0;
-       device_wakeup_disable(&data->udev->dev);
        usb_autopm_put_interface(data->intf);
 
 failed:
index 9a970fd..31dec43 100644 (file)
@@ -309,13 +309,14 @@ static void qca_wq_awake_device(struct work_struct *work)
                                            ws_awake_device);
        struct hci_uart *hu = qca->hu;
        unsigned long retrans_delay;
+       unsigned long flags;
 
        BT_DBG("hu %p wq awake device", hu);
 
        /* Vote for serial clock */
        serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_ON, hu);
 
-       spin_lock(&qca->hci_ibs_lock);
+       spin_lock_irqsave(&qca->hci_ibs_lock, flags);
 
        /* Send wake indication to device */
        if (send_hci_ibs_cmd(HCI_IBS_WAKE_IND, hu) < 0)
@@ -327,7 +328,7 @@ static void qca_wq_awake_device(struct work_struct *work)
        retrans_delay = msecs_to_jiffies(qca->wake_retrans);
        mod_timer(&qca->wake_retrans_timer, jiffies + retrans_delay);
 
-       spin_unlock(&qca->hci_ibs_lock);
+       spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
 
        /* Actually send the packets */
        hci_uart_tx_wakeup(hu);
@@ -338,12 +339,13 @@ static void qca_wq_awake_rx(struct work_struct *work)
        struct qca_data *qca = container_of(work, struct qca_data,
                                            ws_awake_rx);
        struct hci_uart *hu = qca->hu;
+       unsigned long flags;
 
        BT_DBG("hu %p wq awake rx", hu);
 
        serial_clock_vote(HCI_IBS_RX_VOTE_CLOCK_ON, hu);
 
-       spin_lock(&qca->hci_ibs_lock);
+       spin_lock_irqsave(&qca->hci_ibs_lock, flags);
        qca->rx_ibs_state = HCI_IBS_RX_AWAKE;
 
        /* Always acknowledge device wake up,
@@ -354,7 +356,7 @@ static void qca_wq_awake_rx(struct work_struct *work)
 
        qca->ibs_sent_wacks++;
 
-       spin_unlock(&qca->hci_ibs_lock);
+       spin_unlock_irqrestore(&qca->hci_ibs_lock, flags);
 
        /* Actually send the packets */
        hci_uart_tx_wakeup(hu);
index 1851112..6b33106 100644 (file)
@@ -29,6 +29,16 @@ config BRCMSTB_GISB_ARB
          arbiter. This driver provides timeout and target abort error handling
          and internal bus master decoding.
 
+config MOXTET
+       tristate "CZ.NIC Turris Mox module configuration bus"
+       depends on SPI_MASTER && OF
+       help
+         Say yes here to add support for the module configuration bus found
+         on CZ.NIC's Turris Mox. This is needed for the ability to discover
+         the order in which the modules are connected and to get/set some of
+         their settings. For example the GPIOs on Mox SFP module are
+         configured through this bus.
+
 config HISILICON_LPC
        bool "Support for ISA I/O space on HiSilicon Hip06/7"
        depends on ARM64 && (ARCH_HISI || COMPILE_TEST)
index ca300b1..16b43d3 100644 (file)
@@ -8,6 +8,7 @@ obj-$(CONFIG_ARM_CCI)           += arm-cci.o
 
 obj-$(CONFIG_HISILICON_LPC)    += hisi_lpc.o
 obj-$(CONFIG_BRCMSTB_GISB_ARB) += brcmstb_gisb.o
+obj-$(CONFIG_MOXTET)           += moxtet.o
 
 # DPAA2 fsl-mc bus
 obj-$(CONFIG_FSL_MC_BUS)       += fsl-mc/
index 8ad7724..cc7bb90 100644 (file)
@@ -330,7 +330,6 @@ void fsl_mc_object_free(struct fsl_mc_device *mc_adev)
 
        fsl_mc_resource_free(resource);
 
-       device_link_del(mc_adev->consumer_link);
        mc_adev->consumer_link = NULL;
 }
 EXPORT_SYMBOL_GPL(fsl_mc_object_free);
index 3ae574a..d9629fc 100644 (file)
@@ -255,7 +255,6 @@ void fsl_mc_portal_free(struct fsl_mc_io *mc_io)
        fsl_destroy_mc_io(mc_io);
        fsl_mc_resource_free(resource);
 
-       device_link_del(dpmcp_dev->consumer_link);
        dpmcp_dev->consumer_link = NULL;
 }
 EXPORT_SYMBOL_GPL(fsl_mc_portal_free);
index 19d7b6f..20c9571 100644 (file)
@@ -456,6 +456,17 @@ struct hisi_lpc_acpi_cell {
        size_t pdata_size;
 };
 
+static void hisi_lpc_acpi_remove(struct device *hostdev)
+{
+       struct acpi_device *adev = ACPI_COMPANION(hostdev);
+       struct acpi_device *child;
+
+       device_for_each_child(hostdev, NULL, hisi_lpc_acpi_remove_subdev);
+
+       list_for_each_entry(child, &adev->children, node)
+               acpi_device_clear_enumerated(child);
+}
+
 /*
  * hisi_lpc_acpi_probe - probe children for ACPI FW
  * @hostdev: LPC host device pointer
@@ -555,8 +566,7 @@ static int hisi_lpc_acpi_probe(struct device *hostdev)
        return 0;
 
 fail:
-       device_for_each_child(hostdev, NULL,
-                             hisi_lpc_acpi_remove_subdev);
+       hisi_lpc_acpi_remove(hostdev);
        return ret;
 }
 
@@ -569,6 +579,10 @@ static int hisi_lpc_acpi_probe(struct device *dev)
 {
        return -ENODEV;
 }
+
+static void hisi_lpc_acpi_remove(struct device *hostdev)
+{
+}
 #endif // CONFIG_ACPI
 
 /*
@@ -606,24 +620,27 @@ static int hisi_lpc_probe(struct platform_device *pdev)
        range->fwnode = dev->fwnode;
        range->flags = LOGIC_PIO_INDIRECT;
        range->size = PIO_INDIRECT_SIZE;
+       range->hostdata = lpcdev;
+       range->ops = &hisi_lpc_ops;
+       lpcdev->io_host = range;
 
        ret = logic_pio_register_range(range);
        if (ret) {
                dev_err(dev, "register IO range failed (%d)!\n", ret);
                return ret;
        }
-       lpcdev->io_host = range;
 
        /* register the LPC host PIO resources */
        if (acpi_device)
                ret = hisi_lpc_acpi_probe(dev);
        else
                ret = of_platform_populate(dev->of_node, NULL, NULL, dev);
-       if (ret)
+       if (ret) {
+               logic_pio_unregister_range(range);
                return ret;
+       }
 
-       lpcdev->io_host->hostdata = lpcdev;
-       lpcdev->io_host->ops = &hisi_lpc_ops;
+       dev_set_drvdata(dev, lpcdev);
 
        io_end = lpcdev->io_host->io_start + lpcdev->io_host->size;
        dev_info(dev, "registered range [%pa - %pa]\n",
@@ -632,6 +649,23 @@ static int hisi_lpc_probe(struct platform_device *pdev)
        return ret;
 }
 
+static int hisi_lpc_remove(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct acpi_device *acpi_device = ACPI_COMPANION(dev);
+       struct hisi_lpc_dev *lpcdev = dev_get_drvdata(dev);
+       struct logic_pio_hwaddr *range = lpcdev->io_host;
+
+       if (acpi_device)
+               hisi_lpc_acpi_remove(dev);
+       else
+               of_platform_depopulate(dev);
+
+       logic_pio_unregister_range(range);
+
+       return 0;
+}
+
 static const struct of_device_id hisi_lpc_of_match[] = {
        { .compatible = "hisilicon,hip06-lpc", },
        { .compatible = "hisilicon,hip07-lpc", },
@@ -645,5 +679,6 @@ static struct platform_driver hisi_lpc_driver = {
                .acpi_match_table = ACPI_PTR(hisi_lpc_acpi_match),
        },
        .probe = hisi_lpc_probe,
+       .remove = hisi_lpc_remove,
 };
 builtin_platform_driver(hisi_lpc_driver);
index db74334..28bb65a 100644 (file)
@@ -19,6 +19,8 @@ struct imx_weim_devtype {
        unsigned int    cs_count;
        unsigned int    cs_regs_count;
        unsigned int    cs_stride;
+       unsigned int    wcr_offset;
+       unsigned int    wcr_bcm;
 };
 
 static const struct imx_weim_devtype imx1_weim_devtype = {
@@ -37,6 +39,8 @@ static const struct imx_weim_devtype imx50_weim_devtype = {
        .cs_count       = 4,
        .cs_regs_count  = 6,
        .cs_stride      = 0x18,
+       .wcr_offset     = 0x90,
+       .wcr_bcm        = BIT(0),
 };
 
 static const struct imx_weim_devtype imx51_weim_devtype = {
@@ -72,7 +76,7 @@ static const struct of_device_id weim_id_table[] = {
 };
 MODULE_DEVICE_TABLE(of, weim_id_table);
 
-static int __init imx_weim_gpr_setup(struct platform_device *pdev)
+static int imx_weim_gpr_setup(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        struct property *prop;
@@ -122,10 +126,10 @@ err:
 }
 
 /* Parse and set the timing for this device. */
-static int __init weim_timing_setup(struct device *dev,
-                                   struct device_node *np, void __iomem *base,
-                                   const struct imx_weim_devtype *devtype,
-                                   struct cs_timing_state *ts)
+static int weim_timing_setup(struct device *dev,
+                            struct device_node *np, void __iomem *base,
+                            const struct imx_weim_devtype *devtype,
+                            struct cs_timing_state *ts)
 {
        u32 cs_idx, value[MAX_CS_REGS_COUNT];
        int i, ret;
@@ -183,8 +187,7 @@ static int __init weim_timing_setup(struct device *dev,
        return 0;
 }
 
-static int __init weim_parse_dt(struct platform_device *pdev,
-                               void __iomem *base)
+static int weim_parse_dt(struct platform_device *pdev, void __iomem *base)
 {
        const struct of_device_id *of_id = of_match_device(weim_id_table,
                                                           &pdev->dev);
@@ -192,6 +195,7 @@ static int __init weim_parse_dt(struct platform_device *pdev,
        struct device_node *child;
        int ret, have_child = 0;
        struct cs_timing_state ts = {};
+       u32 reg;
 
        if (devtype == &imx50_weim_devtype) {
                ret = imx_weim_gpr_setup(pdev);
@@ -199,6 +203,17 @@ static int __init weim_parse_dt(struct platform_device *pdev,
                        return ret;
        }
 
+       if (of_property_read_bool(pdev->dev.of_node, "fsl,burst-clk-enable")) {
+               if (devtype->wcr_bcm) {
+                       reg = readl(base + devtype->wcr_offset);
+                       writel(reg | devtype->wcr_bcm,
+                               base + devtype->wcr_offset);
+               } else {
+                       dev_err(&pdev->dev, "burst clk mode not supported.\n");
+                       return -EINVAL;
+               }
+       }
+
        for_each_available_child_of_node(pdev->dev.of_node, child) {
                ret = weim_timing_setup(&pdev->dev, child, base, devtype, &ts);
                if (ret)
@@ -217,7 +232,7 @@ static int __init weim_parse_dt(struct platform_device *pdev,
        return ret;
 }
 
-static int __init weim_probe(struct platform_device *pdev)
+static int weim_probe(struct platform_device *pdev)
 {
        struct resource *res;
        struct clk *clk;
@@ -254,8 +269,9 @@ static struct platform_driver weim_driver = {
                .name           = "imx-weim",
                .of_match_table = weim_id_table,
        },
+       .probe = weim_probe,
 };
-module_platform_driver_probe(weim_driver, weim_probe);
+module_platform_driver(weim_driver);
 
 MODULE_AUTHOR("Freescale Semiconductor Inc.");
 MODULE_DESCRIPTION("i.MX EIM Controller Driver");
diff --git a/drivers/bus/moxtet.c b/drivers/bus/moxtet.c
new file mode 100644 (file)
index 0000000..36cf13e
--- /dev/null
@@ -0,0 +1,885 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Turris Mox module configuration bus driver
+ *
+ * Copyright (C) 2019 Marek Behun <marek.behun@nic.cz>
+ */
+
+#include <dt-bindings/bus/moxtet.h>
+#include <linux/bitops.h>
+#include <linux/debugfs.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/moxtet.h>
+#include <linux/mutex.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/spi/spi.h>
+
+/*
+ * @name:      module name for sysfs
+ * @hwirq_base:        base index for IRQ for this module (-1 if no IRQs)
+ * @nirqs:     how many interrupts does the shift register provide
+ * @desc:      module description for kernel log
+ */
+static const struct {
+       const char *name;
+       int hwirq_base;
+       int nirqs;
+       const char *desc;
+} mox_module_table[] = {
+       /* do not change order of this array! */
+       { NULL,          0,                     0, NULL },
+       { "sfp",        -1,                     0, "MOX D (SFP cage)" },
+       { "pci",        MOXTET_IRQ_PCI,         1, "MOX B (Mini-PCIe)" },
+       { "topaz",      MOXTET_IRQ_TOPAZ,       1, "MOX C (4 port switch)" },
+       { "peridot",    MOXTET_IRQ_PERIDOT(0),  1, "MOX E (8 port switch)" },
+       { "usb3",       MOXTET_IRQ_USB3,        2, "MOX F (USB 3.0)" },
+       { "pci-bridge", -1,                     0, "MOX G (Mini-PCIe bridge)" },
+};
+
+static inline bool mox_module_known(unsigned int id)
+{
+       return id >= TURRIS_MOX_MODULE_FIRST && id <= TURRIS_MOX_MODULE_LAST;
+}
+
+static inline const char *mox_module_name(unsigned int id)
+{
+       if (mox_module_known(id))
+               return mox_module_table[id].name;
+       else
+               return "unknown";
+}
+
+#define DEF_MODULE_ATTR(name, fmt, ...)                                        \
+static ssize_t                                                         \
+module_##name##_show(struct device *dev, struct device_attribute *a,   \
+                    char *buf)                                         \
+{                                                                      \
+       struct moxtet_device *mdev = to_moxtet_device(dev);             \
+       return sprintf(buf, (fmt), __VA_ARGS__);                        \
+}                                                                      \
+static DEVICE_ATTR_RO(module_##name)
+
+DEF_MODULE_ATTR(id, "0x%x\n", mdev->id);
+DEF_MODULE_ATTR(name, "%s\n", mox_module_name(mdev->id));
+DEF_MODULE_ATTR(description, "%s\n",
+               mox_module_known(mdev->id) ? mox_module_table[mdev->id].desc
+                                          : "");
+
+static struct attribute *moxtet_dev_attrs[] = {
+       &dev_attr_module_id.attr,
+       &dev_attr_module_name.attr,
+       &dev_attr_module_description.attr,
+       NULL,
+};
+
+static const struct attribute_group moxtet_dev_group = {
+       .attrs = moxtet_dev_attrs,
+};
+
+static const struct attribute_group *moxtet_dev_groups[] = {
+       &moxtet_dev_group,
+       NULL,
+};
+
+static int moxtet_match(struct device *dev, struct device_driver *drv)
+{
+       struct moxtet_device *mdev = to_moxtet_device(dev);
+       struct moxtet_driver *tdrv = to_moxtet_driver(drv);
+       const enum turris_mox_module_id *t;
+
+       if (of_driver_match_device(dev, drv))
+               return 1;
+
+       if (!tdrv->id_table)
+               return 0;
+
+       for (t = tdrv->id_table; *t; ++t)
+               if (*t == mdev->id)
+                       return 1;
+
+       return 0;
+}
+
+struct bus_type moxtet_bus_type = {
+       .name           = "moxtet",
+       .dev_groups     = moxtet_dev_groups,
+       .match          = moxtet_match,
+};
+EXPORT_SYMBOL_GPL(moxtet_bus_type);
+
+int __moxtet_register_driver(struct module *owner,
+                            struct moxtet_driver *mdrv)
+{
+       mdrv->driver.owner = owner;
+       mdrv->driver.bus = &moxtet_bus_type;
+       return driver_register(&mdrv->driver);
+}
+EXPORT_SYMBOL_GPL(__moxtet_register_driver);
+
+static int moxtet_dev_check(struct device *dev, void *data)
+{
+       struct moxtet_device *mdev = to_moxtet_device(dev);
+       struct moxtet_device *new_dev = data;
+
+       if (mdev->moxtet == new_dev->moxtet && mdev->id == new_dev->id &&
+           mdev->idx == new_dev->idx)
+               return -EBUSY;
+       return 0;
+}
+
+static void moxtet_dev_release(struct device *dev)
+{
+       struct moxtet_device *mdev = to_moxtet_device(dev);
+
+       put_device(mdev->moxtet->dev);
+       kfree(mdev);
+}
+
+static struct moxtet_device *
+moxtet_alloc_device(struct moxtet *moxtet)
+{
+       struct moxtet_device *dev;
+
+       if (!get_device(moxtet->dev))
+               return NULL;
+
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (!dev) {
+               put_device(moxtet->dev);
+               return NULL;
+       }
+
+       dev->moxtet = moxtet;
+       dev->dev.parent = moxtet->dev;
+       dev->dev.bus = &moxtet_bus_type;
+       dev->dev.release = moxtet_dev_release;
+
+       device_initialize(&dev->dev);
+
+       return dev;
+}
+
+static int moxtet_add_device(struct moxtet_device *dev)
+{
+       static DEFINE_MUTEX(add_mutex);
+       int ret;
+
+       if (dev->idx >= TURRIS_MOX_MAX_MODULES || dev->id > 0xf)
+               return -EINVAL;
+
+       dev_set_name(&dev->dev, "moxtet-%s.%u", mox_module_name(dev->id),
+                    dev->idx);
+
+       mutex_lock(&add_mutex);
+
+       ret = bus_for_each_dev(&moxtet_bus_type, NULL, dev,
+                              moxtet_dev_check);
+       if (ret)
+               goto done;
+
+       ret = device_add(&dev->dev);
+       if (ret < 0)
+               dev_err(dev->moxtet->dev, "can't add %s, status %d\n",
+                       dev_name(dev->moxtet->dev), ret);
+
+done:
+       mutex_unlock(&add_mutex);
+       return ret;
+}
+
+static int __unregister(struct device *dev, void *null)
+{
+       if (dev->of_node) {
+               of_node_clear_flag(dev->of_node, OF_POPULATED);
+               of_node_put(dev->of_node);
+       }
+
+       device_unregister(dev);
+
+       return 0;
+}
+
+static struct moxtet_device *
+of_register_moxtet_device(struct moxtet *moxtet, struct device_node *nc)
+{
+       struct moxtet_device *dev;
+       u32 val;
+       int ret;
+
+       dev = moxtet_alloc_device(moxtet);
+       if (!dev) {
+               dev_err(moxtet->dev,
+                       "Moxtet device alloc error for %pOF\n", nc);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       ret = of_property_read_u32(nc, "reg", &val);
+       if (ret) {
+               dev_err(moxtet->dev, "%pOF has no valid 'reg' property (%d)\n",
+                       nc, ret);
+               goto err_put;
+       }
+
+       dev->idx = val;
+
+       if (dev->idx >= TURRIS_MOX_MAX_MODULES) {
+               dev_err(moxtet->dev, "%pOF Moxtet address 0x%x out of range\n",
+                       nc, dev->idx);
+               ret = -EINVAL;
+               goto err_put;
+       }
+
+       dev->id = moxtet->modules[dev->idx];
+
+       if (!dev->id) {
+               dev_err(moxtet->dev, "%pOF Moxtet address 0x%x is empty\n", nc,
+                       dev->idx);
+               ret = -ENODEV;
+               goto err_put;
+       }
+
+       of_node_get(nc);
+       dev->dev.of_node = nc;
+
+       ret = moxtet_add_device(dev);
+       if (ret) {
+               dev_err(moxtet->dev,
+                       "Moxtet device register error for %pOF\n", nc);
+               of_node_put(nc);
+               goto err_put;
+       }
+
+       return dev;
+
+err_put:
+       put_device(&dev->dev);
+       return ERR_PTR(ret);
+}
+
+static void of_register_moxtet_devices(struct moxtet *moxtet)
+{
+       struct moxtet_device *dev;
+       struct device_node *nc;
+
+       if (!moxtet->dev->of_node)
+               return;
+
+       for_each_available_child_of_node(moxtet->dev->of_node, nc) {
+               if (of_node_test_and_set_flag(nc, OF_POPULATED))
+                       continue;
+               dev = of_register_moxtet_device(moxtet, nc);
+               if (IS_ERR(dev)) {
+                       dev_warn(moxtet->dev,
+                                "Failed to create Moxtet device for %pOF\n",
+                                nc);
+                       of_node_clear_flag(nc, OF_POPULATED);
+               }
+       }
+}
+
+static void
+moxtet_register_devices_from_topology(struct moxtet *moxtet)
+{
+       struct moxtet_device *dev;
+       int i, ret;
+
+       for (i = 0; i < moxtet->count; ++i) {
+               dev = moxtet_alloc_device(moxtet);
+               if (!dev) {
+                       dev_err(moxtet->dev, "Moxtet device %u alloc error\n",
+                               i);
+                       continue;
+               }
+
+               dev->idx = i;
+               dev->id = moxtet->modules[i];
+
+               ret = moxtet_add_device(dev);
+               if (ret && ret != -EBUSY) {
+                       put_device(&dev->dev);
+                       dev_err(moxtet->dev,
+                               "Moxtet device %u register error: %i\n", i,
+                               ret);
+               }
+       }
+}
+
+/*
+ * @nsame:     how many modules with same id are already in moxtet->modules
+ */
+static int moxtet_set_irq(struct moxtet *moxtet, int idx, int id, int nsame)
+{
+       int i, first;
+       struct moxtet_irqpos *pos;
+
+       first = mox_module_table[id].hwirq_base +
+               nsame * mox_module_table[id].nirqs;
+
+       if (first + mox_module_table[id].nirqs > MOXTET_NIRQS)
+               return -EINVAL;
+
+       for (i = 0; i < mox_module_table[id].nirqs; ++i) {
+               pos = &moxtet->irq.position[first + i];
+               pos->idx = idx;
+               pos->bit = i;
+               moxtet->irq.exists |= BIT(first + i);
+       }
+
+       return 0;
+}
+
+static int moxtet_find_topology(struct moxtet *moxtet)
+{
+       u8 buf[TURRIS_MOX_MAX_MODULES];
+       int cnts[TURRIS_MOX_MODULE_LAST];
+       int i, ret;
+
+       memset(cnts, 0, sizeof(cnts));
+
+       ret = spi_read(to_spi_device(moxtet->dev), buf, TURRIS_MOX_MAX_MODULES);
+       if (ret < 0)
+               return ret;
+
+       if (buf[0] == TURRIS_MOX_CPU_ID_EMMC) {
+               dev_info(moxtet->dev, "Found MOX A (eMMC CPU) module\n");
+       } else if (buf[0] == TURRIS_MOX_CPU_ID_SD) {
+               dev_info(moxtet->dev, "Found MOX A (CPU) module\n");
+       } else {
+               dev_err(moxtet->dev, "Invalid Turris MOX A CPU module 0x%02x\n",
+                       buf[0]);
+               return -ENODEV;
+       }
+
+       moxtet->count = 0;
+
+       for (i = 1; i < TURRIS_MOX_MAX_MODULES; ++i) {
+               int id;
+
+               if (buf[i] == 0xff)
+                       break;
+
+               id = buf[i] & 0xf;
+
+               moxtet->modules[i-1] = id;
+               ++moxtet->count;
+
+               if (mox_module_known(id)) {
+                       dev_info(moxtet->dev, "Found %s module\n",
+                                mox_module_table[id].desc);
+
+                       if (moxtet_set_irq(moxtet, i-1, id, cnts[id]++) < 0)
+                               dev_err(moxtet->dev,
+                                       "  Cannot set IRQ for module %s\n",
+                                       mox_module_table[id].desc);
+               } else {
+                       dev_warn(moxtet->dev,
+                                "Unknown Moxtet module found (ID 0x%02x)\n",
+                                id);
+               }
+       }
+
+       return 0;
+}
+
+static int moxtet_spi_read(struct moxtet *moxtet, u8 *buf)
+{
+       struct spi_transfer xfer = {
+               .rx_buf = buf,
+               .tx_buf = moxtet->tx,
+               .len = moxtet->count + 1
+       };
+       int ret;
+
+       mutex_lock(&moxtet->lock);
+
+       ret = spi_sync_transfer(to_spi_device(moxtet->dev), &xfer, 1);
+
+       mutex_unlock(&moxtet->lock);
+
+       return ret;
+}
+
+int moxtet_device_read(struct device *dev)
+{
+       struct moxtet_device *mdev = to_moxtet_device(dev);
+       struct moxtet *moxtet = mdev->moxtet;
+       u8 buf[TURRIS_MOX_MAX_MODULES];
+       int ret;
+
+       if (mdev->idx >= moxtet->count)
+               return -EINVAL;
+
+       ret = moxtet_spi_read(moxtet, buf);
+       if (ret < 0)
+               return ret;
+
+       return buf[mdev->idx + 1] >> 4;
+}
+EXPORT_SYMBOL_GPL(moxtet_device_read);
+
+int moxtet_device_write(struct device *dev, u8 val)
+{
+       struct moxtet_device *mdev = to_moxtet_device(dev);
+       struct moxtet *moxtet = mdev->moxtet;
+       int ret;
+
+       if (mdev->idx >= moxtet->count)
+               return -EINVAL;
+
+       mutex_lock(&moxtet->lock);
+
+       moxtet->tx[moxtet->count - mdev->idx] = val;
+
+       ret = spi_write(to_spi_device(moxtet->dev), moxtet->tx,
+                       moxtet->count + 1);
+
+       mutex_unlock(&moxtet->lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(moxtet_device_write);
+
+int moxtet_device_written(struct device *dev)
+{
+       struct moxtet_device *mdev = to_moxtet_device(dev);
+       struct moxtet *moxtet = mdev->moxtet;
+
+       if (mdev->idx >= moxtet->count)
+               return -EINVAL;
+
+       return moxtet->tx[moxtet->count - mdev->idx];
+}
+EXPORT_SYMBOL_GPL(moxtet_device_written);
+
+#ifdef CONFIG_DEBUG_FS
+static int moxtet_debug_open(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+
+       return nonseekable_open(inode, file);
+}
+
+static ssize_t input_read(struct file *file, char __user *buf, size_t len,
+                         loff_t *ppos)
+{
+       struct moxtet *moxtet = file->private_data;
+       u8 bin[TURRIS_MOX_MAX_MODULES];
+       u8 hex[sizeof(buf) * 2 + 1];
+       int ret, n;
+
+       ret = moxtet_spi_read(moxtet, bin);
+       if (ret < 0)
+               return ret;
+
+       n = moxtet->count + 1;
+       bin2hex(hex, bin, n);
+
+       hex[2*n] = '\n';
+
+       return simple_read_from_buffer(buf, len, ppos, hex, 2*n + 1);
+}
+
+static const struct file_operations input_fops = {
+       .owner  = THIS_MODULE,
+       .open   = moxtet_debug_open,
+       .read   = input_read,
+       .llseek = no_llseek,
+};
+
+static ssize_t output_read(struct file *file, char __user *buf, size_t len,
+                          loff_t *ppos)
+{
+       struct moxtet *moxtet = file->private_data;
+       u8 hex[TURRIS_MOX_MAX_MODULES * 2 + 1];
+       u8 *p = hex;
+       int i;
+
+       mutex_lock(&moxtet->lock);
+
+       for (i = 0; i < moxtet->count; ++i)
+               p = hex_byte_pack(p, moxtet->tx[moxtet->count - i]);
+
+       mutex_unlock(&moxtet->lock);
+
+       *p++ = '\n';
+
+       return simple_read_from_buffer(buf, len, ppos, hex, p - hex);
+}
+
+static ssize_t output_write(struct file *file, const char __user *buf,
+                           size_t len, loff_t *ppos)
+{
+       struct moxtet *moxtet = file->private_data;
+       u8 bin[TURRIS_MOX_MAX_MODULES];
+       u8 hex[sizeof(bin) * 2 + 1];
+       ssize_t res;
+       loff_t dummy = 0;
+       int err, i;
+
+       if (len > 2 * moxtet->count + 1 || len < 2 * moxtet->count)
+               return -EINVAL;
+
+       res = simple_write_to_buffer(hex, sizeof(hex), &dummy, buf, len);
+       if (res < 0)
+               return res;
+
+       if (len % 2 == 1 && hex[len - 1] != '\n')
+               return -EINVAL;
+
+       err = hex2bin(bin, hex, moxtet->count);
+       if (err < 0)
+               return -EINVAL;
+
+       mutex_lock(&moxtet->lock);
+
+       for (i = 0; i < moxtet->count; ++i)
+               moxtet->tx[moxtet->count - i] = bin[i];
+
+       err = spi_write(to_spi_device(moxtet->dev), moxtet->tx,
+                       moxtet->count + 1);
+
+       mutex_unlock(&moxtet->lock);
+
+       return err < 0 ? err : len;
+}
+
+static const struct file_operations output_fops = {
+       .owner  = THIS_MODULE,
+       .open   = moxtet_debug_open,
+       .read   = output_read,
+       .write  = output_write,
+       .llseek = no_llseek,
+};
+
+static int moxtet_register_debugfs(struct moxtet *moxtet)
+{
+       struct dentry *root, *entry;
+
+       root = debugfs_create_dir("moxtet", NULL);
+
+       if (IS_ERR(root))
+               return PTR_ERR(root);
+
+       entry = debugfs_create_file_unsafe("input", 0444, root, moxtet,
+                                          &input_fops);
+       if (IS_ERR(entry))
+               goto err_remove;
+
+       entry = debugfs_create_file_unsafe("output", 0644, root, moxtet,
+                                          &output_fops);
+       if (IS_ERR(entry))
+               goto err_remove;
+
+       moxtet->debugfs_root = root;
+
+       return 0;
+err_remove:
+       debugfs_remove_recursive(root);
+       return PTR_ERR(entry);
+}
+
+static void moxtet_unregister_debugfs(struct moxtet *moxtet)
+{
+       debugfs_remove_recursive(moxtet->debugfs_root);
+}
+#else
+static inline int moxtet_register_debugfs(struct moxtet *moxtet)
+{
+       return 0;
+}
+
+static inline void moxtet_unregister_debugfs(struct moxtet *moxtet)
+{
+}
+#endif
+
+static int moxtet_irq_domain_map(struct irq_domain *d, unsigned int irq,
+                                irq_hw_number_t hw)
+{
+       struct moxtet *moxtet = d->host_data;
+
+       if (hw >= MOXTET_NIRQS || !(moxtet->irq.exists & BIT(hw))) {
+               dev_err(moxtet->dev, "Invalid hw irq number\n");
+               return -EINVAL;
+       }
+
+       irq_set_chip_data(irq, d->host_data);
+       irq_set_chip_and_handler(irq, &moxtet->irq.chip, handle_level_irq);
+
+       return 0;
+}
+
+static int moxtet_irq_domain_xlate(struct irq_domain *d,
+                                  struct device_node *ctrlr,
+                                  const u32 *intspec, unsigned int intsize,
+                                  unsigned long *out_hwirq,
+                                  unsigned int *out_type)
+{
+       struct moxtet *moxtet = d->host_data;
+       int irq;
+
+       if (WARN_ON(intsize < 1))
+               return -EINVAL;
+
+       irq = intspec[0];
+
+       if (irq >= MOXTET_NIRQS || !(moxtet->irq.exists & BIT(irq)))
+               return -EINVAL;
+
+       *out_hwirq = irq;
+       *out_type = IRQ_TYPE_NONE;
+       return 0;
+}
+
+static const struct irq_domain_ops moxtet_irq_domain = {
+       .map = moxtet_irq_domain_map,
+       .xlate = moxtet_irq_domain_xlate,
+};
+
+static void moxtet_irq_mask(struct irq_data *d)
+{
+       struct moxtet *moxtet = irq_data_get_irq_chip_data(d);
+
+       moxtet->irq.masked |= BIT(d->hwirq);
+}
+
+static void moxtet_irq_unmask(struct irq_data *d)
+{
+       struct moxtet *moxtet = irq_data_get_irq_chip_data(d);
+
+       moxtet->irq.masked &= ~BIT(d->hwirq);
+}
+
+static void moxtet_irq_print_chip(struct irq_data *d, struct seq_file *p)
+{
+       struct moxtet *moxtet = irq_data_get_irq_chip_data(d);
+       struct moxtet_irqpos *pos = &moxtet->irq.position[d->hwirq];
+       int id;
+
+       id = moxtet->modules[pos->idx];
+
+       seq_printf(p, " moxtet-%s.%i#%i", mox_module_name(id), pos->idx,
+                  pos->bit);
+}
+
+static const struct irq_chip moxtet_irq_chip = {
+       .name                   = "moxtet",
+       .irq_mask               = moxtet_irq_mask,
+       .irq_unmask             = moxtet_irq_unmask,
+       .irq_print_chip         = moxtet_irq_print_chip,
+};
+
+static int moxtet_irq_read(struct moxtet *moxtet, unsigned long *map)
+{
+       struct moxtet_irqpos *pos = moxtet->irq.position;
+       u8 buf[TURRIS_MOX_MAX_MODULES];
+       int i, ret;
+
+       ret = moxtet_spi_read(moxtet, buf);
+       if (ret < 0)
+               return ret;
+
+       *map = 0;
+
+       for_each_set_bit(i, &moxtet->irq.exists, MOXTET_NIRQS) {
+               if (!(buf[pos[i].idx + 1] & BIT(4 + pos[i].bit)))
+                       set_bit(i, map);
+       }
+
+       return 0;
+}
+
+static irqreturn_t moxtet_irq_thread_fn(int irq, void *data)
+{
+       struct moxtet *moxtet = data;
+       unsigned long set;
+       int nhandled = 0, i, sub_irq, ret;
+
+       ret = moxtet_irq_read(moxtet, &set);
+       if (ret < 0)
+               goto out;
+
+       set &= ~moxtet->irq.masked;
+
+       do {
+               for_each_set_bit(i, &set, MOXTET_NIRQS) {
+                       sub_irq = irq_find_mapping(moxtet->irq.domain, i);
+                       handle_nested_irq(sub_irq);
+                       dev_dbg(moxtet->dev, "%i irq\n", i);
+                       ++nhandled;
+               }
+
+               ret = moxtet_irq_read(moxtet, &set);
+               if (ret < 0)
+                       goto out;
+
+               set &= ~moxtet->irq.masked;
+       } while (set);
+
+out:
+       return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
+}
+
+static void moxtet_irq_free(struct moxtet *moxtet)
+{
+       int i, irq;
+
+       for (i = 0; i < MOXTET_NIRQS; ++i) {
+               if (moxtet->irq.exists & BIT(i)) {
+                       irq = irq_find_mapping(moxtet->irq.domain, i);
+                       irq_dispose_mapping(irq);
+               }
+       }
+
+       irq_domain_remove(moxtet->irq.domain);
+}
+
+static int moxtet_irq_setup(struct moxtet *moxtet)
+{
+       int i, ret;
+
+       moxtet->irq.domain = irq_domain_add_simple(moxtet->dev->of_node,
+                                                  MOXTET_NIRQS, 0,
+                                                  &moxtet_irq_domain, moxtet);
+       if (moxtet->irq.domain == NULL) {
+               dev_err(moxtet->dev, "Could not add IRQ domain\n");
+               return -ENOMEM;
+       }
+
+       for (i = 0; i < MOXTET_NIRQS; ++i)
+               if (moxtet->irq.exists & BIT(i))
+                       irq_create_mapping(moxtet->irq.domain, i);
+
+       moxtet->irq.chip = moxtet_irq_chip;
+       moxtet->irq.masked = ~0;
+
+       ret = request_threaded_irq(moxtet->dev_irq, NULL, moxtet_irq_thread_fn,
+                                  IRQF_ONESHOT, "moxtet", moxtet);
+       if (ret < 0)
+               goto err_free;
+
+       return 0;
+
+err_free:
+       moxtet_irq_free(moxtet);
+       return ret;
+}
+
+static int moxtet_probe(struct spi_device *spi)
+{
+       struct moxtet *moxtet;
+       int ret;
+
+       ret = spi_setup(spi);
+       if (ret < 0)
+               return ret;
+
+       moxtet = devm_kzalloc(&spi->dev, sizeof(struct moxtet),
+                             GFP_KERNEL);
+       if (!moxtet)
+               return -ENOMEM;
+
+       moxtet->dev = &spi->dev;
+       spi_set_drvdata(spi, moxtet);
+
+       mutex_init(&moxtet->lock);
+
+       moxtet->dev_irq = of_irq_get(moxtet->dev->of_node, 0);
+       if (moxtet->dev_irq == -EPROBE_DEFER)
+               return -EPROBE_DEFER;
+
+       if (moxtet->dev_irq <= 0) {
+               dev_err(moxtet->dev, "No IRQ resource found\n");
+               return -ENXIO;
+       }
+
+       ret = moxtet_find_topology(moxtet);
+       if (ret < 0)
+               return ret;
+
+       if (moxtet->irq.exists) {
+               ret = moxtet_irq_setup(moxtet);
+               if (ret < 0)
+                       return ret;
+       }
+
+       of_register_moxtet_devices(moxtet);
+       moxtet_register_devices_from_topology(moxtet);
+
+       ret = moxtet_register_debugfs(moxtet);
+       if (ret < 0)
+               dev_warn(moxtet->dev, "Failed creating debugfs entries: %i\n",
+                        ret);
+
+       return 0;
+}
+
+static int moxtet_remove(struct spi_device *spi)
+{
+       struct moxtet *moxtet = spi_get_drvdata(spi);
+
+       free_irq(moxtet->dev_irq, moxtet);
+
+       moxtet_irq_free(moxtet);
+
+       moxtet_unregister_debugfs(moxtet);
+
+       device_for_each_child(moxtet->dev, NULL, __unregister);
+
+       mutex_destroy(&moxtet->lock);
+
+       return 0;
+}
+
+static const struct of_device_id moxtet_dt_ids[] = {
+       { .compatible = "cznic,moxtet" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, moxtet_dt_ids);
+
+static struct spi_driver moxtet_spi_driver = {
+       .driver = {
+               .name           = "moxtet",
+               .of_match_table = moxtet_dt_ids,
+       },
+       .probe          = moxtet_probe,
+       .remove         = moxtet_remove,
+};
+
+static int __init moxtet_init(void)
+{
+       int ret;
+
+       ret = bus_register(&moxtet_bus_type);
+       if (ret < 0) {
+               pr_err("moxtet bus registration failed: %d\n", ret);
+               goto error;
+       }
+
+       ret = spi_register_driver(&moxtet_spi_driver);
+       if (ret < 0) {
+               pr_err("moxtet spi driver registration failed: %d\n", ret);
+               goto error_bus;
+       }
+
+       return 0;
+
+error_bus:
+       bus_unregister(&moxtet_bus_type);
+error:
+       return ret;
+}
+postcore_initcall_sync(moxtet_init);
+
+static void __exit moxtet_exit(void)
+{
+       spi_unregister_driver(&moxtet_spi_driver);
+       bus_unregister(&moxtet_bus_type);
+}
+module_exit(moxtet_exit);
+
+MODULE_AUTHOR("Marek Behun <marek.behun@nic.cz>");
+MODULE_DESCRIPTION("CZ.NIC's Turris Mox module configuration bus");
+MODULE_LICENSE("GPL v2");
index 1b76d95..be79d6c 100644 (file)
@@ -651,10 +651,8 @@ static int sunxi_rsb_probe(struct platform_device *pdev)
                return PTR_ERR(rsb->regs);
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(dev, "failed to retrieve irq: %d\n", irq);
+       if (irq < 0)
                return irq;
-       }
 
        rsb->clk = devm_clk_get(dev, NULL);
        if (IS_ERR(rsb->clk)) {
index e6deabd..2db474a 100644 (file)
@@ -949,7 +949,7 @@ static int sysc_best_idle_mode(u32 idlemodes, u32 *best_mode)
                *best_mode = SYSC_IDLE_SMART_WKUP;
        else if (idlemodes & BIT(SYSC_IDLE_SMART))
                *best_mode = SYSC_IDLE_SMART;
-       else if (idlemodes & SYSC_IDLE_FORCE)
+       else if (idlemodes & BIT(SYSC_IDLE_FORCE))
                *best_mode = SYSC_IDLE_FORCE;
        else
                return -EINVAL;
@@ -1267,7 +1267,8 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        SYSC_QUIRK("control", 0, 0, 0x10, -1, 0x40000900, 0xffffffff, 0),
        SYSC_QUIRK("cpgmac", 0, 0x1200, 0x1208, 0x1204, 0x4edb1902,
                   0xffff00f0, 0),
-       SYSC_QUIRK("dcan", 0, 0, -1, -1, 0xffffffff, 0xffffffff, 0),
+       SYSC_QUIRK("dcan", 0, 0x20, -1, -1, 0xa3170504, 0xffffffff, 0),
+       SYSC_QUIRK("dcan", 0, 0x20, -1, -1, 0x4edb1902, 0xffffffff, 0),
        SYSC_QUIRK("dmic", 0, 0, 0x10, -1, 0x50010000, 0xffffffff, 0),
        SYSC_QUIRK("dwc3", 0, 0, 0x10, -1, 0x500a0200, 0xffffffff, 0),
        SYSC_QUIRK("epwmss", 0, 0, 0x4, -1, 0x47400001, 0xffffffff, 0),
@@ -1692,10 +1693,7 @@ static int sysc_init_sysc_mask(struct sysc *ddata)
        if (error)
                return 0;
 
-       if (val)
-               ddata->cfg.sysc_val = val & ddata->cap->sysc_mask;
-       else
-               ddata->cfg.sysc_val = ddata->cap->sysc_mask;
+       ddata->cfg.sysc_val = val & ddata->cap->sysc_mask;
 
        return 0;
 }
@@ -2385,27 +2383,27 @@ static int sysc_probe(struct platform_device *pdev)
 
        error = sysc_init_dts_quirks(ddata);
        if (error)
-               goto unprepare;
+               return error;
 
        error = sysc_map_and_check_registers(ddata);
        if (error)
-               goto unprepare;
+               return error;
 
        error = sysc_init_sysc_mask(ddata);
        if (error)
-               goto unprepare;
+               return error;
 
        error = sysc_init_idlemodes(ddata);
        if (error)
-               goto unprepare;
+               return error;
 
        error = sysc_init_syss_mask(ddata);
        if (error)
-               goto unprepare;
+               return error;
 
        error = sysc_init_pdata(ddata);
        if (error)
-               goto unprepare;
+               return error;
 
        sysc_init_early_quirks(ddata);
 
@@ -2415,7 +2413,7 @@ static int sysc_probe(struct platform_device *pdev)
 
        error = sysc_init_resets(ddata);
        if (error)
-               return error;
+               goto unprepare;
 
        error = sysc_init_module(ddata);
        if (error)
index e845c1a..f70deda 100644 (file)
@@ -176,7 +176,6 @@ static int uniphier_system_bus_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct uniphier_system_bus_priv *priv;
-       struct resource *regs;
        const __be32 *ranges;
        u32 cells, addr, size;
        u64 paddr;
@@ -186,8 +185,7 @@ static int uniphier_system_bus_probe(struct platform_device *pdev)
        if (!priv)
                return -ENOMEM;
 
-       regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       priv->membase = devm_ioremap_resource(dev, regs);
+       priv->membase = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(priv->membase))
                return PTR_ERR(priv->membase);
 
index 3e86688..df0fc99 100644 (file)
@@ -26,28 +26,6 @@ config DEVKMEM
          kind of kernel debugging operations.
          When in doubt, say "N".
 
-config SGI_SNSC
-       bool "SGI Altix system controller communication support"
-       depends on (IA64_SGI_SN2 || IA64_GENERIC)
-       help
-         If you have an SGI Altix and you want to enable system
-         controller communication from user space (you want this!),
-         say Y.  Otherwise, say N.
-
-config SGI_TIOCX
-       bool "SGI TIO CX driver support"
-       depends on (IA64_SGI_SN2 || IA64_GENERIC)
-       help
-         If you have an SGI Altix and you have fpga devices attached
-         to your TIO, say Y here, otherwise say N.
-
-config SGI_MBCS
-       tristate "SGI FPGA Core Services driver support"
-       depends on SGI_TIOCX
-       help
-         If you have an SGI Altix with an attached SABrick
-         say Y or M here, otherwise say N.
-
 source "drivers/tty/serial/Kconfig"
 source "drivers/tty/serdev/Kconfig"
 
@@ -573,3 +551,12 @@ config RANDOM_TRUST_CPU
        has not installed a hidden back door to compromise the CPU's
        random number generation facilities. This can also be configured
        at boot with "random.trust_cpu=on/off".
+
+config RANDOM_TRUST_BOOTLOADER
+       bool "Trust the bootloader to initialize Linux's CRNG"
+       help
+       Some bootloaders can provide entropy to increase the kernel's initial
+       device randomness. Say Y here to assume the entropy provided by the
+       booloader is trustworthy so it will be added to the kernel's entropy
+       pool. Otherwise, say N here so it will be regarded as device input that
+       only mixes the entropy pool.
\ No newline at end of file
index fbea7dd..7c5ea6f 100644 (file)
@@ -9,11 +9,9 @@ obj-y                          += misc.o
 obj-$(CONFIG_ATARI_DSP56K)     += dsp56k.o
 obj-$(CONFIG_VIRTIO_CONSOLE)   += virtio_console.o
 obj-$(CONFIG_RAW_DRIVER)       += raw.o
-obj-$(CONFIG_SGI_SNSC)         += snsc.o snsc_event.o
 obj-$(CONFIG_MSPEC)            += mspec.o
 obj-$(CONFIG_UV_MMTIMER)       += uv_mmtimer.o
 obj-$(CONFIG_IBM_BSR)          += bsr.o
-obj-$(CONFIG_SGI_MBCS)         += mbcs.o
 
 obj-$(CONFIG_PRINTER)          += lp.o
 
index 6231714..812d6aa 100644 (file)
@@ -111,14 +111,14 @@ config AGP_VIA
 
 config AGP_I460
        tristate "Intel 460GX chipset support"
-       depends on AGP && (IA64_DIG || IA64_GENERIC)
+       depends on AGP && IA64
        help
          This option gives you AGP GART support for the Intel 460GX chipset
          for IA64 processors.
 
 config AGP_HP_ZX1
        tristate "HP ZX1 chipset AGP support"
-       depends on AGP && (IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB || IA64_GENERIC)
+       depends on AGP && IA64
        help
          This option gives you AGP GART support for the HP ZX1 chipset
          for IA64 processors.
@@ -150,13 +150,6 @@ config AGP_EFFICEON
          This option gives you AGP support for the Transmeta Efficeon
          series processors with integrated northbridges.
 
-config AGP_SGI_TIOCA
-        tristate "SGI TIO chipset AGP support"
-        depends on AGP && (IA64_SGI_SN2 || IA64_GENERIC)
-        help
-          This option gives you AGP GART support for the SGI TIO chipset
-          for IA64 processors.
-
 config INTEL_GTT
        tristate
        depends on X86 && PCI
index 4a786ff..cb2497d 100644 (file)
@@ -16,7 +16,6 @@ obj-$(CONFIG_AGP_I460)                += i460-agp.o
 obj-$(CONFIG_AGP_INTEL)                += intel-agp.o
 obj-$(CONFIG_INTEL_GTT)                += intel-gtt.o
 obj-$(CONFIG_AGP_NVIDIA)       += nvidia-agp.o
-obj-$(CONFIG_AGP_SGI_TIOCA)    += sgi-agp.o
 obj-$(CONFIG_AGP_SIS)          += sis-agp.o
 obj-$(CONFIG_AGP_SWORKS)       += sworks-agp.o
 obj-$(CONFIG_AGP_UNINORTH)     += uninorth-agp.o
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
deleted file mode 100644 (file)
index e7d5bdc..0000000
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2003-2005 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-/*
- * SGI TIOCA AGPGART routines.
- *
- */
-
-#include <linux/acpi.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/agp_backend.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/io.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/tioca_provider.h>
-#include "agp.h"
-
-extern int agp_memory_reserved;
-extern uint32_t tioca_gart_found;
-extern struct list_head tioca_list;
-static struct agp_bridge_data **sgi_tioca_agp_bridges;
-
-/*
- * The aperature size and related information is set up at TIOCA init time.
- * Values for this table will be extracted and filled in at
- * sgi_tioca_fetch_size() time.
- */
-
-static struct aper_size_info_fixed sgi_tioca_sizes[] = {
-       {0, 0, 0},
-};
-
-static struct page *sgi_tioca_alloc_page(struct agp_bridge_data *bridge)
-{
-       struct page *page;
-       int nid;
-       struct tioca_kernel *info =
-           (struct tioca_kernel *)bridge->dev_private_data;
-
-       nid = info->ca_closest_node;
-       page = alloc_pages_node(nid, GFP_KERNEL, 0);
-       if (!page)
-               return NULL;
-
-       get_page(page);
-       atomic_inc(&agp_bridge->current_memory_agp);
-       return page;
-}
-
-/*
- * Flush GART tlb's.  Cannot selectively flush based on memory so the mem
- * arg is ignored.
- */
-
-static void sgi_tioca_tlbflush(struct agp_memory *mem)
-{
-       tioca_tlbflush(mem->bridge->dev_private_data);
-}
-
-/*
- * Given an address of a host physical page, turn it into a valid gart
- * entry.
- */
-static unsigned long
-sgi_tioca_mask_memory(struct agp_bridge_data *bridge, dma_addr_t addr,
-                     int type)
-{
-       return tioca_physpage_to_gart(addr);
-}
-
-static void sgi_tioca_agp_enable(struct agp_bridge_data *bridge, u32 mode)
-{
-       tioca_fastwrite_enable(bridge->dev_private_data);
-}
-
-/*
- * sgi_tioca_configure() doesn't have anything to do since the base CA driver
- * has alreay set up the GART.
- */
-
-static int sgi_tioca_configure(void)
-{
-       return 0;
-}
-
-/*
- * Determine gfx aperature size.  This has already been determined by the
- * CA driver init, so just need to set agp_bridge values accordingly.
- */
-
-static int sgi_tioca_fetch_size(void)
-{
-       struct tioca_kernel *info =
-           (struct tioca_kernel *)agp_bridge->dev_private_data;
-
-       sgi_tioca_sizes[0].size = info->ca_gfxap_size / MB(1);
-       sgi_tioca_sizes[0].num_entries = info->ca_gfxgart_entries;
-
-       return sgi_tioca_sizes[0].size;
-}
-
-static int sgi_tioca_create_gatt_table(struct agp_bridge_data *bridge)
-{
-       struct tioca_kernel *info =
-           (struct tioca_kernel *)bridge->dev_private_data;
-
-       bridge->gatt_table_real = (u32 *) info->ca_gfxgart;
-       bridge->gatt_table = bridge->gatt_table_real;
-       bridge->gatt_bus_addr = info->ca_gfxgart_base;
-
-       return 0;
-}
-
-static int sgi_tioca_free_gatt_table(struct agp_bridge_data *bridge)
-{
-       return 0;
-}
-
-static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start,
-                                  int type)
-{
-       int num_entries;
-       size_t i;
-       off_t j;
-       void *temp;
-       struct agp_bridge_data *bridge;
-       u64 *table;
-
-       bridge = mem->bridge;
-       if (!bridge)
-               return -EINVAL;
-
-       table = (u64 *)bridge->gatt_table;
-
-       temp = bridge->current_size;
-
-       switch (bridge->driver->size_type) {
-       case U8_APER_SIZE:
-               num_entries = A_SIZE_8(temp)->num_entries;
-               break;
-       case U16_APER_SIZE:
-               num_entries = A_SIZE_16(temp)->num_entries;
-               break;
-       case U32_APER_SIZE:
-               num_entries = A_SIZE_32(temp)->num_entries;
-               break;
-       case FIXED_APER_SIZE:
-               num_entries = A_SIZE_FIX(temp)->num_entries;
-               break;
-       case LVL2_APER_SIZE:
-               return -EINVAL;
-       default:
-               num_entries = 0;
-               break;
-       }
-
-       num_entries -= agp_memory_reserved / PAGE_SIZE;
-       if (num_entries < 0)
-               num_entries = 0;
-
-       if (type != 0 || mem->type != 0) {
-               return -EINVAL;
-       }
-
-       if ((pg_start + mem->page_count) > num_entries)
-               return -EINVAL;
-
-       j = pg_start;
-
-       while (j < (pg_start + mem->page_count)) {
-               if (table[j])
-                       return -EBUSY;
-               j++;
-       }
-
-       if (!mem->is_flushed) {
-               bridge->driver->cache_flush();
-               mem->is_flushed = true;
-       }
-
-       for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
-               table[j] =
-                   bridge->driver->mask_memory(bridge,
-                                               page_to_phys(mem->pages[i]),
-                                               mem->type);
-       }
-
-       bridge->driver->tlb_flush(mem);
-       return 0;
-}
-
-static int sgi_tioca_remove_memory(struct agp_memory *mem, off_t pg_start,
-                                  int type)
-{
-       size_t i;
-       struct agp_bridge_data *bridge;
-       u64 *table;
-
-       bridge = mem->bridge;
-       if (!bridge)
-               return -EINVAL;
-
-       if (type != 0 || mem->type != 0) {
-               return -EINVAL;
-       }
-
-       table = (u64 *)bridge->gatt_table;
-
-       for (i = pg_start; i < (mem->page_count + pg_start); i++) {
-               table[i] = 0;
-       }
-
-       bridge->driver->tlb_flush(mem);
-       return 0;
-}
-
-static void sgi_tioca_cache_flush(void)
-{
-}
-
-/*
- * Cleanup.  Nothing to do as the CA driver owns the GART.
- */
-
-static void sgi_tioca_cleanup(void)
-{
-}
-
-static struct agp_bridge_data *sgi_tioca_find_bridge(struct pci_dev *pdev)
-{
-       struct agp_bridge_data *bridge;
-
-       list_for_each_entry(bridge, &agp_bridges, list) {
-               if (bridge->dev->bus == pdev->bus)
-                       break;
-       }
-       return bridge;
-}
-
-const struct agp_bridge_driver sgi_tioca_driver = {
-       .owner = THIS_MODULE,
-       .size_type = U16_APER_SIZE,
-       .configure = sgi_tioca_configure,
-       .fetch_size = sgi_tioca_fetch_size,
-       .cleanup = sgi_tioca_cleanup,
-       .tlb_flush = sgi_tioca_tlbflush,
-       .mask_memory = sgi_tioca_mask_memory,
-       .agp_enable = sgi_tioca_agp_enable,
-       .cache_flush = sgi_tioca_cache_flush,
-       .create_gatt_table = sgi_tioca_create_gatt_table,
-       .free_gatt_table = sgi_tioca_free_gatt_table,
-       .insert_memory = sgi_tioca_insert_memory,
-       .remove_memory = sgi_tioca_remove_memory,
-       .alloc_by_type = agp_generic_alloc_by_type,
-       .free_by_type = agp_generic_free_by_type,
-       .agp_alloc_page = sgi_tioca_alloc_page,
-       .agp_destroy_page = agp_generic_destroy_page,
-       .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
-       .cant_use_aperture = true,
-       .needs_scratch_page = false,
-       .num_aperture_sizes = 1,
-};
-
-static int agp_sgi_init(void)
-{
-       unsigned int j;
-       struct tioca_kernel *info;
-       struct pci_dev *pdev = NULL;
-
-       if (tioca_gart_found)
-               printk(KERN_INFO PFX "SGI TIO CA GART driver initialized.\n");
-       else
-               return 0;
-
-       sgi_tioca_agp_bridges = kmalloc_array(tioca_gart_found,
-                                             sizeof(struct agp_bridge_data *),
-                                             GFP_KERNEL);
-       if (!sgi_tioca_agp_bridges)
-               return -ENOMEM;
-
-       j = 0;
-       list_for_each_entry(info, &tioca_list, ca_list) {
-               if (list_empty(info->ca_devices))
-                       continue;
-               list_for_each_entry(pdev, info->ca_devices, bus_list) {
-                       u8 cap_ptr;
-
-                       if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8))
-                               continue;
-                       cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
-                       if (!cap_ptr)
-                               continue;
-               }
-               sgi_tioca_agp_bridges[j] = agp_alloc_bridge();
-               printk(KERN_INFO PFX "bridge %d = 0x%p\n", j,
-                      sgi_tioca_agp_bridges[j]);
-               if (sgi_tioca_agp_bridges[j]) {
-                       sgi_tioca_agp_bridges[j]->dev = pdev;
-                       sgi_tioca_agp_bridges[j]->dev_private_data = info;
-                       sgi_tioca_agp_bridges[j]->driver = &sgi_tioca_driver;
-                       sgi_tioca_agp_bridges[j]->gart_bus_addr =
-                           info->ca_gfxap_base;
-                       sgi_tioca_agp_bridges[j]->mode = (0x7D << 24) | /* 126 requests */
-                           (0x1 << 9) |        /* SBA supported */
-                           (0x1 << 5) |        /* 64-bit addresses supported */
-                           (0x1 << 4) |        /* FW supported */
-                           (0x1 << 3) |        /* AGP 3.0 mode */
-                           0x2;        /* 8x transfer only */
-                       sgi_tioca_agp_bridges[j]->current_size =
-                           sgi_tioca_agp_bridges[j]->previous_size =
-                           (void *)&sgi_tioca_sizes[0];
-                       agp_add_bridge(sgi_tioca_agp_bridges[j]);
-               }
-               j++;
-       }
-
-       agp_find_bridge = &sgi_tioca_find_bridge;
-       return 0;
-}
-
-static void agp_sgi_cleanup(void)
-{
-       kfree(sgi_tioca_agp_bridges);
-       sgi_tioca_agp_bridges = NULL;
-}
-
-module_init(agp_sgi_init);
-module_exit(agp_sgi_cleanup);
-
-MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
deleted file mode 100644 (file)
index 0a31b60..0000000
+++ /dev/null
@@ -1,831 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2005 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/*
- *     MOATB Core Services driver.
- */
-
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/types.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/notifier.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/device.h>
-#include <linux/mm.h>
-#include <linux/uio.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/pagemap.h>
-#include <asm/io.h>
-#include <linux/uaccess.h>
-#include <asm/pgtable.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/tiocx.h>
-#include "mbcs.h"
-
-#define MBCS_DEBUG 0
-#if MBCS_DEBUG
-#define DBG(fmt...)    printk(KERN_ALERT fmt)
-#else
-#define DBG(fmt...)
-#endif
-static DEFINE_MUTEX(mbcs_mutex);
-static int mbcs_major;
-
-static LIST_HEAD(soft_list);
-
-/*
- * file operations
- */
-static const struct file_operations mbcs_ops = {
-       .owner = THIS_MODULE,
-       .open = mbcs_open,
-       .llseek = mbcs_sram_llseek,
-       .read = mbcs_sram_read,
-       .write = mbcs_sram_write,
-       .mmap = mbcs_gscr_mmap,
-};
-
-struct mbcs_callback_arg {
-       int minor;
-       struct cx_dev *cx_dev;
-};
-
-static inline void mbcs_getdma_init(struct getdma *gdma)
-{
-       memset(gdma, 0, sizeof(struct getdma));
-       gdma->DoneIntEnable = 1;
-}
-
-static inline void mbcs_putdma_init(struct putdma *pdma)
-{
-       memset(pdma, 0, sizeof(struct putdma));
-       pdma->DoneIntEnable = 1;
-}
-
-static inline void mbcs_algo_init(struct algoblock *algo_soft)
-{
-       memset(algo_soft, 0, sizeof(struct algoblock));
-}
-
-static inline void mbcs_getdma_set(void *mmr,
-                      uint64_t hostAddr,
-                      uint64_t localAddr,
-                      uint64_t localRamSel,
-                      uint64_t numPkts,
-                      uint64_t amoEnable,
-                      uint64_t intrEnable,
-                      uint64_t peerIO,
-                      uint64_t amoHostDest,
-                      uint64_t amoModType, uint64_t intrHostDest,
-                      uint64_t intrVector)
-{
-       union dma_control rdma_control;
-       union dma_amo_dest amo_dest;
-       union intr_dest intr_dest;
-       union dma_localaddr local_addr;
-       union dma_hostaddr host_addr;
-
-       rdma_control.dma_control_reg = 0;
-       amo_dest.dma_amo_dest_reg = 0;
-       intr_dest.intr_dest_reg = 0;
-       local_addr.dma_localaddr_reg = 0;
-       host_addr.dma_hostaddr_reg = 0;
-
-       host_addr.dma_sys_addr = hostAddr;
-       MBCS_MMR_SET(mmr, MBCS_RD_DMA_SYS_ADDR, host_addr.dma_hostaddr_reg);
-
-       local_addr.dma_ram_addr = localAddr;
-       local_addr.dma_ram_sel = localRamSel;
-       MBCS_MMR_SET(mmr, MBCS_RD_DMA_LOC_ADDR, local_addr.dma_localaddr_reg);
-
-       rdma_control.dma_op_length = numPkts;
-       rdma_control.done_amo_en = amoEnable;
-       rdma_control.done_int_en = intrEnable;
-       rdma_control.pio_mem_n = peerIO;
-       MBCS_MMR_SET(mmr, MBCS_RD_DMA_CTRL, rdma_control.dma_control_reg);
-
-       amo_dest.dma_amo_sys_addr = amoHostDest;
-       amo_dest.dma_amo_mod_type = amoModType;
-       MBCS_MMR_SET(mmr, MBCS_RD_DMA_AMO_DEST, amo_dest.dma_amo_dest_reg);
-
-       intr_dest.address = intrHostDest;
-       intr_dest.int_vector = intrVector;
-       MBCS_MMR_SET(mmr, MBCS_RD_DMA_INT_DEST, intr_dest.intr_dest_reg);
-
-}
-
-static inline void mbcs_putdma_set(void *mmr,
-                      uint64_t hostAddr,
-                      uint64_t localAddr,
-                      uint64_t localRamSel,
-                      uint64_t numPkts,
-                      uint64_t amoEnable,
-                      uint64_t intrEnable,
-                      uint64_t peerIO,
-                      uint64_t amoHostDest,
-                      uint64_t amoModType,
-                      uint64_t intrHostDest, uint64_t intrVector)
-{
-       union dma_control wdma_control;
-       union dma_amo_dest amo_dest;
-       union intr_dest intr_dest;
-       union dma_localaddr local_addr;
-       union dma_hostaddr host_addr;
-
-       wdma_control.dma_control_reg = 0;
-       amo_dest.dma_amo_dest_reg = 0;
-       intr_dest.intr_dest_reg = 0;
-       local_addr.dma_localaddr_reg = 0;
-       host_addr.dma_hostaddr_reg = 0;
-
-       host_addr.dma_sys_addr = hostAddr;
-       MBCS_MMR_SET(mmr, MBCS_WR_DMA_SYS_ADDR, host_addr.dma_hostaddr_reg);
-
-       local_addr.dma_ram_addr = localAddr;
-       local_addr.dma_ram_sel = localRamSel;
-       MBCS_MMR_SET(mmr, MBCS_WR_DMA_LOC_ADDR, local_addr.dma_localaddr_reg);
-
-       wdma_control.dma_op_length = numPkts;
-       wdma_control.done_amo_en = amoEnable;
-       wdma_control.done_int_en = intrEnable;
-       wdma_control.pio_mem_n = peerIO;
-       MBCS_MMR_SET(mmr, MBCS_WR_DMA_CTRL, wdma_control.dma_control_reg);
-
-       amo_dest.dma_amo_sys_addr = amoHostDest;
-       amo_dest.dma_amo_mod_type = amoModType;
-       MBCS_MMR_SET(mmr, MBCS_WR_DMA_AMO_DEST, amo_dest.dma_amo_dest_reg);
-
-       intr_dest.address = intrHostDest;
-       intr_dest.int_vector = intrVector;
-       MBCS_MMR_SET(mmr, MBCS_WR_DMA_INT_DEST, intr_dest.intr_dest_reg);
-
-}
-
-static inline void mbcs_algo_set(void *mmr,
-                    uint64_t amoHostDest,
-                    uint64_t amoModType,
-                    uint64_t intrHostDest,
-                    uint64_t intrVector, uint64_t algoStepCount)
-{
-       union dma_amo_dest amo_dest;
-       union intr_dest intr_dest;
-       union algo_step step;
-
-       step.algo_step_reg = 0;
-       intr_dest.intr_dest_reg = 0;
-       amo_dest.dma_amo_dest_reg = 0;
-
-       amo_dest.dma_amo_sys_addr = amoHostDest;
-       amo_dest.dma_amo_mod_type = amoModType;
-       MBCS_MMR_SET(mmr, MBCS_ALG_AMO_DEST, amo_dest.dma_amo_dest_reg);
-
-       intr_dest.address = intrHostDest;
-       intr_dest.int_vector = intrVector;
-       MBCS_MMR_SET(mmr, MBCS_ALG_INT_DEST, intr_dest.intr_dest_reg);
-
-       step.alg_step_cnt = algoStepCount;
-       MBCS_MMR_SET(mmr, MBCS_ALG_STEP, step.algo_step_reg);
-}
-
-static inline int mbcs_getdma_start(struct mbcs_soft *soft)
-{
-       void *mmr_base;
-       struct getdma *gdma;
-       uint64_t numPkts;
-       union cm_control cm_control;
-
-       mmr_base = soft->mmr_base;
-       gdma = &soft->getdma;
-
-       /* check that host address got setup */
-       if (!gdma->hostAddr)
-               return -1;
-
-       numPkts =
-           (gdma->bytes + (MBCS_CACHELINE_SIZE - 1)) / MBCS_CACHELINE_SIZE;
-
-       /* program engine */
-       mbcs_getdma_set(mmr_base, tiocx_dma_addr(gdma->hostAddr),
-                  gdma->localAddr,
-                  (gdma->localAddr < MB2) ? 0 :
-                  (gdma->localAddr < MB4) ? 1 :
-                  (gdma->localAddr < MB6) ? 2 : 3,
-                  numPkts,
-                  gdma->DoneAmoEnable,
-                  gdma->DoneIntEnable,
-                  gdma->peerIO,
-                  gdma->amoHostDest,
-                  gdma->amoModType,
-                  gdma->intrHostDest, gdma->intrVector);
-
-       /* start engine */
-       cm_control.cm_control_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
-       cm_control.rd_dma_go = 1;
-       MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, cm_control.cm_control_reg);
-
-       return 0;
-
-}
-
-static inline int mbcs_putdma_start(struct mbcs_soft *soft)
-{
-       void *mmr_base;
-       struct putdma *pdma;
-       uint64_t numPkts;
-       union cm_control cm_control;
-
-       mmr_base = soft->mmr_base;
-       pdma = &soft->putdma;
-
-       /* check that host address got setup */
-       if (!pdma->hostAddr)
-               return -1;
-
-       numPkts =
-           (pdma->bytes + (MBCS_CACHELINE_SIZE - 1)) / MBCS_CACHELINE_SIZE;
-
-       /* program engine */
-       mbcs_putdma_set(mmr_base, tiocx_dma_addr(pdma->hostAddr),
-                  pdma->localAddr,
-                  (pdma->localAddr < MB2) ? 0 :
-                  (pdma->localAddr < MB4) ? 1 :
-                  (pdma->localAddr < MB6) ? 2 : 3,
-                  numPkts,
-                  pdma->DoneAmoEnable,
-                  pdma->DoneIntEnable,
-                  pdma->peerIO,
-                  pdma->amoHostDest,
-                  pdma->amoModType,
-                  pdma->intrHostDest, pdma->intrVector);
-
-       /* start engine */
-       cm_control.cm_control_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
-       cm_control.wr_dma_go = 1;
-       MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, cm_control.cm_control_reg);
-
-       return 0;
-
-}
-
-static inline int mbcs_algo_start(struct mbcs_soft *soft)
-{
-       struct algoblock *algo_soft = &soft->algo;
-       void *mmr_base = soft->mmr_base;
-       union cm_control cm_control;
-
-       if (mutex_lock_interruptible(&soft->algolock))
-               return -ERESTARTSYS;
-
-       atomic_set(&soft->algo_done, 0);
-
-       mbcs_algo_set(mmr_base,
-                algo_soft->amoHostDest,
-                algo_soft->amoModType,
-                algo_soft->intrHostDest,
-                algo_soft->intrVector, algo_soft->algoStepCount);
-
-       /* start algorithm */
-       cm_control.cm_control_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
-       cm_control.alg_done_int_en = 1;
-       cm_control.alg_go = 1;
-       MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, cm_control.cm_control_reg);
-
-       mutex_unlock(&soft->algolock);
-
-       return 0;
-}
-
-static inline ssize_t
-do_mbcs_sram_dmawrite(struct mbcs_soft *soft, uint64_t hostAddr,
-                     size_t len, loff_t * off)
-{
-       int rv = 0;
-
-       if (mutex_lock_interruptible(&soft->dmawritelock))
-               return -ERESTARTSYS;
-
-       atomic_set(&soft->dmawrite_done, 0);
-
-       soft->putdma.hostAddr = hostAddr;
-       soft->putdma.localAddr = *off;
-       soft->putdma.bytes = len;
-
-       if (mbcs_putdma_start(soft) < 0) {
-               DBG(KERN_ALERT "do_mbcs_sram_dmawrite: "
-                                       "mbcs_putdma_start failed\n");
-               rv = -EAGAIN;
-               goto dmawrite_exit;
-       }
-
-       if (wait_event_interruptible(soft->dmawrite_queue,
-                                       atomic_read(&soft->dmawrite_done))) {
-               rv = -ERESTARTSYS;
-               goto dmawrite_exit;
-       }
-
-       rv = len;
-       *off += len;
-
-dmawrite_exit:
-       mutex_unlock(&soft->dmawritelock);
-
-       return rv;
-}
-
-static inline ssize_t
-do_mbcs_sram_dmaread(struct mbcs_soft *soft, uint64_t hostAddr,
-                    size_t len, loff_t * off)
-{
-       int rv = 0;
-
-       if (mutex_lock_interruptible(&soft->dmareadlock))
-               return -ERESTARTSYS;
-
-       atomic_set(&soft->dmawrite_done, 0);
-
-       soft->getdma.hostAddr = hostAddr;
-       soft->getdma.localAddr = *off;
-       soft->getdma.bytes = len;
-
-       if (mbcs_getdma_start(soft) < 0) {
-               DBG(KERN_ALERT "mbcs_strategy: mbcs_getdma_start failed\n");
-               rv = -EAGAIN;
-               goto dmaread_exit;
-       }
-
-       if (wait_event_interruptible(soft->dmaread_queue,
-                                       atomic_read(&soft->dmaread_done))) {
-               rv = -ERESTARTSYS;
-               goto dmaread_exit;
-       }
-
-       rv = len;
-       *off += len;
-
-dmaread_exit:
-       mutex_unlock(&soft->dmareadlock);
-
-       return rv;
-}
-
-static int mbcs_open(struct inode *ip, struct file *fp)
-{
-       struct mbcs_soft *soft;
-       int minor;
-
-       mutex_lock(&mbcs_mutex);
-       minor = iminor(ip);
-
-       /* Nothing protects access to this list... */
-       list_for_each_entry(soft, &soft_list, list) {
-               if (soft->nasid == minor) {
-                       fp->private_data = soft->cxdev;
-                       mutex_unlock(&mbcs_mutex);
-                       return 0;
-               }
-       }
-
-       mutex_unlock(&mbcs_mutex);
-       return -ENODEV;
-}
-
-static ssize_t mbcs_sram_read(struct file * fp, char __user *buf, size_t len, loff_t * off)
-{
-       struct cx_dev *cx_dev = fp->private_data;
-       struct mbcs_soft *soft = cx_dev->soft;
-       uint64_t hostAddr;
-       int rv = 0;
-
-       hostAddr = __get_dma_pages(GFP_KERNEL, get_order(len));
-       if (hostAddr == 0)
-               return -ENOMEM;
-
-       rv = do_mbcs_sram_dmawrite(soft, hostAddr, len, off);
-       if (rv < 0)
-               goto exit;
-
-       if (copy_to_user(buf, (void *)hostAddr, len))
-               rv = -EFAULT;
-
-      exit:
-       free_pages(hostAddr, get_order(len));
-
-       return rv;
-}
-
-static ssize_t
-mbcs_sram_write(struct file * fp, const char __user *buf, size_t len, loff_t * off)
-{
-       struct cx_dev *cx_dev = fp->private_data;
-       struct mbcs_soft *soft = cx_dev->soft;
-       uint64_t hostAddr;
-       int rv = 0;
-
-       hostAddr = __get_dma_pages(GFP_KERNEL, get_order(len));
-       if (hostAddr == 0)
-               return -ENOMEM;
-
-       if (copy_from_user((void *)hostAddr, buf, len)) {
-               rv = -EFAULT;
-               goto exit;
-       }
-
-       rv = do_mbcs_sram_dmaread(soft, hostAddr, len, off);
-
-      exit:
-       free_pages(hostAddr, get_order(len));
-
-       return rv;
-}
-
-static loff_t mbcs_sram_llseek(struct file * filp, loff_t off, int whence)
-{
-       return generic_file_llseek_size(filp, off, whence, MAX_LFS_FILESIZE,
-                                       MBCS_SRAM_SIZE);
-}
-
-static uint64_t mbcs_pioaddr(struct mbcs_soft *soft, uint64_t offset)
-{
-       uint64_t mmr_base;
-
-       mmr_base = (uint64_t) (soft->mmr_base + offset);
-
-       return mmr_base;
-}
-
-static void mbcs_debug_pioaddr_set(struct mbcs_soft *soft)
-{
-       soft->debug_addr = mbcs_pioaddr(soft, MBCS_DEBUG_START);
-}
-
-static void mbcs_gscr_pioaddr_set(struct mbcs_soft *soft)
-{
-       soft->gscr_addr = mbcs_pioaddr(soft, MBCS_GSCR_START);
-}
-
-static int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma)
-{
-       struct cx_dev *cx_dev = fp->private_data;
-       struct mbcs_soft *soft = cx_dev->soft;
-
-       if (vma->vm_pgoff != 0)
-               return -EINVAL;
-
-       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-       /* Remap-pfn-range will mark the range VM_IO */
-       if (remap_pfn_range(vma,
-                           vma->vm_start,
-                           __pa(soft->gscr_addr) >> PAGE_SHIFT,
-                           PAGE_SIZE,
-                           vma->vm_page_prot))
-               return -EAGAIN;
-
-       return 0;
-}
-
-/**
- * mbcs_completion_intr_handler - Primary completion handler.
- * @irq: irq
- * @arg: soft struct for device
- *
- */
-static irqreturn_t
-mbcs_completion_intr_handler(int irq, void *arg)
-{
-       struct mbcs_soft *soft = (struct mbcs_soft *)arg;
-       void *mmr_base;
-       union cm_status cm_status;
-       union cm_control cm_control;
-
-       mmr_base = soft->mmr_base;
-       cm_status.cm_status_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_STATUS);
-
-       if (cm_status.rd_dma_done) {
-               /* stop dma-read engine, clear status */
-               cm_control.cm_control_reg =
-                   MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
-               cm_control.rd_dma_clr = 1;
-               MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL,
-                            cm_control.cm_control_reg);
-               atomic_set(&soft->dmaread_done, 1);
-               wake_up(&soft->dmaread_queue);
-       }
-       if (cm_status.wr_dma_done) {
-               /* stop dma-write engine, clear status */
-               cm_control.cm_control_reg =
-                   MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
-               cm_control.wr_dma_clr = 1;
-               MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL,
-                            cm_control.cm_control_reg);
-               atomic_set(&soft->dmawrite_done, 1);
-               wake_up(&soft->dmawrite_queue);
-       }
-       if (cm_status.alg_done) {
-               /* clear status */
-               cm_control.cm_control_reg =
-                   MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
-               cm_control.alg_done_clr = 1;
-               MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL,
-                            cm_control.cm_control_reg);
-               atomic_set(&soft->algo_done, 1);
-               wake_up(&soft->algo_queue);
-       }
-
-       return IRQ_HANDLED;
-}
-
-/**
- * mbcs_intr_alloc - Allocate interrupts.
- * @dev: device pointer
- *
- */
-static int mbcs_intr_alloc(struct cx_dev *dev)
-{
-       struct sn_irq_info *sn_irq;
-       struct mbcs_soft *soft;
-       struct getdma *getdma;
-       struct putdma *putdma;
-       struct algoblock *algo;
-
-       soft = dev->soft;
-       getdma = &soft->getdma;
-       putdma = &soft->putdma;
-       algo = &soft->algo;
-
-       soft->get_sn_irq = NULL;
-       soft->put_sn_irq = NULL;
-       soft->algo_sn_irq = NULL;
-
-       sn_irq = tiocx_irq_alloc(dev->cx_id.nasid, TIOCX_CORELET, -1, -1, -1);
-       if (sn_irq == NULL)
-               return -EAGAIN;
-       soft->get_sn_irq = sn_irq;
-       getdma->intrHostDest = sn_irq->irq_xtalkaddr;
-       getdma->intrVector = sn_irq->irq_irq;
-       if (request_irq(sn_irq->irq_irq,
-                       (void *)mbcs_completion_intr_handler, IRQF_SHARED,
-                       "MBCS get intr", (void *)soft)) {
-               tiocx_irq_free(soft->get_sn_irq);
-               return -EAGAIN;
-       }
-
-       sn_irq = tiocx_irq_alloc(dev->cx_id.nasid, TIOCX_CORELET, -1, -1, -1);
-       if (sn_irq == NULL) {
-               free_irq(soft->get_sn_irq->irq_irq, soft);
-               tiocx_irq_free(soft->get_sn_irq);
-               return -EAGAIN;
-       }
-       soft->put_sn_irq = sn_irq;
-       putdma->intrHostDest = sn_irq->irq_xtalkaddr;
-       putdma->intrVector = sn_irq->irq_irq;
-       if (request_irq(sn_irq->irq_irq,
-                       (void *)mbcs_completion_intr_handler, IRQF_SHARED,
-                       "MBCS put intr", (void *)soft)) {
-               tiocx_irq_free(soft->put_sn_irq);
-               free_irq(soft->get_sn_irq->irq_irq, soft);
-               tiocx_irq_free(soft->get_sn_irq);
-               return -EAGAIN;
-       }
-
-       sn_irq = tiocx_irq_alloc(dev->cx_id.nasid, TIOCX_CORELET, -1, -1, -1);
-       if (sn_irq == NULL) {
-               free_irq(soft->put_sn_irq->irq_irq, soft);
-               tiocx_irq_free(soft->put_sn_irq);
-               free_irq(soft->get_sn_irq->irq_irq, soft);
-               tiocx_irq_free(soft->get_sn_irq);
-               return -EAGAIN;
-       }
-       soft->algo_sn_irq = sn_irq;
-       algo->intrHostDest = sn_irq->irq_xtalkaddr;
-       algo->intrVector = sn_irq->irq_irq;
-       if (request_irq(sn_irq->irq_irq,
-                       (void *)mbcs_completion_intr_handler, IRQF_SHARED,
-                       "MBCS algo intr", (void *)soft)) {
-               tiocx_irq_free(soft->algo_sn_irq);
-               free_irq(soft->put_sn_irq->irq_irq, soft);
-               tiocx_irq_free(soft->put_sn_irq);
-               free_irq(soft->get_sn_irq->irq_irq, soft);
-               tiocx_irq_free(soft->get_sn_irq);
-               return -EAGAIN;
-       }
-
-       return 0;
-}
-
-/**
- * mbcs_intr_dealloc - Remove interrupts.
- * @dev: device pointer
- *
- */
-static void mbcs_intr_dealloc(struct cx_dev *dev)
-{
-       struct mbcs_soft *soft;
-
-       soft = dev->soft;
-
-       free_irq(soft->get_sn_irq->irq_irq, soft);
-       tiocx_irq_free(soft->get_sn_irq);
-       free_irq(soft->put_sn_irq->irq_irq, soft);
-       tiocx_irq_free(soft->put_sn_irq);
-       free_irq(soft->algo_sn_irq->irq_irq, soft);
-       tiocx_irq_free(soft->algo_sn_irq);
-}
-
-static inline int mbcs_hw_init(struct mbcs_soft *soft)
-{
-       void *mmr_base = soft->mmr_base;
-       union cm_control cm_control;
-       union cm_req_timeout cm_req_timeout;
-       uint64_t err_stat;
-
-       cm_req_timeout.cm_req_timeout_reg =
-           MBCS_MMR_GET(mmr_base, MBCS_CM_REQ_TOUT);
-
-       cm_req_timeout.time_out = MBCS_CM_CONTROL_REQ_TOUT_MASK;
-       MBCS_MMR_SET(mmr_base, MBCS_CM_REQ_TOUT,
-                    cm_req_timeout.cm_req_timeout_reg);
-
-       mbcs_gscr_pioaddr_set(soft);
-       mbcs_debug_pioaddr_set(soft);
-
-       /* clear errors */
-       err_stat = MBCS_MMR_GET(mmr_base, MBCS_CM_ERR_STAT);
-       MBCS_MMR_SET(mmr_base, MBCS_CM_CLR_ERR_STAT, err_stat);
-       MBCS_MMR_ZERO(mmr_base, MBCS_CM_ERROR_DETAIL1);
-
-       /* enable interrupts */
-       /* turn off 2^23 (INT_EN_PIO_REQ_ADDR_INV) */
-       MBCS_MMR_SET(mmr_base, MBCS_CM_ERR_INT_EN, 0x3ffffff7e00ffUL);
-
-       /* arm status regs and clear engines */
-       cm_control.cm_control_reg = MBCS_MMR_GET(mmr_base, MBCS_CM_CONTROL);
-       cm_control.rearm_stat_regs = 1;
-       cm_control.alg_clr = 1;
-       cm_control.wr_dma_clr = 1;
-       cm_control.rd_dma_clr = 1;
-
-       MBCS_MMR_SET(mmr_base, MBCS_CM_CONTROL, cm_control.cm_control_reg);
-
-       return 0;
-}
-
-static ssize_t show_algo(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct cx_dev *cx_dev = to_cx_dev(dev);
-       struct mbcs_soft *soft = cx_dev->soft;
-       uint64_t debug0;
-
-       /*
-        * By convention, the first debug register contains the
-        * algorithm number and revision.
-        */
-       debug0 = *(uint64_t *) soft->debug_addr;
-
-       return sprintf(buf, "0x%x 0x%x\n",
-                      upper_32_bits(debug0), lower_32_bits(debug0));
-}
-
-static ssize_t store_algo(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-       int n;
-       struct cx_dev *cx_dev = to_cx_dev(dev);
-       struct mbcs_soft *soft = cx_dev->soft;
-
-       if (count <= 0)
-               return 0;
-
-       n = simple_strtoul(buf, NULL, 0);
-
-       if (n == 1) {
-               mbcs_algo_start(soft);
-               if (wait_event_interruptible(soft->algo_queue,
-                                       atomic_read(&soft->algo_done)))
-                       return -ERESTARTSYS;
-       }
-
-       return count;
-}
-
-DEVICE_ATTR(algo, 0644, show_algo, store_algo);
-
-/**
- * mbcs_probe - Initialize for device
- * @dev: device pointer
- * @device_id: id table pointer
- *
- */
-static int mbcs_probe(struct cx_dev *dev, const struct cx_device_id *id)
-{
-       struct mbcs_soft *soft;
-
-       dev->soft = NULL;
-
-       soft = kzalloc(sizeof(struct mbcs_soft), GFP_KERNEL);
-       if (soft == NULL)
-               return -ENOMEM;
-
-       soft->nasid = dev->cx_id.nasid;
-       list_add(&soft->list, &soft_list);
-       soft->mmr_base = (void *)tiocx_swin_base(dev->cx_id.nasid);
-       dev->soft = soft;
-       soft->cxdev = dev;
-
-       init_waitqueue_head(&soft->dmawrite_queue);
-       init_waitqueue_head(&soft->dmaread_queue);
-       init_waitqueue_head(&soft->algo_queue);
-
-       mutex_init(&soft->dmawritelock);
-       mutex_init(&soft->dmareadlock);
-       mutex_init(&soft->algolock);
-
-       mbcs_getdma_init(&soft->getdma);
-       mbcs_putdma_init(&soft->putdma);
-       mbcs_algo_init(&soft->algo);
-
-       mbcs_hw_init(soft);
-
-       /* Allocate interrupts */
-       mbcs_intr_alloc(dev);
-
-       device_create_file(&dev->dev, &dev_attr_algo);
-
-       return 0;
-}
-
-static int mbcs_remove(struct cx_dev *dev)
-{
-       if (dev->soft) {
-               mbcs_intr_dealloc(dev);
-               kfree(dev->soft);
-       }
-
-       device_remove_file(&dev->dev, &dev_attr_algo);
-
-       return 0;
-}
-
-static const struct cx_device_id mbcs_id_table[] = {
-       {
-        .part_num = MBCS_PART_NUM,
-        .mfg_num = MBCS_MFG_NUM,
-        },
-       {
-        .part_num = MBCS_PART_NUM_ALG0,
-        .mfg_num = MBCS_MFG_NUM,
-        },
-       {0, 0}
-};
-
-MODULE_DEVICE_TABLE(cx, mbcs_id_table);
-
-static struct cx_drv mbcs_driver = {
-       .name = DEVICE_NAME,
-       .id_table = mbcs_id_table,
-       .probe = mbcs_probe,
-       .remove = mbcs_remove,
-};
-
-static void __exit mbcs_exit(void)
-{
-       unregister_chrdev(mbcs_major, DEVICE_NAME);
-       cx_driver_unregister(&mbcs_driver);
-}
-
-static int __init mbcs_init(void)
-{
-       int rv;
-
-       if (!ia64_platform_is("sn2"))
-               return -ENODEV;
-
-       // Put driver into chrdevs[].  Get major number.
-       rv = register_chrdev(mbcs_major, DEVICE_NAME, &mbcs_ops);
-       if (rv < 0) {
-               DBG(KERN_ALERT "mbcs_init: can't get major number. %d\n", rv);
-               return rv;
-       }
-       mbcs_major = rv;
-
-       return cx_driver_register(&mbcs_driver);
-}
-
-module_init(mbcs_init);
-module_exit(mbcs_exit);
-
-MODULE_AUTHOR("Bruce Losure <blosure@sgi.com>");
-MODULE_DESCRIPTION("Driver for MOATB Core Services");
-MODULE_LICENSE("GPL");
diff --git a/drivers/char/mbcs.h b/drivers/char/mbcs.h
deleted file mode 100644 (file)
index 1a36884..0000000
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2005 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#ifndef __MBCS_H__
-#define __MBCS_H__
-
-/*
- * General macros
- */
-#define MB     (1024*1024)
-#define MB2    (2*MB)
-#define MB4    (4*MB)
-#define MB6    (6*MB)
-
-/*
- * Offsets and masks
- */
-#define MBCS_CM_ID             0x0000  /* Identification */
-#define MBCS_CM_STATUS         0x0008  /* Status */
-#define MBCS_CM_ERROR_DETAIL1  0x0010  /* Error Detail1 */
-#define MBCS_CM_ERROR_DETAIL2  0x0018  /* Error Detail2 */
-#define MBCS_CM_CONTROL                0x0020  /* Control */
-#define MBCS_CM_REQ_TOUT       0x0028  /* Request Time-out */
-#define MBCS_CM_ERR_INT_DEST   0x0038  /* Error Interrupt Destination */
-#define MBCS_CM_TARG_FL                0x0050  /* Target Flush */
-#define MBCS_CM_ERR_STAT       0x0060  /* Error Status */
-#define MBCS_CM_CLR_ERR_STAT   0x0068  /* Clear Error Status */
-#define MBCS_CM_ERR_INT_EN     0x0070  /* Error Interrupt Enable */
-#define MBCS_RD_DMA_SYS_ADDR   0x0100  /* Read DMA System Address */
-#define MBCS_RD_DMA_LOC_ADDR   0x0108  /* Read DMA Local Address */
-#define MBCS_RD_DMA_CTRL       0x0110  /* Read DMA Control */
-#define MBCS_RD_DMA_AMO_DEST   0x0118  /* Read DMA AMO Destination */
-#define MBCS_RD_DMA_INT_DEST   0x0120  /* Read DMA Interrupt Destination */
-#define MBCS_RD_DMA_AUX_STAT   0x0130  /* Read DMA Auxiliary Status */
-#define MBCS_WR_DMA_SYS_ADDR   0x0200  /* Write DMA System Address */
-#define MBCS_WR_DMA_LOC_ADDR   0x0208  /* Write DMA Local Address */
-#define MBCS_WR_DMA_CTRL       0x0210  /* Write DMA Control */
-#define MBCS_WR_DMA_AMO_DEST   0x0218  /* Write DMA AMO Destination */
-#define MBCS_WR_DMA_INT_DEST   0x0220  /* Write DMA Interrupt Destination */
-#define MBCS_WR_DMA_AUX_STAT   0x0230  /* Write DMA Auxiliary Status */
-#define MBCS_ALG_AMO_DEST      0x0300  /* Algorithm AMO Destination */
-#define MBCS_ALG_INT_DEST      0x0308  /* Algorithm Interrupt Destination */
-#define MBCS_ALG_OFFSETS       0x0310
-#define MBCS_ALG_STEP          0x0318  /* Algorithm Step */
-
-#define MBCS_GSCR_START                0x0000000
-#define MBCS_DEBUG_START       0x0100000
-#define MBCS_RAM0_START                0x0200000
-#define MBCS_RAM1_START                0x0400000
-#define MBCS_RAM2_START                0x0600000
-
-#define MBCS_CM_CONTROL_REQ_TOUT_MASK 0x0000000000ffffffUL
-//#define PIO_BASE_ADDR_BASE_OFFSET_MASK 0x00fffffffff00000UL
-
-#define MBCS_SRAM_SIZE         (1024*1024)
-#define MBCS_CACHELINE_SIZE    128
-
-/*
- * MMR get's and put's
- */
-#define MBCS_MMR_ADDR(mmr_base, offset)((uint64_t *)(mmr_base + offset))
-#define MBCS_MMR_SET(mmr_base, offset, value) {                        \
-       uint64_t *mbcs_mmr_set_u64p, readback;                          \
-       mbcs_mmr_set_u64p = (uint64_t *)(mmr_base + offset);    \
-       *mbcs_mmr_set_u64p = value;                                     \
-       readback = *mbcs_mmr_set_u64p; \
-}
-#define MBCS_MMR_GET(mmr_base, offset) *(uint64_t *)(mmr_base + offset)
-#define MBCS_MMR_ZERO(mmr_base, offset) MBCS_MMR_SET(mmr_base, offset, 0)
-
-/*
- * MBCS mmr structures
- */
-union cm_id {
-       uint64_t cm_id_reg;
-       struct {
-               uint64_t always_one:1,  // 0
-                mfg_id:11,     // 11:1
-                part_num:16,   // 27:12
-                bitstream_rev:8,       // 35:28
-               :28;            // 63:36
-       };
-};
-
-union cm_status {
-       uint64_t cm_status_reg;
-       struct {
-               uint64_t pending_reads:8,       // 7:0
-                pending_writes:8,      // 15:8
-                ice_rsp_credits:8,     // 23:16
-                ice_req_credits:8,     // 31:24
-                cm_req_credits:8,      // 39:32
-               :1,             // 40
-                rd_dma_in_progress:1,  // 41
-                rd_dma_done:1, // 42
-               :1,             // 43
-                wr_dma_in_progress:1,  // 44
-                wr_dma_done:1, // 45
-                alg_waiting:1, // 46
-                alg_pipe_running:1,    // 47
-                alg_done:1,    // 48
-               :3,             // 51:49
-                pending_int_reqs:8,    // 59:52
-               :3,             // 62:60
-                alg_half_speed_sel:1;  // 63
-       };
-};
-
-union cm_error_detail1 {
-       uint64_t cm_error_detail1_reg;
-       struct {
-               uint64_t packet_type:4, // 3:0
-                source_id:2,   // 5:4
-                data_size:2,   // 7:6
-                tnum:8,        // 15:8
-                byte_enable:8, // 23:16
-                gfx_cred:8,    // 31:24
-                read_type:2,   // 33:32
-                pio_or_memory:1,       // 34
-                head_cw_error:1,       // 35
-               :12,            // 47:36
-                head_error_bit:1,      // 48
-                data_error_bit:1,      // 49
-               :13,            // 62:50
-                valid:1;       // 63
-       };
-};
-
-union cm_error_detail2 {
-       uint64_t cm_error_detail2_reg;
-       struct {
-               uint64_t address:56,    // 55:0
-               :8;             // 63:56
-       };
-};
-
-union cm_control {
-       uint64_t cm_control_reg;
-       struct {
-               uint64_t cm_id:2,       // 1:0
-               :2,             // 3:2
-                max_trans:5,   // 8:4
-               :3,             // 11:9
-                address_mode:1,        // 12
-               :7,             // 19:13
-                credit_limit:8,        // 27:20
-               :5,             // 32:28
-                rearm_stat_regs:1,     // 33
-                prescalar_byp:1,       // 34
-                force_gap_war:1,       // 35
-                rd_dma_go:1,   // 36
-                wr_dma_go:1,   // 37
-                alg_go:1,      // 38
-                rd_dma_clr:1,  // 39
-                wr_dma_clr:1,  // 40
-                alg_clr:1,     // 41
-               :2,             // 43:42
-                alg_wait_step:1,       // 44
-                alg_done_amo_en:1,     // 45
-                alg_done_int_en:1,     // 46
-               :1,             // 47
-                alg_sram0_locked:1,    // 48
-                alg_sram1_locked:1,    // 49
-                alg_sram2_locked:1,    // 50
-                alg_done_clr:1,        // 51
-               :12;            // 63:52
-       };
-};
-
-union cm_req_timeout {
-       uint64_t cm_req_timeout_reg;
-       struct {
-               uint64_t time_out:24,   // 23:0
-               :40;            // 63:24
-       };
-};
-
-union intr_dest {
-       uint64_t intr_dest_reg;
-       struct {
-               uint64_t address:56,    // 55:0
-                int_vector:8;  // 63:56
-       };
-};
-
-union cm_error_status {
-       uint64_t cm_error_status_reg;
-       struct {
-               uint64_t ecc_sbe:1,     // 0
-                ecc_mbe:1,     // 1
-                unsupported_req:1,     // 2
-                unexpected_rsp:1,      // 3
-                bad_length:1,  // 4
-                bad_datavalid:1,       // 5
-                buffer_overflow:1,     // 6
-                request_timeout:1,     // 7
-               :8,             // 15:8
-                head_inv_data_size:1,  // 16
-                rsp_pactype_inv:1,     // 17
-                head_sb_err:1, // 18
-                missing_head:1,        // 19
-                head_inv_rd_type:1,    // 20
-                head_cmd_err_bit:1,    // 21
-                req_addr_align_inv:1,  // 22
-                pio_req_addr_inv:1,    // 23
-                req_range_dsize_inv:1, // 24
-                early_term:1,  // 25
-                early_tail:1,  // 26
-                missing_tail:1,        // 27
-                data_flit_sb_err:1,    // 28
-                cm2hcm_req_cred_of:1,  // 29
-                cm2hcm_rsp_cred_of:1,  // 30
-                rx_bad_didn:1, // 31
-                rd_dma_err_rsp:1,      // 32
-                rd_dma_tnum_tout:1,    // 33
-                rd_dma_multi_tnum_tou:1,       // 34
-                wr_dma_err_rsp:1,      // 35
-                wr_dma_tnum_tout:1,    // 36
-                wr_dma_multi_tnum_tou:1,       // 37
-                alg_data_overflow:1,   // 38
-                alg_data_underflow:1,  // 39
-                ram0_access_conflict:1,        // 40
-                ram1_access_conflict:1,        // 41
-                ram2_access_conflict:1,        // 42
-                ram0_perr:1,   // 43
-                ram1_perr:1,   // 44
-                ram2_perr:1,   // 45
-                int_gen_rsp_err:1,     // 46
-                int_gen_tnum_tout:1,   // 47
-                rd_dma_prog_err:1,     // 48
-                wr_dma_prog_err:1,     // 49
-               :14;            // 63:50
-       };
-};
-
-union cm_clr_error_status {
-       uint64_t cm_clr_error_status_reg;
-       struct {
-               uint64_t clr_ecc_sbe:1, // 0
-                clr_ecc_mbe:1, // 1
-                clr_unsupported_req:1, // 2
-                clr_unexpected_rsp:1,  // 3
-                clr_bad_length:1,      // 4
-                clr_bad_datavalid:1,   // 5
-                clr_buffer_overflow:1, // 6
-                clr_request_timeout:1, // 7
-               :8,             // 15:8
-                clr_head_inv_data_siz:1,       // 16
-                clr_rsp_pactype_inv:1, // 17
-                clr_head_sb_err:1,     // 18
-                clr_missing_head:1,    // 19
-                clr_head_inv_rd_type:1,        // 20
-                clr_head_cmd_err_bit:1,        // 21
-                clr_req_addr_align_in:1,       // 22
-                clr_pio_req_addr_inv:1,        // 23
-                clr_req_range_dsize_i:1,       // 24
-                clr_early_term:1,      // 25
-                clr_early_tail:1,      // 26
-                clr_missing_tail:1,    // 27
-                clr_data_flit_sb_err:1,        // 28
-                clr_cm2hcm_req_cred_o:1,       // 29
-                clr_cm2hcm_rsp_cred_o:1,       // 30
-                clr_rx_bad_didn:1,     // 31
-                clr_rd_dma_err_rsp:1,  // 32
-                clr_rd_dma_tnum_tout:1,        // 33
-                clr_rd_dma_multi_tnum:1,       // 34
-                clr_wr_dma_err_rsp:1,  // 35
-                clr_wr_dma_tnum_tout:1,        // 36
-                clr_wr_dma_multi_tnum:1,       // 37
-                clr_alg_data_overflow:1,       // 38
-                clr_alg_data_underflo:1,       // 39
-                clr_ram0_access_confl:1,       // 40
-                clr_ram1_access_confl:1,       // 41
-                clr_ram2_access_confl:1,       // 42
-                clr_ram0_perr:1,       // 43
-                clr_ram1_perr:1,       // 44
-                clr_ram2_perr:1,       // 45
-                clr_int_gen_rsp_err:1, // 46
-                clr_int_gen_tnum_tout:1,       // 47
-                clr_rd_dma_prog_err:1, // 48
-                clr_wr_dma_prog_err:1, // 49
-               :14;            // 63:50
-       };
-};
-
-union cm_error_intr_enable {
-       uint64_t cm_error_intr_enable_reg;
-       struct {
-               uint64_t int_en_ecc_sbe:1,      // 0
-                int_en_ecc_mbe:1,      // 1
-                int_en_unsupported_re:1,       // 2
-                int_en_unexpected_rsp:1,       // 3
-                int_en_bad_length:1,   // 4
-                int_en_bad_datavalid:1,        // 5
-                int_en_buffer_overflo:1,       // 6
-                int_en_request_timeou:1,       // 7
-               :8,             // 15:8
-                int_en_head_inv_data_:1,       // 16
-                int_en_rsp_pactype_in:1,       // 17
-                int_en_head_sb_err:1,  // 18
-                int_en_missing_head:1, // 19
-                int_en_head_inv_rd_ty:1,       // 20
-                int_en_head_cmd_err_b:1,       // 21
-                int_en_req_addr_align:1,       // 22
-                int_en_pio_req_addr_i:1,       // 23
-                int_en_req_range_dsiz:1,       // 24
-                int_en_early_term:1,   // 25
-                int_en_early_tail:1,   // 26
-                int_en_missing_tail:1, // 27
-                int_en_data_flit_sb_e:1,       // 28
-                int_en_cm2hcm_req_cre:1,       // 29
-                int_en_cm2hcm_rsp_cre:1,       // 30
-                int_en_rx_bad_didn:1,  // 31
-                int_en_rd_dma_err_rsp:1,       // 32
-                int_en_rd_dma_tnum_to:1,       // 33
-                int_en_rd_dma_multi_t:1,       // 34
-                int_en_wr_dma_err_rsp:1,       // 35
-                int_en_wr_dma_tnum_to:1,       // 36
-                int_en_wr_dma_multi_t:1,       // 37
-                int_en_alg_data_overf:1,       // 38
-                int_en_alg_data_under:1,       // 39
-                int_en_ram0_access_co:1,       // 40
-                int_en_ram1_access_co:1,       // 41
-                int_en_ram2_access_co:1,       // 42
-                int_en_ram0_perr:1,    // 43
-                int_en_ram1_perr:1,    // 44
-                int_en_ram2_perr:1,    // 45
-                int_en_int_gen_rsp_er:1,       // 46
-                int_en_int_gen_tnum_t:1,       // 47
-                int_en_rd_dma_prog_er:1,       // 48
-                int_en_wr_dma_prog_er:1,       // 49
-               :14;            // 63:50
-       };
-};
-
-struct cm_mmr {
-       union cm_id id;
-       union cm_status status;
-       union cm_error_detail1 err_detail1;
-       union cm_error_detail2 err_detail2;
-       union cm_control control;
-       union cm_req_timeout req_timeout;
-       uint64_t reserved1[1];
-       union intr_dest int_dest;
-       uint64_t reserved2[2];
-       uint64_t targ_flush;
-       uint64_t reserved3[1];
-       union cm_error_status err_status;
-       union cm_clr_error_status clr_err_status;
-       union cm_error_intr_enable int_enable;
-};
-
-union dma_hostaddr {
-       uint64_t dma_hostaddr_reg;
-       struct {
-               uint64_t dma_sys_addr:56,       // 55:0
-               :8;             // 63:56
-       };
-};
-
-union dma_localaddr {
-       uint64_t dma_localaddr_reg;
-       struct {
-               uint64_t dma_ram_addr:21,       // 20:0
-                dma_ram_sel:2, // 22:21
-               :41;            // 63:23
-       };
-};
-
-union dma_control {
-       uint64_t dma_control_reg;
-       struct {
-               uint64_t dma_op_length:16,      // 15:0
-               :18,            // 33:16
-                done_amo_en:1, // 34
-                done_int_en:1, // 35
-               :1,             // 36
-                pio_mem_n:1,   // 37
-               :26;            // 63:38
-       };
-};
-
-union dma_amo_dest {
-       uint64_t dma_amo_dest_reg;
-       struct {
-               uint64_t dma_amo_sys_addr:56,   // 55:0
-                dma_amo_mod_type:3,    // 58:56
-               :5;             // 63:59
-       };
-};
-
-union rdma_aux_status {
-       uint64_t rdma_aux_status_reg;
-       struct {
-               uint64_t op_num_pacs_left:17,   // 16:0
-               :5,             // 21:17
-                lrsp_buff_empty:1,     // 22
-               :17,            // 39:23
-                pending_reqs_left:6,   // 45:40
-               :18;            // 63:46
-       };
-};
-
-struct rdma_mmr {
-       union dma_hostaddr host_addr;
-       union dma_localaddr local_addr;
-       union dma_control control;
-       union dma_amo_dest amo_dest;
-       union intr_dest intr_dest;
-       union rdma_aux_status aux_status;
-};
-
-union wdma_aux_status {
-       uint64_t wdma_aux_status_reg;
-       struct {
-               uint64_t op_num_pacs_left:17,   // 16:0
-               :4,             // 20:17
-                lreq_buff_empty:1,     // 21
-               :18,            // 39:22
-                pending_reqs_left:6,   // 45:40
-               :18;            // 63:46
-       };
-};
-
-struct wdma_mmr {
-       union dma_hostaddr host_addr;
-       union dma_localaddr local_addr;
-       union dma_control control;
-       union dma_amo_dest amo_dest;
-       union intr_dest intr_dest;
-       union wdma_aux_status aux_status;
-};
-
-union algo_step {
-       uint64_t algo_step_reg;
-       struct {
-               uint64_t alg_step_cnt:16,       // 15:0
-               :48;            // 63:16
-       };
-};
-
-struct algo_mmr {
-       union dma_amo_dest amo_dest;
-       union intr_dest intr_dest;
-       union {
-               uint64_t algo_offset_reg;
-               struct {
-                       uint64_t sram0_offset:7,        // 6:0
-                       reserved0:1,    // 7
-                       sram1_offset:7, // 14:8
-                       reserved1:1,    // 15
-                       sram2_offset:7, // 22:16
-                       reserved2:14;   // 63:23
-               };
-       } sram_offset;
-       union algo_step step;
-};
-
-struct mbcs_mmr {
-       struct cm_mmr cm;
-       uint64_t reserved1[17];
-       struct rdma_mmr rdDma;
-       uint64_t reserved2[25];
-       struct wdma_mmr wrDma;
-       uint64_t reserved3[25];
-       struct algo_mmr algo;
-       uint64_t reserved4[156];
-};
-
-/*
- * defines
- */
-#define DEVICE_NAME "mbcs"
-#define MBCS_PART_NUM 0xfff0
-#define MBCS_PART_NUM_ALG0 0xf001
-#define MBCS_MFG_NUM  0x1
-
-struct algoblock {
-       uint64_t amoHostDest;
-       uint64_t amoModType;
-       uint64_t intrHostDest;
-       uint64_t intrVector;
-       uint64_t algoStepCount;
-};
-
-struct getdma {
-       uint64_t hostAddr;
-       uint64_t localAddr;
-       uint64_t bytes;
-       uint64_t DoneAmoEnable;
-       uint64_t DoneIntEnable;
-       uint64_t peerIO;
-       uint64_t amoHostDest;
-       uint64_t amoModType;
-       uint64_t intrHostDest;
-       uint64_t intrVector;
-};
-
-struct putdma {
-       uint64_t hostAddr;
-       uint64_t localAddr;
-       uint64_t bytes;
-       uint64_t DoneAmoEnable;
-       uint64_t DoneIntEnable;
-       uint64_t peerIO;
-       uint64_t amoHostDest;
-       uint64_t amoModType;
-       uint64_t intrHostDest;
-       uint64_t intrVector;
-};
-
-struct mbcs_soft {
-       struct list_head list;
-       struct cx_dev *cxdev;
-       int major;
-       int nasid;
-       void *mmr_base;
-       wait_queue_head_t dmawrite_queue;
-       wait_queue_head_t dmaread_queue;
-       wait_queue_head_t algo_queue;
-       struct sn_irq_info *get_sn_irq;
-       struct sn_irq_info *put_sn_irq;
-       struct sn_irq_info *algo_sn_irq;
-       struct getdma getdma;
-       struct putdma putdma;
-       struct algoblock algo;
-       uint64_t gscr_addr;     // pio addr
-       uint64_t ram0_addr;     // pio addr
-       uint64_t ram1_addr;     // pio addr
-       uint64_t ram2_addr;     // pio addr
-       uint64_t debug_addr;    // pio addr
-       atomic_t dmawrite_done;
-       atomic_t dmaread_done;
-       atomic_t algo_done;
-       struct mutex dmawritelock;
-       struct mutex dmareadlock;
-       struct mutex algolock;
-};
-
-static int mbcs_open(struct inode *ip, struct file *fp);
-static ssize_t mbcs_sram_read(struct file *fp, char __user *buf, size_t len,
-                             loff_t * off);
-static ssize_t mbcs_sram_write(struct file *fp, const char __user *buf, size_t len,
-                              loff_t * off);
-static loff_t mbcs_sram_llseek(struct file *filp, loff_t off, int whence);
-static int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma);
-
-#endif                         // __MBCS_H__
index e75c9df..a9d9f07 100644 (file)
@@ -9,11 +9,8 @@
  *
  * This driver exports the SN special memory (mspec) facility to user
  * processes.
- * There are three types of memory made available thru this driver:
- * fetchops, uncached and cached.
- *
- * Fetchops are atomic memory operations that are implemented in the
- * memory controller on SGI SN hardware.
+ * There are two types of memory made available thru this driver:
+ * uncached and cached.
  *
  * Uncached are used for memory write combining feature of the ia64
  * cpu.
 #include <linux/atomic.h>
 #include <asm/tlbflush.h>
 #include <asm/uncached.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/mspec.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/io.h>
-#include <asm/sn/bte.h>
-#include <asm/sn/shubio.h>
 
 
-#define FETCHOP_ID     "SGI Fetchop,"
 #define CACHED_ID      "Cached,"
 #define UNCACHED_ID    "Uncached"
 #define REVISION       "4.0"
  * Page types allocated by the device.
  */
 enum mspec_page_type {
-       MSPEC_FETCHOP = 1,
-       MSPEC_CACHED,
+       MSPEC_CACHED = 2,
        MSPEC_UNCACHED
 };
 
-#ifdef CONFIG_SGI_SN
-static int is_sn2;
-#else
-#define is_sn2         0
-#endif
-
 /*
  * One of these structures is allocated when an mspec region is mmaped. The
  * structure is pointed to by the vma->vm_private_data field in the vma struct.
@@ -96,39 +78,6 @@ struct vma_data {
        unsigned long maddr[0]; /* Array of MSPEC addresses. */
 };
 
-/* used on shub2 to clear FOP cache in the HUB */
-static unsigned long scratch_page[MAX_NUMNODES];
-#define SH2_AMO_CACHE_ENTRIES  4
-
-static inline int
-mspec_zero_block(unsigned long addr, int len)
-{
-       int status;
-
-       if (is_sn2) {
-               if (is_shub2()) {
-                       int nid;
-                       void *p;
-                       int i;
-
-                       nid = nasid_to_cnodeid(get_node_number(__pa(addr)));
-                       p = (void *)TO_AMO(scratch_page[nid]);
-
-                       for (i=0; i < SH2_AMO_CACHE_ENTRIES; i++) {
-                               FETCHOP_LOAD_OP(p, FETCHOP_LOAD);
-                               p += FETCHOP_VAR_SIZE;
-                       }
-               }
-
-               status = bte_copy(0, addr & ~__IA64_UNCACHED_OFFSET, len,
-                                 BTE_WACQUIRE | BTE_ZERO_FILL, NULL);
-       } else {
-               memset((char *) addr, 0, len);
-               status = 0;
-       }
-       return status;
-}
-
 /*
  * mspec_open
  *
@@ -173,11 +122,8 @@ mspec_close(struct vm_area_struct *vma)
                 */
                my_page = vdata->maddr[index];
                vdata->maddr[index] = 0;
-               if (!mspec_zero_block(my_page, PAGE_SIZE))
-                       uncached_free_page(my_page, 1);
-               else
-                       printk(KERN_WARNING "mspec_close(): "
-                              "failed to zero page %ld\n", my_page);
+               memset((char *)my_page, 0, PAGE_SIZE);
+               uncached_free_page(my_page, 1);
        }
 
        kvfree(vdata);
@@ -213,11 +159,7 @@ mspec_fault(struct vm_fault *vmf)
                spin_unlock(&vdata->lock);
        }
 
-       if (vdata->type == MSPEC_FETCHOP)
-               paddr = TO_AMO(maddr);
-       else
-               paddr = maddr & ~__IA64_UNCACHED_OFFSET;
-
+       paddr = maddr & ~__IA64_UNCACHED_OFFSET;
        pfn = paddr >> PAGE_SHIFT;
 
        return vmf_insert_pfn(vmf->vma, vmf->address, pfn);
@@ -269,7 +211,7 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma,
        vma->vm_private_data = vdata;
 
        vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP;
-       if (vdata->type == MSPEC_FETCHOP || vdata->type == MSPEC_UNCACHED)
+       if (vdata->type == MSPEC_UNCACHED)
                vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
        vma->vm_ops = &mspec_vm_ops;
 
@@ -277,12 +219,6 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma,
 }
 
 static int
-fetchop_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       return mspec_mmap(file, vma, MSPEC_FETCHOP);
-}
-
-static int
 cached_mmap(struct file *file, struct vm_area_struct *vma)
 {
        return mspec_mmap(file, vma, MSPEC_CACHED);
@@ -294,18 +230,6 @@ uncached_mmap(struct file *file, struct vm_area_struct *vma)
        return mspec_mmap(file, vma, MSPEC_UNCACHED);
 }
 
-static const struct file_operations fetchop_fops = {
-       .owner = THIS_MODULE,
-       .mmap = fetchop_mmap,
-       .llseek = noop_llseek,
-};
-
-static struct miscdevice fetchop_miscdev = {
-       .minor = MISC_DYNAMIC_MINOR,
-       .name = "sgi_fetchop",
-       .fops = &fetchop_fops
-};
-
 static const struct file_operations cached_fops = {
        .owner = THIS_MODULE,
        .mmap = cached_mmap,
@@ -339,89 +263,32 @@ static int __init
 mspec_init(void)
 {
        int ret;
-       int nid;
-
-       /*
-        * The fetchop device only works on SN2 hardware, uncached and cached
-        * memory drivers should both be valid on all ia64 hardware
-        */
-#ifdef CONFIG_SGI_SN
-       if (ia64_platform_is("sn2")) {
-               is_sn2 = 1;
-               if (is_shub2()) {
-                       ret = -ENOMEM;
-                       for_each_node_state(nid, N_ONLINE) {
-                               int actual_nid;
-                               int nasid;
-                               unsigned long phys;
-
-                               scratch_page[nid] = uncached_alloc_page(nid, 1);
-                               if (scratch_page[nid] == 0)
-                                       goto free_scratch_pages;
-                               phys = __pa(scratch_page[nid]);
-                               nasid = get_node_number(phys);
-                               actual_nid = nasid_to_cnodeid(nasid);
-                               if (actual_nid != nid)
-                                       goto free_scratch_pages;
-                       }
-               }
 
-               ret = misc_register(&fetchop_miscdev);
-               if (ret) {
-                       printk(KERN_ERR
-                              "%s: failed to register device %i\n",
-                              FETCHOP_ID, ret);
-                       goto free_scratch_pages;
-               }
-       }
-#endif
        ret = misc_register(&cached_miscdev);
        if (ret) {
                printk(KERN_ERR "%s: failed to register device %i\n",
                       CACHED_ID, ret);
-               if (is_sn2)
-                       misc_deregister(&fetchop_miscdev);
-               goto free_scratch_pages;
+               return ret;
        }
        ret = misc_register(&uncached_miscdev);
        if (ret) {
                printk(KERN_ERR "%s: failed to register device %i\n",
                       UNCACHED_ID, ret);
                misc_deregister(&cached_miscdev);
-               if (is_sn2)
-                       misc_deregister(&fetchop_miscdev);
-               goto free_scratch_pages;
+               return ret;
        }
 
-       printk(KERN_INFO "%s %s initialized devices: %s %s %s\n",
-              MSPEC_BASENAME, REVISION, is_sn2 ? FETCHOP_ID : "",
-              CACHED_ID, UNCACHED_ID);
+       printk(KERN_INFO "%s %s initialized devices: %s %s\n",
+              MSPEC_BASENAME, REVISION, CACHED_ID, UNCACHED_ID);
 
        return 0;
-
- free_scratch_pages:
-       for_each_node(nid) {
-               if (scratch_page[nid] != 0)
-                       uncached_free_page(scratch_page[nid], 1);
-       }
-       return ret;
 }
 
 static void __exit
 mspec_exit(void)
 {
-       int nid;
-
        misc_deregister(&uncached_miscdev);
        misc_deregister(&cached_miscdev);
-       if (is_sn2) {
-               misc_deregister(&fetchop_miscdev);
-
-               for_each_node(nid) {
-                       if (scratch_page[nid] != 0)
-                               uncached_free_page(scratch_page[nid], 1);
-               }
-       }
 }
 
 module_init(mspec_init);
index 5d5ea4c..566922d 100644 (file)
@@ -2445,3 +2445,17 @@ void add_hwgenerator_randomness(const char *buffer, size_t count,
        credit_entropy_bits(poolp, entropy);
 }
 EXPORT_SYMBOL_GPL(add_hwgenerator_randomness);
+
+/* Handle random seed passed by bootloader.
+ * If the seed is trustworthy, it would be regarded as hardware RNGs. Otherwise
+ * it would be regarded as device data.
+ * The decision is controlled by CONFIG_RANDOM_TRUST_BOOTLOADER.
+ */
+void add_bootloader_randomness(const void *buf, unsigned int size)
+{
+       if (IS_ENABLED(CONFIG_RANDOM_TRUST_BOOTLOADER))
+               add_hwgenerator_randomness(buf, size, size * 8);
+       else
+               add_device_randomness(buf, size);
+}
+EXPORT_SYMBOL_GPL(add_bootloader_randomness);
\ No newline at end of file
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
deleted file mode 100644 (file)
index 5918ea7..0000000
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- * SN Platform system controller communication support
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004, 2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * System controller communication driver
- *
- * This driver allows a user process to communicate with the system
- * controller (a.k.a. "IRouter") network in an SGI SN system.
- */
-
-#include <linux/interrupt.h>
-#include <linux/sched/signal.h>
-#include <linux/device.h>
-#include <linux/poll.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/module.h>
-#include <asm/sn/geo.h>
-#include <asm/sn/nodepda.h>
-#include "snsc.h"
-
-#define SYSCTL_BASENAME        "snsc"
-
-#define SCDRV_BUFSZ    2048
-#define SCDRV_TIMEOUT  1000
-
-static DEFINE_MUTEX(scdrv_mutex);
-static irqreturn_t
-scdrv_interrupt(int irq, void *subch_data)
-{
-       struct subch_data_s *sd = subch_data;
-       unsigned long flags;
-       int status;
-
-       spin_lock_irqsave(&sd->sd_rlock, flags);
-       spin_lock(&sd->sd_wlock);
-       status = ia64_sn_irtr_intr(sd->sd_nasid, sd->sd_subch);
-
-       if (status > 0) {
-               if (status & SAL_IROUTER_INTR_RECV) {
-                       wake_up(&sd->sd_rq);
-               }
-               if (status & SAL_IROUTER_INTR_XMIT) {
-                       ia64_sn_irtr_intr_disable
-                           (sd->sd_nasid, sd->sd_subch,
-                            SAL_IROUTER_INTR_XMIT);
-                       wake_up(&sd->sd_wq);
-               }
-       }
-       spin_unlock(&sd->sd_wlock);
-       spin_unlock_irqrestore(&sd->sd_rlock, flags);
-       return IRQ_HANDLED;
-}
-
-/*
- * scdrv_open
- *
- * Reserve a subchannel for system controller communication.
- */
-
-static int
-scdrv_open(struct inode *inode, struct file *file)
-{
-       struct sysctl_data_s *scd;
-       struct subch_data_s *sd;
-       int rv;
-
-       /* look up device info for this device file */
-       scd = container_of(inode->i_cdev, struct sysctl_data_s, scd_cdev);
-
-       /* allocate memory for subchannel data */
-       sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL);
-       if (sd == NULL) {
-               printk("%s: couldn't allocate subchannel data\n",
-                      __func__);
-               return -ENOMEM;
-       }
-
-       /* initialize subch_data_s fields */
-       sd->sd_nasid = scd->scd_nasid;
-       sd->sd_subch = ia64_sn_irtr_open(scd->scd_nasid);
-
-       if (sd->sd_subch < 0) {
-               kfree(sd);
-               printk("%s: couldn't allocate subchannel\n", __func__);
-               return -EBUSY;
-       }
-
-       spin_lock_init(&sd->sd_rlock);
-       spin_lock_init(&sd->sd_wlock);
-       init_waitqueue_head(&sd->sd_rq);
-       init_waitqueue_head(&sd->sd_wq);
-       sema_init(&sd->sd_rbs, 1);
-       sema_init(&sd->sd_wbs, 1);
-
-       file->private_data = sd;
-
-       /* hook this subchannel up to the system controller interrupt */
-       mutex_lock(&scdrv_mutex);
-       rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt,
-                        IRQF_SHARED, SYSCTL_BASENAME, sd);
-       if (rv) {
-               ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch);
-               kfree(sd);
-               printk("%s: irq request failed (%d)\n", __func__, rv);
-               mutex_unlock(&scdrv_mutex);
-               return -EBUSY;
-       }
-       mutex_unlock(&scdrv_mutex);
-       return 0;
-}
-
-/*
- * scdrv_release
- *
- * Release a previously-reserved subchannel.
- */
-
-static int
-scdrv_release(struct inode *inode, struct file *file)
-{
-       struct subch_data_s *sd = (struct subch_data_s *) file->private_data;
-       int rv;
-
-       /* free the interrupt */
-       free_irq(SGI_UART_VECTOR, sd);
-
-       /* ask SAL to close the subchannel */
-       rv = ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch);
-
-       kfree(sd);
-       return rv;
-}
-
-/*
- * scdrv_read
- *
- * Called to read bytes from the open IRouter pipe.
- *
- */
-
-static inline int
-read_status_check(struct subch_data_s *sd, int *len)
-{
-       return ia64_sn_irtr_recv(sd->sd_nasid, sd->sd_subch, sd->sd_rb, len);
-}
-
-static ssize_t
-scdrv_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos)
-{
-       int status;
-       int len;
-       unsigned long flags;
-       struct subch_data_s *sd = (struct subch_data_s *) file->private_data;
-
-       /* try to get control of the read buffer */
-       if (down_trylock(&sd->sd_rbs)) {
-               /* somebody else has it now;
-                * if we're non-blocking, then exit...
-                */
-               if (file->f_flags & O_NONBLOCK) {
-                       return -EAGAIN;
-               }
-               /* ...or if we want to block, then do so here */
-               if (down_interruptible(&sd->sd_rbs)) {
-                       /* something went wrong with wait */
-                       return -ERESTARTSYS;
-               }
-       }
-
-       /* anything to read? */
-       len = CHUNKSIZE;
-       spin_lock_irqsave(&sd->sd_rlock, flags);
-       status = read_status_check(sd, &len);
-
-       /* if not, and we're blocking I/O, loop */
-       while (status < 0) {
-               DECLARE_WAITQUEUE(wait, current);
-
-               if (file->f_flags & O_NONBLOCK) {
-                       spin_unlock_irqrestore(&sd->sd_rlock, flags);
-                       up(&sd->sd_rbs);
-                       return -EAGAIN;
-               }
-
-               len = CHUNKSIZE;
-               set_current_state(TASK_INTERRUPTIBLE);
-               add_wait_queue(&sd->sd_rq, &wait);
-               spin_unlock_irqrestore(&sd->sd_rlock, flags);
-
-               schedule_timeout(msecs_to_jiffies(SCDRV_TIMEOUT));
-
-               remove_wait_queue(&sd->sd_rq, &wait);
-               if (signal_pending(current)) {
-                       /* wait was interrupted */
-                       up(&sd->sd_rbs);
-                       return -ERESTARTSYS;
-               }
-
-               spin_lock_irqsave(&sd->sd_rlock, flags);
-               status = read_status_check(sd, &len);
-       }
-       spin_unlock_irqrestore(&sd->sd_rlock, flags);
-
-       if (len > 0) {
-               /* we read something in the last read_status_check(); copy
-                * it out to user space
-                */
-               if (count < len) {
-                       pr_debug("%s: only accepting %d of %d bytes\n",
-                                __func__, (int) count, len);
-               }
-               len = min((int) count, len);
-               if (copy_to_user(buf, sd->sd_rb, len))
-                       len = -EFAULT;
-       }
-
-       /* release the read buffer and wake anyone who might be
-        * waiting for it
-        */
-       up(&sd->sd_rbs);
-
-       /* return the number of characters read in */
-       return len;
-}
-
-/*
- * scdrv_write
- *
- * Writes a chunk of an IRouter packet (or other system controller data)
- * to the system controller.
- *
- */
-static inline int
-write_status_check(struct subch_data_s *sd, int count)
-{
-       return ia64_sn_irtr_send(sd->sd_nasid, sd->sd_subch, sd->sd_wb, count);
-}
-
-static ssize_t
-scdrv_write(struct file *file, const char __user *buf,
-           size_t count, loff_t *f_pos)
-{
-       unsigned long flags;
-       int status;
-       struct subch_data_s *sd = (struct subch_data_s *) file->private_data;
-
-       /* try to get control of the write buffer */
-       if (down_trylock(&sd->sd_wbs)) {
-               /* somebody else has it now;
-                * if we're non-blocking, then exit...
-                */
-               if (file->f_flags & O_NONBLOCK) {
-                       return -EAGAIN;
-               }
-               /* ...or if we want to block, then do so here */
-               if (down_interruptible(&sd->sd_wbs)) {
-                       /* something went wrong with wait */
-                       return -ERESTARTSYS;
-               }
-       }
-
-       count = min((int) count, CHUNKSIZE);
-       if (copy_from_user(sd->sd_wb, buf, count)) {
-               up(&sd->sd_wbs);
-               return -EFAULT;
-       }
-
-       /* try to send the buffer */
-       spin_lock_irqsave(&sd->sd_wlock, flags);
-       status = write_status_check(sd, count);
-
-       /* if we failed, and we want to block, then loop */
-       while (status <= 0) {
-               DECLARE_WAITQUEUE(wait, current);
-
-               if (file->f_flags & O_NONBLOCK) {
-                       spin_unlock_irqrestore(&sd->sd_wlock, flags);
-                       up(&sd->sd_wbs);
-                       return -EAGAIN;
-               }
-
-               set_current_state(TASK_INTERRUPTIBLE);
-               add_wait_queue(&sd->sd_wq, &wait);
-               spin_unlock_irqrestore(&sd->sd_wlock, flags);
-
-               schedule_timeout(msecs_to_jiffies(SCDRV_TIMEOUT));
-
-               remove_wait_queue(&sd->sd_wq, &wait);
-               if (signal_pending(current)) {
-                       /* wait was interrupted */
-                       up(&sd->sd_wbs);
-                       return -ERESTARTSYS;
-               }
-
-               spin_lock_irqsave(&sd->sd_wlock, flags);
-               status = write_status_check(sd, count);
-       }
-       spin_unlock_irqrestore(&sd->sd_wlock, flags);
-
-       /* release the write buffer and wake anyone who's waiting for it */
-       up(&sd->sd_wbs);
-
-       /* return the number of characters accepted (should be the complete
-        * "chunk" as requested)
-        */
-       if ((status >= 0) && (status < count)) {
-               pr_debug("Didn't accept the full chunk; %d of %d\n",
-                        status, (int) count);
-       }
-       return status;
-}
-
-static __poll_t
-scdrv_poll(struct file *file, struct poll_table_struct *wait)
-{
-       __poll_t mask = 0;
-       int status = 0;
-       struct subch_data_s *sd = (struct subch_data_s *) file->private_data;
-       unsigned long flags;
-
-       poll_wait(file, &sd->sd_rq, wait);
-       poll_wait(file, &sd->sd_wq, wait);
-
-       spin_lock_irqsave(&sd->sd_rlock, flags);
-       spin_lock(&sd->sd_wlock);
-       status = ia64_sn_irtr_intr(sd->sd_nasid, sd->sd_subch);
-       spin_unlock(&sd->sd_wlock);
-       spin_unlock_irqrestore(&sd->sd_rlock, flags);
-
-       if (status > 0) {
-               if (status & SAL_IROUTER_INTR_RECV) {
-                       mask |= EPOLLIN | EPOLLRDNORM;
-               }
-               if (status & SAL_IROUTER_INTR_XMIT) {
-                       mask |= EPOLLOUT | EPOLLWRNORM;
-               }
-       }
-
-       return mask;
-}
-
-static const struct file_operations scdrv_fops = {
-       .owner =        THIS_MODULE,
-       .read =         scdrv_read,
-       .write =        scdrv_write,
-       .poll =         scdrv_poll,
-       .open =         scdrv_open,
-       .release =      scdrv_release,
-       .llseek =       noop_llseek,
-};
-
-static struct class *snsc_class;
-
-/*
- * scdrv_init
- *
- * Called at boot time to initialize the system controller communication
- * facility.
- */
-int __init
-scdrv_init(void)
-{
-       geoid_t geoid;
-       cnodeid_t cnode;
-       char devname[32];
-       char *devnamep;
-       struct sysctl_data_s *scd;
-       void *salbuf;
-       dev_t first_dev, dev;
-       nasid_t event_nasid;
-
-       if (!ia64_platform_is("sn2"))
-               return -ENODEV;
-
-       event_nasid = ia64_sn_get_console_nasid();
-
-       snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME);
-       if (IS_ERR(snsc_class)) {
-               printk("%s: failed to allocate class\n", __func__);
-               return PTR_ERR(snsc_class);
-       }
-
-       if (alloc_chrdev_region(&first_dev, 0, num_cnodes,
-                               SYSCTL_BASENAME) < 0) {
-               printk("%s: failed to register SN system controller device\n",
-                      __func__);
-               return -ENODEV;
-       }
-
-       for (cnode = 0; cnode < num_cnodes; cnode++) {
-                       geoid = cnodeid_get_geoid(cnode);
-                       devnamep = devname;
-                       format_module_id(devnamep, geo_module(geoid),
-                                        MODULE_FORMAT_BRIEF);
-                       devnamep = devname + strlen(devname);
-                       sprintf(devnamep, "^%d#%d", geo_slot(geoid),
-                               geo_slab(geoid));
-
-                       /* allocate sysctl device data */
-                       scd = kzalloc(sizeof (struct sysctl_data_s),
-                                     GFP_KERNEL);
-                       if (!scd) {
-                               printk("%s: failed to allocate device info"
-                                      "for %s/%s\n", __func__,
-                                      SYSCTL_BASENAME, devname);
-                               continue;
-                       }
-
-                       /* initialize sysctl device data fields */
-                       scd->scd_nasid = cnodeid_to_nasid(cnode);
-                       if (!(salbuf = kmalloc(SCDRV_BUFSZ, GFP_KERNEL))) {
-                               printk("%s: failed to allocate driver buffer"
-                                      "(%s%s)\n", __func__,
-                                      SYSCTL_BASENAME, devname);
-                               kfree(scd);
-                               continue;
-                       }
-
-                       if (ia64_sn_irtr_init(scd->scd_nasid, salbuf,
-                                             SCDRV_BUFSZ) < 0) {
-                               printk
-                                   ("%s: failed to initialize SAL for"
-                                    " system controller communication"
-                                    " (%s/%s): outdated PROM?\n",
-                                    __func__, SYSCTL_BASENAME, devname);
-                               kfree(scd);
-                               kfree(salbuf);
-                               continue;
-                       }
-
-                       dev = first_dev + cnode;
-                       cdev_init(&scd->scd_cdev, &scdrv_fops);
-                       if (cdev_add(&scd->scd_cdev, dev, 1)) {
-                               printk("%s: failed to register system"
-                                      " controller device (%s%s)\n",
-                                      __func__, SYSCTL_BASENAME, devname);
-                               kfree(scd);
-                               kfree(salbuf);
-                               continue;
-                       }
-
-                       device_create(snsc_class, NULL, dev, NULL,
-                                     "%s", devname);
-
-                       ia64_sn_irtr_intr_enable(scd->scd_nasid,
-                                                0 /*ignored */ ,
-                                                SAL_IROUTER_INTR_RECV);
-
-                        /* on the console nasid, prepare to receive
-                         * system controller environmental events
-                         */
-                        if(scd->scd_nasid == event_nasid) {
-                                scdrv_event_init(scd);
-                        }
-       }
-       return 0;
-}
-device_initcall(scdrv_init);
diff --git a/drivers/char/snsc.h b/drivers/char/snsc.h
deleted file mode 100644 (file)
index e8c52c8..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * SN Platform system controller communication support
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * This file contains macros and data types for communication with the
- * system controllers in SGI SN systems.
- */
-
-#ifndef _SN_SYSCTL_H_
-#define _SN_SYSCTL_H_
-
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include <linux/fs.h>
-#include <linux/cdev.h>
-#include <linux/semaphore.h>
-#include <asm/sn/types.h>
-
-#define CHUNKSIZE 127
-
-/* This structure is used to track an open subchannel. */
-struct subch_data_s {
-       nasid_t sd_nasid;       /* node on which the subchannel was opened */
-       int sd_subch;           /* subchannel number */
-       spinlock_t sd_rlock;    /* monitor lock for rsv */
-       spinlock_t sd_wlock;    /* monitor lock for wsv */
-       wait_queue_head_t sd_rq;        /* wait queue for readers */
-       wait_queue_head_t sd_wq;        /* wait queue for writers */
-       struct semaphore sd_rbs;        /* semaphore for read buffer */
-       struct semaphore sd_wbs;        /* semaphore for write buffer */
-
-       char sd_rb[CHUNKSIZE];  /* read buffer */
-       char sd_wb[CHUNKSIZE];  /* write buffer */
-};
-
-struct sysctl_data_s {
-       struct cdev scd_cdev;   /* Character device info */
-       nasid_t scd_nasid;      /* Node on which subchannels are opened. */
-};
-
-
-/* argument types */
-#define IR_ARG_INT              0x00    /* 4-byte integer (big-endian)  */
-#define IR_ARG_ASCII            0x01    /* null-terminated ASCII string */
-#define IR_ARG_UNKNOWN          0x80    /* unknown data type.  The low
-                                         * 7 bits will contain the data
-                                         * length.                      */
-#define IR_ARG_UNKNOWN_LENGTH_MASK     0x7f
-
-
-/* system controller event codes */
-#define EV_CLASS_MASK          0xf000ul
-#define EV_SEVERITY_MASK       0x0f00ul
-#define EV_COMPONENT_MASK      0x00fful
-
-#define EV_CLASS_POWER         0x1000ul
-#define EV_CLASS_FAN           0x2000ul
-#define EV_CLASS_TEMP          0x3000ul
-#define EV_CLASS_ENV           0x4000ul
-#define EV_CLASS_TEST_FAULT    0x5000ul
-#define EV_CLASS_TEST_WARNING  0x6000ul
-#define EV_CLASS_PWRD_NOTIFY   0x8000ul
-
-/* ENV class codes */
-#define ENV_PWRDN_PEND         0x4101ul
-
-#define EV_SEVERITY_POWER_STABLE       0x0000ul
-#define EV_SEVERITY_POWER_LOW_WARNING  0x0100ul
-#define EV_SEVERITY_POWER_HIGH_WARNING 0x0200ul
-#define EV_SEVERITY_POWER_HIGH_FAULT   0x0300ul
-#define EV_SEVERITY_POWER_LOW_FAULT    0x0400ul
-
-#define EV_SEVERITY_FAN_STABLE         0x0000ul
-#define EV_SEVERITY_FAN_WARNING                0x0100ul
-#define EV_SEVERITY_FAN_FAULT          0x0200ul
-
-#define EV_SEVERITY_TEMP_STABLE                0x0000ul
-#define EV_SEVERITY_TEMP_ADVISORY      0x0100ul
-#define EV_SEVERITY_TEMP_CRITICAL      0x0200ul
-#define EV_SEVERITY_TEMP_FAULT         0x0300ul
-
-void scdrv_event_init(struct sysctl_data_s *);
-
-#endif /* _SN_SYSCTL_H_ */
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
deleted file mode 100644 (file)
index e452673..0000000
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * SN Platform system controller communication support
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * System controller event handler
- *
- * These routines deal with environmental events arriving from the
- * system controllers.
- */
-
-#include <linux/interrupt.h>
-#include <linux/sched/signal.h>
-#include <linux/slab.h>
-#include <asm/byteorder.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/unaligned.h>
-#include "snsc.h"
-
-static struct subch_data_s *event_sd;
-
-void scdrv_event(unsigned long);
-DECLARE_TASKLET(sn_sysctl_event, scdrv_event, 0);
-
-/*
- * scdrv_event_interrupt
- *
- * Pull incoming environmental events off the physical link to the
- * system controller and put them in a temporary holding area in SAL.
- * Schedule scdrv_event() to move them along to their ultimate
- * destination.
- */
-static irqreturn_t
-scdrv_event_interrupt(int irq, void *subch_data)
-{
-       struct subch_data_s *sd = subch_data;
-       unsigned long flags;
-       int status;
-
-       spin_lock_irqsave(&sd->sd_rlock, flags);
-       status = ia64_sn_irtr_intr(sd->sd_nasid, sd->sd_subch);
-
-       if ((status > 0) && (status & SAL_IROUTER_INTR_RECV)) {
-               tasklet_schedule(&sn_sysctl_event);
-       }
-       spin_unlock_irqrestore(&sd->sd_rlock, flags);
-       return IRQ_HANDLED;
-}
-
-
-/*
- * scdrv_parse_event
- *
- * Break an event (as read from SAL) into useful pieces so we can decide
- * what to do with it.
- */
-static int
-scdrv_parse_event(char *event, int *src, int *code, int *esp_code, char *desc)
-{
-       char *desc_end;
-
-       /* record event source address */
-       *src = get_unaligned_be32(event);
-       event += 4;                     /* move on to event code */
-
-       /* record the system controller's event code */
-       *code = get_unaligned_be32(event);
-       event += 4;                     /* move on to event arguments */
-
-       /* how many arguments are in the packet? */
-       if (*event++ != 2) {
-               /* if not 2, give up */
-               return -1;
-       }
-
-       /* parse out the ESP code */
-       if (*event++ != IR_ARG_INT) {
-               /* not an integer argument, so give up */
-               return -1;
-       }
-       *esp_code = get_unaligned_be32(event);
-       event += 4;
-
-       /* parse out the event description */
-       if (*event++ != IR_ARG_ASCII) {
-               /* not an ASCII string, so give up */
-               return -1;
-       }
-       event[CHUNKSIZE-1] = '\0';      /* ensure this string ends! */
-       event += 2;                     /* skip leading CR/LF */
-       desc_end = desc + sprintf(desc, "%s", event);
-
-       /* strip trailing CR/LF (if any) */
-       for (desc_end--;
-            (desc_end != desc) && ((*desc_end == 0xd) || (*desc_end == 0xa));
-            desc_end--) {
-               *desc_end = '\0';
-       }
-
-       return 0;
-}
-
-
-/*
- * scdrv_event_severity
- *
- * Figure out how urgent a message we should write to the console/syslog
- * via printk.
- */
-static char *
-scdrv_event_severity(int code)
-{
-       int ev_class = (code & EV_CLASS_MASK);
-       int ev_severity = (code & EV_SEVERITY_MASK);
-       char *pk_severity = KERN_NOTICE;
-
-       switch (ev_class) {
-       case EV_CLASS_POWER:
-               switch (ev_severity) {
-               case EV_SEVERITY_POWER_LOW_WARNING:
-               case EV_SEVERITY_POWER_HIGH_WARNING:
-                       pk_severity = KERN_WARNING;
-                       break;
-               case EV_SEVERITY_POWER_HIGH_FAULT:
-               case EV_SEVERITY_POWER_LOW_FAULT:
-                       pk_severity = KERN_ALERT;
-                       break;
-               }
-               break;
-       case EV_CLASS_FAN:
-               switch (ev_severity) {
-               case EV_SEVERITY_FAN_WARNING:
-                       pk_severity = KERN_WARNING;
-                       break;
-               case EV_SEVERITY_FAN_FAULT:
-                       pk_severity = KERN_CRIT;
-                       break;
-               }
-               break;
-       case EV_CLASS_TEMP:
-               switch (ev_severity) {
-               case EV_SEVERITY_TEMP_ADVISORY:
-                       pk_severity = KERN_WARNING;
-                       break;
-               case EV_SEVERITY_TEMP_CRITICAL:
-                       pk_severity = KERN_CRIT;
-                       break;
-               case EV_SEVERITY_TEMP_FAULT:
-                       pk_severity = KERN_ALERT;
-                       break;
-               }
-               break;
-       case EV_CLASS_ENV:
-               pk_severity = KERN_ALERT;
-               break;
-       case EV_CLASS_TEST_FAULT:
-               pk_severity = KERN_ALERT;
-               break;
-       case EV_CLASS_TEST_WARNING:
-               pk_severity = KERN_WARNING;
-               break;
-       case EV_CLASS_PWRD_NOTIFY:
-               pk_severity = KERN_ALERT;
-               break;
-       }
-
-       return pk_severity;
-}
-
-
-/*
- * scdrv_dispatch_event
- *
- * Do the right thing with an incoming event.  That's often nothing
- * more than printing it to the system log.  For power-down notifications
- * we start a graceful shutdown.
- */
-static void
-scdrv_dispatch_event(char *event, int len)
-{
-       static int snsc_shutting_down = 0;
-       int code, esp_code, src, class;
-       char desc[CHUNKSIZE];
-       char *severity;
-
-       if (scdrv_parse_event(event, &src, &code, &esp_code, desc) < 0) {
-               /* ignore uninterpretible event */
-               return;
-       }
-
-       /* how urgent is the message? */
-       severity = scdrv_event_severity(code);
-
-       class = (code & EV_CLASS_MASK);
-
-       if (class == EV_CLASS_PWRD_NOTIFY || code == ENV_PWRDN_PEND) {
-               if (snsc_shutting_down)
-                       return;
-
-               snsc_shutting_down = 1;
-
-               /* give a message for each type of event */
-               if (class == EV_CLASS_PWRD_NOTIFY)
-                       printk(KERN_NOTICE "Power off indication received."
-                              " Sending SIGPWR to init...\n");
-               else if (code == ENV_PWRDN_PEND)
-                       printk(KERN_CRIT "WARNING: Shutting down the system"
-                              " due to a critical environmental condition."
-                              " Sending SIGPWR to init...\n");
-
-               /* give a SIGPWR signal to init proc */
-               kill_cad_pid(SIGPWR, 0);
-       } else {
-               /* print to system log */
-               printk("%s|$(0x%x)%s\n", severity, esp_code, desc);
-       }
-}
-
-
-/*
- * scdrv_event
- *
- * Called as a tasklet when an event arrives from the L1.  Read the event
- * from where it's temporarily stored in SAL and call scdrv_dispatch_event()
- * to send it on its way.  Keep trying to read events until SAL indicates
- * that there are no more immediately available.
- */
-void
-scdrv_event(unsigned long dummy)
-{
-       int status;
-       int len;
-       unsigned long flags;
-       struct subch_data_s *sd = event_sd;
-
-       /* anything to read? */
-       len = CHUNKSIZE;
-       spin_lock_irqsave(&sd->sd_rlock, flags);
-       status = ia64_sn_irtr_recv(sd->sd_nasid, sd->sd_subch,
-                                  sd->sd_rb, &len);
-
-       while (!(status < 0)) {
-               spin_unlock_irqrestore(&sd->sd_rlock, flags);
-               scdrv_dispatch_event(sd->sd_rb, len);
-               len = CHUNKSIZE;
-               spin_lock_irqsave(&sd->sd_rlock, flags);
-               status = ia64_sn_irtr_recv(sd->sd_nasid, sd->sd_subch,
-                                          sd->sd_rb, &len);
-       }
-       spin_unlock_irqrestore(&sd->sd_rlock, flags);
-}
-
-
-/*
- * scdrv_event_init
- *
- * Sets up a system controller subchannel to begin receiving event
- * messages. This is sort of a specialized version of scdrv_open()
- * in drivers/char/sn_sysctl.c.
- */
-void
-scdrv_event_init(struct sysctl_data_s *scd)
-{
-       int rv;
-
-       event_sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL);
-       if (event_sd == NULL) {
-               printk(KERN_WARNING "%s: couldn't allocate subchannel info"
-                      " for event monitoring\n", __func__);
-               return;
-       }
-
-       /* initialize subch_data_s fields */
-       event_sd->sd_nasid = scd->scd_nasid;
-       spin_lock_init(&event_sd->sd_rlock);
-
-       /* ask the system controllers to send events to this node */
-       event_sd->sd_subch = ia64_sn_sysctl_event_init(scd->scd_nasid);
-
-       if (event_sd->sd_subch < 0) {
-               kfree(event_sd);
-               printk(KERN_WARNING "%s: couldn't open event subchannel\n",
-                      __func__);
-               return;
-       }
-
-       /* hook event subchannel up to the system controller interrupt */
-       rv = request_irq(SGI_UART_VECTOR, scdrv_event_interrupt,
-                        IRQF_SHARED, "system controller events", event_sd);
-       if (rv) {
-               printk(KERN_WARNING "%s: irq request failed (%d)\n",
-                      __func__, rv);
-               ia64_sn_irtr_close(event_sd->sd_nasid, event_sd->sd_subch);
-               kfree(event_sd);
-               return;
-       }
-}
index 88a3c06..9c37047 100644 (file)
@@ -164,6 +164,11 @@ config TCG_VTPM_PROXY
          /dev/vtpmX and a server-side file descriptor on which the vTPM
          can receive commands.
 
+config TCG_FTPM_TEE
+       tristate "TEE based fTPM Interface"
+       depends on TEE && OPTEE
+       help
+         This driver proxies for firmware TPM running in TEE.
 
 source "drivers/char/tpm/st33zp24/Kconfig"
 endif # TCG_TPM
index a01c4ca..c354cdf 100644 (file)
@@ -33,3 +33,4 @@ obj-$(CONFIG_TCG_TIS_ST33ZP24) += st33zp24/
 obj-$(CONFIG_TCG_XEN) += xen-tpmfront.o
 obj-$(CONFIG_TCG_CRB) += tpm_crb.o
 obj-$(CONFIG_TCG_VTPM_PROXY) += tpm_vtpm_proxy.o
+obj-$(CONFIG_TCG_FTPM_TEE) += tpm_ftpm_tee.o
index 4838c6a..3d6d394 100644 (file)
@@ -287,12 +287,9 @@ static void tpm_devs_release(struct device *dev)
  * @dev: device to which the chip is associated.
  *
  * Issues a TPM2_Shutdown command prior to loss of power, as required by the
- * TPM 2.0 spec.
- * Then, calls bus- and device- specific shutdown code.
+ * TPM 2.0 spec. Then, calls bus- and device- specific shutdown code.
  *
- * XXX: This codepath relies on the fact that sysfs is not enabled for
- * TPM2: sysfs uses an implicit lock on chip->ops, so this could race if TPM2
- * has sysfs support enabled before TPM sysfs's implicit locking is fixed.
+ * Return: always 0 (i.e. success)
  */
 static int tpm_class_shutdown(struct device *dev)
 {
index d9caedd..edfa891 100644 (file)
@@ -329,16 +329,9 @@ static const struct attribute_group tpm_dev_group = {
 
 void tpm_sysfs_add_device(struct tpm_chip *chip)
 {
-       /* XXX: If you wish to remove this restriction, you must first update
-        * tpm_sysfs to explicitly lock chip->ops.
-        */
        if (chip->flags & TPM_CHIP_FLAG_TPM2)
                return;
 
-       /* The sysfs routines rely on an implicit tpm_try_get_ops, device_del
-        * is called before ops is null'd and the sysfs core synchronizes this
-        * removal so that no callbacks are running or can run again
-        */
        WARN_ON(chip->groups_cnt != 0);
        chip->groups[chip->groups_cnt++] = &tpm_dev_group;
 }
diff --git a/drivers/char/tpm/tpm_ftpm_tee.c b/drivers/char/tpm/tpm_ftpm_tee.c
new file mode 100644 (file)
index 0000000..6640a14
--- /dev/null
@@ -0,0 +1,350 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) Microsoft Corporation
+ *
+ * Implements a firmware TPM as described here:
+ * https://www.microsoft.com/en-us/research/publication/ftpm-software-implementation-tpm-chip/
+ *
+ * A reference implementation is available here:
+ * https://github.com/microsoft/ms-tpm-20-ref/tree/master/Samples/ARM32-FirmwareTPM/optee_ta/fTPM
+ */
+
+#include <linux/acpi.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/tee_drv.h>
+#include <linux/tpm.h>
+#include <linux/uuid.h>
+
+#include "tpm.h"
+#include "tpm_ftpm_tee.h"
+
+/*
+ * TA_FTPM_UUID: BC50D971-D4C9-42C4-82CB-343FB7F37896
+ *
+ * Randomly generated, and must correspond to the GUID on the TA side.
+ * Defined here in the reference implementation:
+ * https://github.com/microsoft/ms-tpm-20-ref/blob/master/Samples/ARM32-FirmwareTPM/optee_ta/fTPM/include/fTPM.h#L42
+ */
+static const uuid_t ftpm_ta_uuid =
+       UUID_INIT(0xBC50D971, 0xD4C9, 0x42C4,
+                 0x82, 0xCB, 0x34, 0x3F, 0xB7, 0xF3, 0x78, 0x96);
+
+/**
+ * ftpm_tee_tpm_op_recv - retrieve fTPM response.
+ * @chip:      the tpm_chip description as specified in driver/char/tpm/tpm.h.
+ * @buf:       the buffer to store data.
+ * @count:     the number of bytes to read.
+ *
+ * Return:
+ *     In case of success the number of bytes received.
+ *     On failure, -errno.
+ */
+static int ftpm_tee_tpm_op_recv(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+       struct ftpm_tee_private *pvt_data = dev_get_drvdata(chip->dev.parent);
+       size_t len;
+
+       len = pvt_data->resp_len;
+       if (count < len) {
+               dev_err(&chip->dev,
+                       "%s: Invalid size in recv: count=%zd, resp_len=%zd\n",
+                       __func__, count, len);
+               return -EIO;
+       }
+
+       memcpy(buf, pvt_data->resp_buf, len);
+       pvt_data->resp_len = 0;
+
+       return len;
+}
+
+/**
+ * ftpm_tee_tpm_op_send - send TPM commands through the TEE shared memory.
+ * @chip:      the tpm_chip description as specified in driver/char/tpm/tpm.h
+ * @buf:       the buffer to send.
+ * @len:       the number of bytes to send.
+ *
+ * Return:
+ *     In case of success, returns 0.
+ *     On failure, -errno
+ */
+static int ftpm_tee_tpm_op_send(struct tpm_chip *chip, u8 *buf, size_t len)
+{
+       struct ftpm_tee_private *pvt_data = dev_get_drvdata(chip->dev.parent);
+       size_t resp_len;
+       int rc;
+       u8 *temp_buf;
+       struct tpm_header *resp_header;
+       struct tee_ioctl_invoke_arg transceive_args;
+       struct tee_param command_params[4];
+       struct tee_shm *shm = pvt_data->shm;
+
+       if (len > MAX_COMMAND_SIZE) {
+               dev_err(&chip->dev,
+                       "%s: len=%zd exceeds MAX_COMMAND_SIZE supported by fTPM TA\n",
+                       __func__, len);
+               return -EIO;
+       }
+
+       memset(&transceive_args, 0, sizeof(transceive_args));
+       memset(command_params, 0, sizeof(command_params));
+       pvt_data->resp_len = 0;
+
+       /* Invoke FTPM_OPTEE_TA_SUBMIT_COMMAND function of fTPM TA */
+       transceive_args = (struct tee_ioctl_invoke_arg) {
+               .func = FTPM_OPTEE_TA_SUBMIT_COMMAND,
+               .session = pvt_data->session,
+               .num_params = 4,
+       };
+
+       /* Fill FTPM_OPTEE_TA_SUBMIT_COMMAND parameters */
+       command_params[0] = (struct tee_param) {
+               .attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT,
+               .u.memref = {
+                       .shm = shm,
+                       .size = len,
+                       .shm_offs = 0,
+               },
+       };
+
+       temp_buf = tee_shm_get_va(shm, 0);
+       if (IS_ERR(temp_buf)) {
+               dev_err(&chip->dev, "%s: tee_shm_get_va failed for transmit\n",
+                       __func__);
+               return PTR_ERR(temp_buf);
+       }
+       memset(temp_buf, 0, (MAX_COMMAND_SIZE + MAX_RESPONSE_SIZE));
+       memcpy(temp_buf, buf, len);
+
+       command_params[1] = (struct tee_param) {
+               .attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT,
+               .u.memref = {
+                       .shm = shm,
+                       .size = MAX_RESPONSE_SIZE,
+                       .shm_offs = MAX_COMMAND_SIZE,
+               },
+       };
+
+       rc = tee_client_invoke_func(pvt_data->ctx, &transceive_args,
+                                   command_params);
+       if ((rc < 0) || (transceive_args.ret != 0)) {
+               dev_err(&chip->dev, "%s: SUBMIT_COMMAND invoke error: 0x%x\n",
+                       __func__, transceive_args.ret);
+               return (rc < 0) ? rc : transceive_args.ret;
+       }
+
+       temp_buf = tee_shm_get_va(shm, command_params[1].u.memref.shm_offs);
+       if (IS_ERR(temp_buf)) {
+               dev_err(&chip->dev, "%s: tee_shm_get_va failed for receive\n",
+                       __func__);
+               return PTR_ERR(temp_buf);
+       }
+
+       resp_header = (struct tpm_header *)temp_buf;
+       resp_len = be32_to_cpu(resp_header->length);
+
+       /* sanity check resp_len */
+       if (resp_len < TPM_HEADER_SIZE) {
+               dev_err(&chip->dev, "%s: tpm response header too small\n",
+                       __func__);
+               return -EIO;
+       }
+       if (resp_len > MAX_RESPONSE_SIZE) {
+               dev_err(&chip->dev,
+                       "%s: resp_len=%zd exceeds MAX_RESPONSE_SIZE\n",
+                       __func__, resp_len);
+               return -EIO;
+       }
+
+       /* sanity checks look good, cache the response */
+       memcpy(pvt_data->resp_buf, temp_buf, resp_len);
+       pvt_data->resp_len = resp_len;
+
+       return 0;
+}
+
+static void ftpm_tee_tpm_op_cancel(struct tpm_chip *chip)
+{
+       /* not supported */
+}
+
+static u8 ftpm_tee_tpm_op_status(struct tpm_chip *chip)
+{
+       return 0;
+}
+
+static bool ftpm_tee_tpm_req_canceled(struct tpm_chip *chip, u8 status)
+{
+       return 0;
+}
+
+static const struct tpm_class_ops ftpm_tee_tpm_ops = {
+       .flags = TPM_OPS_AUTO_STARTUP,
+       .recv = ftpm_tee_tpm_op_recv,
+       .send = ftpm_tee_tpm_op_send,
+       .cancel = ftpm_tee_tpm_op_cancel,
+       .status = ftpm_tee_tpm_op_status,
+       .req_complete_mask = 0,
+       .req_complete_val = 0,
+       .req_canceled = ftpm_tee_tpm_req_canceled,
+};
+
+/*
+ * Check whether this driver supports the fTPM TA in the TEE instance
+ * represented by the params (ver/data) to this function.
+ */
+static int ftpm_tee_match(struct tee_ioctl_version_data *ver, const void *data)
+{
+       /*
+        * Currently this driver only support GP Complaint OPTEE based fTPM TA
+        */
+       if ((ver->impl_id == TEE_IMPL_ID_OPTEE) &&
+               (ver->gen_caps & TEE_GEN_CAP_GP))
+               return 1;
+       else
+               return 0;
+}
+
+/**
+ * ftpm_tee_probe - initialize the fTPM
+ * @pdev: the platform_device description.
+ *
+ * Return:
+ *     On success, 0. On failure, -errno.
+ */
+static int ftpm_tee_probe(struct platform_device *pdev)
+{
+       int rc;
+       struct tpm_chip *chip;
+       struct device *dev = &pdev->dev;
+       struct ftpm_tee_private *pvt_data = NULL;
+       struct tee_ioctl_open_session_arg sess_arg;
+
+       pvt_data = devm_kzalloc(dev, sizeof(struct ftpm_tee_private),
+                               GFP_KERNEL);
+       if (!pvt_data)
+               return -ENOMEM;
+
+       dev_set_drvdata(dev, pvt_data);
+
+       /* Open context with TEE driver */
+       pvt_data->ctx = tee_client_open_context(NULL, ftpm_tee_match, NULL,
+                                               NULL);
+       if (IS_ERR(pvt_data->ctx)) {
+               if (PTR_ERR(pvt_data->ctx) == -ENOENT)
+                       return -EPROBE_DEFER;
+               dev_err(dev, "%s: tee_client_open_context failed\n", __func__);
+               return PTR_ERR(pvt_data->ctx);
+       }
+
+       /* Open a session with fTPM TA */
+       memset(&sess_arg, 0, sizeof(sess_arg));
+       memcpy(sess_arg.uuid, ftpm_ta_uuid.b, TEE_IOCTL_UUID_LEN);
+       sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC;
+       sess_arg.num_params = 0;
+
+       rc = tee_client_open_session(pvt_data->ctx, &sess_arg, NULL);
+       if ((rc < 0) || (sess_arg.ret != 0)) {
+               dev_err(dev, "%s: tee_client_open_session failed, err=%x\n",
+                       __func__, sess_arg.ret);
+               rc = -EINVAL;
+               goto out_tee_session;
+       }
+       pvt_data->session = sess_arg.session;
+
+       /* Allocate dynamic shared memory with fTPM TA */
+       pvt_data->shm = tee_shm_alloc(pvt_data->ctx,
+                                     MAX_COMMAND_SIZE + MAX_RESPONSE_SIZE,
+                                     TEE_SHM_MAPPED | TEE_SHM_DMA_BUF);
+       if (IS_ERR(pvt_data->shm)) {
+               dev_err(dev, "%s: tee_shm_alloc failed\n", __func__);
+               rc = -ENOMEM;
+               goto out_shm_alloc;
+       }
+
+       /* Allocate new struct tpm_chip instance */
+       chip = tpm_chip_alloc(dev, &ftpm_tee_tpm_ops);
+       if (IS_ERR(chip)) {
+               dev_err(dev, "%s: tpm_chip_alloc failed\n", __func__);
+               rc = PTR_ERR(chip);
+               goto out_chip_alloc;
+       }
+
+       pvt_data->chip = chip;
+       pvt_data->chip->flags |= TPM_CHIP_FLAG_TPM2;
+
+       /* Create a character device for the fTPM */
+       rc = tpm_chip_register(pvt_data->chip);
+       if (rc) {
+               dev_err(dev, "%s: tpm_chip_register failed with rc=%d\n",
+                       __func__, rc);
+               goto out_chip;
+       }
+
+       return 0;
+
+out_chip:
+       put_device(&pvt_data->chip->dev);
+out_chip_alloc:
+       tee_shm_free(pvt_data->shm);
+out_shm_alloc:
+       tee_client_close_session(pvt_data->ctx, pvt_data->session);
+out_tee_session:
+       tee_client_close_context(pvt_data->ctx);
+
+       return rc;
+}
+
+/**
+ * ftpm_tee_remove - remove the TPM device
+ * @pdev: the platform_device description.
+ *
+ * Return:
+ *     0 always.
+ */
+static int ftpm_tee_remove(struct platform_device *pdev)
+{
+       struct ftpm_tee_private *pvt_data = dev_get_drvdata(&pdev->dev);
+
+       /* Release the chip */
+       tpm_chip_unregister(pvt_data->chip);
+
+       /* frees chip */
+       put_device(&pvt_data->chip->dev);
+
+       /* Free the shared memory pool */
+       tee_shm_free(pvt_data->shm);
+
+       /* close the existing session with fTPM TA*/
+       tee_client_close_session(pvt_data->ctx, pvt_data->session);
+
+       /* close the context with TEE driver */
+       tee_client_close_context(pvt_data->ctx);
+
+       /* memory allocated with devm_kzalloc() is freed automatically */
+
+       return 0;
+}
+
+static const struct of_device_id of_ftpm_tee_ids[] = {
+       { .compatible = "microsoft,ftpm" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, of_ftpm_tee_ids);
+
+static struct platform_driver ftpm_tee_driver = {
+       .driver = {
+               .name = "ftpm-tee",
+               .of_match_table = of_match_ptr(of_ftpm_tee_ids),
+       },
+       .probe = ftpm_tee_probe,
+       .remove = ftpm_tee_remove,
+};
+
+module_platform_driver(ftpm_tee_driver);
+
+MODULE_AUTHOR("Thirupathaiah Annapureddy <thiruan@microsoft.com>");
+MODULE_DESCRIPTION("TPM Driver for fTPM TA in TEE");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/char/tpm/tpm_ftpm_tee.h b/drivers/char/tpm/tpm_ftpm_tee.h
new file mode 100644 (file)
index 0000000..f98daa7
--- /dev/null
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) Microsoft Corporation
+ */
+
+#ifndef __TPM_FTPM_TEE_H__
+#define __TPM_FTPM_TEE_H__
+
+#include <linux/tee_drv.h>
+#include <linux/tpm.h>
+#include <linux/uuid.h>
+
+/* The TAFs ID implemented in this TA */
+#define FTPM_OPTEE_TA_SUBMIT_COMMAND  (0)
+#define FTPM_OPTEE_TA_EMULATE_PPI     (1)
+
+/* max. buffer size supported by fTPM  */
+#define MAX_COMMAND_SIZE       4096
+#define MAX_RESPONSE_SIZE      4096
+
+/**
+ * struct ftpm_tee_private - fTPM's private data
+ * @chip:     struct tpm_chip instance registered with tpm framework.
+ * @state:    internal state
+ * @session:  fTPM TA session identifier.
+ * @resp_len: cached response buffer length.
+ * @resp_buf: cached response buffer.
+ * @ctx:      TEE context handler.
+ * @shm:      Memory pool shared with fTPM TA in TEE.
+ */
+struct ftpm_tee_private {
+       struct tpm_chip *chip;
+       u32 session;
+       size_t resp_len;
+       u8 resp_buf[MAX_RESPONSE_SIZE];
+       struct tee_context *ctx;
+       struct tee_shm *shm;
+};
+
+#endif /* __TPM_FTPM_TEE_H__ */
index c3181ea..270f43a 100644 (file)
@@ -980,6 +980,8 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
                        goto out_err;
                }
 
+               tpm_chip_start(chip);
+               chip->flags |= TPM_CHIP_FLAG_IRQ;
                if (irq) {
                        tpm_tis_probe_irq_single(chip, intmask, IRQF_SHARED,
                                                 irq);
@@ -989,6 +991,7 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
                } else {
                        tpm_tis_probe_irq(chip, intmask);
                }
+               tpm_chip_stop(chip);
        }
 
        rc = tpm_chip_register(chip);
index a2287c7..886f7c5 100644 (file)
@@ -69,7 +69,7 @@ static int scmi_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 {
        struct scmi_clk *clk = to_scmi_clk(hw);
 
-       return clk->handle->clk_ops->rate_set(clk->handle, clk->id, 0, rate);
+       return clk->handle->clk_ops->rate_set(clk->handle, clk->id, rate);
 }
 
 static int scmi_clk_enable(struct clk_hw *hw)
index 1c46bab..ca99e9d 100644 (file)
@@ -2510,6 +2510,12 @@ runtime_put:
        return ret;
 }
 
+int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *parent)
+{
+       return clk_core_set_parent_nolock(hw->core, parent->core);
+}
+EXPORT_SYMBOL_GPL(clk_hw_set_parent);
+
 /**
  * clk_set_parent - switch the parent of a mux clk
  * @clk: the mux clk whose input we are switching
index 0eaf418..1ac0c79 100644 (file)
@@ -14,6 +14,12 @@ config CLK_IMX8MM
        help
            Build the driver for i.MX8MM CCM Clock Driver
 
+config CLK_IMX8MN
+       bool "IMX8MN CCM Clock Driver"
+       depends on ARCH_MXC && ARM64
+       help
+           Build the driver for i.MX8MN CCM Clock Driver
+
 config CLK_IMX8MQ
        bool "IMX8MQ CCM Clock Driver"
        depends on ARCH_MXC && ARM64
index 05641c6..77a3d71 100644 (file)
@@ -26,6 +26,7 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
        clk-lpcg-scu.o
 
 obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
+obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
 obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
 
index 6b8e75d..43fa9c3 100644 (file)
@@ -26,23 +26,6 @@ static u32 share_count_dcss;
 static u32 share_count_pdm;
 static u32 share_count_nand;
 
-#define PLL_1416X_RATE(_rate, _m, _p, _s)              \
-       {                                               \
-               .rate   =       (_rate),                \
-               .mdiv   =       (_m),                   \
-               .pdiv   =       (_p),                   \
-               .sdiv   =       (_s),                   \
-       }
-
-#define PLL_1443X_RATE(_rate, _m, _p, _s, _k)          \
-       {                                               \
-               .rate   =       (_rate),                \
-               .mdiv   =       (_m),                   \
-               .pdiv   =       (_p),                   \
-               .sdiv   =       (_s),                   \
-               .kdiv   =       (_k),                   \
-       }
-
 static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = {
        PLL_1416X_RATE(1800000000U, 225, 3, 0),
        PLL_1416X_RATE(1600000000U, 200, 3, 0),
diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c
new file mode 100644 (file)
index 0000000..07481a5
--- /dev/null
@@ -0,0 +1,636 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2018-2019 NXP.
+ */
+
+#include <dt-bindings/clock/imx8mn-clock.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+static u32 share_count_sai2;
+static u32 share_count_sai3;
+static u32 share_count_sai5;
+static u32 share_count_sai6;
+static u32 share_count_sai7;
+static u32 share_count_disp;
+static u32 share_count_pdm;
+static u32 share_count_nand;
+
+enum {
+       ARM_PLL,
+       GPU_PLL,
+       VPU_PLL,
+       SYS_PLL1,
+       SYS_PLL2,
+       SYS_PLL3,
+       DRAM_PLL,
+       AUDIO_PLL1,
+       AUDIO_PLL2,
+       VIDEO_PLL2,
+       NR_PLLS,
+};
+
+static const struct imx_pll14xx_rate_table imx8mn_pll1416x_tbl[] = {
+       PLL_1416X_RATE(1800000000U, 225, 3, 0),
+       PLL_1416X_RATE(1600000000U, 200, 3, 0),
+       PLL_1416X_RATE(1200000000U, 300, 3, 1),
+       PLL_1416X_RATE(1000000000U, 250, 3, 1),
+       PLL_1416X_RATE(800000000U,  200, 3, 1),
+       PLL_1416X_RATE(750000000U,  250, 2, 2),
+       PLL_1416X_RATE(700000000U,  350, 3, 2),
+       PLL_1416X_RATE(600000000U,  300, 3, 2),
+};
+
+static const struct imx_pll14xx_rate_table imx8mn_audiopll_tbl[] = {
+       PLL_1443X_RATE(786432000U, 655, 5, 2, 23593),
+       PLL_1443X_RATE(722534400U, 301, 5, 1, 3670),
+};
+
+static const struct imx_pll14xx_rate_table imx8mn_videopll_tbl[] = {
+       PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+       PLL_1443X_RATE(594000000U, 198, 2, 2, 0),
+};
+
+static const struct imx_pll14xx_rate_table imx8mn_drampll_tbl[] = {
+       PLL_1443X_RATE(650000000U, 325, 3, 2, 0),
+};
+
+static struct imx_pll14xx_clk imx8mn_audio_pll = {
+               .type = PLL_1443X,
+               .rate_table = imx8mn_audiopll_tbl,
+};
+
+static struct imx_pll14xx_clk imx8mn_video_pll = {
+               .type = PLL_1443X,
+               .rate_table = imx8mn_videopll_tbl,
+};
+
+static struct imx_pll14xx_clk imx8mn_dram_pll = {
+               .type = PLL_1443X,
+               .rate_table = imx8mn_drampll_tbl,
+};
+
+static struct imx_pll14xx_clk imx8mn_arm_pll = {
+               .type = PLL_1416X,
+               .rate_table = imx8mn_pll1416x_tbl,
+};
+
+static struct imx_pll14xx_clk imx8mn_gpu_pll = {
+               .type = PLL_1416X,
+               .rate_table = imx8mn_pll1416x_tbl,
+};
+
+static struct imx_pll14xx_clk imx8mn_vpu_pll = {
+               .type = PLL_1416X,
+               .rate_table = imx8mn_pll1416x_tbl,
+};
+
+static struct imx_pll14xx_clk imx8mn_sys_pll = {
+               .type = PLL_1416X,
+               .rate_table = imx8mn_pll1416x_tbl,
+};
+
+static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
+static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
+static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
+static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", };
+static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
+static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+
+static const char * const imx8mn_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m",
+                                              "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
+                                              "audio_pll1_out", "sys_pll3_out", };
+
+static const char * const imx8mn_gpu_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+                                                   "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                   "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mn_gpu_shader_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+                                                     "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                     "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mn_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m",
+                                                   "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out",
+                                                   "video_pll1_out", "sys_pll1_100m",};
+
+static const char * const imx8mn_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
+                                                   "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
+                                                   "video_pll1_out", "sys_pll3_out", };
+
+static const char * const imx8mn_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
+                                                     "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
+                                                     "sys_pll2_250m", "audio_pll1_out", };
+
+static const char * const imx8mn_disp_axi_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m",
+                                                   "sys_pll3_out", "sys_pll1_40m", "audio_pll2_out",
+                                                   "clk_ext1", "clk_ext4", };
+
+static const char * const imx8mn_disp_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll1_800m",
+                                                   "sys_pll3_out", "sys1_pll_40m", "audio_pll2_out",
+                                                   "clk_ext1", "clk_ext3", };
+
+static const char * const imx8mn_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
+                                                  "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
+                                                  "clk_ext4", "audio_pll2_out", };
+
+static const char * const imx8mn_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
+                                                  "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                  "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mn_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
+                                                  "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                  "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mn_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
+                                              "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
+                                              "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mn_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m",
+                                              "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out",
+                                              "audio_pll1_out", "video_pll1_out", };
+
+static const char * const imx8mn_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
+                                                    "sys_pll2_1000m", "sys_pll2_166m", "sys_pll3_out",
+                                                    "audio_pll1_out", "video_pll1_out", };
+
+static const char * const imx8mn_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m",
+                                                   "sys_pll2_500m", "sys_pll2_1000m", "sys_pll3_out",
+                                                   "audio_pll1_out", "sys_pll1_266m", };
+
+static const char * const imx8mn_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                                   "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                                   "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mn_disp_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
+                                                     "audio_pll1_out", "sys_pll1_800m", "sys_pll2_1000m",
+                                                     "sys_pll3_out", "clk_ext4", };
+
+static const char * const imx8mn_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext3", "clk_ext4", };
+
+static const char * const imx8mn_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext3", "clk_ext4", };
+
+static const char * const imx8mn_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext2", "clk_ext3", };
+
+static const char * const imx8mn_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext3", "clk_ext4", };
+
+static const char * const imx8mn_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext3", "clk_ext4", };
+
+static const char * const imx8mn_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                                 "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                                 "clk_ext2", "clk_ext3", };
+
+static const char * const imx8mn_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
+                                                   "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
+                                                   "video_pll1_out", "clk_ext4", };
+
+static const char * const imx8mn_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
+                                                     "clk_ext1", "clk_ext2", "clk_ext3",
+                                                     "clk_ext4", "video_pll1_out", };
+
+static const char * const imx8mn_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m",
+                                                   "sys_pll2_200m", "sys_pll2_500m", "video_pll1_out",
+                                                   "audio_pll2_out", };
+
+static const char * const imx8mn_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out",
+                                               "sys_pll1_400m", "audio_pll2_out", "sys_pll3_out",
+                                               "sys_pll2_250m", "video_pll1_out", };
+
+static const char * const imx8mn_qspi_sels[] = {"osc_24m", "sys1_pll_400m", "sys_pll1_800m",
+                                               "sys2_pll_500m", "audio_pll2_out", "sys1_pll_266m",
+                                               "sys3_pll2_out", "sys1_pll_100m", };
+
+static const char * const imx8mn_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
+                                                 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+                                                 "audio_pll2_out", "sys_pll1_100m", };
+
+static const char * const imx8mn_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
+                                                 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+                                                 "audio_pll2_out", "sys_pll1_100m", };
+
+static const char * const imx8mn_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mn_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mn_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mn_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mn_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
+                                                "clk_ext4", "audio_pll2_out", };
+
+static const char * const imx8mn_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
+                                                "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mn_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
+                                                "clk_ext4", "audio_pll2_out", };
+
+static const char * const imx8mn_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
+                                                "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mn_usb_core_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m",
+                                                   "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
+                                                   "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mn_usb_phy_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m",
+                                                  "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
+                                                  "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mn_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                                 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                                 "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mn_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                                 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                                 "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mn_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+                                               "sys_pll1_40m", "sys_pll3_out", "clk_ext1",
+                                               "sys_pll1_80m", "video_pll1_out", };
+
+static const char * const imx8mn_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+                                               "sys_pll1_40m", "sys_pll3_out", "clk_ext1",
+                                               "sys_pll1_80m", "video_pll1_out", };
+
+static const char * const imx8mn_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+                                               "sys_pll1_40m", "sys3_pll2_out", "clk_ext2",
+                                               "sys_pll1_80m", "video_pll1_out", };
+
+static const char * const imx8mn_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+                                               "sys_pll1_40m", "sys_pll3_out", "clk_ext2",
+                                               "sys_pll1_80m", "video_pll1_out", };
+
+static const char * const imx8mn_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m",
+                                               "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out",
+                                               "sys_pll1_80m", "sys_pll2_166m", };
+
+static const char * const imx8mn_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out",
+                                                "sys_pll3_out", "sys_pll2_200m", "sys_pll1_266m",
+                                                "sys_pll2_500m", "sys_pll1_100m", };
+
+static const char * const imx8mn_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
+                                                   "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                                   "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mn_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m",
+                                                  "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+                                                  "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mn_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m",
+                                                  "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                                  "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mn_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
+                                                 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+                                                 "audio_pll2_clk", "sys_pll1_100m", };
+
+static const char * const imx8mn_camera_pixel_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
+                                                       "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                                       "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mn_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
+                                                   "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+                                                   "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mn_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
+                                                   "sys_pll1_800m", "sys_pll2_1000m", "clk_ext2",
+                                                   "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mn_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
+                                                   "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                                   "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mn_ecspi3_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                                 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                                 "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mn_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
+                                              "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                              "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mn_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
+
+static const char * const imx8mn_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m",
+                                                "sys_pll1_200m", "audio_pll2_clk", "vpu_pll",
+                                                "sys_pll1_80m", };
+static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m",
+                                                "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out",
+                                                "video_pll1_out", "osc_32k", };
+
+static struct clk *clks[IMX8MN_CLK_END];
+static struct clk_onecell_data clk_data;
+
+static int imx8mn_clocks_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       void __iomem *base;
+       int ret;
+
+       clks[IMX8MN_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
+       clks[IMX8MN_CLK_24M] = of_clk_get_by_name(np, "osc_24m");
+       clks[IMX8MN_CLK_32K] = of_clk_get_by_name(np, "osc_32k");
+       clks[IMX8MN_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
+       clks[IMX8MN_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
+       clks[IMX8MN_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
+       clks[IMX8MN_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop");
+       base = of_iomap(np, 0);
+       if (WARN_ON(!base)) {
+               ret = -ENOMEM;
+               goto unregister_clks;
+       }
+
+       clks[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_SYS_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       clks[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+       clks[IMX8MN_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mn_audio_pll);
+       clks[IMX8MN_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mn_audio_pll);
+       clks[IMX8MN_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mn_video_pll);
+       clks[IMX8MN_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mn_dram_pll);
+       clks[IMX8MN_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mn_gpu_pll);
+       clks[IMX8MN_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mn_vpu_pll);
+       clks[IMX8MN_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mn_arm_pll);
+       clks[IMX8MN_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mn_sys_pll);
+       clks[IMX8MN_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mn_sys_pll);
+       clks[IMX8MN_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mn_sys_pll);
+
+       /* PLL bypass out */
+       clks[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       clks[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+
+       /* unbypass all the plls */
+       clk_set_parent(clks[IMX8MN_AUDIO_PLL1_BYPASS], clks[IMX8MN_AUDIO_PLL1]);
+       clk_set_parent(clks[IMX8MN_AUDIO_PLL2_BYPASS], clks[IMX8MN_AUDIO_PLL2]);
+       clk_set_parent(clks[IMX8MN_VIDEO_PLL1_BYPASS], clks[IMX8MN_VIDEO_PLL1]);
+       clk_set_parent(clks[IMX8MN_DRAM_PLL_BYPASS], clks[IMX8MN_DRAM_PLL]);
+       clk_set_parent(clks[IMX8MN_GPU_PLL_BYPASS], clks[IMX8MN_GPU_PLL]);
+       clk_set_parent(clks[IMX8MN_VPU_PLL_BYPASS], clks[IMX8MN_VPU_PLL]);
+       clk_set_parent(clks[IMX8MN_ARM_PLL_BYPASS], clks[IMX8MN_ARM_PLL]);
+       clk_set_parent(clks[IMX8MN_SYS_PLL1_BYPASS], clks[IMX8MN_SYS_PLL1]);
+       clk_set_parent(clks[IMX8MN_SYS_PLL2_BYPASS], clks[IMX8MN_SYS_PLL2]);
+       clk_set_parent(clks[IMX8MN_SYS_PLL3_BYPASS], clks[IMX8MN_SYS_PLL3]);
+
+       /* PLL out gate */
+       clks[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
+       clks[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
+       clks[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
+       clks[IMX8MN_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
+       clks[IMX8MN_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 13);
+       clks[IMX8MN_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 13);
+       clks[IMX8MN_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 13);
+       clks[IMX8MN_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 13);
+       clks[IMX8MN_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 13);
+       clks[IMX8MN_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 13);
+
+       /* SYS PLL fixed output */
+       clks[IMX8MN_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
+       clks[IMX8MN_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
+       clks[IMX8MN_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
+       clks[IMX8MN_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
+       clks[IMX8MN_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
+       clks[IMX8MN_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
+       clks[IMX8MN_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
+       clks[IMX8MN_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
+       clks[IMX8MN_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+
+       clks[IMX8MN_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
+       clks[IMX8MN_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
+       clks[IMX8MN_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
+       clks[IMX8MN_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
+       clks[IMX8MN_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
+       clks[IMX8MN_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
+       clks[IMX8MN_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
+       clks[IMX8MN_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
+       clks[IMX8MN_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
+
+       np = dev->of_node;
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (WARN_ON(IS_ERR(base))) {
+               ret = PTR_ERR(base);
+               goto unregister_clks;
+       }
+
+       /* CORE */
+       clks[IMX8MN_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels));
+       clks[IMX8MN_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3,  imx8mn_gpu_core_sels, ARRAY_SIZE(imx8mn_gpu_core_sels));
+       clks[IMX8MN_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mn_gpu_shader_sels,  ARRAY_SIZE(imx8mn_gpu_shader_sels));
+       clks[IMX8MN_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
+       clks[IMX8MN_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
+       clks[IMX8MN_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
+
+       clks[IMX8MN_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+       clks[IMX8MN_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
+       clks[IMX8MN_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
+
+       /* BUS */
+       clks[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800);
+       clks[IMX8MN_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
+       clks[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_composite("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
+       clks[IMX8MN_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
+       clks[IMX8MN_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
+       clks[IMX8MN_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
+       clks[IMX8MN_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
+       clks[IMX8MN_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
+       clks[IMX8MN_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mn_noc_sels, base + 0x8d00);
+
+       clks[IMX8MN_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mn_ahb_sels, base + 0x9000);
+       clks[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
+       clks[IMX8MN_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
+       clks[IMX8MN_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
+       clks[IMX8MN_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mn_dram_core_sels, ARRAY_SIZE(imx8mn_dram_core_sels), CLK_IS_CRITICAL);
+       clks[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000);
+       clks[IMX8MN_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080);
+       clks[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500);
+       clks[IMX8MN_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mn_sai2_sels, base + 0xa600);
+       clks[IMX8MN_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mn_sai3_sels, base + 0xa680);
+       clks[IMX8MN_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mn_sai5_sels, base + 0xa780);
+       clks[IMX8MN_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mn_sai6_sels, base + 0xa800);
+       clks[IMX8MN_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mn_spdif1_sels, base + 0xa880);
+       clks[IMX8MN_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mn_enet_ref_sels, base + 0xa980);
+       clks[IMX8MN_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mn_enet_timer_sels, base + 0xaa00);
+       clks[IMX8MN_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mn_enet_phy_sels, base + 0xaa80);
+       clks[IMX8MN_CLK_NAND] = imx8m_clk_composite("nand", imx8mn_nand_sels, base + 0xab00);
+       clks[IMX8MN_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mn_qspi_sels, base + 0xab80);
+       clks[IMX8MN_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mn_usdhc1_sels, base + 0xac00);
+       clks[IMX8MN_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mn_usdhc2_sels, base + 0xac80);
+       clks[IMX8MN_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mn_i2c1_sels, base + 0xad00);
+       clks[IMX8MN_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mn_i2c2_sels, base + 0xad80);
+       clks[IMX8MN_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mn_i2c3_sels, base + 0xae00);
+       clks[IMX8MN_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mn_i2c4_sels, base + 0xae80);
+       clks[IMX8MN_CLK_UART1] = imx8m_clk_composite("uart1", imx8mn_uart1_sels, base + 0xaf00);
+       clks[IMX8MN_CLK_UART2] = imx8m_clk_composite("uart2", imx8mn_uart2_sels, base + 0xaf80);
+       clks[IMX8MN_CLK_UART3] = imx8m_clk_composite("uart3", imx8mn_uart3_sels, base + 0xb000);
+       clks[IMX8MN_CLK_UART4] = imx8m_clk_composite("uart4", imx8mn_uart4_sels, base + 0xb080);
+       clks[IMX8MN_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mn_usb_core_sels, base + 0xb100);
+       clks[IMX8MN_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mn_usb_phy_sels, base + 0xb180);
+       clks[IMX8MN_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mn_ecspi1_sels, base + 0xb280);
+       clks[IMX8MN_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mn_ecspi2_sels, base + 0xb300);
+       clks[IMX8MN_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mn_pwm1_sels, base + 0xb380);
+       clks[IMX8MN_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400);
+       clks[IMX8MN_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480);
+       clks[IMX8MN_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500);
+       clks[IMX8MN_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mn_wdog_sels, base + 0xb900);
+       clks[IMX8MN_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mn_wrclk_sels, base + 0xb980);
+       clks[IMX8MN_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mn_clko1_sels, base + 0xba00);
+       clks[IMX8MN_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mn_clko2_sels, base + 0xba80);
+       clks[IMX8MN_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mn_dsi_core_sels, base + 0xbb00);
+       clks[IMX8MN_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mn_dsi_phy_sels, base + 0xbb80);
+       clks[IMX8MN_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mn_dsi_dbi_sels, base + 0xbc00);
+       clks[IMX8MN_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mn_usdhc3_sels, base + 0xbc80);
+       clks[IMX8MN_CLK_CAMERA_PIXEL] = imx8m_clk_composite("camera_pixel", imx8mn_camera_pixel_sels, base + 0xbd00);
+       clks[IMX8MN_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mn_csi1_phy_sels, base + 0xbd80);
+       clks[IMX8MN_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mn_csi2_phy_sels, base + 0xbf00);
+       clks[IMX8MN_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mn_csi2_esc_sels, base + 0xbf80);
+       clks[IMX8MN_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mn_ecspi3_sels, base + 0xc180);
+       clks[IMX8MN_CLK_PDM] = imx8m_clk_composite("pdm", imx8mn_pdm_sels, base + 0xc200);
+       clks[IMX8MN_CLK_SAI7] = imx8m_clk_composite("sai7", imx8mn_sai7_sels, base + 0xc300);
+
+       clks[IMX8MN_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
+       clks[IMX8MN_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
+       clks[IMX8MN_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
+       clks[IMX8MN_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
+       clks[IMX8MN_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
+       clks[IMX8MN_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
+       clks[IMX8MN_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
+       clks[IMX8MN_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
+       clks[IMX8MN_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
+       clks[IMX8MN_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
+       clks[IMX8MN_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
+       clks[IMX8MN_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
+       clks[IMX8MN_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
+       clks[IMX8MN_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
+       clks[IMX8MN_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
+       clks[IMX8MN_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
+       clks[IMX8MN_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
+       clks[IMX8MN_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
+       clks[IMX8MN_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
+       clks[IMX8MN_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
+       clks[IMX8MN_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
+       clks[IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
+       clks[IMX8MN_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
+       clks[IMX8MN_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
+       clks[IMX8MN_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
+       clks[IMX8MN_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
+       clks[IMX8MN_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
+       clks[IMX8MN_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
+       clks[IMX8MN_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
+       clks[IMX8MN_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
+       clks[IMX8MN_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
+       clks[IMX8MN_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
+       clks[IMX8MN_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
+       clks[IMX8MN_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
+       clks[IMX8MN_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
+       clks[IMX8MN_CLK_GPU_CORE_ROOT] = imx_clk_gate4("gpu_core_root_clk", "gpu_core_div", base + 0x44f0, 0);
+       clks[IMX8MN_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
+       clks[IMX8MN_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
+       clks[IMX8MN_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
+       clks[IMX8MN_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
+       clks[IMX8MN_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
+       clks[IMX8MN_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
+       clks[IMX8MN_CLK_ASRC_ROOT] = imx_clk_gate4("asrc_root_clk", "audio_ahb", base + 0x4580, 0);
+       clks[IMX8MN_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
+       clks[IMX8MN_CLK_PDM_IPG]  = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
+       clks[IMX8MN_CLK_DISP_AXI_ROOT]  = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp);
+       clks[IMX8MN_CLK_DISP_APB_ROOT]  = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp);
+       clks[IMX8MN_CLK_CAMERA_PIXEL_ROOT] = imx_clk_gate2_shared2("camera_pixel_clk", "camera_pixel", base + 0x45d0, 0, &share_count_disp);
+       clks[IMX8MN_CLK_DISP_PIXEL_ROOT] = imx_clk_gate2_shared2("disp_pixel_clk", "disp_pixel", base + 0x45d0, 0, &share_count_disp);
+       clks[IMX8MN_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
+       clks[IMX8MN_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
+       clks[IMX8MN_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
+       clks[IMX8MN_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
+       clks[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
+       clks[IMX8MN_CLK_SAI7_ROOT] = imx_clk_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7);
+
+       clks[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
+
+       clks[IMX8MN_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
+                                          clks[IMX8MN_CLK_A53_DIV],
+                                          clks[IMX8MN_CLK_A53_SRC],
+                                          clks[IMX8MN_ARM_PLL_OUT],
+                                          clks[IMX8MN_CLK_24M]);
+
+       imx_check_clocks(clks, ARRAY_SIZE(clks));
+
+       clk_data.clks = clks;
+       clk_data.clk_num = ARRAY_SIZE(clks);
+       ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       if (ret < 0) {
+               dev_err(dev, "failed to register clks for i.MX8MN\n");
+               goto unregister_clks;
+       }
+
+       return 0;
+
+unregister_clks:
+       imx_unregister_clocks(clks, ARRAY_SIZE(clks));
+
+       return ret;
+}
+
+static const struct of_device_id imx8mn_clk_of_match[] = {
+       { .compatible = "fsl,imx8mn-ccm" },
+       { /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, imx8mn_clk_of_match);
+
+static struct platform_driver imx8mn_clk_driver = {
+       .probe = imx8mn_clocks_probe,
+       .driver = {
+               .name = "imx8mn-ccm",
+               .of_match_table = of_match_ptr(imx8mn_clk_of_match),
+       },
+};
+module_platform_driver(imx8mn_clk_driver);
index fb6edf1..c0aff7c 100644 (file)
@@ -72,6 +72,11 @@ static const struct imx8qxp_lpcg_data imx8qxp_lpcg_adma[] = {
        { IMX_ADMA_LPCG_I2C2_CLK, "i2c2_lpcg_clk", "i2c2_clk", 0, ADMA_LPI2C_2_LPCG, 0, 0, },
        { IMX_ADMA_LPCG_I2C3_IPG_CLK, "i2c3_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_LPI2C_3_LPCG, 16, 0, },
        { IMX_ADMA_LPCG_I2C3_CLK, "i2c3_lpcg_clk", "i2c3_clk", 0, ADMA_LPI2C_3_LPCG, 0, 0, },
+
+       { IMX_ADMA_LPCG_DSP_CORE_CLK, "dsp_lpcg_core_clk", "dma_ipg_clk_root", 0, ADMA_HIFI_LPCG, 28, 0, },
+       { IMX_ADMA_LPCG_DSP_IPG_CLK, "dsp_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_HIFI_LPCG, 20, 0, },
+       { IMX_ADMA_LPCG_DSP_ADB_CLK, "dsp_lpcg_adb_clk", "dma_ipg_clk_root", 0, ADMA_HIFI_LPCG, 16, 0, },
+       { IMX_ADMA_LPCG_OCRAM_IPG_CLK, "ocram_lpcg_ipg_clk", "dma_ipg_clk_root", 0, ADMA_OCRAM_LPCG, 16, 0, },
 };
 
 static const struct imx8qxp_ss_lpcg imx8qxp_ss_adma = {
index f628071..cfc05e4 100644 (file)
 
 DEFINE_SPINLOCK(imx_ccm_lock);
 
+void imx_unregister_clocks(struct clk *clks[], unsigned int count)
+{
+       unsigned int i;
+
+       for (i = 0; i < count; i++)
+               clk_unregister(clks[i]);
+}
+
 void __init imx_mmdc_mask_handshake(void __iomem *ccm_base,
                                    unsigned int chn)
 {
index d94d9cb..bb4ec1b 100644 (file)
@@ -12,6 +12,7 @@ void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
 void imx_register_uart_clocks(struct clk ** const clks[]);
 void imx_register_uart_clocks_hws(struct clk_hw ** const hws[]);
 void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn);
+void imx_unregister_clocks(struct clk *clks[], unsigned int count);
 
 extern void imx_cscmr1_fixup(u32 *val);
 
@@ -153,6 +154,23 @@ enum imx_pllv3_type {
 struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
                const char *parent_name, void __iomem *base, u32 div_mask);
 
+#define PLL_1416X_RATE(_rate, _m, _p, _s)              \
+       {                                               \
+               .rate   =       (_rate),                \
+               .mdiv   =       (_m),                   \
+               .pdiv   =       (_p),                   \
+               .sdiv   =       (_s),                   \
+       }
+
+#define PLL_1443X_RATE(_rate, _m, _p, _s, _k)          \
+       {                                               \
+               .rate   =       (_rate),                \
+               .mdiv   =       (_m),                   \
+               .pdiv   =       (_p),                   \
+               .sdiv   =       (_s),                   \
+               .kdiv   =       (_k),                   \
+       }
+
 struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name,
                             void __iomem *base);
 
index a6b20e1..dabeb43 100644 (file)
@@ -1,7 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
-config COMMON_CLK_MESON_INPUT
-       tristate
-
 config COMMON_CLK_MESON_REGMAP
        tristate
        select REGMAP
@@ -33,13 +30,15 @@ config COMMON_CLK_MESON_VID_PLL_DIV
 config COMMON_CLK_MESON_AO_CLKC
        tristate
        select COMMON_CLK_MESON_REGMAP
-       select COMMON_CLK_MESON_INPUT
        select RESET_CONTROLLER
 
 config COMMON_CLK_MESON_EE_CLKC
        tristate
        select COMMON_CLK_MESON_REGMAP
-       select COMMON_CLK_MESON_INPUT
+
+config COMMON_CLK_MESON_CPU_DYNDIV
+       tristate
+       select COMMON_CLK_MESON_REGMAP
 
 config COMMON_CLK_MESON8B
        bool
@@ -86,7 +85,6 @@ config COMMON_CLK_AXG
 config COMMON_CLK_AXG_AUDIO
        tristate "Meson AXG Audio Clock Controller Driver"
        depends on ARCH_MESON
-       select COMMON_CLK_MESON_INPUT
        select COMMON_CLK_MESON_REGMAP
        select COMMON_CLK_MESON_PHASE
        select COMMON_CLK_MESON_SCLK_DIV
@@ -104,6 +102,7 @@ config COMMON_CLK_G12A
        select COMMON_CLK_MESON_PLL
        select COMMON_CLK_MESON_AO_CLKC
        select COMMON_CLK_MESON_EE_CLKC
+       select COMMON_CLK_MESON_CPU_DYNDIV
        select MFD_SYSCON
        help
          Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2
index bc35a4e..3939f21 100644 (file)
@@ -2,9 +2,9 @@
 # Amlogic clock drivers
 
 obj-$(CONFIG_COMMON_CLK_MESON_AO_CLKC) += meson-aoclk.o
+obj-$(CONFIG_COMMON_CLK_MESON_CPU_DYNDIV) += clk-cpu-dyndiv.o
 obj-$(CONFIG_COMMON_CLK_MESON_DUALDIV) += clk-dualdiv.o
 obj-$(CONFIG_COMMON_CLK_MESON_EE_CLKC) += meson-eeclk.o
-obj-$(CONFIG_COMMON_CLK_MESON_INPUT) += clk-input.o
 obj-$(CONFIG_COMMON_CLK_MESON_MPLL) += clk-mpll.o
 obj-$(CONFIG_COMMON_CLK_MESON_PHASE) += clk-phase.o
 obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
index 0086f31..b488b40 100644 (file)
@@ -18,8 +18,6 @@
 #include "clk-regmap.h"
 #include "clk-dualdiv.h"
 
-#define IN_PREFIX "ao-in-"
-
 /*
  * AO Configuration Clock registers offsets
  * Register offsets from the data sheet must be multiplied by 4.
@@ -42,7 +40,9 @@ static struct clk_regmap axg_aoclk_##_name = {                                \
        .hw.init = &(struct clk_init_data) {                            \
                .name =  "axg_ao_" #_name,                              \
                .ops = &clk_regmap_gate_ops,                            \
-               .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \
+               .parent_data = &(const struct clk_parent_data) {        \
+                       .fw_name = "mpeg-clk",                          \
+               },                                                      \
                .num_parents = 1,                                       \
                .flags = CLK_IGNORE_UNUSED,                             \
        },                                                              \
@@ -64,7 +64,9 @@ static struct clk_regmap axg_aoclk_cts_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_oscin",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -77,7 +79,9 @@ static struct clk_regmap axg_aoclk_32k_pre = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_32k_pre",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_oscin" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_aoclk_cts_oscin.hw
+               },
                .num_parents = 1,
        },
 };
@@ -124,7 +128,9 @@ static struct clk_regmap axg_aoclk_32k_div = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_32k_div",
                .ops = &meson_clk_dualdiv_ops,
-               .parent_names = (const char *[]){ "axg_ao_32k_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_aoclk_32k_pre.hw
+               },
                .num_parents = 1,
        },
 };
@@ -139,8 +145,10 @@ static struct clk_regmap axg_aoclk_32k_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_32k_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "axg_ao_32k_div",
-                                                 "axg_ao_32k_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_aoclk_32k_div.hw,
+                       &axg_aoclk_32k_pre.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -154,7 +162,9 @@ static struct clk_regmap axg_aoclk_32k = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_32k",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "axg_ao_32k_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_aoclk_32k_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -170,8 +180,10 @@ static struct clk_regmap axg_aoclk_cts_rtc_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_cts_rtc_oscin",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "axg_ao_32k",
-                                                 IN_PREFIX "ext_32k-0" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .hw = &axg_aoclk_32k.hw },
+                       { .fw_name = "ext_32k-0", },
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -187,8 +199,10 @@ static struct clk_regmap axg_aoclk_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_clk81",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk",
-                                                 "axg_ao_cts_rtc_oscin"},
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "mpeg-clk", },
+                       { .hw = &axg_aoclk_cts_rtc_oscin.hw },
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -203,8 +217,10 @@ static struct clk_regmap axg_aoclk_saradc_mux = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_saradc_mux",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "axg_ao_clk81" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &axg_aoclk_clk81.hw },
+               },
                .num_parents = 2,
        },
 };
@@ -218,7 +234,9 @@ static struct clk_regmap axg_aoclk_saradc_div = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_saradc_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "axg_ao_saradc_mux" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_aoclk_saradc_mux.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -232,7 +250,9 @@ static struct clk_regmap axg_aoclk_saradc_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "axg_ao_saradc_gate",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "axg_ao_saradc_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_aoclk_saradc_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -290,12 +310,6 @@ static const struct clk_hw_onecell_data axg_aoclk_onecell_data = {
        .num = NR_CLKS,
 };
 
-static const struct meson_aoclk_input axg_aoclk_inputs[] = {
-       { .name = "xtal",       .required = true  },
-       { .name = "mpeg-clk",   .required = true  },
-       { .name = "ext-32k-0",  .required = false },
-};
-
 static const struct meson_aoclk_data axg_aoclkc_data = {
        .reset_reg      = AO_RTI_GEN_CNTL_REG0,
        .num_reset      = ARRAY_SIZE(axg_aoclk_reset),
@@ -303,9 +317,6 @@ static const struct meson_aoclk_data axg_aoclkc_data = {
        .num_clks       = ARRAY_SIZE(axg_aoclk_regmap),
        .clks           = axg_aoclk_regmap,
        .hw_data        = &axg_aoclk_onecell_data,
-       .inputs         = axg_aoclk_inputs,
-       .num_inputs     = ARRAY_SIZE(axg_aoclk_inputs),
-       .input_prefix   = IN_PREFIX,
 };
 
 static const struct of_device_id axg_aoclkc_match_table[] = {
index 8028ff6..741df7e 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/slab.h>
 
 #include "axg-audio.h"
-#include "clk-input.h"
 #include "clk-regmap.h"
 #include "clk-phase.h"
 #include "sclk-div.h"
@@ -24,7 +23,7 @@
 #define AUD_SLV_SCLK_COUNT     10
 #define AUD_SLV_LRCLK_COUNT    10
 
-#define AUD_GATE(_name, _reg, _bit, _pname, _iflags)                   \
+#define AUD_GATE(_name, _reg, _bit, _phws, _iflags)                    \
 struct clk_regmap aud_##_name = {                                      \
        .data = &(struct clk_regmap_gate_data){                         \
                .offset = (_reg),                                       \
@@ -33,13 +32,13 @@ struct clk_regmap aud_##_name = {                                   \
        .hw.init = &(struct clk_init_data) {                            \
                .name = "aud_"#_name,                                   \
                .ops = &clk_regmap_gate_ops,                            \
-               .parent_names = (const char *[]){ _pname },             \
+               .parent_hws = (const struct clk_hw *[]) { &_phws.hw },  \
                .num_parents = 1,                                       \
                .flags = CLK_DUTY_CYCLE_PARENT | (_iflags),             \
        },                                                              \
 }
 
-#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pnames, _iflags) \
+#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pdata, _iflags)  \
 struct clk_regmap aud_##_name = {                                      \
        .data = &(struct clk_regmap_mux_data){                          \
                .offset = (_reg),                                       \
@@ -50,13 +49,13 @@ struct clk_regmap aud_##_name = {                                   \
        .hw.init = &(struct clk_init_data){                             \
                .name = "aud_"#_name,                                   \
                .ops = &clk_regmap_mux_ops,                             \
-               .parent_names = (_pnames),                              \
-               .num_parents = ARRAY_SIZE(_pnames),                     \
+               .parent_data = _pdata,                                  \
+               .num_parents = ARRAY_SIZE(_pdata),                      \
                .flags = CLK_DUTY_CYCLE_PARENT | (_iflags),             \
        },                                                              \
 }
 
-#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) \
+#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _phws, _iflags)  \
 struct clk_regmap aud_##_name = {                                      \
        .data = &(struct clk_regmap_div_data){                          \
                .offset = (_reg),                                       \
@@ -67,15 +66,27 @@ struct clk_regmap aud_##_name = {                                   \
        .hw.init = &(struct clk_init_data){                             \
                .name = "aud_"#_name,                                   \
                .ops = &clk_regmap_divider_ops,                         \
-               .parent_names = (const char *[]) { _pname },            \
+               .parent_hws = (const struct clk_hw *[]) { &_phws.hw },  \
                .num_parents = 1,                                       \
                .flags = (_iflags),                                     \
        },                                                              \
 }
 
 #define AUD_PCLK_GATE(_name, _bit)                             \
-       AUD_GATE(_name, AUDIO_CLK_GATE_EN, _bit, "audio_pclk", 0)
-
+struct clk_regmap aud_##_name = {                                      \
+       .data = &(struct clk_regmap_gate_data){                         \
+               .offset = (AUDIO_CLK_GATE_EN),                          \
+               .bit_idx = (_bit),                                      \
+       },                                                              \
+       .hw.init = &(struct clk_init_data) {                            \
+               .name = "aud_"#_name,                                   \
+               .ops = &clk_regmap_gate_ops,                            \
+               .parent_data = &(const struct clk_parent_data) {        \
+                       .fw_name = "pclk",                              \
+               },                                                      \
+               .num_parents = 1,                                       \
+       },                                                              \
+}
 /* Audio peripheral clocks */
 static AUD_PCLK_GATE(ddr_arb,     0);
 static AUD_PCLK_GATE(pdm,         1);
@@ -100,14 +111,20 @@ static AUD_PCLK_GATE(power_detect, 19);
 static AUD_PCLK_GATE(spdifout_b,   21);
 
 /* Audio Master Clocks */
-static const char * const mst_mux_parent_names[] = {
-       "aud_mst_in0", "aud_mst_in1", "aud_mst_in2", "aud_mst_in3",
-       "aud_mst_in4", "aud_mst_in5", "aud_mst_in6", "aud_mst_in7",
+static const struct clk_parent_data mst_mux_parent_data[] = {
+       { .fw_name = "mst_in0", },
+       { .fw_name = "mst_in1", },
+       { .fw_name = "mst_in2", },
+       { .fw_name = "mst_in3", },
+       { .fw_name = "mst_in4", },
+       { .fw_name = "mst_in5", },
+       { .fw_name = "mst_in6", },
+       { .fw_name = "mst_in7", },
 };
 
 #define AUD_MST_MUX(_name, _reg, _flag)                                \
        AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag,              \
-               mst_mux_parent_names, CLK_SET_RATE_PARENT)
+               mst_mux_parent_data, 0)
 
 #define AUD_MST_MCLK_MUX(_name, _reg)                          \
        AUD_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST)
@@ -129,7 +146,7 @@ static AUD_MST_MCLK_MUX(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL);
 
 #define AUD_MST_DIV(_name, _reg, _flag)                                \
        AUD_DIV(_name##_div, _reg, 0, 16, _flag,                \
-                   "aud_"#_name"_sel", CLK_SET_RATE_PARENT)    \
+                   aud_##_name##_sel, CLK_SET_RATE_PARENT)     \
 
 #define AUD_MST_MCLK_DIV(_name, _reg)                          \
        AUD_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST)
@@ -150,7 +167,7 @@ static AUD_MST_SYS_DIV(pdm_sysclk,    AUDIO_CLK_PDMIN_CTRL1);
 static AUD_MST_MCLK_DIV(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL);
 
 #define AUD_MST_MCLK_GATE(_name, _reg)                         \
-       AUD_GATE(_name, _reg, 31,  "aud_"#_name"_div",  \
+       AUD_GATE(_name, _reg, 31,  aud_##_name##_div,           \
                 CLK_SET_RATE_PARENT)
 
 static AUD_MST_MCLK_GATE(mst_a_mclk,   AUDIO_MCLK_A_CTRL);
@@ -168,7 +185,7 @@ static AUD_MST_MCLK_GATE(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL);
 /* Sample Clocks */
 #define AUD_MST_SCLK_PRE_EN(_name, _reg)                       \
        AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31,           \
-                "aud_mst_"#_name"_mclk", 0)
+                aud_mst_##_name##_mclk, 0)
 
 static AUD_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0);
 static AUD_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0);
@@ -178,7 +195,7 @@ static AUD_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0);
 static AUD_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0);
 
 #define AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width,              \
-                        _hi_shift, _hi_width, _pname, _iflags)         \
+                        _hi_shift, _hi_width, _phws, _iflags)          \
 struct clk_regmap aud_##_name = {                                      \
        .data = &(struct meson_sclk_div_data) {                         \
                .div = {                                                \
@@ -195,7 +212,7 @@ struct clk_regmap aud_##_name = {                                   \
        .hw.init = &(struct clk_init_data) {                            \
                .name = "aud_"#_name,                                   \
                .ops = &meson_sclk_div_ops,                             \
-               .parent_names = (const char *[]) { _pname },            \
+               .parent_hws = (const struct clk_hw *[]) { &_phws.hw },  \
                .num_parents = 1,                                       \
                .flags = (_iflags),                                     \
        },                                                              \
@@ -203,7 +220,7 @@ struct clk_regmap aud_##_name = {                                   \
 
 #define AUD_MST_SCLK_DIV(_name, _reg)                                  \
        AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0,        \
-                    "aud_mst_"#_name"_sclk_pre_en",                    \
+                    aud_mst_##_name##_sclk_pre_en,                     \
                     CLK_SET_RATE_PARENT)
 
 static AUD_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0);
@@ -214,8 +231,8 @@ static AUD_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0);
 static AUD_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0);
 
 #define AUD_MST_SCLK_POST_EN(_name, _reg)                              \
-       AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30,          \
-                "aud_mst_"#_name"_sclk_div", CLK_SET_RATE_PARENT)
+       AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30,                  \
+                aud_mst_##_name##_sclk_div, CLK_SET_RATE_PARENT)
 
 static AUD_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0);
 static AUD_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0);
@@ -224,8 +241,8 @@ static AUD_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0);
 static AUD_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0);
 static AUD_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0);
 
-#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \
-                        _pname, _iflags)                               \
+#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2,   \
+                        _phws, _iflags)                                \
 struct clk_regmap aud_##_name = {                                      \
        .data = &(struct meson_clk_triphase_data) {                     \
                .ph0 = {                                                \
@@ -247,7 +264,7 @@ struct clk_regmap aud_##_name = {                                   \
        .hw.init = &(struct clk_init_data) {                            \
                .name = "aud_"#_name,                                   \
                .ops = &meson_clk_triphase_ops,                         \
-               .parent_names = (const char *[]) { _pname },            \
+               .parent_hws = (const struct clk_hw *[]) { &_phws.hw },  \
                .num_parents = 1,                                       \
                .flags = CLK_DUTY_CYCLE_PARENT | (_iflags),             \
        },                                                              \
@@ -255,7 +272,7 @@ struct clk_regmap aud_##_name = {                                   \
 
 #define AUD_MST_SCLK(_name, _reg)                                      \
        AUD_TRIPHASE(mst_##_name##_sclk, _reg, 1, 0, 2, 4,              \
-                    "aud_mst_"#_name"_sclk_post_en", CLK_SET_RATE_PARENT)
+                    aud_mst_##_name##_sclk_post_en, CLK_SET_RATE_PARENT)
 
 static AUD_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1);
 static AUD_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1);
@@ -266,7 +283,7 @@ static AUD_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1);
 
 #define AUD_MST_LRCLK_DIV(_name, _reg)                                 \
        AUD_SCLK_DIV(mst_##_name##_lrclk_div, _reg, 0, 10, 10, 10,      \
-                    "aud_mst_"#_name"_sclk_post_en", 0)                \
+                    aud_mst_##_name##_sclk_post_en, 0)                 \
 
 static AUD_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0);
 static AUD_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0);
@@ -277,7 +294,7 @@ static AUD_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0);
 
 #define AUD_MST_LRCLK(_name, _reg)                                     \
        AUD_TRIPHASE(mst_##_name##_lrclk, _reg, 1, 1, 3, 5,             \
-                    "aud_mst_"#_name"_lrclk_div", CLK_SET_RATE_PARENT)
+                    aud_mst_##_name##_lrclk_div, CLK_SET_RATE_PARENT)
 
 static AUD_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1);
 static AUD_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1);
@@ -286,19 +303,29 @@ static AUD_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1);
 static AUD_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1);
 static AUD_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1);
 
-static const char * const tdm_sclk_parent_names[] = {
-       "aud_mst_a_sclk", "aud_mst_b_sclk", "aud_mst_c_sclk",
-       "aud_mst_d_sclk", "aud_mst_e_sclk", "aud_mst_f_sclk",
-       "aud_slv_sclk0", "aud_slv_sclk1", "aud_slv_sclk2",
-       "aud_slv_sclk3", "aud_slv_sclk4", "aud_slv_sclk5",
-       "aud_slv_sclk6", "aud_slv_sclk7", "aud_slv_sclk8",
-       "aud_slv_sclk9"
+static const struct clk_parent_data tdm_sclk_parent_data[] = {
+       { .hw = &aud_mst_a_sclk.hw, },
+       { .hw = &aud_mst_b_sclk.hw, },
+       { .hw = &aud_mst_c_sclk.hw, },
+       { .hw = &aud_mst_d_sclk.hw, },
+       { .hw = &aud_mst_e_sclk.hw, },
+       { .hw = &aud_mst_f_sclk.hw, },
+       { .fw_name = "slv_sclk0", },
+       { .fw_name = "slv_sclk1", },
+       { .fw_name = "slv_sclk2", },
+       { .fw_name = "slv_sclk3", },
+       { .fw_name = "slv_sclk4", },
+       { .fw_name = "slv_sclk5", },
+       { .fw_name = "slv_sclk6", },
+       { .fw_name = "slv_sclk7", },
+       { .fw_name = "slv_sclk8", },
+       { .fw_name = "slv_sclk9", },
 };
 
 #define AUD_TDM_SCLK_MUX(_name, _reg)                          \
        AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24,           \
                    CLK_MUX_ROUND_CLOSEST,                      \
-                   tdm_sclk_parent_names, 0)
+                   tdm_sclk_parent_data, 0)
 
 static AUD_TDM_SCLK_MUX(in_a,  AUDIO_CLK_TDMIN_A_CTRL);
 static AUD_TDM_SCLK_MUX(in_b,  AUDIO_CLK_TDMIN_B_CTRL);
@@ -310,7 +337,7 @@ static AUD_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
 
 #define AUD_TDM_SCLK_PRE_EN(_name, _reg)                               \
        AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31,                    \
-                "aud_tdm"#_name"_sclk_sel", CLK_SET_RATE_PARENT)
+                aud_tdm##_name##_sclk_sel, CLK_SET_RATE_PARENT)
 
 static AUD_TDM_SCLK_PRE_EN(in_a,  AUDIO_CLK_TDMIN_A_CTRL);
 static AUD_TDM_SCLK_PRE_EN(in_b,  AUDIO_CLK_TDMIN_B_CTRL);
@@ -322,7 +349,7 @@ static AUD_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
 
 #define AUD_TDM_SCLK_POST_EN(_name, _reg)                              \
        AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30,                   \
-                "aud_tdm"#_name"_sclk_pre_en", CLK_SET_RATE_PARENT)
+                aud_tdm##_name##_sclk_pre_en, CLK_SET_RATE_PARENT)
 
 static AUD_TDM_SCLK_POST_EN(in_a,  AUDIO_CLK_TDMIN_A_CTRL);
 static AUD_TDM_SCLK_POST_EN(in_b,  AUDIO_CLK_TDMIN_B_CTRL);
@@ -344,8 +371,9 @@ static AUD_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
        .hw.init = &(struct clk_init_data) {                            \
                .name = "aud_tdm"#_name"_sclk",                         \
                .ops = &meson_clk_phase_ops,                            \
-               .parent_names = (const char *[])                        \
-               { "aud_tdm"#_name"_sclk_post_en" },                     \
+               .parent_hws = (const struct clk_hw *[]) {               \
+                       &aud_tdm##_name##_sclk_post_en.hw               \
+               },                                                      \
                .num_parents = 1,                                       \
                .flags = CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT,   \
        },                                                              \
@@ -359,19 +387,29 @@ static AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
 static AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
 static AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
 
-static const char * const tdm_lrclk_parent_names[] = {
-       "aud_mst_a_lrclk", "aud_mst_b_lrclk", "aud_mst_c_lrclk",
-       "aud_mst_d_lrclk", "aud_mst_e_lrclk", "aud_mst_f_lrclk",
-       "aud_slv_lrclk0", "aud_slv_lrclk1", "aud_slv_lrclk2",
-       "aud_slv_lrclk3", "aud_slv_lrclk4", "aud_slv_lrclk5",
-       "aud_slv_lrclk6", "aud_slv_lrclk7", "aud_slv_lrclk8",
-       "aud_slv_lrclk9"
+static const struct clk_parent_data tdm_lrclk_parent_data[] = {
+       { .hw = &aud_mst_a_lrclk.hw, },
+       { .hw = &aud_mst_b_lrclk.hw, },
+       { .hw = &aud_mst_c_lrclk.hw, },
+       { .hw = &aud_mst_d_lrclk.hw, },
+       { .hw = &aud_mst_e_lrclk.hw, },
+       { .hw = &aud_mst_f_lrclk.hw, },
+       { .fw_name = "slv_lrclk0", },
+       { .fw_name = "slv_lrclk1", },
+       { .fw_name = "slv_lrclk2", },
+       { .fw_name = "slv_lrclk3", },
+       { .fw_name = "slv_lrclk4", },
+       { .fw_name = "slv_lrclk5", },
+       { .fw_name = "slv_lrclk6", },
+       { .fw_name = "slv_lrclk7", },
+       { .fw_name = "slv_lrclk8", },
+       { .fw_name = "slv_lrclk9", },
 };
 
-#define AUD_TDM_LRLCK(_name, _reg)                    \
-       AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20,     \
-               CLK_MUX_ROUND_CLOSEST,                 \
-               tdm_lrclk_parent_names, 0)
+#define AUD_TDM_LRLCK(_name, _reg)                     \
+       AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20,      \
+               CLK_MUX_ROUND_CLOSEST,                  \
+               tdm_lrclk_parent_data, 0)
 
 static AUD_TDM_LRLCK(in_a,  AUDIO_CLK_TDMIN_A_CTRL);
 static AUD_TDM_LRLCK(in_b,  AUDIO_CLK_TDMIN_B_CTRL);
@@ -386,39 +424,51 @@ static AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
        AUD_MUX(tdm_##_name, _reg, 0x7, _shift, 0, _parents,    \
                CLK_SET_RATE_NO_REPARENT)
 
-static const char * const mclk_pad_ctrl_parent_names[] = {
-       "aud_mst_a_mclk", "aud_mst_b_mclk", "aud_mst_c_mclk",
-       "aud_mst_d_mclk", "aud_mst_e_mclk", "aud_mst_f_mclk",
+static const struct clk_parent_data mclk_pad_ctrl_parent_data[] = {
+       { .hw = &aud_mst_a_mclk.hw },
+       { .hw = &aud_mst_b_mclk.hw },
+       { .hw = &aud_mst_c_mclk.hw },
+       { .hw = &aud_mst_d_mclk.hw },
+       { .hw = &aud_mst_e_mclk.hw },
+       { .hw = &aud_mst_f_mclk.hw },
 };
 
 static AUD_TDM_PAD_CTRL(mclk_pad_0, AUDIO_MST_PAD_CTRL0, 0,
-                       mclk_pad_ctrl_parent_names);
+                       mclk_pad_ctrl_parent_data);
 static AUD_TDM_PAD_CTRL(mclk_pad_1, AUDIO_MST_PAD_CTRL0, 4,
-                       mclk_pad_ctrl_parent_names);
-
-static const char * const lrclk_pad_ctrl_parent_names[] = {
-       "aud_mst_a_lrclk", "aud_mst_b_lrclk", "aud_mst_c_lrclk",
-       "aud_mst_d_lrclk", "aud_mst_e_lrclk", "aud_mst_f_lrclk",
+                       mclk_pad_ctrl_parent_data);
+
+static const struct clk_parent_data lrclk_pad_ctrl_parent_data[] = {
+       { .hw = &aud_mst_a_lrclk.hw },
+       { .hw = &aud_mst_b_lrclk.hw },
+       { .hw = &aud_mst_c_lrclk.hw },
+       { .hw = &aud_mst_d_lrclk.hw },
+       { .hw = &aud_mst_e_lrclk.hw },
+       { .hw = &aud_mst_f_lrclk.hw },
 };
 
 static AUD_TDM_PAD_CTRL(lrclk_pad_0, AUDIO_MST_PAD_CTRL1, 16,
-                       lrclk_pad_ctrl_parent_names);
+                       lrclk_pad_ctrl_parent_data);
 static AUD_TDM_PAD_CTRL(lrclk_pad_1, AUDIO_MST_PAD_CTRL1, 20,
-                       lrclk_pad_ctrl_parent_names);
+                       lrclk_pad_ctrl_parent_data);
 static AUD_TDM_PAD_CTRL(lrclk_pad_2, AUDIO_MST_PAD_CTRL1, 24,
-                       lrclk_pad_ctrl_parent_names);
-
-static const char * const sclk_pad_ctrl_parent_names[] = {
-       "aud_mst_a_sclk", "aud_mst_b_sclk", "aud_mst_c_sclk",
-       "aud_mst_d_sclk", "aud_mst_e_sclk", "aud_mst_f_sclk",
+                       lrclk_pad_ctrl_parent_data);
+
+static const struct clk_parent_data sclk_pad_ctrl_parent_data[] = {
+       { .hw = &aud_mst_a_sclk.hw },
+       { .hw = &aud_mst_b_sclk.hw },
+       { .hw = &aud_mst_c_sclk.hw },
+       { .hw = &aud_mst_d_sclk.hw },
+       { .hw = &aud_mst_e_sclk.hw },
+       { .hw = &aud_mst_f_sclk.hw },
 };
 
 static AUD_TDM_PAD_CTRL(sclk_pad_0, AUDIO_MST_PAD_CTRL1, 0,
-                       sclk_pad_ctrl_parent_names);
+                       sclk_pad_ctrl_parent_data);
 static AUD_TDM_PAD_CTRL(sclk_pad_1, AUDIO_MST_PAD_CTRL1, 4,
-                       sclk_pad_ctrl_parent_names);
+                       sclk_pad_ctrl_parent_data);
 static AUD_TDM_PAD_CTRL(sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8,
-                       sclk_pad_ctrl_parent_names);
+                       sclk_pad_ctrl_parent_data);
 
 /*
  * Array of all clocks provided by this provider
@@ -868,54 +918,6 @@ static int devm_clk_get_enable(struct device *dev, char *id)
        return 0;
 }
 
-static int axg_register_clk_hw_input(struct device *dev,
-                                    const char *name)
-{
-       char *clk_name;
-       struct clk_hw *hw;
-       int err = 0;
-
-       clk_name = kasprintf(GFP_KERNEL, "aud_%s", name);
-       if (!clk_name)
-               return -ENOMEM;
-
-       hw = meson_clk_hw_register_input(dev, name, clk_name, 0);
-       if (IS_ERR(hw)) {
-               /* It is ok if an input clock is missing */
-               if (PTR_ERR(hw) == -ENOENT) {
-                       dev_dbg(dev, "%s not provided", name);
-               } else {
-                       err = PTR_ERR(hw);
-                       if (err != -EPROBE_DEFER)
-                               dev_err(dev, "failed to get %s clock", name);
-               }
-       }
-
-       kfree(clk_name);
-       return err;
-}
-
-static int axg_register_clk_hw_inputs(struct device *dev,
-                                     const char *basename,
-                                     unsigned int count)
-{
-       char *name;
-       int i, ret;
-
-       for (i = 0; i < count; i++) {
-               name = kasprintf(GFP_KERNEL, "%s%d", basename, i);
-               if (!name)
-                       return -ENOMEM;
-
-               ret = axg_register_clk_hw_input(dev, name);
-               kfree(name);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-
 static const struct regmap_config axg_audio_regmap_cfg = {
        .reg_bits       = 32,
        .val_bits       = 32,
@@ -963,29 +965,6 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
                return ret;
        }
 
-       /* Register the peripheral input clock */
-       hw = meson_clk_hw_register_input(dev, "pclk", "audio_pclk", 0);
-       if (IS_ERR(hw))
-               return PTR_ERR(hw);
-
-       /* Register optional input master clocks */
-       ret = axg_register_clk_hw_inputs(dev, "mst_in",
-                                        AUD_MST_IN_COUNT);
-       if (ret)
-               return ret;
-
-       /* Register optional input slave sclks */
-       ret = axg_register_clk_hw_inputs(dev, "slv_sclk",
-                                        AUD_SLV_SCLK_COUNT);
-       if (ret)
-               return ret;
-
-       /* Register optional input slave lrclks */
-       ret = axg_register_clk_hw_inputs(dev, "slv_lrclk",
-                                        AUD_SLV_LRCLK_COUNT);
-       if (ret)
-               return ret;
-
        /* Populate regmap for the regmap backed clocks */
        for (i = 0; i < ARRAY_SIZE(aud_clk_regmaps); i++)
                aud_clk_regmaps[i]->map = map;
index 3ddd0ef..13fc000 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 
-#include "clk-input.h"
 #include "clk-regmap.h"
 #include "clk-pll.h"
 #include "clk-mpll.h"
@@ -59,7 +58,9 @@ static struct clk_regmap axg_fixed_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -74,7 +75,9 @@ static struct clk_regmap axg_fixed_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fixed_pll_dco.hw
+               },
                .num_parents = 1,
                /*
                 * This clock won't ever change at runtime so
@@ -114,7 +117,9 @@ static struct clk_regmap axg_sys_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -129,7 +134,9 @@ static struct clk_regmap axg_sys_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "sys_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_sys_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -215,7 +222,9 @@ static struct clk_regmap axg_gp0_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "gp0_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -230,7 +239,9 @@ static struct clk_regmap axg_gp0_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "gp0_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "gp0_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_gp0_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -284,7 +295,9 @@ static struct clk_regmap axg_hifi_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "hifi_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -299,7 +312,9 @@ static struct clk_regmap axg_hifi_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "hifi_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "hifi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_hifi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -311,7 +326,7 @@ static struct clk_fixed_factor axg_fclk_div2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -324,7 +339,9 @@ static struct clk_regmap axg_fclk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fclk_div2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_IS_CRITICAL,
        },
@@ -336,7 +353,7 @@ static struct clk_fixed_factor axg_fclk_div3_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div3_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -349,7 +366,9 @@ static struct clk_regmap axg_fclk_div3 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div3",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div3_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fclk_div3_div.hw
+               },
                .num_parents = 1,
                /*
                 * FIXME:
@@ -372,7 +391,7 @@ static struct clk_fixed_factor axg_fclk_div4_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -385,7 +404,9 @@ static struct clk_regmap axg_fclk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div4_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fclk_div4_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -396,7 +417,7 @@ static struct clk_fixed_factor axg_fclk_div5_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -409,7 +430,9 @@ static struct clk_regmap axg_fclk_div5 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div5_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fclk_div5_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -420,7 +443,9 @@ static struct clk_fixed_factor axg_fclk_div7_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -433,7 +458,9 @@ static struct clk_regmap axg_fclk_div7 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div7_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fclk_div7_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -447,7 +474,9 @@ static struct clk_regmap axg_mpll_prediv = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll_prediv",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -480,7 +509,9 @@ static struct clk_regmap axg_mpll0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -493,7 +524,9 @@ static struct clk_regmap axg_mpll0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -527,7 +560,9 @@ static struct clk_regmap axg_mpll1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -540,7 +575,9 @@ static struct clk_regmap axg_mpll1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -579,7 +616,9 @@ static struct clk_regmap axg_mpll2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -592,7 +631,9 @@ static struct clk_regmap axg_mpll2 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -626,7 +667,9 @@ static struct clk_regmap axg_mpll3_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll3_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -639,7 +682,9 @@ static struct clk_regmap axg_mpll3 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll3",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll3_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpll3_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -702,7 +747,9 @@ static struct clk_regmap axg_pcie_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -717,7 +764,9 @@ static struct clk_regmap axg_pcie_pll_od = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll_od",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "pcie_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_pcie_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -733,7 +782,9 @@ static struct clk_regmap axg_pcie_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "pcie_pll_od" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_pcie_pll_od.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -750,7 +801,7 @@ static struct clk_regmap axg_pcie_mux = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_mux",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "pcie_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_pcie_pll.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -767,7 +818,7 @@ static struct clk_regmap axg_pcie_ref = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_ref",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "pcie_mux" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_pcie_mux.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -781,7 +832,7 @@ static struct clk_regmap axg_pcie_cml_en0 = {
        .hw.init = &(struct clk_init_data) {
                .name = "pcie_cml_en0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "pcie_ref" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_pcie_ref.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
 
@@ -796,16 +847,21 @@ static struct clk_regmap axg_pcie_cml_en1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "pcie_cml_en1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "pcie_ref" },
+               .parent_hws = (const struct clk_hw *[]) { &axg_pcie_ref.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
 static u32 mux_table_clk81[]   = { 0, 2, 3, 4, 5, 6, 7 };
-static const char * const clk81_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
-       "fclk_div3", "fclk_div5"
+static const struct clk_parent_data clk81_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &axg_fclk_div7.hw },
+       { .hw = &axg_mpll1.hw },
+       { .hw = &axg_mpll2.hw },
+       { .hw = &axg_fclk_div4.hw },
+       { .hw = &axg_fclk_div3.hw },
+       { .hw = &axg_fclk_div5.hw },
 };
 
 static struct clk_regmap axg_mpeg_clk_sel = {
@@ -818,8 +874,8 @@ static struct clk_regmap axg_mpeg_clk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mpeg_clk_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = clk81_parent_names,
-               .num_parents = ARRAY_SIZE(clk81_parent_names),
+               .parent_data = clk81_parent_data,
+               .num_parents = ARRAY_SIZE(clk81_parent_data),
        },
 };
 
@@ -832,7 +888,9 @@ static struct clk_regmap axg_mpeg_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpeg_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpeg_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -846,15 +904,20 @@ static struct clk_regmap axg_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "clk81",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_mpeg_clk_div.hw
+               },
                .num_parents = 1,
                .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
        },
 };
 
-static const char * const axg_sd_emmc_clk0_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
-
+static const struct clk_parent_data axg_sd_emmc_clk0_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &axg_fclk_div2.hw },
+       { .hw = &axg_fclk_div3.hw },
+       { .hw = &axg_fclk_div5.hw },
+       { .hw = &axg_fclk_div7.hw },
        /*
         * Following these parent clocks, we should also have had mpll2, mpll3
         * and gp0_pll but these clocks are too precious to be used here. All
@@ -873,8 +936,8 @@ static struct clk_regmap axg_sd_emmc_b_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_b_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = axg_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
+               .parent_data = axg_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -889,7 +952,9 @@ static struct clk_regmap axg_sd_emmc_b_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_b_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_sd_emmc_b_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -903,7 +968,9 @@ static struct clk_regmap axg_sd_emmc_b_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_b_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_sd_emmc_b_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -919,8 +986,8 @@ static struct clk_regmap axg_sd_emmc_c_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_c_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = axg_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
+               .parent_data = axg_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -935,7 +1002,9 @@ static struct clk_regmap axg_sd_emmc_c_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_c_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_sd_emmc_c_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -949,7 +1018,9 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_c_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_sd_emmc_c_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -957,9 +1028,18 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
 
 static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8,
                                    9, 10, 11, 13, 14, };
-static const char * const gen_clk_parent_names[] = {
-       IN_PREFIX "xtal", "hifi_pll", "mpll0", "mpll1", "mpll2", "mpll3",
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll",
+static const struct clk_parent_data gen_clk_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &axg_hifi_pll.hw },
+       { .hw = &axg_mpll0.hw },
+       { .hw = &axg_mpll1.hw },
+       { .hw = &axg_mpll2.hw },
+       { .hw = &axg_mpll3.hw },
+       { .hw = &axg_fclk_div4.hw },
+       { .hw = &axg_fclk_div3.hw },
+       { .hw = &axg_fclk_div5.hw },
+       { .hw = &axg_fclk_div7.hw },
+       { .hw = &axg_gp0_pll.hw },
 };
 
 static struct clk_regmap axg_gen_clk_sel = {
@@ -978,8 +1058,8 @@ static struct clk_regmap axg_gen_clk_sel = {
                 * hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4,
                 * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll
                 */
-               .parent_names = gen_clk_parent_names,
-               .num_parents = ARRAY_SIZE(gen_clk_parent_names),
+               .parent_data = gen_clk_parent_data,
+               .num_parents = ARRAY_SIZE(gen_clk_parent_data),
        },
 };
 
@@ -992,7 +1072,9 @@ static struct clk_regmap axg_gen_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "gen_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "gen_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_gen_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1006,12 +1088,17 @@ static struct clk_regmap axg_gen_clk = {
        .hw.init = &(struct clk_init_data){
                .name = "gen_clk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "gen_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &axg_gen_clk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
+#define MESON_GATE(_name, _reg, _bit) \
+       MESON_PCLK(_name, _reg, _bit, &axg_clk81.hw)
+
 /* Everything Else (EE) domain gates */
 static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0);
 static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2);
diff --git a/drivers/clk/meson/clk-cpu-dyndiv.c b/drivers/clk/meson/clk-cpu-dyndiv.c
new file mode 100644 (file)
index 0000000..3697692
--- /dev/null
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+
+#include "clk-regmap.h"
+#include "clk-cpu-dyndiv.h"
+
+static inline struct meson_clk_cpu_dyndiv_data *
+meson_clk_cpu_dyndiv_data(struct clk_regmap *clk)
+{
+       return (struct meson_clk_cpu_dyndiv_data *)clk->data;
+}
+
+static unsigned long meson_clk_cpu_dyndiv_recalc_rate(struct clk_hw *hw,
+                                                     unsigned long prate)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk);
+
+       return divider_recalc_rate(hw, prate,
+                                  meson_parm_read(clk->map, &data->div),
+                                  NULL, 0, data->div.width);
+}
+
+static long meson_clk_cpu_dyndiv_round_rate(struct clk_hw *hw,
+                                           unsigned long rate,
+                                           unsigned long *prate)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk);
+
+       return divider_round_rate(hw, rate, prate, NULL, data->div.width, 0);
+}
+
+static int meson_clk_cpu_dyndiv_set_rate(struct clk_hw *hw, unsigned long rate,
+                                         unsigned long parent_rate)
+{
+       struct clk_regmap *clk = to_clk_regmap(hw);
+       struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk);
+       unsigned int val;
+       int ret;
+
+       ret = divider_get_val(rate, parent_rate, NULL, data->div.width, 0);
+       if (ret < 0)
+               return ret;
+
+       val = (unsigned int)ret << data->div.shift;
+
+       /* Write the SYS_CPU_DYN_ENABLE bit before changing the divider */
+       meson_parm_write(clk->map, &data->dyn, 1);
+
+       /* Update the divider while removing the SYS_CPU_DYN_ENABLE bit */
+       return regmap_update_bits(clk->map, data->div.reg_off,
+                                 SETPMASK(data->div.width, data->div.shift) |
+                                 SETPMASK(data->dyn.width, data->dyn.shift),
+                                 val);
+};
+
+const struct clk_ops meson_clk_cpu_dyndiv_ops = {
+       .recalc_rate = meson_clk_cpu_dyndiv_recalc_rate,
+       .round_rate = meson_clk_cpu_dyndiv_round_rate,
+       .set_rate = meson_clk_cpu_dyndiv_set_rate,
+};
+EXPORT_SYMBOL_GPL(meson_clk_cpu_dyndiv_ops);
+
+MODULE_DESCRIPTION("Amlogic CPU Dynamic Clock divider");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-cpu-dyndiv.h b/drivers/clk/meson/clk-cpu-dyndiv.h
new file mode 100644 (file)
index 0000000..f490840
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#ifndef __MESON_CLK_CPU_DYNDIV_H
+#define __MESON_CLK_CPU_DYNDIV_H
+
+#include <linux/clk-provider.h>
+#include "parm.h"
+
+struct meson_clk_cpu_dyndiv_data {
+       struct parm div;
+       struct parm dyn;
+};
+
+extern const struct clk_ops meson_clk_cpu_dyndiv_ops;
+
+#endif /* __MESON_CLK_CPU_DYNDIV_H */
diff --git a/drivers/clk/meson/clk-input.c b/drivers/clk/meson/clk-input.c
deleted file mode 100644 (file)
index 086226e..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (c) 2018 BayLibre, SAS.
- * Author: Jerome Brunet <jbrunet@baylibre.com>
- */
-
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include "clk-input.h"
-
-static const struct clk_ops meson_clk_no_ops = {};
-
-struct clk_hw *meson_clk_hw_register_input(struct device *dev,
-                                          const char *of_name,
-                                          const char *clk_name,
-                                          unsigned long flags)
-{
-       struct clk *parent_clk = devm_clk_get(dev, of_name);
-       struct clk_init_data init;
-       const char *parent_name;
-       struct clk_hw *hw;
-       int ret;
-
-       if (IS_ERR(parent_clk))
-               return (struct clk_hw *)parent_clk;
-
-       hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
-       if (!hw)
-               return ERR_PTR(-ENOMEM);
-
-       parent_name = __clk_get_name(parent_clk);
-       init.name = clk_name;
-       init.ops = &meson_clk_no_ops;
-       init.flags = flags;
-       init.parent_names = &parent_name;
-       init.num_parents = 1;
-       hw->init = &init;
-
-       ret = devm_clk_hw_register(dev, hw);
-
-       return ret ? ERR_PTR(ret) : hw;
-}
-EXPORT_SYMBOL_GPL(meson_clk_hw_register_input);
-
-MODULE_DESCRIPTION("Amlogic clock input helper");
-MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-input.h b/drivers/clk/meson/clk-input.h
deleted file mode 100644 (file)
index 4a541b9..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2019 BayLibre, SAS.
- * Author: Jerome Brunet <jbrunet@baylibre.com>
- */
-
-#ifndef __MESON_CLK_INPUT_H
-#define __MESON_CLK_INPUT_H
-
-#include <linux/clk-provider.h>
-
-struct device;
-
-struct clk_hw *meson_clk_hw_register_input(struct device *dev,
-                                          const char *of_name,
-                                          const char *clk_name,
-                                          unsigned long flags);
-
-#endif /* __MESON_CLK_INPUT_H */
index 1dd0abe..c4a3960 100644 (file)
@@ -111,7 +111,7 @@ clk_get_regmap_mux_data(struct clk_regmap *clk)
 extern const struct clk_ops clk_regmap_mux_ops;
 extern const struct clk_ops clk_regmap_mux_ro_ops;
 
-#define __MESON_GATE(_name, _reg, _bit, _ops)                          \
+#define __MESON_PCLK(_name, _reg, _bit, _ops, _pname)                  \
 struct clk_regmap _name = {                                            \
        .data = &(struct clk_regmap_gate_data){                         \
                .offset = (_reg),                                       \
@@ -120,15 +120,15 @@ struct clk_regmap _name = {                                               \
        .hw.init = &(struct clk_init_data) {                            \
                .name = #_name,                                         \
                .ops = _ops,                                            \
-               .parent_names = (const char *[]){ "clk81" },            \
+               .parent_hws = (const struct clk_hw *[]) { _pname },     \
                .num_parents = 1,                                       \
                .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED),     \
        },                                                              \
 }
 
-#define MESON_GATE(_name, _reg, _bit)  \
-       __MESON_GATE(_name, _reg, _bit, &clk_regmap_gate_ops)
+#define MESON_PCLK(_name, _reg, _bit, _pname)  \
+       __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pname)
 
-#define MESON_GATE_RO(_name, _reg, _bit)       \
-       __MESON_GATE(_name, _reg, _bit, &clk_regmap_gate_ro_ops)
+#define MESON_PCLK_RO(_name, _reg, _bit, _pname)       \
+       __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname)
 #endif /* __CLK_REGMAP_H */
index 1994e73..6249956 100644 (file)
@@ -18,8 +18,6 @@
 #include "clk-regmap.h"
 #include "clk-dualdiv.h"
 
-#define IN_PREFIX "ao-in-"
-
 /*
  * AO Configuration Clock registers offsets
  * Register offsets from the data sheet must be multiplied by 4.
@@ -51,7 +49,9 @@ static struct clk_regmap g12a_aoclk_##_name = {                               \
        .hw.init = &(struct clk_init_data) {                            \
                .name =  "g12a_ao_" #_name,                             \
                .ops = &clk_regmap_gate_ops,                            \
-               .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \
+               .parent_data = &(const struct clk_parent_data) {        \
+                       .fw_name = "mpeg-clk",                          \
+               },                                                      \
                .num_parents = 1,                                       \
                .flags = CLK_IGNORE_UNUSED,                             \
        },                                                              \
@@ -81,7 +81,9 @@ static struct clk_regmap g12a_aoclk_cts_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_oscin",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -106,7 +108,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_pre = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_32k_by_oscin_pre",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_oscin" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_cts_oscin.hw
+               },
                .num_parents = 1,
        },
 };
@@ -143,7 +147,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_div = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_32k_by_oscin_div",
                .ops = &meson_clk_dualdiv_ops,
-               .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_32k_by_oscin_pre.hw
+               },
                .num_parents = 1,
        },
 };
@@ -158,8 +164,10 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_32k_by_oscin_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_div",
-                                                 "g12a_ao_32k_by_oscin_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_32k_by_oscin_div.hw,
+                       &g12a_aoclk_32k_by_oscin_pre.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -173,7 +181,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_32k_by_oscin",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_32k_by_oscin_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -189,7 +199,9 @@ static struct clk_regmap g12a_aoclk_cec_pre = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_cec_pre",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_oscin" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_cts_oscin.hw
+               },
                .num_parents = 1,
        },
 };
@@ -226,7 +238,9 @@ static struct clk_regmap g12a_aoclk_cec_div = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_cec_div",
                .ops = &meson_clk_dualdiv_ops,
-               .parent_names = (const char *[]){ "g12a_ao_cec_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_cec_pre.hw
+               },
                .num_parents = 1,
        },
 };
@@ -241,8 +255,10 @@ static struct clk_regmap g12a_aoclk_cec_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_cec_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "g12a_ao_cec_div",
-                                                 "g12a_ao_cec_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_cec_div.hw,
+                       &g12a_aoclk_cec_pre.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -256,7 +272,9 @@ static struct clk_regmap g12a_aoclk_cec = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_cec",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "g12a_ao_cec_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_cec_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -272,8 +290,10 @@ static struct clk_regmap g12a_aoclk_cts_rtc_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_cts_rtc_oscin",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin",
-                                                 IN_PREFIX "ext_32k-0" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .hw = &g12a_aoclk_32k_by_oscin.hw },
+                       { .fw_name = "ext-32k-0", },
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -289,8 +309,10 @@ static struct clk_regmap g12a_aoclk_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_clk81",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk",
-                                                 "g12a_ao_cts_rtc_oscin"},
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "mpeg-clk", },
+                       { .hw = &g12a_aoclk_cts_rtc_oscin.hw },
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -305,8 +327,10 @@ static struct clk_regmap g12a_aoclk_saradc_mux = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_saradc_mux",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "g12a_ao_clk81" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_aoclk_clk81.hw },
+               },
                .num_parents = 2,
        },
 };
@@ -320,7 +344,9 @@ static struct clk_regmap g12a_aoclk_saradc_div = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_saradc_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "g12a_ao_saradc_mux" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_saradc_mux.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -334,7 +360,9 @@ static struct clk_regmap g12a_aoclk_saradc_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "g12a_ao_saradc_gate",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "g12a_ao_saradc_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_aoclk_saradc_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -417,12 +445,6 @@ static const struct clk_hw_onecell_data g12a_aoclk_onecell_data = {
        .num = NR_CLKS,
 };
 
-static const struct meson_aoclk_input g12a_aoclk_inputs[] = {
-       { .name = "xtal",       .required = true  },
-       { .name = "mpeg-clk",   .required = true  },
-       { .name = "ext-32k-0",  .required = false },
-};
-
 static const struct meson_aoclk_data g12a_aoclkc_data = {
        .reset_reg      = AO_RTI_GEN_CNTL_REG0,
        .num_reset      = ARRAY_SIZE(g12a_aoclk_reset),
@@ -430,9 +452,6 @@ static const struct meson_aoclk_data g12a_aoclkc_data = {
        .num_clks       = ARRAY_SIZE(g12a_aoclk_regmap),
        .clks           = g12a_aoclk_regmap,
        .hw_data        = &g12a_aoclk_onecell_data,
-       .inputs         = g12a_aoclk_inputs,
-       .num_inputs     = ARRAY_SIZE(g12a_aoclk_inputs),
-       .input_prefix   = IN_PREFIX,
 };
 
 static const struct of_device_id g12a_aoclkc_match_table[] = {
index db1c4ed..c3f0ffc 100644 (file)
 #include <linux/init.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/clk.h>
 
-#include "clk-input.h"
 #include "clk-mpll.h"
 #include "clk-pll.h"
 #include "clk-regmap.h"
+#include "clk-cpu-dyndiv.h"
 #include "vid-pll-div.h"
 #include "meson-eeclk.h"
 #include "g12a.h"
@@ -61,7 +62,9 @@ static struct clk_regmap g12a_fixed_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -76,7 +79,9 @@ static struct clk_regmap g12a_fixed_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fixed_pll_dco.hw
+               },
                .num_parents = 1,
                /*
                 * This clock won't ever change at runtime so
@@ -85,16 +90,9 @@ static struct clk_regmap g12a_fixed_pll = {
        },
 };
 
-/*
- * Internal sys pll emulation configuration parameters
- */
-static const struct reg_sequence g12a_sys_init_regs[] = {
-       { .reg = HHI_SYS_PLL_CNTL1,     .def = 0x00000000 },
-       { .reg = HHI_SYS_PLL_CNTL2,     .def = 0x00000000 },
-       { .reg = HHI_SYS_PLL_CNTL3,     .def = 0x48681c00 },
-       { .reg = HHI_SYS_PLL_CNTL4,     .def = 0x88770290 },
-       { .reg = HHI_SYS_PLL_CNTL5,     .def = 0x39272000 },
-       { .reg = HHI_SYS_PLL_CNTL6,     .def = 0x56540000 },
+static const struct pll_mult_range g12a_sys_pll_mult_range = {
+       .min = 128,
+       .max = 250,
 };
 
 static struct clk_regmap g12a_sys_pll_dco = {
@@ -124,14 +122,17 @@ static struct clk_regmap g12a_sys_pll_dco = {
                        .shift   = 29,
                        .width   = 1,
                },
-               .init_regs = g12a_sys_init_regs,
-               .init_count = ARRAY_SIZE(g12a_sys_init_regs),
+               .range = &g12a_sys_pll_mult_range,
        },
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll_dco",
-               .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .ops = &meson_clk_pll_ops,
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
+               /* This clock feeds the CPU, avoid disabling it */
+               .flags = CLK_IS_CRITICAL,
        },
 };
 
@@ -144,9 +145,12 @@ static struct clk_regmap g12a_sys_pll = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll",
-               .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "sys_pll_dco" },
+               .ops = &clk_regmap_divider_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sys_pll_dco.hw
+               },
                .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -177,12 +181,17 @@ static struct clk_regmap g12b_sys1_pll_dco = {
                        .shift   = 29,
                        .width   = 1,
                },
+               .range = &g12a_sys_pll_mult_range,
        },
        .hw.init = &(struct clk_init_data){
                .name = "sys1_pll_dco",
-               .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .ops = &meson_clk_pll_ops,
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
+               /* This clock feeds the CPU, avoid disabling it */
+               .flags = CLK_IS_CRITICAL,
        },
 };
 
@@ -195,9 +204,12 @@ static struct clk_regmap g12b_sys1_pll = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "sys1_pll",
-               .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "sys1_pll_dco" },
+               .ops = &clk_regmap_divider_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_sys1_pll_dco.hw
+               },
                .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -209,7 +221,7 @@ static struct clk_regmap g12a_sys_pll_div16_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "sys_pll_div16_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "sys_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_sys_pll.hw },
                .num_parents = 1,
                /*
                 * This clock is used to debug the sys_pll range
@@ -226,7 +238,9 @@ static struct clk_regmap g12b_sys1_pll_div16_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "sys1_pll_div16_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "sys1_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_sys1_pll.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is used to debug the sys_pll range
@@ -241,7 +255,9 @@ static struct clk_fixed_factor g12a_sys_pll_div16 = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll_div16",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "sys_pll_div16_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sys_pll_div16_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -252,11 +268,75 @@ static struct clk_fixed_factor g12b_sys1_pll_div16 = {
        .hw.init = &(struct clk_init_data){
                .name = "sys1_pll_div16",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "sys1_pll_div16_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_sys1_pll_div16_en.hw
+               },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_fixed_factor g12a_fclk_div2_div = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div2_div",
+               .ops = &clk_fixed_factor_ops,
+               .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_regmap g12a_fclk_div2 = {
+       .data = &(struct clk_regmap_gate_data){
+               .offset = HHI_FIX_PLL_CNTL1,
+               .bit_idx = 24,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div2",
+               .ops = &clk_regmap_gate_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fclk_div2_div.hw
+               },
                .num_parents = 1,
        },
 };
 
+static struct clk_fixed_factor g12a_fclk_div3_div = {
+       .mult = 1,
+       .div = 3,
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div3_div",
+               .ops = &clk_fixed_factor_ops,
+               .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_regmap g12a_fclk_div3 = {
+       .data = &(struct clk_regmap_gate_data){
+               .offset = HHI_FIX_PLL_CNTL1,
+               .bit_idx = 20,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "fclk_div3",
+               .ops = &clk_regmap_gate_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fclk_div3_div.hw
+               },
+               .num_parents = 1,
+               /*
+                * This clock is used by the resident firmware and is required
+                * by the platform to operate correctly.
+                * Until the following condition are met, we need this clock to
+                * be marked as critical:
+                * a) Mark the clock used by a firmware resource, if possible
+                * b) CCF has a clock hand-off mechanism to make the sure the
+                *    clock stays on until the proper driver comes along
+                */
+               .flags = CLK_IS_CRITICAL,
+       },
+};
+
 /* Datasheet names this field as "premux0" */
 static struct clk_regmap g12a_cpu_clk_premux0 = {
        .data = &(struct clk_regmap_mux_data){
@@ -266,26 +346,61 @@ static struct clk_regmap g12a_cpu_clk_premux0 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn0_sel",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "fclk_div2",
-                                                 "fclk_div3" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_fclk_div2.hw },
+                       { .hw = &g12a_fclk_div3.hw },
+               },
                .num_parents = 3,
+               /* This sub-tree is used a parking clock */
+               .flags = CLK_SET_RATE_NO_REPARENT,
+       },
+};
+
+/* Datasheet names this field as "premux1" */
+static struct clk_regmap g12a_cpu_clk_premux1 = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_SYS_CPU_CLK_CNTL0,
+               .mask = 0x3,
+               .shift = 16,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "cpu_clk_dyn1_sel",
+               .ops = &clk_regmap_mux_ops,
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_fclk_div2.hw },
+                       { .hw = &g12a_fclk_div3.hw },
+               },
+               .num_parents = 3,
+               /* This sub-tree is used a parking clock */
+               .flags = CLK_SET_RATE_NO_REPARENT
        },
 };
 
 /* Datasheet names this field as "mux0_divn_tcnt" */
 static struct clk_regmap g12a_cpu_clk_mux0_div = {
-       .data = &(struct clk_regmap_div_data){
-               .offset = HHI_SYS_CPU_CLK_CNTL0,
-               .shift = 4,
-               .width = 6,
+       .data = &(struct meson_clk_cpu_dyndiv_data){
+               .div = {
+                       .reg_off = HHI_SYS_CPU_CLK_CNTL0,
+                       .shift = 4,
+                       .width = 6,
+               },
+               .dyn = {
+                       .reg_off = HHI_SYS_CPU_CLK_CNTL0,
+                       .shift = 26,
+                       .width = 1,
+               },
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn0_div",
-               .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn0_sel" },
+               .ops = &meson_clk_cpu_dyndiv_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_premux0.hw
+               },
                .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -298,27 +413,13 @@ static struct clk_regmap g12a_cpu_clk_postmux0 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn0",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn0_sel",
-                                                 "cpu_clk_dyn0_div" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_premux0.hw,
+                       &g12a_cpu_clk_mux0_div.hw,
+               },
                .num_parents = 2,
-       },
-};
-
-/* Datasheet names this field as "premux1" */
-static struct clk_regmap g12a_cpu_clk_premux1 = {
-       .data = &(struct clk_regmap_mux_data){
-               .offset = HHI_SYS_CPU_CLK_CNTL0,
-               .mask = 0x3,
-               .shift = 16,
-       },
-       .hw.init = &(struct clk_init_data){
-               .name = "cpu_clk_dyn1_sel",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "fclk_div2",
-                                                 "fclk_div3" },
-               .num_parents = 3,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -332,7 +433,9 @@ static struct clk_regmap g12a_cpu_clk_mux1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn1_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_premux1.hw
+               },
                .num_parents = 1,
        },
 };
@@ -346,10 +449,14 @@ static struct clk_regmap g12a_cpu_clk_postmux1 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn1",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn1_sel",
-                                                 "cpu_clk_dyn1_div" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_premux1.hw,
+                       &g12a_cpu_clk_mux1_div.hw,
+               },
                .num_parents = 2,
+               /* This sub-tree is used a parking clock */
+               .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
 
@@ -362,10 +469,13 @@ static struct clk_regmap g12a_cpu_clk_dyn = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_dyn",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn0",
-                                                 "cpu_clk_dyn1" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_postmux0.hw,
+                       &g12a_cpu_clk_postmux1.hw,
+               },
                .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -378,10 +488,13 @@ static struct clk_regmap g12a_cpu_clk = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn",
-                                                 "sys_pll" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_dyn.hw,
+                       &g12a_sys_pll.hw,
+               },
                .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -394,10 +507,13 @@ static struct clk_regmap g12b_cpu_clk = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_dyn",
-                                                 "sys1_pll" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_dyn.hw,
+                       &g12b_sys1_pll.hw
+               },
                .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -410,26 +526,38 @@ static struct clk_regmap g12b_cpub_clk_premux0 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn0_sel",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "fclk_div2",
-                                                 "fclk_div3" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_fclk_div2.hw },
+                       { .hw = &g12a_fclk_div3.hw },
+               },
                .num_parents = 3,
        },
 };
 
 /* Datasheet names this field as "mux0_divn_tcnt" */
 static struct clk_regmap g12b_cpub_clk_mux0_div = {
-       .data = &(struct clk_regmap_div_data){
-               .offset = HHI_SYS_CPUB_CLK_CNTL,
-               .shift = 4,
-               .width = 6,
+       .data = &(struct meson_clk_cpu_dyndiv_data){
+               .div = {
+                       .reg_off = HHI_SYS_CPUB_CLK_CNTL,
+                       .shift = 4,
+                       .width = 6,
+               },
+               .dyn = {
+                       .reg_off = HHI_SYS_CPUB_CLK_CNTL,
+                       .shift = 26,
+                       .width = 1,
+               },
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn0_div",
-               .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_dyn0_sel" },
+               .ops = &meson_clk_cpu_dyndiv_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_premux0.hw
+               },
                .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -442,10 +570,13 @@ static struct clk_regmap g12b_cpub_clk_postmux0 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn0",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_dyn0_sel",
-                                                 "cpub_clk_dyn0_div" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_premux0.hw,
+                       &g12b_cpub_clk_mux0_div.hw
+               },
                .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -458,11 +589,15 @@ static struct clk_regmap g12b_cpub_clk_premux1 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn1_sel",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "fclk_div2",
-                                                 "fclk_div3" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_fclk_div2.hw },
+                       { .hw = &g12a_fclk_div3.hw },
+               },
                .num_parents = 3,
+               /* This sub-tree is used a parking clock */
+               .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
 
@@ -476,7 +611,9 @@ static struct clk_regmap g12b_cpub_clk_mux1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn1_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_dyn1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_premux1.hw
+               },
                .num_parents = 1,
        },
 };
@@ -490,10 +627,14 @@ static struct clk_regmap g12b_cpub_clk_postmux1 = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn1",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_dyn1_sel",
-                                                 "cpub_clk_dyn1_div" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_premux1.hw,
+                       &g12b_cpub_clk_mux1_div.hw
+               },
                .num_parents = 2,
+               /* This sub-tree is used a parking clock */
+               .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
 
@@ -506,10 +647,13 @@ static struct clk_regmap g12b_cpub_clk_dyn = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_dyn",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_dyn0",
-                                                 "cpub_clk_dyn1" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_postmux0.hw,
+                       &g12b_cpub_clk_postmux1.hw
+               },
                .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
@@ -522,13 +666,227 @@ static struct clk_regmap g12b_cpub_clk = {
        },
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk",
-               .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_dyn",
-                                                 "sys_pll" },
+               .ops = &clk_regmap_mux_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_dyn.hw,
+                       &g12a_sys_pll.hw
+               },
                .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
        },
 };
 
+static int g12a_cpu_clk_mux_notifier_cb(struct notifier_block *nb,
+                                       unsigned long event, void *data)
+{
+       if (event == POST_RATE_CHANGE || event == PRE_RATE_CHANGE) {
+               /* Wait for clock propagation before/after changing the mux */
+               udelay(100);
+               return NOTIFY_OK;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block g12a_cpu_clk_mux_nb = {
+       .notifier_call = g12a_cpu_clk_mux_notifier_cb,
+};
+
+struct g12a_cpu_clk_postmux_nb_data {
+       struct notifier_block nb;
+       struct clk_hw *xtal;
+       struct clk_hw *cpu_clk_dyn;
+       struct clk_hw *cpu_clk_postmux0;
+       struct clk_hw *cpu_clk_postmux1;
+       struct clk_hw *cpu_clk_premux1;
+};
+
+static int g12a_cpu_clk_postmux_notifier_cb(struct notifier_block *nb,
+                                           unsigned long event, void *data)
+{
+       struct g12a_cpu_clk_postmux_nb_data *nb_data =
+               container_of(nb, struct g12a_cpu_clk_postmux_nb_data, nb);
+
+       switch (event) {
+       case PRE_RATE_CHANGE:
+               /*
+                * This notifier means cpu_clk_postmux0 clock will be changed
+                * to feed cpu_clk, this is the current path :
+                * cpu_clk
+                *    \- cpu_clk_dyn
+                *          \- cpu_clk_postmux0
+                *                \- cpu_clk_muxX_div
+                *                      \- cpu_clk_premux0
+                *                              \- fclk_div3 or fclk_div2
+                *              OR
+                *                \- cpu_clk_premux0
+                *                      \- fclk_div3 or fclk_div2
+                */
+
+               /* Setup cpu_clk_premux1 to xtal */
+               clk_hw_set_parent(nb_data->cpu_clk_premux1,
+                                 nb_data->xtal);
+
+               /* Setup cpu_clk_postmux1 to bypass divider */
+               clk_hw_set_parent(nb_data->cpu_clk_postmux1,
+                                 nb_data->cpu_clk_premux1);
+
+               /* Switch to parking clk on cpu_clk_postmux1 */
+               clk_hw_set_parent(nb_data->cpu_clk_dyn,
+                                 nb_data->cpu_clk_postmux1);
+
+               /*
+                * Now, cpu_clk is 24MHz in the current path :
+                * cpu_clk
+                *    \- cpu_clk_dyn
+                *          \- cpu_clk_postmux1
+                *                \- cpu_clk_premux1
+                *                      \- xtal
+                */
+
+               udelay(100);
+
+               return NOTIFY_OK;
+
+       case POST_RATE_CHANGE:
+               /*
+                * The cpu_clk_postmux0 has ben updated, now switch back
+                * cpu_clk_dyn to cpu_clk_postmux0 and take the changes
+                * in account.
+                */
+
+               /* Configure cpu_clk_dyn back to cpu_clk_postmux0 */
+               clk_hw_set_parent(nb_data->cpu_clk_dyn,
+                                 nb_data->cpu_clk_postmux0);
+
+               /*
+                * new path :
+                * cpu_clk
+                *    \- cpu_clk_dyn
+                *          \- cpu_clk_postmux0
+                *                \- cpu_clk_muxX_div
+                *                      \- cpu_clk_premux0
+                *                              \- fclk_div3 or fclk_div2
+                *              OR
+                *                \- cpu_clk_premux0
+                *                      \- fclk_div3 or fclk_div2
+                */
+
+               udelay(100);
+
+               return NOTIFY_OK;
+
+       default:
+               return NOTIFY_DONE;
+       }
+}
+
+static struct g12a_cpu_clk_postmux_nb_data g12a_cpu_clk_postmux0_nb_data = {
+       .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
+       .cpu_clk_postmux0 = &g12a_cpu_clk_postmux0.hw,
+       .cpu_clk_postmux1 = &g12a_cpu_clk_postmux1.hw,
+       .cpu_clk_premux1 = &g12a_cpu_clk_premux1.hw,
+       .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb,
+};
+
+static struct g12a_cpu_clk_postmux_nb_data g12b_cpub_clk_postmux0_nb_data = {
+       .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw,
+       .cpu_clk_postmux0 = &g12b_cpub_clk_postmux0.hw,
+       .cpu_clk_postmux1 = &g12b_cpub_clk_postmux1.hw,
+       .cpu_clk_premux1 = &g12b_cpub_clk_premux1.hw,
+       .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb,
+};
+
+struct g12a_sys_pll_nb_data {
+       struct notifier_block nb;
+       struct clk_hw *sys_pll;
+       struct clk_hw *cpu_clk;
+       struct clk_hw *cpu_clk_dyn;
+};
+
+static int g12a_sys_pll_notifier_cb(struct notifier_block *nb,
+                                   unsigned long event, void *data)
+{
+       struct g12a_sys_pll_nb_data *nb_data =
+               container_of(nb, struct g12a_sys_pll_nb_data, nb);
+
+       switch (event) {
+       case PRE_RATE_CHANGE:
+               /*
+                * This notifier means sys_pll clock will be changed
+                * to feed cpu_clk, this the current path :
+                * cpu_clk
+                *    \- sys_pll
+                *          \- sys_pll_dco
+                */
+
+               /* Configure cpu_clk to use cpu_clk_dyn */
+               clk_hw_set_parent(nb_data->cpu_clk,
+                                 nb_data->cpu_clk_dyn);
+
+               /*
+                * Now, cpu_clk uses the dyn path
+                * cpu_clk
+                *    \- cpu_clk_dyn
+                *          \- cpu_clk_dynX
+                *                \- cpu_clk_dynX_sel
+                *                   \- cpu_clk_dynX_div
+                *                      \- xtal/fclk_div2/fclk_div3
+                *                   \- xtal/fclk_div2/fclk_div3
+                */
+
+               udelay(100);
+
+               return NOTIFY_OK;
+
+       case POST_RATE_CHANGE:
+               /*
+                * The sys_pll has ben updated, now switch back cpu_clk to
+                * sys_pll
+                */
+
+               /* Configure cpu_clk to use sys_pll */
+               clk_hw_set_parent(nb_data->cpu_clk,
+                                 nb_data->sys_pll);
+
+               udelay(100);
+
+               /* new path :
+                * cpu_clk
+                *    \- sys_pll
+                *          \- sys_pll_dco
+                */
+
+               return NOTIFY_OK;
+
+       default:
+               return NOTIFY_DONE;
+       }
+}
+
+static struct g12a_sys_pll_nb_data g12a_sys_pll_nb_data = {
+       .sys_pll = &g12a_sys_pll.hw,
+       .cpu_clk = &g12a_cpu_clk.hw,
+       .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
+       .nb.notifier_call = g12a_sys_pll_notifier_cb,
+};
+
+/* G12B first CPU cluster uses sys1_pll */
+static struct g12a_sys_pll_nb_data g12b_cpu_clk_sys1_pll_nb_data = {
+       .sys_pll = &g12b_sys1_pll.hw,
+       .cpu_clk = &g12b_cpu_clk.hw,
+       .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
+       .nb.notifier_call = g12a_sys_pll_notifier_cb,
+};
+
+/* G12B second CPU cluster uses sys_pll */
+static struct g12a_sys_pll_nb_data g12b_cpub_clk_sys_pll_nb_data = {
+       .sys_pll = &g12a_sys_pll.hw,
+       .cpu_clk = &g12b_cpub_clk.hw,
+       .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw,
+       .nb.notifier_call = g12a_sys_pll_notifier_cb,
+};
+
 static struct clk_regmap g12a_cpu_clk_div16_en = {
        .data = &(struct clk_regmap_gate_data){
                .offset = HHI_SYS_CPU_CLK_CNTL1,
@@ -537,7 +895,9 @@ static struct clk_regmap g12a_cpu_clk_div16_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpu_clk_div16_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is used to debug the cpu_clk range
@@ -554,7 +914,9 @@ static struct clk_regmap g12b_cpub_clk_div16_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpub_clk_div16_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is used to debug the cpu_clk range
@@ -569,7 +931,9 @@ static struct clk_fixed_factor g12a_cpu_clk_div16 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div16",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk_div16_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_div16_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -580,7 +944,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div16 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div16",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk_div16_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_div16_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -595,7 +961,7 @@ static struct clk_regmap g12a_cpu_clk_apb_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_apb_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
                .num_parents = 1,
        },
 };
@@ -608,7 +974,9 @@ static struct clk_regmap g12a_cpu_clk_apb = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpu_clk_apb",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_apb_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_apb_div.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -627,7 +995,7 @@ static struct clk_regmap g12a_cpu_clk_atb_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_atb_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
                .num_parents = 1,
        },
 };
@@ -640,7 +1008,9 @@ static struct clk_regmap g12a_cpu_clk_atb = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpu_clk_atb",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_atb_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_atb_div.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -659,7 +1029,7 @@ static struct clk_regmap g12a_cpu_clk_axi_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_axi_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
                .num_parents = 1,
        },
 };
@@ -672,7 +1042,9 @@ static struct clk_regmap g12a_cpu_clk_axi = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpu_clk_axi",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_axi_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_axi_div.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -691,7 +1063,17 @@ static struct clk_regmap g12a_cpu_clk_trace_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_trace_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_data = &(const struct clk_parent_data) {
+                       /*
+                        * Note:
+                        * G12A and G12B have different cpu_clks (with
+                        * different struct clk_hw). We fallback to the global
+                        * naming string mechanism so cpu_clk_trace_div picks
+                        * up the appropriate one.
+                        */
+                       .name = "cpu_clk",
+                       .index = -1,
+               },
                .num_parents = 1,
        },
 };
@@ -704,7 +1086,9 @@ static struct clk_regmap g12a_cpu_clk_trace = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpu_clk_trace",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpu_clk_trace_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cpu_clk_trace_div.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -719,7 +1103,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -730,7 +1116,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div3 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div3",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -741,7 +1129,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -752,7 +1142,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div5 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div5",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -763,7 +1155,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div6 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -774,7 +1168,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div7 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div7",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -785,7 +1181,9 @@ static struct clk_fixed_factor g12b_cpub_clk_div8 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_div8",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpub_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -801,13 +1199,15 @@ static struct clk_regmap g12b_cpub_clk_apb_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_apb_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_div2",
-                                                 "cpub_clk_div3",
-                                                 "cpub_clk_div4",
-                                                 "cpub_clk_div5",
-                                                 "cpub_clk_div6",
-                                                 "cpub_clk_div7",
-                                                 "cpub_clk_div8" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_div2.hw,
+                       &g12b_cpub_clk_div3.hw,
+                       &g12b_cpub_clk_div4.hw,
+                       &g12b_cpub_clk_div5.hw,
+                       &g12b_cpub_clk_div6.hw,
+                       &g12b_cpub_clk_div7.hw,
+                       &g12b_cpub_clk_div8.hw
+               },
                .num_parents = 7,
        },
 };
@@ -821,7 +1221,9 @@ static struct clk_regmap g12b_cpub_clk_apb = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpub_clk_apb",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_apb_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_apb_sel.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -840,13 +1242,15 @@ static struct clk_regmap g12b_cpub_clk_atb_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_atb_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_div2",
-                                                 "cpub_clk_div3",
-                                                 "cpub_clk_div4",
-                                                 "cpub_clk_div5",
-                                                 "cpub_clk_div6",
-                                                 "cpub_clk_div7",
-                                                 "cpub_clk_div8" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_div2.hw,
+                       &g12b_cpub_clk_div3.hw,
+                       &g12b_cpub_clk_div4.hw,
+                       &g12b_cpub_clk_div5.hw,
+                       &g12b_cpub_clk_div6.hw,
+                       &g12b_cpub_clk_div7.hw,
+                       &g12b_cpub_clk_div8.hw
+               },
                .num_parents = 7,
        },
 };
@@ -860,7 +1264,9 @@ static struct clk_regmap g12b_cpub_clk_atb = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpub_clk_atb",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_atb_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_atb_sel.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -879,13 +1285,15 @@ static struct clk_regmap g12b_cpub_clk_axi_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_axi_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_div2",
-                                                 "cpub_clk_div3",
-                                                 "cpub_clk_div4",
-                                                 "cpub_clk_div5",
-                                                 "cpub_clk_div6",
-                                                 "cpub_clk_div7",
-                                                 "cpub_clk_div8" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_div2.hw,
+                       &g12b_cpub_clk_div3.hw,
+                       &g12b_cpub_clk_div4.hw,
+                       &g12b_cpub_clk_div5.hw,
+                       &g12b_cpub_clk_div6.hw,
+                       &g12b_cpub_clk_div7.hw,
+                       &g12b_cpub_clk_div8.hw
+               },
                .num_parents = 7,
        },
 };
@@ -899,7 +1307,9 @@ static struct clk_regmap g12b_cpub_clk_axi = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpub_clk_axi",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_axi_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_axi_sel.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -918,13 +1328,15 @@ static struct clk_regmap g12b_cpub_clk_trace_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cpub_clk_trace_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_div2",
-                                                 "cpub_clk_div3",
-                                                 "cpub_clk_div4",
-                                                 "cpub_clk_div5",
-                                                 "cpub_clk_div6",
-                                                 "cpub_clk_div7",
-                                                 "cpub_clk_div8" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_div2.hw,
+                       &g12b_cpub_clk_div3.hw,
+                       &g12b_cpub_clk_div4.hw,
+                       &g12b_cpub_clk_div5.hw,
+                       &g12b_cpub_clk_div6.hw,
+                       &g12b_cpub_clk_div7.hw,
+                       &g12b_cpub_clk_div8.hw
+               },
                .num_parents = 7,
        },
 };
@@ -938,7 +1350,9 @@ static struct clk_regmap g12b_cpub_clk_trace = {
        .hw.init = &(struct clk_init_data) {
                .name = "cpub_clk_trace",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cpub_clk_trace_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12b_cpub_clk_trace_sel.hw
+               },
                .num_parents = 1,
                /*
                 * This clock is set by the ROM monitor code,
@@ -1003,7 +1417,9 @@ static struct clk_regmap g12a_gp0_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "gp0_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -1019,7 +1435,9 @@ static struct clk_regmap g12a_gp0_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "gp0_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "gp0_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_gp0_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1077,7 +1495,9 @@ static struct clk_regmap g12a_hifi_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "hifi_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -1093,7 +1513,9 @@ static struct clk_regmap g12a_hifi_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "hifi_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "hifi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_hifi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1164,7 +1586,9 @@ static struct clk_regmap g12a_pcie_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll_dco",
                .ops = &meson_clk_pcie_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -1175,7 +1599,9 @@ static struct clk_fixed_factor g12a_pcie_pll_dco_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll_dco_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "pcie_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_pcie_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1193,7 +1619,9 @@ static struct clk_regmap g12a_pcie_pll_od = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll_od",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "pcie_pll_dco_div2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_pcie_pll_dco_div2.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1205,7 +1633,9 @@ static struct clk_fixed_factor g12a_pcie_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "pcie_pll_pll",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "pcie_pll_od" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_pcie_pll_od.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1247,7 +1677,9 @@ static struct clk_regmap g12a_hdmi_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
                /*
                 * Display directly handle hdmi pll registers ATM, we need
@@ -1267,7 +1699,9 @@ static struct clk_regmap g12a_hdmi_pll_od = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_od",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_hdmi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -1283,7 +1717,9 @@ static struct clk_regmap g12a_hdmi_pll_od2 = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_od2",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_od" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_hdmi_pll_od.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -1299,77 +1735,21 @@ static struct clk_regmap g12a_hdmi_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_od2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_hdmi_pll_od2.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
 };
 
-static struct clk_fixed_factor g12a_fclk_div2_div = {
-       .mult = 1,
-       .div = 2,
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div2_div",
-               .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
-               .num_parents = 1,
-       },
-};
-
-static struct clk_regmap g12a_fclk_div2 = {
-       .data = &(struct clk_regmap_gate_data){
-               .offset = HHI_FIX_PLL_CNTL1,
-               .bit_idx = 24,
-       },
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div2",
-               .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div2_div" },
-               .num_parents = 1,
-       },
-};
-
-static struct clk_fixed_factor g12a_fclk_div3_div = {
-       .mult = 1,
-       .div = 3,
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div3_div",
-               .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
-               .num_parents = 1,
-       },
-};
-
-static struct clk_regmap g12a_fclk_div3 = {
-       .data = &(struct clk_regmap_gate_data){
-               .offset = HHI_FIX_PLL_CNTL1,
-               .bit_idx = 20,
-       },
-       .hw.init = &(struct clk_init_data){
-               .name = "fclk_div3",
-               .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div3_div" },
-               .num_parents = 1,
-               /*
-                * This clock is used by the resident firmware and is required
-                * by the platform to operate correctly.
-                * Until the following condition are met, we need this clock to
-                * be marked as critical:
-                * a) Mark the clock used by a firmware resource, if possible
-                * b) CCF has a clock hand-off mechanism to make the sure the
-                *    clock stays on until the proper driver comes along
-                */
-               .flags = CLK_IS_CRITICAL,
-       },
-};
-
 static struct clk_fixed_factor g12a_fclk_div4_div = {
        .mult = 1,
        .div = 4,
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -1382,7 +1762,9 @@ static struct clk_regmap g12a_fclk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div4_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fclk_div4_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1393,7 +1775,7 @@ static struct clk_fixed_factor g12a_fclk_div5_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -1406,7 +1788,9 @@ static struct clk_regmap g12a_fclk_div5 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div5_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fclk_div5_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1417,7 +1801,7 @@ static struct clk_fixed_factor g12a_fclk_div7_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -1430,7 +1814,9 @@ static struct clk_regmap g12a_fclk_div7 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div7_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fclk_div7_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1441,7 +1827,9 @@ static struct clk_fixed_factor g12a_fclk_div2p5_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2p5_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fixed_pll_dco.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1454,7 +1842,9 @@ static struct clk_regmap g12a_fclk_div2p5 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2p5",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div2p5_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fclk_div2p5_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1465,7 +1855,9 @@ static struct clk_fixed_factor g12a_mpll_50m_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll_50m_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fixed_pll_dco.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1479,8 +1871,10 @@ static struct clk_regmap g12a_mpll_50m = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll_50m",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal",
-                                                 "mpll_50m_div" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &g12a_mpll_50m_div.hw },
+               },
                .num_parents = 2,
        },
 };
@@ -1491,7 +1885,9 @@ static struct clk_fixed_factor g12a_mpll_prediv = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll_prediv",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_fixed_pll_dco.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1529,7 +1925,9 @@ static struct clk_regmap g12a_mpll0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1542,7 +1940,7 @@ static struct clk_regmap g12a_mpll0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll0_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_mpll0_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1581,7 +1979,9 @@ static struct clk_regmap g12a_mpll1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1594,7 +1994,7 @@ static struct clk_regmap g12a_mpll1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll1_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_mpll1_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1633,7 +2033,9 @@ static struct clk_regmap g12a_mpll2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1646,7 +2048,7 @@ static struct clk_regmap g12a_mpll2 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll2_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_mpll2_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1685,7 +2087,9 @@ static struct clk_regmap g12a_mpll3_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll3_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1698,16 +2102,21 @@ static struct clk_regmap g12a_mpll3 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll3",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll3_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_mpll3_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
 static u32 mux_table_clk81[]   = { 0, 2, 3, 4, 5, 6, 7 };
-static const char * const clk81_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
-       "fclk_div3", "fclk_div5"
+static const struct clk_parent_data clk81_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &g12a_fclk_div7.hw },
+       { .hw = &g12a_mpll1.hw },
+       { .hw = &g12a_mpll2.hw },
+       { .hw = &g12a_fclk_div4.hw },
+       { .hw = &g12a_fclk_div3.hw },
+       { .hw = &g12a_fclk_div5.hw },
 };
 
 static struct clk_regmap g12a_mpeg_clk_sel = {
@@ -1720,8 +2129,8 @@ static struct clk_regmap g12a_mpeg_clk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mpeg_clk_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = clk81_parent_names,
-               .num_parents = ARRAY_SIZE(clk81_parent_names),
+               .parent_data = clk81_parent_data,
+               .num_parents = ARRAY_SIZE(clk81_parent_data),
        },
 };
 
@@ -1734,7 +2143,9 @@ static struct clk_regmap g12a_mpeg_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpeg_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mpeg_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1748,15 +2159,20 @@ static struct clk_regmap g12a_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "clk81",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mpeg_clk_div.hw
+               },
                .num_parents = 1,
                .flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
        },
 };
 
-static const char * const g12a_sd_emmc_clk0_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
-
+static const struct clk_parent_data g12a_sd_emmc_clk0_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &g12a_fclk_div2.hw },
+       { .hw = &g12a_fclk_div3.hw },
+       { .hw = &g12a_fclk_div5.hw },
+       { .hw = &g12a_fclk_div7.hw },
        /*
         * Following these parent clocks, we should also have had mpll2, mpll3
         * and gp0_pll but these clocks are too precious to be used here. All
@@ -1775,8 +2191,8 @@ static struct clk_regmap g12a_sd_emmc_a_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_a_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names),
+               .parent_data = g12a_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1790,7 +2206,9 @@ static struct clk_regmap g12a_sd_emmc_a_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_a_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sd_emmc_a_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1804,7 +2222,9 @@ static struct clk_regmap g12a_sd_emmc_a_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_a_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sd_emmc_a_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1820,8 +2240,8 @@ static struct clk_regmap g12a_sd_emmc_b_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_b_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names),
+               .parent_data = g12a_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1835,7 +2255,9 @@ static struct clk_regmap g12a_sd_emmc_b_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_b_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sd_emmc_b_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1849,7 +2271,9 @@ static struct clk_regmap g12a_sd_emmc_b_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_b_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sd_emmc_b_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1865,8 +2289,8 @@ static struct clk_regmap g12a_sd_emmc_c_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_c_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_names),
+               .parent_data = g12a_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1880,7 +2304,9 @@ static struct clk_regmap g12a_sd_emmc_c_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_c_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sd_emmc_c_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1894,17 +2320,89 @@ static struct clk_regmap g12a_sd_emmc_c_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_c_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_sd_emmc_c_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
+/* Video Clocks */
+
+static struct clk_regmap g12a_vid_pll_div = {
+       .data = &(struct meson_vid_pll_div_data){
+               .val = {
+                       .reg_off = HHI_VID_PLL_CLK_DIV,
+                       .shift   = 0,
+                       .width   = 15,
+               },
+               .sel = {
+                       .reg_off = HHI_VID_PLL_CLK_DIV,
+                       .shift   = 16,
+                       .width   = 2,
+               },
+       },
+       .hw.init = &(struct clk_init_data) {
+               .name = "vid_pll_div",
+               .ops = &meson_vid_pll_div_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_pll.hw },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static const struct clk_hw *g12a_vid_pll_parent_hws[] = {
+       &g12a_vid_pll_div.hw,
+       &g12a_hdmi_pll.hw,
+};
+
+static struct clk_regmap g12a_vid_pll_sel = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_VID_PLL_CLK_DIV,
+               .mask = 0x1,
+               .shift = 18,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "vid_pll_sel",
+               .ops = &clk_regmap_mux_ops,
+               /*
+                * bit 18 selects from 2 possible parents:
+                * vid_pll_div or hdmi_pll
+                */
+               .parent_hws = g12a_vid_pll_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vid_pll_parent_hws),
+               .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
+       },
+};
+
+static struct clk_regmap g12a_vid_pll = {
+       .data = &(struct clk_regmap_gate_data){
+               .offset = HHI_VID_PLL_CLK_DIV,
+               .bit_idx = 19,
+       },
+       .hw.init = &(struct clk_init_data) {
+               .name = "vid_pll",
+               .ops = &clk_regmap_gate_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vid_pll_sel.hw
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
+       },
+};
+
 /* VPU Clock */
 
-static const char * const g12a_vpu_parent_names[] = {
-       "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7",
-       "mpll1", "vid_pll", "hifi_pll", "gp0_pll",
+static const struct clk_hw *g12a_vpu_parent_hws[] = {
+       &g12a_fclk_div3.hw,
+       &g12a_fclk_div4.hw,
+       &g12a_fclk_div5.hw,
+       &g12a_fclk_div7.hw,
+       &g12a_mpll1.hw,
+       &g12a_vid_pll.hw,
+       &g12a_hifi_pll.hw,
+       &g12a_gp0_pll.hw,
 };
 
 static struct clk_regmap g12a_vpu_0_sel = {
@@ -1916,8 +2414,8 @@ static struct clk_regmap g12a_vpu_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vpu_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vpu_parent_names),
+               .parent_hws = g12a_vpu_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vpu_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -1931,7 +2429,7 @@ static struct clk_regmap g12a_vpu_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vpu_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_0_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1945,7 +2443,7 @@ static struct clk_regmap g12a_vpu_0 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vpu_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vpu_0_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_0_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1960,8 +2458,8 @@ static struct clk_regmap g12a_vpu_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vpu_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vpu_parent_names),
+               .parent_hws = g12a_vpu_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vpu_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -1975,7 +2473,7 @@ static struct clk_regmap g12a_vpu_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vpu_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_1_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1989,7 +2487,7 @@ static struct clk_regmap g12a_vpu_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vpu_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vpu_1_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vpu_1_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2008,7 +2506,10 @@ static struct clk_regmap g12a_vpu = {
                 * bit 31 selects from 2 possible parents:
                 * vpu_0 or vpu_1
                 */
-               .parent_names = (const char *[]){ "vpu_0", "vpu_1" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vpu_0.hw,
+                       &g12a_vpu_1.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -2016,9 +2517,14 @@ static struct clk_regmap g12a_vpu = {
 
 /* VDEC clocks */
 
-static const char * const g12a_vdec_parent_names[] = {
-       "fclk_div2p5", "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7",
-       "hifi_pll", "gp0_pll",
+static const struct clk_hw *g12a_vdec_parent_hws[] = {
+       &g12a_fclk_div2p5.hw,
+       &g12a_fclk_div3.hw,
+       &g12a_fclk_div4.hw,
+       &g12a_fclk_div5.hw,
+       &g12a_fclk_div7.hw,
+       &g12a_hifi_pll.hw,
+       &g12a_gp0_pll.hw,
 };
 
 static struct clk_regmap g12a_vdec_1_sel = {
@@ -2031,8 +2537,8 @@ static struct clk_regmap g12a_vdec_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vdec_parent_names),
+               .parent_hws = g12a_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2047,7 +2553,9 @@ static struct clk_regmap g12a_vdec_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vdec_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2061,7 +2569,9 @@ static struct clk_regmap g12a_vdec_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vdec_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2077,8 +2587,8 @@ static struct clk_regmap g12a_vdec_hevcf_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevcf_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vdec_parent_names),
+               .parent_hws = g12a_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2093,7 +2603,9 @@ static struct clk_regmap g12a_vdec_hevcf_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevcf_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_hevcf_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vdec_hevcf_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2107,7 +2619,9 @@ static struct clk_regmap g12a_vdec_hevcf = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_hevcf",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_hevcf_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vdec_hevcf_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2123,8 +2637,8 @@ static struct clk_regmap g12a_vdec_hevc_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevc_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vdec_parent_names),
+               .parent_hws = g12a_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2139,7 +2653,9 @@ static struct clk_regmap g12a_vdec_hevc_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevc_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_hevc_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vdec_hevc_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2153,7 +2669,9 @@ static struct clk_regmap g12a_vdec_hevc = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_hevc",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_hevc_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vdec_hevc_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2161,9 +2679,15 @@ static struct clk_regmap g12a_vdec_hevc = {
 
 /* VAPB Clock */
 
-static const char * const g12a_vapb_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7",
-       "mpll1", "vid_pll", "mpll2", "fclk_div2p5",
+static const struct clk_hw *g12a_vapb_parent_hws[] = {
+       &g12a_fclk_div4.hw,
+       &g12a_fclk_div3.hw,
+       &g12a_fclk_div5.hw,
+       &g12a_fclk_div7.hw,
+       &g12a_mpll1.hw,
+       &g12a_vid_pll.hw,
+       &g12a_mpll2.hw,
+       &g12a_fclk_div2p5.hw,
 };
 
 static struct clk_regmap g12a_vapb_0_sel = {
@@ -2175,8 +2699,8 @@ static struct clk_regmap g12a_vapb_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vapb_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vapb_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vapb_parent_names),
+               .parent_hws = g12a_vapb_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vapb_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -2190,7 +2714,9 @@ static struct clk_regmap g12a_vapb_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vapb_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vapb_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vapb_0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2204,7 +2730,9 @@ static struct clk_regmap g12a_vapb_0 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vapb_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vapb_0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vapb_0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2219,8 +2747,8 @@ static struct clk_regmap g12a_vapb_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vapb_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vapb_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vapb_parent_names),
+               .parent_hws = g12a_vapb_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vapb_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -2234,7 +2762,9 @@ static struct clk_regmap g12a_vapb_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vapb_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vapb_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vapb_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2248,7 +2778,9 @@ static struct clk_regmap g12a_vapb_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vapb_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vapb_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vapb_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2267,7 +2799,10 @@ static struct clk_regmap g12a_vapb_sel = {
                 * bit 31 selects from 2 possible parents:
                 * vapb_0 or vapb_1
                 */
-               .parent_names = (const char *[]){ "vapb_0", "vapb_1" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vapb_0.hw,
+                       &g12a_vapb_1.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -2281,75 +2816,21 @@ static struct clk_regmap g12a_vapb = {
        .hw.init = &(struct clk_init_data) {
                .name = "vapb",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vapb_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vapb_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
 };
 
-/* Video Clocks */
-
-static struct clk_regmap g12a_vid_pll_div = {
-       .data = &(struct meson_vid_pll_div_data){
-               .val = {
-                       .reg_off = HHI_VID_PLL_CLK_DIV,
-                       .shift   = 0,
-                       .width   = 15,
-               },
-               .sel = {
-                       .reg_off = HHI_VID_PLL_CLK_DIV,
-                       .shift   = 16,
-                       .width   = 2,
-               },
-       },
-       .hw.init = &(struct clk_init_data) {
-               .name = "vid_pll_div",
-               .ops = &meson_vid_pll_div_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll" },
-               .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
-       },
-};
-
-static const char * const g12a_vid_pll_parent_names[] = { "vid_pll_div",
-                                                         "hdmi_pll" };
-
-static struct clk_regmap g12a_vid_pll_sel = {
-       .data = &(struct clk_regmap_mux_data){
-               .offset = HHI_VID_PLL_CLK_DIV,
-               .mask = 0x1,
-               .shift = 18,
-       },
-       .hw.init = &(struct clk_init_data){
-               .name = "vid_pll_sel",
-               .ops = &clk_regmap_mux_ops,
-               /*
-                * bit 18 selects from 2 possible parents:
-                * vid_pll_div or hdmi_pll
-                */
-               .parent_names = g12a_vid_pll_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vid_pll_parent_names),
-               .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
-       },
-};
-
-static struct clk_regmap g12a_vid_pll = {
-       .data = &(struct clk_regmap_gate_data){
-               .offset = HHI_VID_PLL_CLK_DIV,
-               .bit_idx = 19,
-       },
-       .hw.init = &(struct clk_init_data) {
-               .name = "vid_pll",
-               .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vid_pll_sel" },
-               .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
-       },
-};
-
-static const char * const g12a_vclk_parent_names[] = {
-       "vid_pll", "gp0_pll", "hifi_pll", "mpll1", "fclk_div3", "fclk_div4",
-       "fclk_div5", "fclk_div7"
+static const struct clk_hw *g12a_vclk_parent_hws[] = {
+       &g12a_vid_pll.hw,
+       &g12a_gp0_pll.hw,
+       &g12a_hifi_pll.hw,
+       &g12a_mpll1.hw,
+       &g12a_fclk_div3.hw,
+       &g12a_fclk_div4.hw,
+       &g12a_fclk_div5.hw,
+       &g12a_fclk_div7.hw,
 };
 
 static struct clk_regmap g12a_vclk_sel = {
@@ -2361,8 +2842,8 @@ static struct clk_regmap g12a_vclk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vclk_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vclk_parent_names),
+               .parent_hws = g12a_vclk_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vclk_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2376,8 +2857,8 @@ static struct clk_regmap g12a_vclk2_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_vclk_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_vclk_parent_names),
+               .parent_hws = g12a_vclk_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_vclk_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2390,7 +2871,7 @@ static struct clk_regmap g12a_vclk_input = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_input",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2404,7 +2885,7 @@ static struct clk_regmap g12a_vclk2_input = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_input",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2419,7 +2900,9 @@ static struct clk_regmap g12a_vclk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vclk_input" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk_input.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -2434,7 +2917,9 @@ static struct clk_regmap g12a_vclk2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vclk2_input" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk2_input.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -2448,7 +2933,7 @@ static struct clk_regmap g12a_vclk = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2462,7 +2947,7 @@ static struct clk_regmap g12a_vclk2 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2476,7 +2961,7 @@ static struct clk_regmap g12a_vclk_div1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2490,7 +2975,7 @@ static struct clk_regmap g12a_vclk_div2_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div2_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2504,7 +2989,7 @@ static struct clk_regmap g12a_vclk_div4_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div4_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2518,7 +3003,7 @@ static struct clk_regmap g12a_vclk_div6_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div6_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2532,7 +3017,7 @@ static struct clk_regmap g12a_vclk_div12_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div12_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2546,7 +3031,7 @@ static struct clk_regmap g12a_vclk2_div1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2560,7 +3045,7 @@ static struct clk_regmap g12a_vclk2_div2_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div2_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2574,7 +3059,7 @@ static struct clk_regmap g12a_vclk2_div4_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div4_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2588,7 +3073,7 @@ static struct clk_regmap g12a_vclk2_div6_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div6_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2602,7 +3087,7 @@ static struct clk_regmap g12a_vclk2_div12_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div12_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2614,7 +3099,9 @@ static struct clk_fixed_factor g12a_vclk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div2_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk_div2_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2625,7 +3112,9 @@ static struct clk_fixed_factor g12a_vclk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div4_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk_div4_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2636,7 +3125,9 @@ static struct clk_fixed_factor g12a_vclk_div6 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div6_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk_div6_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2647,7 +3138,9 @@ static struct clk_fixed_factor g12a_vclk_div12 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div12",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div12_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk_div12_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2658,7 +3151,9 @@ static struct clk_fixed_factor g12a_vclk2_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div2_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk2_div2_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2669,7 +3164,9 @@ static struct clk_fixed_factor g12a_vclk2_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div4_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk2_div4_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2680,7 +3177,9 @@ static struct clk_fixed_factor g12a_vclk2_div6 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div6_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk2_div6_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -2691,16 +3190,25 @@ static struct clk_fixed_factor g12a_vclk2_div12 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div12",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div12_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_vclk2_div12_en.hw
+               },
                .num_parents = 1,
        },
 };
 
 static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
-static const char * const g12a_cts_parent_names[] = {
-       "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6",
-       "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4",
-       "vclk2_div6", "vclk2_div12"
+static const struct clk_hw *g12a_cts_parent_hws[] = {
+       &g12a_vclk_div1.hw,
+       &g12a_vclk_div2.hw,
+       &g12a_vclk_div4.hw,
+       &g12a_vclk_div6.hw,
+       &g12a_vclk_div12.hw,
+       &g12a_vclk2_div1.hw,
+       &g12a_vclk2_div2.hw,
+       &g12a_vclk2_div4.hw,
+       &g12a_vclk2_div6.hw,
+       &g12a_vclk2_div12.hw,
 };
 
 static struct clk_regmap g12a_cts_enci_sel = {
@@ -2713,8 +3221,8 @@ static struct clk_regmap g12a_cts_enci_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_enci_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_cts_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_cts_parent_names),
+               .parent_hws = g12a_cts_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_cts_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2729,8 +3237,8 @@ static struct clk_regmap g12a_cts_encp_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_encp_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_cts_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_cts_parent_names),
+               .parent_hws = g12a_cts_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_cts_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2745,18 +3253,25 @@ static struct clk_regmap g12a_cts_vdac_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_vdac_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_cts_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_cts_parent_names),
+               .parent_hws = g12a_cts_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_cts_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
 
 /* TOFIX: add support for cts_tcon */
 static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
-static const char * const g12a_cts_hdmi_tx_parent_names[] = {
-       "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6",
-       "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4",
-       "vclk2_div6", "vclk2_div12"
+static const struct clk_hw *g12a_cts_hdmi_tx_parent_hws[] = {
+       &g12a_vclk_div1.hw,
+       &g12a_vclk_div2.hw,
+       &g12a_vclk_div4.hw,
+       &g12a_vclk_div6.hw,
+       &g12a_vclk_div12.hw,
+       &g12a_vclk2_div1.hw,
+       &g12a_vclk2_div2.hw,
+       &g12a_vclk2_div4.hw,
+       &g12a_vclk2_div6.hw,
+       &g12a_vclk2_div12.hw,
 };
 
 static struct clk_regmap g12a_hdmi_tx_sel = {
@@ -2769,8 +3284,8 @@ static struct clk_regmap g12a_hdmi_tx_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_tx_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_cts_hdmi_tx_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_cts_hdmi_tx_parent_names),
+               .parent_hws = g12a_cts_hdmi_tx_parent_hws,
+               .num_parents = ARRAY_SIZE(g12a_cts_hdmi_tx_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2783,7 +3298,9 @@ static struct clk_regmap g12a_cts_enci = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_enci",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_enci_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cts_enci_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2797,7 +3314,9 @@ static struct clk_regmap g12a_cts_encp = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_encp",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_encp_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cts_encp_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2811,7 +3330,9 @@ static struct clk_regmap g12a_cts_vdac = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_vdac",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_vdac_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_cts_vdac_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2825,7 +3346,9 @@ static struct clk_regmap g12a_hdmi_tx = {
        .hw.init = &(struct clk_init_data) {
                .name = "hdmi_tx",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "hdmi_tx_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_hdmi_tx_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2833,8 +3356,11 @@ static struct clk_regmap g12a_hdmi_tx = {
 
 /* HDMI Clocks */
 
-static const char * const g12a_hdmi_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div4", "fclk_div3", "fclk_div5"
+static const struct clk_parent_data g12a_hdmi_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &g12a_fclk_div4.hw },
+       { .hw = &g12a_fclk_div3.hw },
+       { .hw = &g12a_fclk_div5.hw },
 };
 
 static struct clk_regmap g12a_hdmi_sel = {
@@ -2847,8 +3373,8 @@ static struct clk_regmap g12a_hdmi_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_hdmi_parent_names,
-               .num_parents = ARRAY_SIZE(g12a_hdmi_parent_names),
+               .parent_data = g12a_hdmi_parent_data,
+               .num_parents = ARRAY_SIZE(g12a_hdmi_parent_data),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2862,7 +3388,7 @@ static struct clk_regmap g12a_hdmi_div = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "hdmi_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_sel.hw },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -2876,7 +3402,7 @@ static struct clk_regmap g12a_hdmi = {
        .hw.init = &(struct clk_init_data) {
                .name = "hdmi",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "hdmi_div" },
+               .parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2886,10 +3412,15 @@ static struct clk_regmap g12a_hdmi = {
  * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
  * muxed by a glitch-free switch.
  */
-
-static const char * const g12a_mali_0_1_parent_names[] = {
-       IN_PREFIX "xtal", "gp0_pll", "hihi_pll", "fclk_div2p5",
-       "fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7"
+static const struct clk_parent_data g12a_mali_0_1_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &g12a_gp0_pll.hw },
+       { .hw = &g12a_hifi_pll.hw },
+       { .hw = &g12a_fclk_div2p5.hw },
+       { .hw = &g12a_fclk_div3.hw },
+       { .hw = &g12a_fclk_div4.hw },
+       { .hw = &g12a_fclk_div5.hw },
+       { .hw = &g12a_fclk_div7.hw },
 };
 
 static struct clk_regmap g12a_mali_0_sel = {
@@ -2901,7 +3432,7 @@ static struct clk_regmap g12a_mali_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_mali_0_1_parent_names,
+               .parent_data = g12a_mali_0_1_parent_data,
                .num_parents = 8,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -2916,7 +3447,9 @@ static struct clk_regmap g12a_mali_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mali_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mali_0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -2930,7 +3463,9 @@ static struct clk_regmap g12a_mali_0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mali_0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mali_0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2945,7 +3480,7 @@ static struct clk_regmap g12a_mali_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_mali_0_1_parent_names,
+               .parent_data = g12a_mali_0_1_parent_data,
                .num_parents = 8,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -2960,7 +3495,9 @@ static struct clk_regmap g12a_mali_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mali_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mali_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -2974,14 +3511,17 @@ static struct clk_regmap g12a_mali_1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mali_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_mali_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const g12a_mali_parent_names[] = {
-       "mali_0", "mali_1"
+static const struct clk_hw *g12a_mali_parent_hws[] = {
+       &g12a_mali_0.hw,
+       &g12a_mali_1.hw,
 };
 
 static struct clk_regmap g12a_mali = {
@@ -2993,7 +3533,7 @@ static struct clk_regmap g12a_mali = {
        .hw.init = &(struct clk_init_data){
                .name = "mali",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = g12a_mali_parent_names,
+               .parent_hws = g12a_mali_parent_hws,
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -3008,7 +3548,9 @@ static struct clk_regmap g12a_ts_div = {
        .hw.init = &(struct clk_init_data){
                .name = "ts_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -3021,11 +3563,19 @@ static struct clk_regmap g12a_ts = {
        .hw.init = &(struct clk_init_data){
                .name = "ts",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "ts_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &g12a_ts_div.hw
+               },
                .num_parents = 1,
        },
 };
 
+#define MESON_GATE(_name, _reg, _bit) \
+       MESON_PCLK(_name, _reg, _bit, &g12a_clk81.hw)
+
+#define MESON_GATE_RO(_name, _reg, _bit) \
+       MESON_PCLK_RO(_name, _reg, _bit, &g12a_clk81.hw)
+
 /* Everything Else (EE) domain gates */
 static MESON_GATE(g12a_ddr,                    HHI_GCLK_MPEG0, 0);
 static MESON_GATE(g12a_dos,                    HHI_GCLK_MPEG0, 1);
@@ -3792,28 +4342,210 @@ static const struct reg_sequence g12a_init_regs[] = {
        { .reg = HHI_MPLL_CNTL0,        .def = 0x00000543 },
 };
 
-static const struct meson_eeclkc_data g12a_clkc_data = {
-       .regmap_clks = g12a_clk_regmaps,
-       .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
-       .hw_onecell_data = &g12a_hw_onecell_data,
-       .init_regs = g12a_init_regs,
-       .init_count = ARRAY_SIZE(g12a_init_regs),
-};
-
-static const struct meson_eeclkc_data g12b_clkc_data = {
-       .regmap_clks = g12a_clk_regmaps,
-       .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
-       .hw_onecell_data = &g12b_hw_onecell_data
+static int meson_g12a_dvfs_setup_common(struct platform_device *pdev,
+                                       struct clk_hw **hws)
+{
+       const char *notifier_clk_name;
+       struct clk *notifier_clk;
+       struct clk_hw *xtal;
+       int ret;
+
+       xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0);
+
+       /* Setup clock notifier for cpu_clk_postmux0 */
+       g12a_cpu_clk_postmux0_nb_data.xtal = xtal;
+       notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_postmux0.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk,
+                                   &g12a_cpu_clk_postmux0_nb_data.nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpu_clk_postmux0 notifier\n");
+               return ret;
+       }
+
+       /* Setup clock notifier for cpu_clk_dyn mux */
+       notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_dyn.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpu_clk_dyn notifier\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int meson_g12b_dvfs_setup(struct platform_device *pdev)
+{
+       struct clk_hw **hws = g12b_hw_onecell_data.hws;
+       const char *notifier_clk_name;
+       struct clk *notifier_clk;
+       struct clk_hw *xtal;
+       int ret;
+
+       ret = meson_g12a_dvfs_setup_common(pdev, hws);
+       if (ret)
+               return ret;
+
+       xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0);
+
+       /* Setup clock notifier for cpu_clk mux */
+       notifier_clk_name = clk_hw_get_name(&g12b_cpu_clk.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n");
+               return ret;
+       }
+
+       /* Setup clock notifier for sys1_pll */
+       notifier_clk_name = clk_hw_get_name(&g12b_sys1_pll.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk,
+                                   &g12b_cpu_clk_sys1_pll_nb_data.nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the sys1_pll notifier\n");
+               return ret;
+       }
+
+       /* Add notifiers for the second CPU cluster */
+
+       /* Setup clock notifier for cpub_clk_postmux0 */
+       g12b_cpub_clk_postmux0_nb_data.xtal = xtal;
+       notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_postmux0.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk,
+                                   &g12b_cpub_clk_postmux0_nb_data.nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpub_clk_postmux0 notifier\n");
+               return ret;
+       }
+
+       /* Setup clock notifier for cpub_clk_dyn mux */
+       notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_dyn.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpub_clk_dyn notifier\n");
+               return ret;
+       }
+
+       /* Setup clock notifier for cpub_clk mux */
+       notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpub_clk notifier\n");
+               return ret;
+       }
+
+       /* Setup clock notifier for sys_pll */
+       notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk,
+                                   &g12b_cpub_clk_sys_pll_nb_data.nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the sys_pll notifier\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int meson_g12a_dvfs_setup(struct platform_device *pdev)
+{
+       struct clk_hw **hws = g12a_hw_onecell_data.hws;
+       const char *notifier_clk_name;
+       struct clk *notifier_clk;
+       int ret;
+
+       ret = meson_g12a_dvfs_setup_common(pdev, hws);
+       if (ret)
+               return ret;
+
+       /* Setup clock notifier for cpu_clk mux */
+       notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n");
+               return ret;
+       }
+
+       /* Setup clock notifier for sys_pll */
+       notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw);
+       notifier_clk = __clk_lookup(notifier_clk_name);
+       ret = clk_notifier_register(notifier_clk, &g12a_sys_pll_nb_data.nb);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to register the sys_pll notifier\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+struct meson_g12a_data {
+       const struct meson_eeclkc_data eeclkc_data;
+       int (*dvfs_setup)(struct platform_device *pdev);
+};
+
+static int meson_g12a_probe(struct platform_device *pdev)
+{
+       const struct meson_eeclkc_data *eeclkc_data;
+       const struct meson_g12a_data *g12a_data;
+       int ret;
+
+       eeclkc_data = of_device_get_match_data(&pdev->dev);
+       if (!eeclkc_data)
+               return -EINVAL;
+
+       ret = meson_eeclkc_probe(pdev);
+       if (ret)
+               return ret;
+
+       g12a_data = container_of(eeclkc_data, struct meson_g12a_data,
+                                eeclkc_data);
+
+       if (g12a_data->dvfs_setup)
+               return g12a_data->dvfs_setup(pdev);
+
+       return 0;
+}
+
+static const struct meson_g12a_data g12a_clkc_data = {
+       .eeclkc_data = {
+               .regmap_clks = g12a_clk_regmaps,
+               .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
+               .hw_onecell_data = &g12a_hw_onecell_data,
+               .init_regs = g12a_init_regs,
+               .init_count = ARRAY_SIZE(g12a_init_regs),
+       },
+       .dvfs_setup = meson_g12a_dvfs_setup,
+};
+
+static const struct meson_g12a_data g12b_clkc_data = {
+       .eeclkc_data = {
+               .regmap_clks = g12a_clk_regmaps,
+               .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
+               .hw_onecell_data = &g12b_hw_onecell_data,
+       },
+       .dvfs_setup = meson_g12b_dvfs_setup,
 };
 
 static const struct of_device_id clkc_match_table[] = {
-       { .compatible = "amlogic,g12a-clkc", .data = &g12a_clkc_data },
-       { .compatible = "amlogic,g12b-clkc", .data = &g12b_clkc_data },
+       {
+               .compatible = "amlogic,g12a-clkc",
+               .data = &g12a_clkc_data.eeclkc_data
+       },
+       {
+               .compatible = "amlogic,g12b-clkc",
+               .data = &g12b_clkc_data.eeclkc_data
+       },
        {}
 };
 
 static struct platform_driver g12a_driver = {
-       .probe          = meson_eeclkc_probe,
+       .probe          = meson_g12a_probe,
        .driver         = {
                .name   = "g12a-clkc",
                .of_match_table = clkc_match_table,
index c8aed31..559a34c 100644 (file)
 #define CLKID_CPUB_CLK_DYN1_DIV                        221
 #define CLKID_CPUB_CLK_DYN1                    222
 #define CLKID_CPUB_CLK_DYN                     223
-#define CLKID_CPUB_CLK                         224
 #define CLKID_CPUB_CLK_DIV16_EN                        225
 #define CLKID_CPUB_CLK_DIV16                   226
 #define CLKID_CPUB_CLK_DIV2                    227
index 449f6ac..e940861 100644 (file)
@@ -11,8 +11,6 @@
 #include "clk-regmap.h"
 #include "clk-dualdiv.h"
 
-#define IN_PREFIX "ao-in-"
-
 /* AO Configuration Clock registers offsets */
 #define AO_RTI_PWR_CNTL_REG1   0x0c
 #define AO_RTI_PWR_CNTL_REG0   0x10
@@ -31,7 +29,9 @@ static struct clk_regmap _name##_ao = {                                       \
        .hw.init = &(struct clk_init_data) {                            \
                .name = #_name "_ao",                                   \
                .ops = &clk_regmap_gate_ops,                            \
-               .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \
+               .parent_data = &(const struct clk_parent_data) {        \
+                       .fw_name = "mpeg-clk",                          \
+               },                                                      \
                .num_parents = 1,                                       \
                .flags = CLK_IGNORE_UNUSED,                             \
        },                                                              \
@@ -52,7 +52,9 @@ static struct clk_regmap ao_cts_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_cts_oscin",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -65,7 +67,7 @@ static struct clk_regmap ao_32k_pre = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_32k_pre",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "ao_cts_oscin" },
+               .parent_hws = (const struct clk_hw *[]) { &ao_cts_oscin.hw },
                .num_parents = 1,
        },
 };
@@ -112,7 +114,7 @@ static struct clk_regmap ao_32k_div = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_32k_div",
                .ops = &meson_clk_dualdiv_ops,
-               .parent_names = (const char *[]){ "ao_32k_pre" },
+               .parent_hws = (const struct clk_hw *[]) { &ao_32k_pre.hw },
                .num_parents = 1,
        },
 };
@@ -127,8 +129,10 @@ static struct clk_regmap ao_32k_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_32k_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "ao_32k_div",
-                                                 "ao_32k_pre" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &ao_32k_div.hw,
+                       &ao_32k_pre.hw
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -142,7 +146,7 @@ static struct clk_regmap ao_32k = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_32k",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "ao_32k_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &ao_32k_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -159,10 +163,12 @@ static struct clk_regmap ao_cts_rtc_oscin = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_cts_rtc_oscin",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "ext-32k-0",
-                                                 IN_PREFIX "ext-32k-1",
-                                                 IN_PREFIX "ext-32k-2",
-                                                 "ao_32k" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "ext-32k-0", },
+                       { .fw_name = "ext-32k-1", },
+                       { .fw_name = "ext-32k-2", },
+                       { .hw = &ao_32k.hw },
+               },
                .num_parents = 4,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -178,8 +184,10 @@ static struct clk_regmap ao_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "ao_clk81",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk",
-                                                 "ao_cts_rtc_oscin" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "mpeg-clk", },
+                       { .hw = &ao_cts_rtc_oscin.hw },
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -208,8 +216,10 @@ static struct clk_regmap ao_cts_cec = {
                 * Until CCF gets fixed, adding this fake parent that won't
                 * ever be registered should work around the problem
                 */
-               .parent_names = (const char *[]){ "fixme",
-                                                 "ao_cts_rtc_oscin" },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .name = "fixme", .index = -1, },
+                       { .hw = &ao_cts_rtc_oscin.hw },
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -261,14 +271,6 @@ static const struct clk_hw_onecell_data gxbb_aoclk_onecell_data = {
        .num = NR_CLKS,
 };
 
-static const struct meson_aoclk_input gxbb_aoclk_inputs[] = {
-       { .name = "xtal",       .required = true,  },
-       { .name = "mpeg-clk",   .required = true,  },
-       {. name = "ext-32k-0",  .required = false, },
-       {. name = "ext-32k-1",  .required = false, },
-       {. name = "ext-32k-2",  .required = false, },
-};
-
 static const struct meson_aoclk_data gxbb_aoclkc_data = {
        .reset_reg      = AO_RTI_GEN_CNTL_REG0,
        .num_reset      = ARRAY_SIZE(gxbb_aoclk_reset),
@@ -276,9 +278,6 @@ static const struct meson_aoclk_data gxbb_aoclkc_data = {
        .num_clks       = ARRAY_SIZE(gxbb_aoclk),
        .clks           = gxbb_aoclk,
        .hw_data        = &gxbb_aoclk_onecell_data,
-       .inputs         = gxbb_aoclk_inputs,
-       .num_inputs     = ARRAY_SIZE(gxbb_aoclk_inputs),
-       .input_prefix   = IN_PREFIX,
 };
 
 static const struct of_device_id gxbb_aoclkc_match_table[] = {
index dab16d9..7cfb998 100644 (file)
 #include <linux/platform_device.h>
 
 #include "gxbb.h"
-#include "clk-input.h"
 #include "clk-regmap.h"
 #include "clk-pll.h"
 #include "clk-mpll.h"
 #include "meson-eeclk.h"
 #include "vid-pll-div.h"
 
-#define IN_PREFIX "ee-in-"
-
 static DEFINE_SPINLOCK(meson_clk_lock);
 
 static const struct pll_params_table gxbb_gp0_pll_params_table[] = {
@@ -121,7 +118,9 @@ static struct clk_regmap gxbb_fixed_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -136,7 +135,9 @@ static struct clk_regmap gxbb_fixed_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fixed_pll_dco.hw
+               },
                .num_parents = 1,
                /*
                 * This clock won't ever change at runtime so
@@ -151,7 +152,9 @@ static struct clk_fixed_factor gxbb_hdmi_pll_pre_mult = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_pre_mult",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -192,7 +195,9 @@ static struct clk_regmap gxbb_hdmi_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_pre_mult" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_hdmi_pll_pre_mult.hw
+               },
                .num_parents = 1,
                /*
                 * Display directly handle hdmi pll registers ATM, we need
@@ -244,7 +249,9 @@ static struct clk_regmap gxl_hdmi_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
                /*
                 * Display directly handle hdmi pll registers ATM, we need
@@ -264,7 +271,9 @@ static struct clk_regmap gxbb_hdmi_pll_od = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_od",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_hdmi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -280,7 +289,9 @@ static struct clk_regmap gxbb_hdmi_pll_od2 = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_od2",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_od" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_hdmi_pll_od.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -296,7 +307,9 @@ static struct clk_regmap gxbb_hdmi_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_od2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_hdmi_pll_od2.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -312,7 +325,9 @@ static struct clk_regmap gxl_hdmi_pll_od = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_od",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxl_hdmi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -328,7 +343,9 @@ static struct clk_regmap gxl_hdmi_pll_od2 = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_od2",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_od" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxl_hdmi_pll_od.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -344,7 +361,9 @@ static struct clk_regmap gxl_hdmi_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_od2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxl_hdmi_pll_od2.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
        },
@@ -381,7 +400,9 @@ static struct clk_regmap gxbb_sys_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -396,7 +417,9 @@ static struct clk_regmap gxbb_sys_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "sys_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sys_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -442,7 +465,9 @@ static struct clk_regmap gxbb_gp0_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "gp0_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -494,7 +519,9 @@ static struct clk_regmap gxl_gp0_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "gp0_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
                .num_parents = 1,
        },
 };
@@ -509,7 +536,17 @@ static struct clk_regmap gxbb_gp0_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "gp0_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "gp0_pll_dco" },
+               .parent_data = &(const struct clk_parent_data) {
+                       /*
+                        * Note:
+                        * GXL and GXBB have different gp0_pll_dco (with
+                        * different struct clk_hw). We fallback to the global
+                        * naming string mechanism so gp0_pll picks up the
+                        * appropriate one.
+                        */
+                       .name = "gp0_pll_dco",
+                       .index = -1,
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -521,7 +558,9 @@ static struct clk_fixed_factor gxbb_fclk_div2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -534,7 +573,9 @@ static struct clk_regmap gxbb_fclk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fclk_div2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_IS_CRITICAL,
        },
@@ -546,7 +587,7 @@ static struct clk_fixed_factor gxbb_fclk_div3_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div3_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -559,7 +600,9 @@ static struct clk_regmap gxbb_fclk_div3 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div3",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div3_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fclk_div3_div.hw
+               },
                .num_parents = 1,
                /*
                 * FIXME:
@@ -582,7 +625,7 @@ static struct clk_fixed_factor gxbb_fclk_div4_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -595,7 +638,9 @@ static struct clk_regmap gxbb_fclk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div4_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fclk_div4_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -606,7 +651,7 @@ static struct clk_fixed_factor gxbb_fclk_div5_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -619,7 +664,9 @@ static struct clk_regmap gxbb_fclk_div5 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div5_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fclk_div5_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -630,7 +677,7 @@ static struct clk_fixed_factor gxbb_fclk_div7_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -643,7 +690,9 @@ static struct clk_regmap gxbb_fclk_div7 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div7_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_fclk_div7_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -657,7 +706,7 @@ static struct clk_regmap gxbb_mpll_prediv = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll_prediv",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_fixed_pll.hw },
                .num_parents = 1,
        },
 };
@@ -684,7 +733,9 @@ static struct clk_regmap gxbb_mpll0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -697,7 +748,7 @@ static struct clk_regmap gxbb_mpll0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll0_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -725,7 +776,9 @@ static struct clk_regmap gxbb_mpll1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -738,7 +791,7 @@ static struct clk_regmap gxbb_mpll1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll1_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll1_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -766,7 +819,9 @@ static struct clk_regmap gxbb_mpll2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -779,16 +834,21 @@ static struct clk_regmap gxbb_mpll2 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll2_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll2_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
 static u32 mux_table_clk81[]   = { 0, 2, 3, 4, 5, 6, 7 };
-static const char * const clk81_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
-       "fclk_div3", "fclk_div5"
+static const struct clk_parent_data clk81_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &gxbb_fclk_div7.hw },
+       { .hw = &gxbb_mpll1.hw },
+       { .hw = &gxbb_mpll2.hw },
+       { .hw = &gxbb_fclk_div4.hw },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
 };
 
 static struct clk_regmap gxbb_mpeg_clk_sel = {
@@ -806,8 +866,8 @@ static struct clk_regmap gxbb_mpeg_clk_sel = {
                 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
                 * fclk_div4, fclk_div3, fclk_div5
                 */
-               .parent_names = clk81_parent_names,
-               .num_parents = ARRAY_SIZE(clk81_parent_names),
+               .parent_data = clk81_parent_data,
+               .num_parents = ARRAY_SIZE(clk81_parent_data),
        },
 };
 
@@ -820,7 +880,9 @@ static struct clk_regmap gxbb_mpeg_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpeg_clk_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpeg_clk_sel.hw
+               },
                .num_parents = 1,
        },
 };
@@ -834,7 +896,9 @@ static struct clk_regmap gxbb_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "clk81",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpeg_clk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_IS_CRITICAL,
        },
@@ -850,7 +914,10 @@ static struct clk_regmap gxbb_sar_adc_clk_sel = {
                .name = "sar_adc_clk_sel",
                .ops = &clk_regmap_mux_ops,
                /* NOTE: The datasheet doesn't list the parents for bit 10 */
-               .parent_names = (const char *[]){ IN_PREFIX "xtal", "clk81", },
+               .parent_data = (const struct clk_parent_data []) {
+                       { .fw_name = "xtal", },
+                       { .hw = &gxbb_clk81.hw },
+               },
                .num_parents = 2,
        },
 };
@@ -864,7 +931,9 @@ static struct clk_regmap gxbb_sar_adc_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "sar_adc_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sar_adc_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sar_adc_clk_sel.hw
+               },
                .num_parents = 1,
        },
 };
@@ -877,7 +946,9 @@ static struct clk_regmap gxbb_sar_adc_clk = {
        .hw.init = &(struct clk_init_data){
                .name = "sar_adc_clk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sar_adc_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sar_adc_clk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -888,9 +959,15 @@ static struct clk_regmap gxbb_sar_adc_clk = {
  * muxed by a glitch-free switch.
  */
 
-static const char * const gxbb_mali_0_1_parent_names[] = {
-       IN_PREFIX "xtal", "gp0_pll", "mpll2", "mpll1", "fclk_div7",
-       "fclk_div4", "fclk_div3", "fclk_div5"
+static const struct clk_parent_data gxbb_mali_0_1_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &gxbb_gp0_pll.hw },
+       { .hw = &gxbb_mpll2.hw },
+       { .hw = &gxbb_mpll1.hw },
+       { .hw = &gxbb_fclk_div7.hw },
+       { .hw = &gxbb_fclk_div4.hw },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
 };
 
 static struct clk_regmap gxbb_mali_0_sel = {
@@ -907,7 +984,7 @@ static struct clk_regmap gxbb_mali_0_sel = {
                 * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
                 * fclk_div4, fclk_div3, fclk_div5
                 */
-               .parent_names = gxbb_mali_0_1_parent_names,
+               .parent_data = gxbb_mali_0_1_parent_data,
                .num_parents = 8,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -922,7 +999,9 @@ static struct clk_regmap gxbb_mali_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mali_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mali_0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -936,7 +1015,9 @@ static struct clk_regmap gxbb_mali_0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mali_0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mali_0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -956,7 +1037,7 @@ static struct clk_regmap gxbb_mali_1_sel = {
                 * xtal, gp0_pll, mpll2, mpll1, fclk_div7,
                 * fclk_div4, fclk_div3, fclk_div5
                 */
-               .parent_names = gxbb_mali_0_1_parent_names,
+               .parent_data = gxbb_mali_0_1_parent_data,
                .num_parents = 8,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -971,7 +1052,9 @@ static struct clk_regmap gxbb_mali_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mali_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mali_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -985,14 +1068,17 @@ static struct clk_regmap gxbb_mali_1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mali_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mali_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const gxbb_mali_parent_names[] = {
-       "mali_0", "mali_1"
+static const struct clk_hw *gxbb_mali_parent_hws[] = {
+       &gxbb_mali_0.hw,
+       &gxbb_mali_1.hw,
 };
 
 static struct clk_regmap gxbb_mali = {
@@ -1004,7 +1090,7 @@ static struct clk_regmap gxbb_mali = {
        .hw.init = &(struct clk_init_data){
                .name = "mali",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_mali_parent_names,
+               .parent_hws = gxbb_mali_parent_hws,
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -1021,7 +1107,11 @@ static struct clk_regmap gxbb_cts_amclk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpll0.hw,
+                       &gxbb_mpll1.hw,
+                       &gxbb_mpll2.hw,
+               },
                .num_parents = 3,
        },
 };
@@ -1036,7 +1126,9 @@ static struct clk_regmap gxbb_cts_amclk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "cts_amclk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_amclk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1050,7 +1142,9 @@ static struct clk_regmap gxbb_cts_amclk = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_amclk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_amclk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1067,7 +1161,11 @@ static struct clk_regmap gxbb_cts_mclk_i958_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_mclk_i958_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "mpll0", "mpll1", "mpll2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_mpll0.hw,
+                       &gxbb_mpll1.hw,
+                       &gxbb_mpll2.hw,
+               },
                .num_parents = 3,
        },
 };
@@ -1082,7 +1180,9 @@ static struct clk_regmap gxbb_cts_mclk_i958_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_mclk_i958_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "cts_mclk_i958_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_mclk_i958_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1096,7 +1196,9 @@ static struct clk_regmap gxbb_cts_mclk_i958 = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_mclk_i958",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_mclk_i958_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_mclk_i958_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1111,7 +1213,10 @@ static struct clk_regmap gxbb_cts_i958 = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_i958",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "cts_amclk", "cts_mclk_i958" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_amclk.hw,
+                       &gxbb_cts_mclk_i958.hw
+               },
                .num_parents = 2,
                /*
                 *The parent is specific to origin of the audio data. Let the
@@ -1121,6 +1226,33 @@ static struct clk_regmap gxbb_cts_i958 = {
        },
 };
 
+static const struct clk_parent_data gxbb_32k_clk_parent_data[] = {
+       { .fw_name = "xtal", },
+       /*
+        * FIXME: This clock is provided by the ao clock controller but the
+        * clock is not yet part of the binding of this controller, so string
+        * name must be use to set this parent.
+        */
+       { .name = "cts_slow_oscin", .index = -1 },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
+};
+
+static struct clk_regmap gxbb_32k_clk_sel = {
+       .data = &(struct clk_regmap_mux_data){
+               .offset = HHI_32K_CLK_CNTL,
+               .mask = 0x3,
+               .shift = 16,
+               },
+       .hw.init = &(struct clk_init_data){
+               .name = "32k_clk_sel",
+               .ops = &clk_regmap_mux_ops,
+               .parent_data = gxbb_32k_clk_parent_data,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
 static struct clk_regmap gxbb_32k_clk_div = {
        .data = &(struct clk_regmap_div_data){
                .offset = HHI_32K_CLK_CNTL,
@@ -1130,7 +1262,9 @@ static struct clk_regmap gxbb_32k_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "32k_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "32k_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_32k_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_DIVIDER_ROUND_CLOSEST,
        },
@@ -1144,34 +1278,20 @@ static struct clk_regmap gxbb_32k_clk = {
        .hw.init = &(struct clk_init_data){
                .name = "32k_clk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "32k_clk_div" },
-               .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT,
-       },
-};
-
-static const char * const gxbb_32k_clk_parent_names[] = {
-       IN_PREFIX "xtal", "cts_slow_oscin", "fclk_div3", "fclk_div5"
-};
-
-static struct clk_regmap gxbb_32k_clk_sel = {
-       .data = &(struct clk_regmap_mux_data){
-               .offset = HHI_32K_CLK_CNTL,
-               .mask = 0x3,
-               .shift = 16,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_32k_clk_div.hw
                },
-       .hw.init = &(struct clk_init_data){
-               .name = "32k_clk_sel",
-               .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_32k_clk_parent_names,
-               .num_parents = 4,
+               .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const gxbb_sd_emmc_clk0_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
-
+static const struct clk_parent_data gxbb_sd_emmc_clk0_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &gxbb_fclk_div2.hw },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
+       { .hw = &gxbb_fclk_div7.hw },
        /*
         * Following these parent clocks, we should also have had mpll2, mpll3
         * and gp0_pll but these clocks are too precious to be used here. All
@@ -1190,8 +1310,8 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_a_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
+               .parent_data = gxbb_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1206,7 +1326,9 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_a_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_a_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sd_emmc_a_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1220,7 +1342,9 @@ static struct clk_regmap gxbb_sd_emmc_a_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_a_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_a_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sd_emmc_a_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1236,8 +1360,8 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_b_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
+               .parent_data = gxbb_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1252,7 +1376,9 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_b_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sd_emmc_b_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1266,7 +1392,9 @@ static struct clk_regmap gxbb_sd_emmc_b_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_b_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sd_emmc_b_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1282,8 +1410,8 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_c_clk0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_sd_emmc_clk0_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_names),
+               .parent_data = gxbb_sd_emmc_clk0_parent_data,
+               .num_parents = ARRAY_SIZE(gxbb_sd_emmc_clk0_parent_data),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1298,7 +1426,9 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "sd_emmc_c_clk0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sd_emmc_c_clk0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1312,7 +1442,9 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0 = {
        .hw.init = &(struct clk_init_data){
                .name = "sd_emmc_c_clk0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_sd_emmc_c_clk0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1320,8 +1452,11 @@ static struct clk_regmap gxbb_sd_emmc_c_clk0 = {
 
 /* VPU Clock */
 
-static const char * const gxbb_vpu_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
+static const struct clk_hw *gxbb_vpu_parent_hws[] = {
+       &gxbb_fclk_div4.hw,
+       &gxbb_fclk_div3.hw,
+       &gxbb_fclk_div5.hw,
+       &gxbb_fclk_div7.hw,
 };
 
 static struct clk_regmap gxbb_vpu_0_sel = {
@@ -1337,8 +1472,8 @@ static struct clk_regmap gxbb_vpu_0_sel = {
                 * bits 9:10 selects from 4 possible parents:
                 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
                 */
-               .parent_names = gxbb_vpu_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vpu_parent_names),
+               .parent_hws = gxbb_vpu_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vpu_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -1352,7 +1487,7 @@ static struct clk_regmap gxbb_vpu_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vpu_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_0_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1366,7 +1501,7 @@ static struct clk_regmap gxbb_vpu_0 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vpu_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vpu_0_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_0_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1385,8 +1520,8 @@ static struct clk_regmap gxbb_vpu_1_sel = {
                 * bits 25:26 selects from 4 possible parents:
                 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
                 */
-               .parent_names = gxbb_vpu_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vpu_parent_names),
+               .parent_hws = gxbb_vpu_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vpu_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -1400,7 +1535,7 @@ static struct clk_regmap gxbb_vpu_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vpu_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_1_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1414,7 +1549,7 @@ static struct clk_regmap gxbb_vpu_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vpu_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vpu_1_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vpu_1_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1433,7 +1568,10 @@ static struct clk_regmap gxbb_vpu = {
                 * bit 31 selects from 2 possible parents:
                 * vpu_0 or vpu_1
                 */
-               .parent_names = (const char *[]){ "vpu_0", "vpu_1" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vpu_0.hw,
+                       &gxbb_vpu_1.hw
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -1441,8 +1579,11 @@ static struct clk_regmap gxbb_vpu = {
 
 /* VAPB Clock */
 
-static const char * const gxbb_vapb_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
+static const struct clk_hw *gxbb_vapb_parent_hws[] = {
+       &gxbb_fclk_div4.hw,
+       &gxbb_fclk_div3.hw,
+       &gxbb_fclk_div5.hw,
+       &gxbb_fclk_div7.hw,
 };
 
 static struct clk_regmap gxbb_vapb_0_sel = {
@@ -1458,8 +1599,8 @@ static struct clk_regmap gxbb_vapb_0_sel = {
                 * bits 9:10 selects from 4 possible parents:
                 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
                 */
-               .parent_names = gxbb_vapb_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vapb_parent_names),
+               .parent_hws = gxbb_vapb_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vapb_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -1473,7 +1614,9 @@ static struct clk_regmap gxbb_vapb_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vapb_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vapb_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vapb_0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1487,7 +1630,9 @@ static struct clk_regmap gxbb_vapb_0 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vapb_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vapb_0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vapb_0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1506,8 +1651,8 @@ static struct clk_regmap gxbb_vapb_1_sel = {
                 * bits 25:26 selects from 4 possible parents:
                 * fclk_div4, fclk_div3, fclk_div5, fclk_div7,
                 */
-               .parent_names = gxbb_vapb_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vapb_parent_names),
+               .parent_hws = gxbb_vapb_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vapb_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
@@ -1521,7 +1666,9 @@ static struct clk_regmap gxbb_vapb_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vapb_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vapb_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vapb_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1535,7 +1682,9 @@ static struct clk_regmap gxbb_vapb_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vapb_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vapb_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vapb_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1554,7 +1703,10 @@ static struct clk_regmap gxbb_vapb_sel = {
                 * bit 31 selects from 2 possible parents:
                 * vapb_0 or vapb_1
                 */
-               .parent_names = (const char *[]){ "vapb_0", "vapb_1" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vapb_0.hw,
+                       &gxbb_vapb_1.hw
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -1568,7 +1720,7 @@ static struct clk_regmap gxbb_vapb = {
        .hw.init = &(struct clk_init_data) {
                .name = "vapb",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vapb_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vapb_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1592,13 +1744,33 @@ static struct clk_regmap gxbb_vid_pll_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "vid_pll_div",
                .ops = &meson_vid_pll_div_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll" },
+               .parent_data = &(const struct clk_parent_data) {
+                       /*
+                        * Note:
+                        * GXL and GXBB have different hdmi_plls (with
+                        * different struct clk_hw). We fallback to the global
+                        * naming string mechanism so vid_pll_div picks up the
+                        * appropriate one.
+                        */
+                       .name = "hdmi_pll",
+                       .index = -1,
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
        },
 };
 
-static const char * const gxbb_vid_pll_parent_names[] = { "vid_pll_div", "hdmi_pll" };
+static const struct clk_parent_data gxbb_vid_pll_parent_data[] = {
+       { .hw = &gxbb_vid_pll_div.hw },
+       /*
+        * Note:
+        * GXL and GXBB have different hdmi_plls (with
+        * different struct clk_hw). We fallback to the global
+        * naming string mechanism so vid_pll_div picks up the
+        * appropriate one.
+        */
+       { .name = "hdmi_pll", .index = -1 },
+};
 
 static struct clk_regmap gxbb_vid_pll_sel = {
        .data = &(struct clk_regmap_mux_data){
@@ -1613,8 +1785,8 @@ static struct clk_regmap gxbb_vid_pll_sel = {
                 * bit 18 selects from 2 possible parents:
                 * vid_pll_div or hdmi_pll
                 */
-               .parent_names = gxbb_vid_pll_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vid_pll_parent_names),
+               .parent_data = gxbb_vid_pll_parent_data,
+               .num_parents = ARRAY_SIZE(gxbb_vid_pll_parent_data),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -1627,15 +1799,22 @@ static struct clk_regmap gxbb_vid_pll = {
        .hw.init = &(struct clk_init_data) {
                .name = "vid_pll",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vid_pll_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vid_pll_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
 };
 
-static const char * const gxbb_vclk_parent_names[] = {
-       "vid_pll", "fclk_div4", "fclk_div3", "fclk_div5", "vid_pll",
-       "fclk_div7", "mpll1",
+static const struct clk_hw *gxbb_vclk_parent_hws[] = {
+       &gxbb_vid_pll.hw,
+       &gxbb_fclk_div4.hw,
+       &gxbb_fclk_div3.hw,
+       &gxbb_fclk_div5.hw,
+       &gxbb_vid_pll.hw,
+       &gxbb_fclk_div7.hw,
+       &gxbb_mpll1.hw,
 };
 
 static struct clk_regmap gxbb_vclk_sel = {
@@ -1652,8 +1831,8 @@ static struct clk_regmap gxbb_vclk_sel = {
                 * vid_pll, fclk_div4, fclk_div3, fclk_div5,
                 * vid_pll, fclk_div7, mp1
                 */
-               .parent_names = gxbb_vclk_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vclk_parent_names),
+               .parent_hws = gxbb_vclk_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vclk_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -1672,8 +1851,8 @@ static struct clk_regmap gxbb_vclk2_sel = {
                 * vid_pll, fclk_div4, fclk_div3, fclk_div5,
                 * vid_pll, fclk_div7, mp1
                 */
-               .parent_names = gxbb_vclk_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vclk_parent_names),
+               .parent_hws = gxbb_vclk_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vclk_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -1686,7 +1865,7 @@ static struct clk_regmap gxbb_vclk_input = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_input",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1700,7 +1879,7 @@ static struct clk_regmap gxbb_vclk2_input = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_input",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2_sel.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1715,7 +1894,9 @@ static struct clk_regmap gxbb_vclk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vclk_input" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk_input.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -1730,7 +1911,9 @@ static struct clk_regmap gxbb_vclk2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vclk2_input" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk2_input.hw
+               },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -1744,7 +1927,7 @@ static struct clk_regmap gxbb_vclk = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1758,7 +1941,7 @@ static struct clk_regmap gxbb_vclk2 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1772,7 +1955,7 @@ static struct clk_regmap gxbb_vclk_div1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1786,7 +1969,7 @@ static struct clk_regmap gxbb_vclk_div2_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div2_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1800,7 +1983,7 @@ static struct clk_regmap gxbb_vclk_div4_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div4_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1814,7 +1997,7 @@ static struct clk_regmap gxbb_vclk_div6_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div6_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1828,7 +2011,7 @@ static struct clk_regmap gxbb_vclk_div12_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk_div12_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1842,7 +2025,7 @@ static struct clk_regmap gxbb_vclk2_div1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1856,7 +2039,7 @@ static struct clk_regmap gxbb_vclk2_div2_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div2_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1870,7 +2053,7 @@ static struct clk_regmap gxbb_vclk2_div4_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div4_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1884,7 +2067,7 @@ static struct clk_regmap gxbb_vclk2_div6_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div6_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1898,7 +2081,7 @@ static struct clk_regmap gxbb_vclk2_div12_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vclk2_div12_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vclk2" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_vclk2.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -1910,7 +2093,9 @@ static struct clk_fixed_factor gxbb_vclk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div2_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk_div2_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1921,7 +2106,9 @@ static struct clk_fixed_factor gxbb_vclk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div4_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk_div4_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1932,7 +2119,9 @@ static struct clk_fixed_factor gxbb_vclk_div6 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div6_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk_div6_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1943,7 +2132,9 @@ static struct clk_fixed_factor gxbb_vclk_div12 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div12",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_div12_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk_div12_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1954,7 +2145,9 @@ static struct clk_fixed_factor gxbb_vclk2_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div2_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk2_div2_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1965,7 +2158,9 @@ static struct clk_fixed_factor gxbb_vclk2_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div4_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk2_div4_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1976,7 +2171,9 @@ static struct clk_fixed_factor gxbb_vclk2_div6 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div6_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk2_div6_en.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1987,16 +2184,25 @@ static struct clk_fixed_factor gxbb_vclk2_div12 = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div12",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_div12_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vclk2_div12_en.hw
+               },
                .num_parents = 1,
        },
 };
 
 static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
-static const char * const gxbb_cts_parent_names[] = {
-       "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6",
-       "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4",
-       "vclk2_div6", "vclk2_div12"
+static const struct clk_hw *gxbb_cts_parent_hws[] = {
+       &gxbb_vclk_div1.hw,
+       &gxbb_vclk_div2.hw,
+       &gxbb_vclk_div4.hw,
+       &gxbb_vclk_div6.hw,
+       &gxbb_vclk_div12.hw,
+       &gxbb_vclk2_div1.hw,
+       &gxbb_vclk2_div2.hw,
+       &gxbb_vclk2_div4.hw,
+       &gxbb_vclk2_div6.hw,
+       &gxbb_vclk2_div12.hw,
 };
 
 static struct clk_regmap gxbb_cts_enci_sel = {
@@ -2009,8 +2215,8 @@ static struct clk_regmap gxbb_cts_enci_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_enci_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_cts_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_cts_parent_names),
+               .parent_hws = gxbb_cts_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2025,8 +2231,8 @@ static struct clk_regmap gxbb_cts_encp_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_encp_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_cts_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_cts_parent_names),
+               .parent_hws = gxbb_cts_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2041,18 +2247,25 @@ static struct clk_regmap gxbb_cts_vdac_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_vdac_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_cts_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_cts_parent_names),
+               .parent_hws = gxbb_cts_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_cts_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
 
 /* TOFIX: add support for cts_tcon */
 static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
-static const char * const gxbb_cts_hdmi_tx_parent_names[] = {
-       "vclk_div1", "vclk_div2", "vclk_div4", "vclk_div6",
-       "vclk_div12", "vclk2_div1", "vclk2_div2", "vclk2_div4",
-       "vclk2_div6", "vclk2_div12"
+static const struct clk_hw *gxbb_cts_hdmi_tx_parent_hws[] = {
+       &gxbb_vclk_div1.hw,
+       &gxbb_vclk_div2.hw,
+       &gxbb_vclk_div4.hw,
+       &gxbb_vclk_div6.hw,
+       &gxbb_vclk_div12.hw,
+       &gxbb_vclk2_div1.hw,
+       &gxbb_vclk2_div2.hw,
+       &gxbb_vclk2_div4.hw,
+       &gxbb_vclk2_div6.hw,
+       &gxbb_vclk2_div12.hw,
 };
 
 static struct clk_regmap gxbb_hdmi_tx_sel = {
@@ -2071,8 +2284,8 @@ static struct clk_regmap gxbb_hdmi_tx_sel = {
                 * vclk2_div1, vclk2_div2, vclk2_div4, vclk2_div6, vclk2_div12,
                 * cts_tcon
                 */
-               .parent_names = gxbb_cts_hdmi_tx_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_cts_hdmi_tx_parent_names),
+               .parent_hws = gxbb_cts_hdmi_tx_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_cts_hdmi_tx_parent_hws),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2085,7 +2298,9 @@ static struct clk_regmap gxbb_cts_enci = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_enci",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_enci_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_enci_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2099,7 +2314,9 @@ static struct clk_regmap gxbb_cts_encp = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_encp",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_encp_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_encp_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2113,7 +2330,9 @@ static struct clk_regmap gxbb_cts_vdac = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_vdac",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_vdac_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_cts_vdac_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2127,7 +2346,9 @@ static struct clk_regmap gxbb_hdmi_tx = {
        .hw.init = &(struct clk_init_data) {
                .name = "hdmi_tx",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "hdmi_tx_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_hdmi_tx_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2135,8 +2356,11 @@ static struct clk_regmap gxbb_hdmi_tx = {
 
 /* HDMI Clocks */
 
-static const char * const gxbb_hdmi_parent_names[] = {
-       IN_PREFIX "xtal", "fclk_div4", "fclk_div3", "fclk_div5"
+static const struct clk_parent_data gxbb_hdmi_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &gxbb_fclk_div4.hw },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
 };
 
 static struct clk_regmap gxbb_hdmi_sel = {
@@ -2149,8 +2373,8 @@ static struct clk_regmap gxbb_hdmi_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_hdmi_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_hdmi_parent_names),
+               .parent_data = gxbb_hdmi_parent_data,
+               .num_parents = ARRAY_SIZE(gxbb_hdmi_parent_data),
                .flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
        },
 };
@@ -2164,7 +2388,7 @@ static struct clk_regmap gxbb_hdmi_div = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "hdmi_sel" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_hdmi_sel.hw },
                .num_parents = 1,
                .flags = CLK_GET_RATE_NOCACHE,
        },
@@ -2178,7 +2402,7 @@ static struct clk_regmap gxbb_hdmi = {
        .hw.init = &(struct clk_init_data) {
                .name = "hdmi",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "hdmi_div" },
+               .parent_hws = (const struct clk_hw *[]) { &gxbb_hdmi_div.hw },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
        },
@@ -2186,8 +2410,11 @@ static struct clk_regmap gxbb_hdmi = {
 
 /* VDEC clocks */
 
-static const char * const gxbb_vdec_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
+static const struct clk_hw *gxbb_vdec_parent_hws[] = {
+       &gxbb_fclk_div4.hw,
+       &gxbb_fclk_div3.hw,
+       &gxbb_fclk_div5.hw,
+       &gxbb_fclk_div7.hw,
 };
 
 static struct clk_regmap gxbb_vdec_1_sel = {
@@ -2200,8 +2427,8 @@ static struct clk_regmap gxbb_vdec_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vdec_parent_names),
+               .parent_hws = gxbb_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2216,7 +2443,9 @@ static struct clk_regmap gxbb_vdec_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vdec_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2230,7 +2459,9 @@ static struct clk_regmap gxbb_vdec_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vdec_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2246,8 +2477,8 @@ static struct clk_regmap gxbb_vdec_hevc_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevc_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = gxbb_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(gxbb_vdec_parent_names),
+               .parent_hws = gxbb_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(gxbb_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2262,7 +2493,9 @@ static struct clk_regmap gxbb_vdec_hevc_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevc_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_hevc_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vdec_hevc_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2276,7 +2509,9 @@ static struct clk_regmap gxbb_vdec_hevc = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_hevc",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_hevc_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_vdec_hevc_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2284,9 +2519,18 @@ static struct clk_regmap gxbb_vdec_hevc = {
 
 static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8,
                                    9, 10, 11, 13, 14, };
-static const char * const gen_clk_parent_names[] = {
-       IN_PREFIX "xtal", "vdec_1", "vdec_hevc", "mpll0", "mpll1", "mpll2",
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll",
+static const struct clk_parent_data gen_clk_parent_data[] = {
+       { .fw_name = "xtal", },
+       { .hw = &gxbb_vdec_1.hw },
+       { .hw = &gxbb_vdec_hevc.hw },
+       { .hw = &gxbb_mpll0.hw },
+       { .hw = &gxbb_mpll1.hw },
+       { .hw = &gxbb_mpll2.hw },
+       { .hw = &gxbb_fclk_div4.hw },
+       { .hw = &gxbb_fclk_div3.hw },
+       { .hw = &gxbb_fclk_div5.hw },
+       { .hw = &gxbb_fclk_div7.hw },
+       { .hw = &gxbb_gp0_pll.hw },
 };
 
 static struct clk_regmap gxbb_gen_clk_sel = {
@@ -2305,8 +2549,8 @@ static struct clk_regmap gxbb_gen_clk_sel = {
                 * vid_pll, vid2_pll (hevc), mpll0, mpll1, mpll2, fdiv4,
                 * fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll
                 */
-               .parent_names = gen_clk_parent_names,
-               .num_parents = ARRAY_SIZE(gen_clk_parent_names),
+               .parent_data = gen_clk_parent_data,
+               .num_parents = ARRAY_SIZE(gen_clk_parent_data),
        },
 };
 
@@ -2319,7 +2563,9 @@ static struct clk_regmap gxbb_gen_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "gen_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "gen_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_gen_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2333,12 +2579,17 @@ static struct clk_regmap gxbb_gen_clk = {
        .hw.init = &(struct clk_init_data){
                .name = "gen_clk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "gen_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &gxbb_gen_clk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
+#define MESON_GATE(_name, _reg, _bit) \
+       MESON_PCLK(_name, _reg, _bit, &gxbb_clk81.hw)
+
 /* Everything Else (EE) domain gates */
 static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0);
 static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1);
index b679519..bf8bea6 100644 (file)
@@ -17,8 +17,6 @@
 #include <linux/slab.h>
 #include "meson-aoclk.h"
 
-#include "clk-input.h"
-
 static int meson_aoclk_do_reset(struct reset_controller_dev *rcdev,
                               unsigned long id)
 {
@@ -33,37 +31,6 @@ static const struct reset_control_ops meson_aoclk_reset_ops = {
        .reset = meson_aoclk_do_reset,
 };
 
-static int meson_aoclkc_register_inputs(struct device *dev,
-                                       struct meson_aoclk_data *data)
-{
-       struct clk_hw *hw;
-       char *str;
-       int i;
-
-       for (i = 0; i < data->num_inputs; i++) {
-               const struct meson_aoclk_input *in = &data->inputs[i];
-
-               str = kasprintf(GFP_KERNEL, "%s%s", data->input_prefix,
-                               in->name);
-               if (!str)
-                       return -ENOMEM;
-
-               hw = meson_clk_hw_register_input(dev, in->name, str, 0);
-               kfree(str);
-
-               if (IS_ERR(hw)) {
-                       if (!in->required && PTR_ERR(hw) == -ENOENT)
-                               continue;
-                       else if (PTR_ERR(hw) != -EPROBE_DEFER)
-                               dev_err(dev, "failed to register input %s\n",
-                                       in->name);
-                       return PTR_ERR(hw);
-               }
-       }
-
-       return 0;
-}
-
 int meson_aoclkc_probe(struct platform_device *pdev)
 {
        struct meson_aoclk_reset_controller *rstc;
@@ -86,10 +53,6 @@ int meson_aoclkc_probe(struct platform_device *pdev)
                return PTR_ERR(regmap);
        }
 
-       ret = meson_aoclkc_register_inputs(dev, data);
-       if (ret)
-               return ret;
-
        /* Reset Controller */
        rstc->data = data;
        rstc->regmap = regmap;
index 999cde3..605b438 100644 (file)
 
 #include "clk-regmap.h"
 
-struct meson_aoclk_input {
-       const char *name;
-       bool required;
-};
-
 struct meson_aoclk_data {
        const unsigned int                      reset_reg;
        const int                               num_reset;
        const unsigned int                      *reset;
        const int                               num_clks;
        struct clk_regmap                       **clks;
-       const int                               num_inputs;
-       const struct meson_aoclk_input          *inputs;
-       const char                              *input_prefix;
        const struct clk_hw_onecell_data        *hw_data;
 };
 
index 6ba2094..a7cb1e7 100644 (file)
@@ -10,7 +10,6 @@
 #include <linux/mfd/syscon.h>
 #include <linux/regmap.h>
 
-#include "clk-input.h"
 #include "clk-regmap.h"
 #include "meson-eeclk.h"
 
@@ -18,7 +17,6 @@ int meson_eeclkc_probe(struct platform_device *pdev)
 {
        const struct meson_eeclkc_data *data;
        struct device *dev = &pdev->dev;
-       struct clk_hw *input;
        struct regmap *map;
        int ret, i;
 
@@ -37,14 +35,6 @@ int meson_eeclkc_probe(struct platform_device *pdev)
        if (data->init_count)
                regmap_multi_reg_write(map, data->init_regs, data->init_count);
 
-       input = meson_clk_hw_register_input(dev, "xtal", IN_PREFIX "xtal", 0);
-       if (IS_ERR(input)) {
-               ret = PTR_ERR(input);
-               if (ret != -EPROBE_DEFER)
-                       dev_err(dev, "failed to get input clock");
-               return ret;
-       }
-
        /* Populate regmap for the regmap backed clocks */
        for (i = 0; i < data->regmap_clk_num; i++)
                data->regmap_clks[i]->map = map;
index 9ab5d6f..7731620 100644 (file)
@@ -10,8 +10,6 @@
 #include <linux/clk-provider.h>
 #include "clk-regmap.h"
 
-#define IN_PREFIX "ee-in-"
-
 struct platform_device;
 
 struct meson_eeclkc_data {
index 537219f..67e6691 100644 (file)
@@ -97,7 +97,9 @@ static struct clk_regmap meson8b_fixed_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ "xtal" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw
+               },
                .num_parents = 1,
        },
 };
@@ -112,7 +114,9 @@ static struct clk_regmap meson8b_fixed_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll_dco.hw
+               },
                .num_parents = 1,
                /*
                 * This clock won't ever change at runtime so
@@ -158,7 +162,9 @@ static struct clk_regmap meson8b_hdmi_pll_dco = {
                /* sometimes also called "HPLL" or "HPLL PLL" */
                .name = "hdmi_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_names = (const char *[]){ "xtal" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw
+               },
                .num_parents = 1,
        },
 };
@@ -173,7 +179,9 @@ static struct clk_regmap meson8b_hdmi_pll_lvds_out = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_lvds_out",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_hdmi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -189,7 +197,9 @@ static struct clk_regmap meson8b_hdmi_pll_hdmi_out = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_pll_hdmi_out",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_hdmi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -227,7 +237,9 @@ static struct clk_regmap meson8b_sys_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ "xtal" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw
+               },
                .num_parents = 1,
        },
 };
@@ -242,7 +254,9 @@ static struct clk_regmap meson8b_sys_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "sys_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_sys_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -254,7 +268,9 @@ static struct clk_fixed_factor meson8b_fclk_div2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -267,7 +283,9 @@ static struct clk_regmap meson8b_fclk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div2_div.hw
+               },
                .num_parents = 1,
                /*
                 * FIXME: Ethernet with a RGMII PHYs is not working if
@@ -285,7 +303,9 @@ static struct clk_fixed_factor meson8b_fclk_div3_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div3_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -298,7 +318,9 @@ static struct clk_regmap meson8b_fclk_div3 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div3",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div3_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div3_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -309,7 +331,9 @@ static struct clk_fixed_factor meson8b_fclk_div4_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -322,7 +346,9 @@ static struct clk_regmap meson8b_fclk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div4",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div4_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div4_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -333,7 +359,9 @@ static struct clk_fixed_factor meson8b_fclk_div5_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -346,7 +374,9 @@ static struct clk_regmap meson8b_fclk_div5 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div5",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div5_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div5_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -357,7 +387,9 @@ static struct clk_fixed_factor meson8b_fclk_div7_div = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7_div",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -370,7 +402,9 @@ static struct clk_regmap meson8b_fclk_div7 = {
        .hw.init = &(struct clk_init_data){
                .name = "fclk_div7",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "fclk_div7_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div7_div.hw
+               },
                .num_parents = 1,
        },
 };
@@ -384,7 +418,9 @@ static struct clk_regmap meson8b_mpll_prediv = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll_prediv",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "fixed_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fixed_pll.hw
+               },
                .num_parents = 1,
        },
 };
@@ -416,7 +452,9 @@ static struct clk_regmap meson8b_mpll0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -429,7 +467,9 @@ static struct clk_regmap meson8b_mpll0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpll0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -457,7 +497,9 @@ static struct clk_regmap meson8b_mpll1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -470,7 +512,9 @@ static struct clk_regmap meson8b_mpll1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpll1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -498,7 +542,9 @@ static struct clk_regmap meson8b_mpll2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2_div",
                .ops = &meson_clk_mpll_ops,
-               .parent_names = (const char *[]){ "mpll_prediv" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpll_prediv.hw
+               },
                .num_parents = 1,
        },
 };
@@ -511,7 +557,9 @@ static struct clk_regmap meson8b_mpll2 = {
        .hw.init = &(struct clk_init_data){
                .name = "mpll2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpll2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpll2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -533,8 +581,11 @@ static struct clk_regmap meson8b_mpeg_clk_sel = {
                 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
                 * fclk_div4, fclk_div3, fclk_div5
                 */
-               .parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
-                       "fclk_div5" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div3.hw,
+                       &meson8b_fclk_div4.hw,
+                       &meson8b_fclk_div5.hw,
+               },
                .num_parents = 3,
        },
 };
@@ -548,7 +599,9 @@ static struct clk_regmap meson8b_mpeg_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mpeg_clk_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpeg_clk_sel.hw
+               },
                .num_parents = 1,
        },
 };
@@ -561,7 +614,9 @@ static struct clk_regmap meson8b_clk81 = {
        .hw.init = &(struct clk_init_data){
                .name = "clk81",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mpeg_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mpeg_clk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_IS_CRITICAL,
        },
@@ -576,7 +631,10 @@ static struct clk_regmap meson8b_cpu_in_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_in_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "xtal", "sys_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw,
+                       &meson8b_sys_pll.hw,
+               },
                .num_parents = 2,
                .flags = (CLK_SET_RATE_PARENT |
                          CLK_SET_RATE_NO_REPARENT),
@@ -589,7 +647,9 @@ static struct clk_fixed_factor meson8b_cpu_in_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_in_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_in_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_in_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -601,7 +661,9 @@ static struct clk_fixed_factor meson8b_cpu_in_div3 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_in_div3",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_in_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_in_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -630,7 +692,9 @@ static struct clk_regmap meson8b_cpu_scale_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_scale_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "cpu_in_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_in_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -649,13 +713,15 @@ static struct clk_regmap meson8b_cpu_scale_out_sel = {
                .ops = &clk_regmap_mux_ops,
                /*
                 * NOTE: We are skipping the parent with value 0x2 (which is
-                * "cpu_in_div3") because it results in a duty cycle of 33%
-                * which makes the system unstable and can result in a lockup
-                * of the whole system.
+                * meson8b_cpu_in_div3) because it results in a duty cycle of
+                * 33% which makes the system unstable and can result in a
+                * lockup of the whole system.
                 */
-               .parent_names = (const char *[]) { "cpu_in_sel",
-                                                  "cpu_in_div2",
-                                                  "cpu_scale_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_in_sel.hw,
+                       &meson8b_cpu_in_div2.hw,
+                       &meson8b_cpu_scale_div.hw,
+               },
                .num_parents = 3,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -670,8 +736,10 @@ static struct clk_regmap meson8b_cpu_clk = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "xtal",
-                                                 "cpu_scale_out_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw,
+                       &meson8b_cpu_scale_out_sel.hw,
+               },
                .num_parents = 2,
                .flags = (CLK_SET_RATE_PARENT |
                          CLK_SET_RATE_NO_REPARENT |
@@ -690,8 +758,13 @@ static struct clk_regmap meson8b_nand_clk_sel = {
                .name = "nand_clk_sel",
                .ops = &clk_regmap_mux_ops,
                /* FIXME all other parents are unknown: */
-               .parent_names = (const char *[]){ "fclk_div4", "fclk_div3",
-                       "fclk_div5", "fclk_div7", "xtal" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_fclk_div4.hw,
+                       &meson8b_fclk_div3.hw,
+                       &meson8b_fclk_div5.hw,
+                       &meson8b_fclk_div7.hw,
+                       &meson8b_xtal.hw,
+               },
                .num_parents = 5,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -707,7 +780,9 @@ static struct clk_regmap meson8b_nand_clk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "nand_clk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "nand_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_nand_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -721,7 +796,9 @@ static struct clk_regmap meson8b_nand_clk_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "nand_clk_gate",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "nand_clk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_nand_clk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -733,7 +810,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div2 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -744,7 +823,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div3 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div3",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -755,7 +836,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div4 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -766,7 +849,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div5 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div5",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -777,7 +862,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div6 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -788,7 +875,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div7 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div7",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -799,7 +888,9 @@ static struct clk_fixed_factor meson8b_cpu_clk_div8 = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk_div8",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "cpu_clk" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk.hw
+               },
                .num_parents = 1,
        },
 };
@@ -815,13 +906,15 @@ static struct clk_regmap meson8b_apb_clk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "apb_clk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "cpu_clk_div2",
-                                                 "cpu_clk_div3",
-                                                 "cpu_clk_div4",
-                                                 "cpu_clk_div5",
-                                                 "cpu_clk_div6",
-                                                 "cpu_clk_div7",
-                                                 "cpu_clk_div8", },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk_div2.hw,
+                       &meson8b_cpu_clk_div3.hw,
+                       &meson8b_cpu_clk_div4.hw,
+                       &meson8b_cpu_clk_div5.hw,
+                       &meson8b_cpu_clk_div6.hw,
+                       &meson8b_cpu_clk_div7.hw,
+                       &meson8b_cpu_clk_div8.hw,
+               },
                .num_parents = 7,
        },
 };
@@ -835,7 +928,9 @@ static struct clk_regmap meson8b_apb_clk_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "apb_clk_dis",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "apb_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_apb_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -850,13 +945,15 @@ static struct clk_regmap meson8b_periph_clk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "periph_clk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "cpu_clk_div2",
-                                                 "cpu_clk_div3",
-                                                 "cpu_clk_div4",
-                                                 "cpu_clk_div5",
-                                                 "cpu_clk_div6",
-                                                 "cpu_clk_div7",
-                                                 "cpu_clk_div8", },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk_div2.hw,
+                       &meson8b_cpu_clk_div3.hw,
+                       &meson8b_cpu_clk_div4.hw,
+                       &meson8b_cpu_clk_div5.hw,
+                       &meson8b_cpu_clk_div6.hw,
+                       &meson8b_cpu_clk_div7.hw,
+                       &meson8b_cpu_clk_div8.hw,
+               },
                .num_parents = 7,
        },
 };
@@ -870,7 +967,9 @@ static struct clk_regmap meson8b_periph_clk_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "periph_clk_dis",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "periph_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_periph_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -887,13 +986,15 @@ static struct clk_regmap meson8b_axi_clk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "axi_clk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "cpu_clk_div2",
-                                                 "cpu_clk_div3",
-                                                 "cpu_clk_div4",
-                                                 "cpu_clk_div5",
-                                                 "cpu_clk_div6",
-                                                 "cpu_clk_div7",
-                                                 "cpu_clk_div8", },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk_div2.hw,
+                       &meson8b_cpu_clk_div3.hw,
+                       &meson8b_cpu_clk_div4.hw,
+                       &meson8b_cpu_clk_div5.hw,
+                       &meson8b_cpu_clk_div6.hw,
+                       &meson8b_cpu_clk_div7.hw,
+                       &meson8b_cpu_clk_div8.hw,
+               },
                .num_parents = 7,
        },
 };
@@ -907,7 +1008,9 @@ static struct clk_regmap meson8b_axi_clk_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "axi_clk_dis",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "axi_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_axi_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -922,13 +1025,15 @@ static struct clk_regmap meson8b_l2_dram_clk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "l2_dram_clk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "cpu_clk_div2",
-                                                 "cpu_clk_div3",
-                                                 "cpu_clk_div4",
-                                                 "cpu_clk_div5",
-                                                 "cpu_clk_div6",
-                                                 "cpu_clk_div7",
-                                                 "cpu_clk_div8", },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cpu_clk_div2.hw,
+                       &meson8b_cpu_clk_div3.hw,
+                       &meson8b_cpu_clk_div4.hw,
+                       &meson8b_cpu_clk_div5.hw,
+                       &meson8b_cpu_clk_div6.hw,
+                       &meson8b_cpu_clk_div7.hw,
+                       &meson8b_cpu_clk_div8.hw,
+               },
                .num_parents = 7,
        },
 };
@@ -942,7 +1047,9 @@ static struct clk_regmap meson8b_l2_dram_clk_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "l2_dram_clk_dis",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "l2_dram_clk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_l2_dram_clk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -963,7 +1070,9 @@ static struct clk_regmap meson8b_vid_pll_in_sel = {
                 * Meson8b: hdmi_pll_dco
                 * Meson8m2: vid2_pll
                 */
-               .parent_names = (const char *[]){ "hdmi_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_hdmi_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -977,7 +1086,9 @@ static struct clk_regmap meson8b_vid_pll_in_en = {
        .hw.init = &(struct clk_init_data){
                .name = "vid_pll_in_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vid_pll_in_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vid_pll_in_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -992,7 +1103,9 @@ static struct clk_regmap meson8b_vid_pll_pre_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vid_pll_pre_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "vid_pll_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vid_pll_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1007,7 +1120,9 @@ static struct clk_regmap meson8b_vid_pll_post_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vid_pll_post_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "vid_pll_pre_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vid_pll_pre_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1023,8 +1138,10 @@ static struct clk_regmap meson8b_vid_pll = {
                .name = "vid_pll",
                .ops = &clk_regmap_mux_ro_ops,
                /* TODO: parent 0x2 is vid_pll_pre_div_mult7_div2 */
-               .parent_names = (const char *[]){ "vid_pll_pre_div",
-                                                 "vid_pll_post_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vid_pll_pre_div.hw,
+                       &meson8b_vid_pll_post_div.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1039,15 +1156,22 @@ static struct clk_regmap meson8b_vid_pll_final_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vid_pll_final_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "vid_pll" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vid_pll.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const meson8b_vclk_mux_parents[] = {
-       "vid_pll_final_div", "fclk_div4", "fclk_div3", "fclk_div5",
-       "vid_pll_final_div", "fclk_div7", "mpll1"
+static const struct clk_hw *meson8b_vclk_mux_parent_hws[] = {
+       &meson8b_vid_pll_final_div.hw,
+       &meson8b_fclk_div4.hw,
+       &meson8b_fclk_div3.hw,
+       &meson8b_fclk_div5.hw,
+       &meson8b_vid_pll_final_div.hw,
+       &meson8b_fclk_div7.hw,
+       &meson8b_mpll1.hw,
 };
 
 static struct clk_regmap meson8b_vclk_in_sel = {
@@ -1059,8 +1183,8 @@ static struct clk_regmap meson8b_vclk_in_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_in_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents),
+               .parent_hws = meson8b_vclk_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1073,7 +1197,9 @@ static struct clk_regmap meson8b_vclk_in_en = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_in_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk_in_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_in_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1087,7 +1213,9 @@ static struct clk_regmap meson8b_vclk_div1_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div1_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1099,7 +1227,9 @@ static struct clk_fixed_factor meson8b_vclk_div2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1113,7 +1243,9 @@ static struct clk_regmap meson8b_vclk_div2_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div2_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk_div2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_div2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1125,7 +1257,9 @@ static struct clk_fixed_factor meson8b_vclk_div4_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1139,7 +1273,9 @@ static struct clk_regmap meson8b_vclk_div4_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div4_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk_div4" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_div4_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1151,7 +1287,9 @@ static struct clk_fixed_factor meson8b_vclk_div6_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1165,7 +1303,9 @@ static struct clk_regmap meson8b_vclk_div6_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div6_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk_div6" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_div6_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1177,7 +1317,9 @@ static struct clk_fixed_factor meson8b_vclk_div12_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div12",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1191,7 +1333,9 @@ static struct clk_regmap meson8b_vclk_div12_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk_div12_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk_div12" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk_div12_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1206,8 +1350,8 @@ static struct clk_regmap meson8b_vclk2_in_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_in_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parents),
+               .parent_hws = meson8b_vclk_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1220,7 +1364,9 @@ static struct clk_regmap meson8b_vclk2_clk_in_en = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_in_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk2_in_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_in_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1234,7 +1380,9 @@ static struct clk_regmap meson8b_vclk2_div1_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div1_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk2_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_clk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1246,7 +1394,9 @@ static struct clk_fixed_factor meson8b_vclk2_div2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div2",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_clk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1260,7 +1410,9 @@ static struct clk_regmap meson8b_vclk2_div2_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div2_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk2_div2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_div2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1272,7 +1424,9 @@ static struct clk_fixed_factor meson8b_vclk2_div4_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div4",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_clk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1286,7 +1440,9 @@ static struct clk_regmap meson8b_vclk2_div4_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div4_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk2_div4" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_div4_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1298,7 +1454,9 @@ static struct clk_fixed_factor meson8b_vclk2_div6_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div6",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_clk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1312,7 +1470,9 @@ static struct clk_regmap meson8b_vclk2_div6_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div6_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk2_div6" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_div6_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1324,7 +1484,9 @@ static struct clk_fixed_factor meson8b_vclk2_div12_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div12",
                .ops = &clk_fixed_factor_ops,
-               .parent_names = (const char *[]){ "vclk2_in_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_clk_in_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        }
@@ -1338,15 +1500,20 @@ static struct clk_regmap meson8b_vclk2_div12_div_gate = {
        .hw.init = &(struct clk_init_data){
                .name = "vclk2_div12_en",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "vclk2_div12" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vclk2_div12_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const meson8b_vclk_enc_mux_parents[] = {
-       "vclk_div1_en", "vclk_div2_en", "vclk_div4_en", "vclk_div6_en",
-       "vclk_div12_en",
+static const struct clk_hw *meson8b_vclk_enc_mux_parent_hws[] = {
+       &meson8b_vclk_div1_gate.hw,
+       &meson8b_vclk_div2_div_gate.hw,
+       &meson8b_vclk_div4_div_gate.hw,
+       &meson8b_vclk_div6_div_gate.hw,
+       &meson8b_vclk_div12_div_gate.hw,
 };
 
 static struct clk_regmap meson8b_cts_enct_sel = {
@@ -1358,8 +1525,8 @@ static struct clk_regmap meson8b_cts_enct_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_enct_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk_enc_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
+               .parent_hws = meson8b_vclk_enc_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1372,7 +1539,9 @@ static struct clk_regmap meson8b_cts_enct = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_enct",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cts_enct_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_enct_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1387,8 +1556,8 @@ static struct clk_regmap meson8b_cts_encp_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_encp_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk_enc_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
+               .parent_hws = meson8b_vclk_enc_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1401,7 +1570,9 @@ static struct clk_regmap meson8b_cts_encp = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_encp",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cts_encp_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_encp_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1416,8 +1587,8 @@ static struct clk_regmap meson8b_cts_enci_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_enci_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk_enc_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
+               .parent_hws = meson8b_vclk_enc_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1430,7 +1601,9 @@ static struct clk_regmap meson8b_cts_enci = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_enci",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cts_enci_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_enci_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1445,8 +1618,8 @@ static struct clk_regmap meson8b_hdmi_tx_pixel_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_tx_pixel_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk_enc_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parents),
+               .parent_hws = meson8b_vclk_enc_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk_enc_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1459,15 +1632,20 @@ static struct clk_regmap meson8b_hdmi_tx_pixel = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_tx_pixel",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_tx_pixel_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_hdmi_tx_pixel_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const meson8b_vclk2_enc_mux_parents[] = {
-       "vclk2_div1_en", "vclk2_div2_en", "vclk2_div4_en", "vclk2_div6_en",
-       "vclk2_div12_en",
+static const struct clk_hw *meson8b_vclk2_enc_mux_parent_hws[] = {
+       &meson8b_vclk2_div1_gate.hw,
+       &meson8b_vclk2_div2_div_gate.hw,
+       &meson8b_vclk2_div4_div_gate.hw,
+       &meson8b_vclk2_div6_div_gate.hw,
+       &meson8b_vclk2_div12_div_gate.hw,
 };
 
 static struct clk_regmap meson8b_cts_encl_sel = {
@@ -1479,8 +1657,8 @@ static struct clk_regmap meson8b_cts_encl_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_encl_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk2_enc_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents),
+               .parent_hws = meson8b_vclk2_enc_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1493,7 +1671,9 @@ static struct clk_regmap meson8b_cts_encl = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_encl",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cts_encl_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_encl_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1508,8 +1688,8 @@ static struct clk_regmap meson8b_cts_vdac0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_vdac0_sel",
                .ops = &clk_regmap_mux_ro_ops,
-               .parent_names = meson8b_vclk2_enc_mux_parents,
-               .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parents),
+               .parent_hws = meson8b_vclk2_enc_mux_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vclk2_enc_mux_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1522,7 +1702,9 @@ static struct clk_regmap meson8b_cts_vdac0 = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_vdac0",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "cts_vdac0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_vdac0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1539,7 +1721,9 @@ static struct clk_regmap meson8b_hdmi_sys_sel = {
                .name = "hdmi_sys_sel",
                .ops = &clk_regmap_mux_ro_ops,
                /* FIXME: all other parents are unknown */
-               .parent_names = (const char *[]){ "xtal" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
@@ -1554,7 +1738,9 @@ static struct clk_regmap meson8b_hdmi_sys_div = {
        .hw.init = &(struct clk_init_data){
                .name = "hdmi_sys_div",
                .ops = &clk_regmap_divider_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_sys_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_hdmi_sys_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1568,7 +1754,9 @@ static struct clk_regmap meson8b_hdmi_sys = {
        .hw.init = &(struct clk_init_data) {
                .name = "hdmi_sys",
                .ops = &clk_regmap_gate_ro_ops,
-               .parent_names = (const char *[]){ "hdmi_sys_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_hdmi_sys_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1579,9 +1767,14 @@ static struct clk_regmap meson8b_hdmi_sys = {
  * muxed by a glitch-free switch on Meson8b and Meson8m2. Meson8 only
  * has mali_0 and no glitch-free mux.
  */
-static const char * const meson8b_mali_0_1_parent_names[] = {
-       "xtal", "mpll2", "mpll1", "fclk_div7", "fclk_div4", "fclk_div3",
-       "fclk_div5"
+static const struct clk_hw *meson8b_mali_0_1_parent_hws[] = {
+       &meson8b_xtal.hw,
+       &meson8b_mpll2.hw,
+       &meson8b_mpll1.hw,
+       &meson8b_fclk_div7.hw,
+       &meson8b_fclk_div4.hw,
+       &meson8b_fclk_div3.hw,
+       &meson8b_fclk_div5.hw,
 };
 
 static u32 meson8b_mali_0_1_mux_table[] = { 0, 2, 3, 4, 5, 6, 7 };
@@ -1596,8 +1789,8 @@ static struct clk_regmap meson8b_mali_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_mali_0_1_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_names),
+               .parent_hws = meson8b_mali_0_1_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws),
                /*
                 * Don't propagate rate changes up because the only changeable
                 * parents are mpll1 and mpll2 but we need those for audio and
@@ -1617,7 +1810,9 @@ static struct clk_regmap meson8b_mali_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mali_0_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mali_0_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1631,7 +1826,9 @@ static struct clk_regmap meson8b_mali_0 = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mali_0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mali_0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1647,8 +1844,8 @@ static struct clk_regmap meson8b_mali_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_mali_0_1_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_names),
+               .parent_hws = meson8b_mali_0_1_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws),
                /*
                 * Don't propagate rate changes up because the only changeable
                 * parents are mpll1 and mpll2 but we need those for audio and
@@ -1668,7 +1865,9 @@ static struct clk_regmap meson8b_mali_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "mali_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mali_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1682,7 +1881,9 @@ static struct clk_regmap meson8b_mali_1 = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "mali_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mali_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1697,7 +1898,10 @@ static struct clk_regmap meson8b_mali = {
        .hw.init = &(struct clk_init_data){
                .name = "mali",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "mali_0", "mali_1" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_mali_0.hw,
+                       &meson8b_mali_1.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1740,7 +1944,9 @@ static struct clk_regmap meson8m2_gp_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "gp_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_names = (const char *[]){ "xtal" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_xtal.hw
+               },
                .num_parents = 1,
        },
 };
@@ -1755,18 +1961,26 @@ static struct clk_regmap meson8m2_gp_pll = {
        .hw.init = &(struct clk_init_data){
                .name = "gp_pll",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "gp_pll_dco" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8m2_gp_pll_dco.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
-static const char * const meson8b_vpu_0_1_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7"
+static const struct clk_hw *meson8b_vpu_0_1_parent_hws[] = {
+       &meson8b_fclk_div4.hw,
+       &meson8b_fclk_div3.hw,
+       &meson8b_fclk_div5.hw,
+       &meson8b_fclk_div7.hw,
 };
 
-static const char * const mmeson8m2_vpu_0_1_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "gp_pll"
+static const struct clk_hw *mmeson8m2_vpu_0_1_parent_hws[] = {
+       &meson8b_fclk_div4.hw,
+       &meson8b_fclk_div3.hw,
+       &meson8b_fclk_div5.hw,
+       &meson8m2_gp_pll.hw,
 };
 
 static struct clk_regmap meson8b_vpu_0_sel = {
@@ -1778,8 +1992,8 @@ static struct clk_regmap meson8b_vpu_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_vpu_0_1_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_names),
+               .parent_hws = meson8b_vpu_0_1_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1793,8 +2007,8 @@ static struct clk_regmap meson8m2_vpu_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = mmeson8m2_vpu_0_1_parent_names,
-               .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_names),
+               .parent_hws = mmeson8m2_vpu_0_1_parent_hws,
+               .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1808,7 +2022,17 @@ static struct clk_regmap meson8b_vpu_0_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_0_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vpu_0_sel" },
+               .parent_data = &(const struct clk_parent_data) {
+                       /*
+                        * Note:
+                        * meson8b and meson8m2 have different vpu_0_sels (with
+                        * different struct clk_hw). We fallback to the global
+                        * naming string mechanism so vpu_0_div picks up the
+                        * appropriate one.
+                        */
+                       .name = "vpu_0_sel",
+                       .index = -1,
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1822,7 +2046,9 @@ static struct clk_regmap meson8b_vpu_0 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vpu_0",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vpu_0_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vpu_0_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1837,8 +2063,8 @@ static struct clk_regmap meson8b_vpu_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_vpu_0_1_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_names),
+               .parent_hws = meson8b_vpu_0_1_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vpu_0_1_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1852,8 +2078,8 @@ static struct clk_regmap meson8m2_vpu_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = mmeson8m2_vpu_0_1_parent_names,
-               .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_names),
+               .parent_hws = mmeson8m2_vpu_0_1_parent_hws,
+               .num_parents = ARRAY_SIZE(mmeson8m2_vpu_0_1_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1867,7 +2093,17 @@ static struct clk_regmap meson8b_vpu_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vpu_1_sel" },
+               .parent_data = &(const struct clk_parent_data) {
+                       /*
+                        * Note:
+                        * meson8b and meson8m2 have different vpu_1_sels (with
+                        * different struct clk_hw). We fallback to the global
+                        * naming string mechanism so vpu_1_div picks up the
+                        * appropriate one.
+                        */
+                       .name = "vpu_1_sel",
+                       .index = -1,
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1881,7 +2117,9 @@ static struct clk_regmap meson8b_vpu_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vpu_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vpu_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vpu_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1896,14 +2134,22 @@ static struct clk_regmap meson8b_vpu = {
        .hw.init = &(struct clk_init_data){
                .name = "vpu",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "vpu_0", "vpu_1" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vpu_0.hw,
+                       &meson8b_vpu_1.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_NO_REPARENT,
        },
 };
 
-static const char * const meson8b_vdec_parent_names[] = {
-       "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "mpll2", "mpll1"
+static const struct clk_hw *meson8b_vdec_parent_hws[] = {
+       &meson8b_fclk_div4.hw,
+       &meson8b_fclk_div3.hw,
+       &meson8b_fclk_div5.hw,
+       &meson8b_fclk_div7.hw,
+       &meson8b_mpll2.hw,
+       &meson8b_mpll1.hw,
 };
 
 static struct clk_regmap meson8b_vdec_1_sel = {
@@ -1916,8 +2162,8 @@ static struct clk_regmap meson8b_vdec_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
+               .parent_hws = meson8b_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -1932,7 +2178,9 @@ static struct clk_regmap meson8b_vdec_1_1_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_1_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1946,7 +2194,9 @@ static struct clk_regmap meson8b_vdec_1_1 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_1_1",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_1_1_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_1_1_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1962,7 +2212,9 @@ static struct clk_regmap meson8b_vdec_1_2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1_2_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_1_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_1_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1976,7 +2228,9 @@ static struct clk_regmap meson8b_vdec_1_2 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_1_2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_1_2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_1_2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -1992,7 +2246,10 @@ static struct clk_regmap meson8b_vdec_1 = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_1",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "vdec_1_1", "vdec_1_2" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_1_1.hw,
+                       &meson8b_vdec_1_2.hw,
+               },
                .num_parents = 2,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2008,8 +2265,8 @@ static struct clk_regmap meson8b_vdec_hcodec_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hcodec_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
+               .parent_hws = meson8b_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2024,7 +2281,9 @@ static struct clk_regmap meson8b_vdec_hcodec_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hcodec_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_hcodec_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_hcodec_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2038,7 +2297,9 @@ static struct clk_regmap meson8b_vdec_hcodec = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_hcodec",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_hcodec_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_hcodec_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2054,8 +2315,8 @@ static struct clk_regmap meson8b_vdec_2_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_2_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
+               .parent_hws = meson8b_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2070,7 +2331,9 @@ static struct clk_regmap meson8b_vdec_2_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_2_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_2_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_2_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2084,7 +2347,9 @@ static struct clk_regmap meson8b_vdec_2 = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_2",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_2_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_2_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2100,8 +2365,8 @@ static struct clk_regmap meson8b_vdec_hevc_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevc_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_vdec_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names),
+               .parent_hws = meson8b_vdec_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_vdec_parent_hws),
                .flags = CLK_SET_RATE_PARENT,
        },
 };
@@ -2116,7 +2381,9 @@ static struct clk_regmap meson8b_vdec_hevc_div = {
        .hw.init = &(struct clk_init_data){
                .name = "vdec_hevc_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "vdec_hevc_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_hevc_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2130,7 +2397,9 @@ static struct clk_regmap meson8b_vdec_hevc_en = {
        .hw.init = &(struct clk_init_data) {
                .name = "vdec_hevc_en",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "vdec_hevc_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_hevc_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2147,15 +2416,19 @@ static struct clk_regmap meson8b_vdec_hevc = {
                .name = "vdec_hevc",
                .ops = &clk_regmap_mux_ops,
                /* TODO: The second parent is currently unknown */
-               .parent_names = (const char *[]){ "vdec_hevc_en" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_vdec_hevc_en.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
 /* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */
-static const char * const meson8b_cts_amclk_parent_names[] = {
-       "mpll0", "mpll1", "mpll2"
+static const struct clk_hw *meson8b_cts_amclk_parent_hws[] = {
+       &meson8b_mpll0.hw,
+       &meson8b_mpll1.hw,
+       &meson8b_mpll2.hw
 };
 
 static u32 meson8b_cts_amclk_mux_table[] = { 1, 2, 3 };
@@ -2171,8 +2444,8 @@ static struct clk_regmap meson8b_cts_amclk_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_cts_amclk_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_cts_amclk_parent_names),
+               .parent_hws = meson8b_cts_amclk_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_cts_amclk_parent_hws),
        },
 };
 
@@ -2186,7 +2459,9 @@ static struct clk_regmap meson8b_cts_amclk_div = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "cts_amclk_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_amclk_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2200,15 +2475,19 @@ static struct clk_regmap meson8b_cts_amclk = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_amclk",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_amclk_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_amclk_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
 };
 
 /* TODO: the clock at index 0 is "DDR_PLL" which we don't support yet */
-static const char * const meson8b_cts_mclk_i958_parent_names[] = {
-       "mpll0", "mpll1", "mpll2"
+static const struct clk_hw *meson8b_cts_mclk_i958_parent_hws[] = {
+       &meson8b_mpll0.hw,
+       &meson8b_mpll1.hw,
+       &meson8b_mpll2.hw
 };
 
 static u32 meson8b_cts_mclk_i958_mux_table[] = { 1, 2, 3 };
@@ -2224,8 +2503,8 @@ static struct clk_regmap meson8b_cts_mclk_i958_sel = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_mclk_i958_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = meson8b_cts_mclk_i958_parent_names,
-               .num_parents = ARRAY_SIZE(meson8b_cts_mclk_i958_parent_names),
+               .parent_hws = meson8b_cts_mclk_i958_parent_hws,
+               .num_parents = ARRAY_SIZE(meson8b_cts_mclk_i958_parent_hws),
        },
 };
 
@@ -2239,7 +2518,9 @@ static struct clk_regmap meson8b_cts_mclk_i958_div = {
        .hw.init = &(struct clk_init_data) {
                .name = "cts_mclk_i958_div",
                .ops = &clk_regmap_divider_ops,
-               .parent_names = (const char *[]){ "cts_mclk_i958_sel" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_mclk_i958_sel.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2253,7 +2534,9 @@ static struct clk_regmap meson8b_cts_mclk_i958 = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_mclk_i958",
                .ops = &clk_regmap_gate_ops,
-               .parent_names = (const char *[]){ "cts_mclk_i958_div" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_mclk_i958_div.hw
+               },
                .num_parents = 1,
                .flags = CLK_SET_RATE_PARENT,
        },
@@ -2268,8 +2551,10 @@ static struct clk_regmap meson8b_cts_i958 = {
        .hw.init = &(struct clk_init_data){
                .name = "cts_i958",
                .ops = &clk_regmap_mux_ops,
-               .parent_names = (const char *[]){ "cts_amclk",
-                                                 "cts_mclk_i958" },
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8b_cts_amclk.hw,
+                       &meson8b_cts_mclk_i958.hw
+               },
                .num_parents = 2,
                /*
                 * The parent is specific to origin of the audio data. Let the
@@ -2279,6 +2564,9 @@ static struct clk_regmap meson8b_cts_i958 = {
        },
 };
 
+#define MESON_GATE(_name, _reg, _bit) \
+       MESON_PCLK(_name, _reg, _bit, &meson8b_clk81.hw)
+
 /* Everything Else (EE) domain gates */
 
 static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
index 09e0311..470c7ef 100644 (file)
@@ -2,6 +2,10 @@
 /*
  * Copyright (C) 2012 Regents of the University of California
  * Copyright (C) 2017 SiFive
+ *
+ * All RISC-V systems have a timer attached to every hart.  These timers can be
+ * read from the "time" and "timeh" CSRs, and can use the SBI to setup
+ * events.
  */
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <asm/smp.h>
 #include <asm/sbi.h>
 
-/*
- * All RISC-V systems have a timer attached to every hart.  These timers can be
- * read by the 'rdcycle' pseudo instruction, and can use the SBI to setup
- * events.  In order to abstract the architecture-specific timer reading and
- * setting functions away from the clock event insertion code, we provide
- * function pointers to the clockevent subsystem that perform two basic
- * operations: rdtime() reads the timer on the current CPU, and
- * next_event(delta) sets the next timer event to 'delta' cycles in the future.
- * As the timers are inherently a per-cpu resource, these callbacks perform
- * operations on the current hart.  There is guaranteed to be exactly one timer
- * per hart on all RISC-V systems.
- */
-
 static int riscv_clock_next_event(unsigned long delta,
                struct clock_event_device *ce)
 {
index 48cb3d4..d853047 100644 (file)
@@ -13,6 +13,16 @@ config ARM_CPUIDLE
           initialized by calling the CPU operations init idle hook
           provided by architecture code.
 
+config ARM_PSCI_CPUIDLE
+       bool "PSCI CPU idle Driver"
+       depends on ARM_PSCI_FW
+       select DT_IDLE_STATES
+       select CPU_IDLE_MULTIPLE_DRIVERS
+       help
+         Select this to enable PSCI firmware based CPUidle driver for ARM.
+         It provides an idle driver that is capable of detecting and
+         managing idle states through the PSCI firmware interface.
+
 config ARM_BIG_LITTLE_CPUIDLE
        bool "Support for ARM big.LITTLE processors"
        depends on ARCH_VEXPRESS_TC2_PM || ARCH_EXYNOS
index 9d7176c..40d0163 100644 (file)
@@ -20,6 +20,7 @@ obj-$(CONFIG_ARM_U8500_CPUIDLE)         += cpuidle-ux500.o
 obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
 obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
 obj-$(CONFIG_ARM_CPUIDLE)              += cpuidle-arm.o
+obj-$(CONFIG_ARM_PSCI_CPUIDLE)         += cpuidle-psci.o
 
 ###############################################################################
 # MIPS drivers
index 5bcd82c..9e5156d 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/slab.h>
-#include <linux/topology.h>
 
 #include <asm/cpuidle.h>
 
@@ -106,11 +105,17 @@ static int __init arm_idle_init_cpu(int cpu)
        ret = arm_cpuidle_init(cpu);
 
        /*
-        * Allow the initialization to continue for other CPUs, if the reported
-        * failure is a HW misconfiguration/breakage (-ENXIO).
+        * Allow the initialization to continue for other CPUs, if the
+        * reported failure is a HW misconfiguration/breakage (-ENXIO).
+        *
+        * Some platforms do not support idle operations
+        * (arm_cpuidle_init() returning -EOPNOTSUPP), we should
+        * not flag this case as an error, it is a valid
+        * configuration.
         */
        if (ret) {
-               pr_err("CPU %d failed to init idle CPU ops\n", cpu);
+               if (ret != -EOPNOTSUPP)
+                       pr_err("CPU %d failed to init idle CPU ops\n", cpu);
                ret = ret == -ENXIO ? 0 : ret;
                goto out_kfree_drv;
        }
diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c
new file mode 100644 (file)
index 0000000..f3c1a23
--- /dev/null
@@ -0,0 +1,236 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * PSCI CPU idle driver.
+ *
+ * Copyright (C) 2019 ARM Ltd.
+ * Author: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
+ */
+
+#define pr_fmt(fmt) "CPUidle PSCI: " fmt
+
+#include <linux/cpuidle.h>
+#include <linux/cpumask.h>
+#include <linux/cpu_pm.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/psci.h>
+#include <linux/slab.h>
+
+#include <asm/cpuidle.h>
+
+#include "dt_idle_states.h"
+
+static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
+
+static int psci_enter_idle_state(struct cpuidle_device *dev,
+                               struct cpuidle_driver *drv, int idx)
+{
+       u32 *state = __this_cpu_read(psci_power_state);
+
+       return CPU_PM_CPU_IDLE_ENTER_PARAM(psci_cpu_suspend_enter,
+                                          idx, state[idx - 1]);
+}
+
+static struct cpuidle_driver psci_idle_driver __initdata = {
+       .name = "psci_idle",
+       .owner = THIS_MODULE,
+       /*
+        * PSCI idle states relies on architectural WFI to
+        * be represented as state index 0.
+        */
+       .states[0] = {
+               .enter                  = psci_enter_idle_state,
+               .exit_latency           = 1,
+               .target_residency       = 1,
+               .power_usage            = UINT_MAX,
+               .name                   = "WFI",
+               .desc                   = "ARM WFI",
+       }
+};
+
+static const struct of_device_id psci_idle_state_match[] __initconst = {
+       { .compatible = "arm,idle-state",
+         .data = psci_enter_idle_state },
+       { },
+};
+
+static int __init psci_dt_parse_state_node(struct device_node *np, u32 *state)
+{
+       int err = of_property_read_u32(np, "arm,psci-suspend-param", state);
+
+       if (err) {
+               pr_warn("%pOF missing arm,psci-suspend-param property\n", np);
+               return err;
+       }
+
+       if (!psci_power_state_is_valid(*state)) {
+               pr_warn("Invalid PSCI power state %#x\n", *state);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int __init psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
+{
+       int i, ret = 0, count = 0;
+       u32 *psci_states;
+       struct device_node *state_node;
+
+       /* Count idle states */
+       while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
+                                             count))) {
+               count++;
+               of_node_put(state_node);
+       }
+
+       if (!count)
+               return -ENODEV;
+
+       psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
+       if (!psci_states)
+               return -ENOMEM;
+
+       for (i = 0; i < count; i++) {
+               state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
+               ret = psci_dt_parse_state_node(state_node, &psci_states[i]);
+               of_node_put(state_node);
+
+               if (ret)
+                       goto free_mem;
+
+               pr_debug("psci-power-state %#x index %d\n", psci_states[i], i);
+       }
+
+       /* Idle states parsed correctly, initialize per-cpu pointer */
+       per_cpu(psci_power_state, cpu) = psci_states;
+       return 0;
+
+free_mem:
+       kfree(psci_states);
+       return ret;
+}
+
+static __init int psci_cpu_init_idle(unsigned int cpu)
+{
+       struct device_node *cpu_node;
+       int ret;
+
+       /*
+        * If the PSCI cpu_suspend function hook has not been initialized
+        * idle states must not be enabled, so bail out
+        */
+       if (!psci_ops.cpu_suspend)
+               return -EOPNOTSUPP;
+
+       cpu_node = of_cpu_device_node_get(cpu);
+       if (!cpu_node)
+               return -ENODEV;
+
+       ret = psci_dt_cpu_init_idle(cpu_node, cpu);
+
+       of_node_put(cpu_node);
+
+       return ret;
+}
+
+static int __init psci_idle_init_cpu(int cpu)
+{
+       struct cpuidle_driver *drv;
+       struct device_node *cpu_node;
+       const char *enable_method;
+       int ret = 0;
+
+       cpu_node = of_cpu_device_node_get(cpu);
+       if (!cpu_node)
+               return -ENODEV;
+
+       /*
+        * Check whether the enable-method for the cpu is PSCI, fail
+        * if it is not.
+        */
+       enable_method = of_get_property(cpu_node, "enable-method", NULL);
+       if (!enable_method || (strcmp(enable_method, "psci")))
+               ret = -ENODEV;
+
+       of_node_put(cpu_node);
+       if (ret)
+               return ret;
+
+       drv = kmemdup(&psci_idle_driver, sizeof(*drv), GFP_KERNEL);
+       if (!drv)
+               return -ENOMEM;
+
+       drv->cpumask = (struct cpumask *)cpumask_of(cpu);
+
+       /*
+        * Initialize idle states data, starting at index 1, since
+        * by default idle state 0 is the quiescent state reached
+        * by the cpu by executing the wfi instruction.
+        *
+        * If no DT idle states are detected (ret == 0) let the driver
+        * initialization fail accordingly since there is no reason to
+        * initialize the idle driver if only wfi is supported, the
+        * default archictectural back-end already executes wfi
+        * on idle entry.
+        */
+       ret = dt_init_idle_driver(drv, psci_idle_state_match, 1);
+       if (ret <= 0) {
+               ret = ret ? : -ENODEV;
+               goto out_kfree_drv;
+       }
+
+       /*
+        * Initialize PSCI idle states.
+        */
+       ret = psci_cpu_init_idle(cpu);
+       if (ret) {
+               pr_err("CPU %d failed to PSCI idle\n", cpu);
+               goto out_kfree_drv;
+       }
+
+       ret = cpuidle_register(drv, NULL);
+       if (ret)
+               goto out_kfree_drv;
+
+       return 0;
+
+out_kfree_drv:
+       kfree(drv);
+       return ret;
+}
+
+/*
+ * psci_idle_init - Initializes PSCI cpuidle driver
+ *
+ * Initializes PSCI cpuidle driver for all CPUs, if any CPU fails
+ * to register cpuidle driver then rollback to cancel all CPUs
+ * registration.
+ */
+static int __init psci_idle_init(void)
+{
+       int cpu, ret;
+       struct cpuidle_driver *drv;
+       struct cpuidle_device *dev;
+
+       for_each_possible_cpu(cpu) {
+               ret = psci_idle_init_cpu(cpu);
+               if (ret)
+                       goto out_fail;
+       }
+
+       return 0;
+
+out_fail:
+       while (--cpu >= 0) {
+               dev = per_cpu(cpuidle_devices, cpu);
+               drv = cpuidle_get_cpu_driver(dev);
+               cpuidle_unregister(drv);
+               kfree(drv);
+       }
+
+       return ret;
+}
+device_initcall(psci_idle_init);
index f79eede..edefa66 100644 (file)
@@ -540,6 +540,10 @@ int ccp_dev_suspend(struct sp_device *sp, pm_message_t state)
        unsigned long flags;
        unsigned int i;
 
+       /* If there's no device there's nothing to do */
+       if (!ccp)
+               return 0;
+
        spin_lock_irqsave(&ccp->cmd_lock, flags);
 
        ccp->suspending = 1;
@@ -564,6 +568,10 @@ int ccp_dev_resume(struct sp_device *sp)
        unsigned long flags;
        unsigned int i;
 
+       /* If there's no device there's nothing to do */
+       if (!ccp)
+               return 0;
+
        spin_lock_irqsave(&ccp->cmd_lock, flags);
 
        ccp->suspending = 0;
index 03fa0c5..413efef 100644 (file)
@@ -294,8 +294,8 @@ config INTEL_IOATDMA
          If unsure, say N.
 
 config INTEL_IOP_ADMA
-       tristate "Intel IOP ADMA support"
-       depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
+       tristate "Intel IOP32x ADMA support"
+       depends on ARCH_IOP32X
        select DMA_ENGINE
        select ASYNC_TX_ENABLE_CHANNEL_SWITCH
        help
index 8101ff2..67100e4 100644 (file)
 #define BCM2835_DMA_MAX_DMA_CHAN_SUPPORTED 14
 #define BCM2835_DMA_CHAN_NAME_SIZE 8
 
+/**
+ * struct bcm2835_dmadev - BCM2835 DMA controller
+ * @ddev: DMA device
+ * @base: base address of register map
+ * @dma_parms: DMA parameters (to convey 1 GByte max segment size to clients)
+ * @zero_page: bus address of zero page (to detect transactions copying from
+ *     zero page and avoid accessing memory if so)
+ */
 struct bcm2835_dmadev {
        struct dma_device ddev;
        void __iomem *base;
        struct device_dma_parameters dma_parms;
+       dma_addr_t zero_page;
 };
 
 struct bcm2835_dma_cb {
@@ -687,11 +696,12 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
        size_t period_len, enum dma_transfer_direction direction,
        unsigned long flags)
 {
+       struct bcm2835_dmadev *od = to_bcm2835_dma_dev(chan->device);
        struct bcm2835_chan *c = to_bcm2835_dma_chan(chan);
        struct bcm2835_desc *d;
        dma_addr_t src, dst;
        u32 info = BCM2835_DMA_WAIT_RESP;
-       u32 extra = BCM2835_DMA_INT_EN;
+       u32 extra = 0;
        size_t max_len = bcm2835_dma_max_frame_length(c);
        size_t frames;
 
@@ -707,6 +717,11 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
                return NULL;
        }
 
+       if (flags & DMA_PREP_INTERRUPT)
+               extra |= BCM2835_DMA_INT_EN;
+       else
+               period_len = buf_len;
+
        /*
         * warn if buf_len is not a multiple of period_len - this may leed
         * to unexpected latencies for interrupts and thus audiable clicks
@@ -732,6 +747,10 @@ static struct dma_async_tx_descriptor *bcm2835_dma_prep_dma_cyclic(
                dst = c->cfg.dst_addr;
                src = buf_addr;
                info |= BCM2835_DMA_D_DREQ | BCM2835_DMA_S_INC;
+
+               /* non-lite channels can write zeroes w/o accessing memory */
+               if (buf_addr == od->zero_page && !c->is_lite_channel)
+                       info |= BCM2835_DMA_S_IGNORE;
        }
 
        /* calculate number of frames */
@@ -778,7 +797,10 @@ static int bcm2835_dma_terminate_all(struct dma_chan *chan)
 
        /* stop DMA activity */
        if (c->desc) {
-               vchan_terminate_vdesc(&c->desc->vd);
+               if (c->desc->vd.tx.flags & DMA_PREP_INTERRUPT)
+                       vchan_terminate_vdesc(&c->desc->vd);
+               else
+                       vchan_vdesc_fini(&c->desc->vd);
                c->desc = NULL;
                bcm2835_dma_abort(c);
        }
@@ -831,6 +853,9 @@ static void bcm2835_dma_free(struct bcm2835_dmadev *od)
                list_del(&c->vc.chan.device_node);
                tasklet_kill(&c->vc.task);
        }
+
+       dma_unmap_page_attrs(od->ddev.dev, od->zero_page, PAGE_SIZE,
+                            DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
 }
 
 static const struct of_device_id bcm2835_dma_of_match[] = {
@@ -907,11 +932,20 @@ static int bcm2835_dma_probe(struct platform_device *pdev)
        od->ddev.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV) |
                              BIT(DMA_MEM_TO_MEM);
        od->ddev.residue_granularity = DMA_RESIDUE_GRANULARITY_BURST;
+       od->ddev.descriptor_reuse = true;
        od->ddev.dev = &pdev->dev;
        INIT_LIST_HEAD(&od->ddev.channels);
 
        platform_set_drvdata(pdev, od);
 
+       od->zero_page = dma_map_page_attrs(od->ddev.dev, ZERO_PAGE(0), 0,
+                                          PAGE_SIZE, DMA_TO_DEVICE,
+                                          DMA_ATTR_SKIP_CPU_SYNC);
+       if (dma_mapping_error(od->ddev.dev, od->zero_page)) {
+               dev_err(&pdev->dev, "Failed to map zero page\n");
+               return -ENOMEM;
+       }
+
        /* Request DMA channel mask from device tree */
        if (of_property_read_u32(pdev->dev.of_node,
                        "brcm,dma-channel-mask",
index c6c0143..03f4a58 100644 (file)
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/prefetch.h>
 #include <linux/memory.h>
 #include <linux/ioport.h>
 #include <linux/raid/pq.h>
 #include <linux/slab.h>
 
-#include <mach/adma.h>
-
+#include "iop-adma.h"
 #include "dmaengine.h"
 
 #define to_iop_adma_chan(chan) container_of(chan, struct iop_adma_chan, common)
@@ -116,9 +116,9 @@ static void __iop_adma_slot_cleanup(struct iop_adma_chan *iop_chan)
        list_for_each_entry_safe(iter, _iter, &iop_chan->chain,
                                        chain_node) {
                pr_debug("\tcookie: %d slot: %d busy: %d "
-                       "this_desc: %#x next_desc: %#x ack: %d\n",
+                       "this_desc: %#x next_desc: %#llx ack: %d\n",
                        iter->async_tx.cookie, iter->idx, busy,
-                       iter->async_tx.phys, iop_desc_get_next_desc(iter),
+                       iter->async_tx.phys, (u64)iop_desc_get_next_desc(iter),
                        async_tx_test_ack(&iter->async_tx));
                prefetch(_iter);
                prefetch(&_iter->async_tx);
@@ -306,9 +306,9 @@ retry:
                                int i;
                                dev_dbg(iop_chan->device->common.dev,
                                        "allocated slot: %d "
-                                       "(desc %p phys: %#x) slots_per_op %d\n",
+                                       "(desc %p phys: %#llx) slots_per_op %d\n",
                                        iter->idx, iter->hw_desc,
-                                       iter->async_tx.phys, slots_per_op);
+                                       (u64)iter->async_tx.phys, slots_per_op);
 
                                /* pre-ack all but the last descriptor */
                                if (num_slots != slots_per_op)
@@ -516,7 +516,7 @@ iop_adma_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dma_dest,
                return NULL;
        BUG_ON(len > IOP_ADMA_MAX_BYTE_COUNT);
 
-       dev_dbg(iop_chan->device->common.dev, "%s len: %u\n",
+       dev_dbg(iop_chan->device->common.dev, "%s len: %zu\n",
                __func__, len);
 
        spin_lock_bh(&iop_chan->lock);
@@ -549,7 +549,7 @@ iop_adma_prep_dma_xor(struct dma_chan *chan, dma_addr_t dma_dest,
        BUG_ON(len > IOP_ADMA_XOR_MAX_BYTE_COUNT);
 
        dev_dbg(iop_chan->device->common.dev,
-               "%s src_cnt: %d len: %u flags: %lx\n",
+               "%s src_cnt: %d len: %zu flags: %lx\n",
                __func__, src_cnt, len, flags);
 
        spin_lock_bh(&iop_chan->lock);
@@ -582,7 +582,7 @@ iop_adma_prep_dma_xor_val(struct dma_chan *chan, dma_addr_t *dma_src,
        if (unlikely(!len))
                return NULL;
 
-       dev_dbg(iop_chan->device->common.dev, "%s src_cnt: %d len: %u\n",
+       dev_dbg(iop_chan->device->common.dev, "%s src_cnt: %d len: %zu\n",
                __func__, src_cnt, len);
 
        spin_lock_bh(&iop_chan->lock);
@@ -620,7 +620,7 @@ iop_adma_prep_dma_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src,
        BUG_ON(len > IOP_ADMA_XOR_MAX_BYTE_COUNT);
 
        dev_dbg(iop_chan->device->common.dev,
-               "%s src_cnt: %d len: %u flags: %lx\n",
+               "%s src_cnt: %d len: %zu flags: %lx\n",
                __func__, src_cnt, len, flags);
 
        if (dmaf_p_disabled_continue(flags))
@@ -683,7 +683,7 @@ iop_adma_prep_dma_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src,
                return NULL;
        BUG_ON(len > IOP_ADMA_XOR_MAX_BYTE_COUNT);
 
-       dev_dbg(iop_chan->device->common.dev, "%s src_cnt: %d len: %u\n",
+       dev_dbg(iop_chan->device->common.dev, "%s src_cnt: %d len: %zu\n",
                __func__, src_cnt, len);
 
        spin_lock_bh(&iop_chan->lock);
similarity index 99%
rename from arch/arm/include/asm/hardware/iop3xx-adma.h
rename to drivers/dma/iop-adma.h
index 6d998df..c499c95 100644 (file)
@@ -6,8 +6,7 @@
 #define _ADMA_H
 #include <linux/types.h>
 #include <linux/io.h>
-#include <mach/hardware.h>
-#include <asm/hardware/iop_adma.h>
+#include <linux/platform_data/dma-iop32x.h>
 
 /* Memory copy units */
 #define DMA_CCR(chan)          (chan->mmr_base + 0x0)
 #define AAU_EDCR1_IDX  17
 #define AAU_EDCR2_IDX  26
 
-#define DMA0_ID 0
-#define DMA1_ID 1
-#define AAU_ID 2
-
 struct iop3xx_aau_desc_ctrl {
        unsigned int int_en:1;
        unsigned int blk1_cmd_ctrl:3;
index 9c41a4e..1072c45 100644 (file)
@@ -192,6 +192,7 @@ struct rcar_dmac_chan {
  * @iomem: remapped I/O memory base
  * @n_channels: number of available channels
  * @channels: array of DMAC channels
+ * @channels_mask: bitfield of which DMA channels are managed by this driver
  * @modules: bitmask of client modules in use
  */
 struct rcar_dmac {
@@ -202,6 +203,7 @@ struct rcar_dmac {
 
        unsigned int n_channels;
        struct rcar_dmac_chan *channels;
+       unsigned int channels_mask;
 
        DECLARE_BITMAP(modules, 256);
 };
@@ -438,7 +440,7 @@ static int rcar_dmac_init(struct rcar_dmac *dmac)
        u16 dmaor;
 
        /* Clear all channels and enable the DMAC globally. */
-       rcar_dmac_write(dmac, RCAR_DMACHCLR, GENMASK(dmac->n_channels - 1, 0));
+       rcar_dmac_write(dmac, RCAR_DMACHCLR, dmac->channels_mask);
        rcar_dmac_write(dmac, RCAR_DMAOR,
                        RCAR_DMAOR_PRI_FIXED | RCAR_DMAOR_DME);
 
@@ -814,6 +816,9 @@ static void rcar_dmac_stop_all_chan(struct rcar_dmac *dmac)
        for (i = 0; i < dmac->n_channels; ++i) {
                struct rcar_dmac_chan *chan = &dmac->channels[i];
 
+               if (!(dmac->channels_mask & BIT(i)))
+                       continue;
+
                /* Stop and reinitialize the channel. */
                spin_lock_irq(&chan->lock);
                rcar_dmac_chan_halt(chan);
@@ -1776,6 +1781,8 @@ static int rcar_dmac_chan_probe(struct rcar_dmac *dmac,
        return 0;
 }
 
+#define RCAR_DMAC_MAX_CHANNELS 32
+
 static int rcar_dmac_parse_of(struct device *dev, struct rcar_dmac *dmac)
 {
        struct device_node *np = dev->of_node;
@@ -1787,12 +1794,16 @@ static int rcar_dmac_parse_of(struct device *dev, struct rcar_dmac *dmac)
                return ret;
        }
 
-       if (dmac->n_channels <= 0 || dmac->n_channels >= 100) {
+       /* The hardware and driver don't support more than 32 bits in CHCLR */
+       if (dmac->n_channels <= 0 ||
+           dmac->n_channels >= RCAR_DMAC_MAX_CHANNELS) {
                dev_err(dev, "invalid number of channels %u\n",
                        dmac->n_channels);
                return -EINVAL;
        }
 
+       dmac->channels_mask = GENMASK(dmac->n_channels - 1, 0);
+
        return 0;
 }
 
@@ -1802,7 +1813,6 @@ static int rcar_dmac_probe(struct platform_device *pdev)
                DMA_SLAVE_BUSWIDTH_2_BYTES | DMA_SLAVE_BUSWIDTH_4_BYTES |
                DMA_SLAVE_BUSWIDTH_8_BYTES | DMA_SLAVE_BUSWIDTH_16_BYTES |
                DMA_SLAVE_BUSWIDTH_32_BYTES | DMA_SLAVE_BUSWIDTH_64_BYTES;
-       unsigned int channels_offset = 0;
        struct dma_device *engine;
        struct rcar_dmac *dmac;
        struct resource *mem;
@@ -1831,10 +1841,8 @@ static int rcar_dmac_probe(struct platform_device *pdev)
         * level we can't disable it selectively, so ignore channel 0 for now if
         * the device is part of an IOMMU group.
         */
-       if (device_iommu_mapped(&pdev->dev)) {
-               dmac->n_channels--;
-               channels_offset = 1;
-       }
+       if (device_iommu_mapped(&pdev->dev))
+               dmac->channels_mask &= ~BIT(0);
 
        dmac->channels = devm_kcalloc(&pdev->dev, dmac->n_channels,
                                      sizeof(*dmac->channels), GFP_KERNEL);
@@ -1892,8 +1900,10 @@ static int rcar_dmac_probe(struct platform_device *pdev)
        INIT_LIST_HEAD(&engine->channels);
 
        for (i = 0; i < dmac->n_channels; ++i) {
-               ret = rcar_dmac_chan_probe(dmac, &dmac->channels[i],
-                                          i + channels_offset);
+               if (!(dmac->channels_mask & BIT(i)))
+                       continue;
+
+               ret = rcar_dmac_chan_probe(dmac, &dmac->channels[i], i);
                if (ret < 0)
                        goto error;
        }
index baac476..525dc73 100644 (file)
@@ -908,6 +908,7 @@ sprd_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
        struct sprd_dma_chn *schan = to_sprd_dma_chan(chan);
        struct dma_slave_config *slave_cfg = &schan->slave_cfg;
        dma_addr_t src = 0, dst = 0;
+       dma_addr_t start_src = 0, start_dst = 0;
        struct sprd_dma_desc *sdesc;
        struct scatterlist *sg;
        u32 len = 0;
@@ -954,6 +955,11 @@ sprd_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
                        dst = sg_dma_address(sg);
                }
 
+               if (!i) {
+                       start_src = src;
+                       start_dst = dst;
+               }
+
                /*
                 * The link-list mode needs at least 2 link-list
                 * configurations. If there is only one sg, it doesn't
@@ -970,8 +976,8 @@ sprd_dma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
                }
        }
 
-       ret = sprd_dma_fill_desc(chan, &sdesc->chn_hw, 0, 0, src, dst, len,
-                                dir, flags, slave_cfg);
+       ret = sprd_dma_fill_desc(chan, &sdesc->chn_hw, 0, 0, start_src,
+                                start_dst, len, dir, flags, slave_cfg);
        if (ret) {
                kfree(sdesc);
                return NULL;
index ad2f0a4..f255056 100644 (file)
@@ -391,8 +391,10 @@ static int ti_dra7_xbar_probe(struct platform_device *pdev)
 
                ret = of_property_read_u32_array(node, pname, (u32 *)rsv_events,
                                                 nelm * 2);
-               if (ret)
+               if (ret) {
+                       kfree(rsv_events);
                        return ret;
+               }
 
                for (i = 0; i < nelm; i++) {
                        ti_dra7_xbar_reserve(rsv_events[i][0], rsv_events[i][1],
index ba27802..d07c0d5 100644 (file)
@@ -1540,8 +1540,10 @@ static int omap_dma_probe(struct platform_device *pdev)
 
                rc = devm_request_irq(&pdev->dev, irq, omap_dma_irq,
                                      IRQF_SHARED, "omap-dma-engine", od);
-               if (rc)
+               if (rc) {
+                       omap_dma_free(od);
                        return rc;
+               }
        }
 
        if (omap_dma_glbl_read(od, CAPS_0) & CAPS_0_SUPPORT_LL123)
index 200c04c..2a2603b 100644 (file)
@@ -510,4 +510,11 @@ config EDAC_ASPEED
          First, ECC must be configured in the bootloader. Then, this driver
          will expose error counters via the EDAC kernel framework.
 
+config EDAC_BLUEFIELD
+       tristate "Mellanox BlueField Memory ECC"
+       depends on ARM64 && ((MELLANOX_PLATFORM && ACPI) || COMPILE_TEST)
+       help
+         Support for error detection and correction on the
+         Mellanox BlueField SoCs.
+
 endif # EDAC
index 165ca65..d265ff9 100644 (file)
@@ -85,3 +85,4 @@ obj-$(CONFIG_EDAC_XGENE)              += xgene_edac.o
 obj-$(CONFIG_EDAC_TI)                  += ti_edac.o
 obj-$(CONFIG_EDAC_QCOM)                        += qcom_edac.o
 obj-$(CONFIG_EDAC_ASPEED)              += aspeed_edac.o
+obj-$(CONFIG_EDAC_BLUEFIELD)           += bluefield_edac.o
index c2e693e..fbda4b8 100644 (file)
@@ -222,7 +222,6 @@ static unsigned long get_total_mem(void)
 static const struct of_device_id altr_sdram_ctrl_of_match[] = {
        { .compatible = "altr,sdram-edac", .data = &c5_data},
        { .compatible = "altr,sdram-edac-a10", .data = &a10_data},
-       { .compatible = "altr,sdram-edac-s10", .data = &a10_data},
        {},
 };
 MODULE_DEVICE_TABLE(of, altr_sdram_ctrl_of_match);
@@ -1170,6 +1169,24 @@ static int __init __maybe_unused altr_init_a10_ecc_device_type(char *compat)
        return 0;
 }
 
+/*********************** SDRAM EDAC Device Functions *********************/
+
+#ifdef CONFIG_EDAC_ALTERA_SDRAM
+
+static const struct edac_device_prv_data s10_sdramecc_data = {
+       .setup = altr_check_ecc_deps,
+       .ce_clear_mask = ALTR_S10_ECC_SERRPENA,
+       .ue_clear_mask = ALTR_S10_ECC_DERRPENA,
+       .ecc_enable_mask = ALTR_S10_ECC_EN,
+       .ecc_en_ofst = ALTR_S10_ECC_CTRL_SDRAM_OFST,
+       .ce_set_mask = ALTR_S10_ECC_TSERRA,
+       .ue_set_mask = ALTR_S10_ECC_TDERRA,
+       .set_err_ofst = ALTR_S10_ECC_INTTEST_OFST,
+       .ecc_irq_handler = altr_edac_a10_ecc_irq,
+       .inject_fops = &altr_edac_a10_device_inject_fops,
+};
+#endif /* CONFIG_EDAC_ALTERA_SDRAM */
+
 /*********************** OCRAM EDAC Device Functions *********************/
 
 #ifdef CONFIG_EDAC_ALTERA_OCRAM
@@ -1759,6 +1776,9 @@ static const struct of_device_id altr_edac_a10_device_of_match[] = {
 #ifdef CONFIG_EDAC_ALTERA_SDMMC
        { .compatible = "altr,socfpga-sdmmc-ecc", .data = &a10_sdmmcecca_data },
 #endif
+#ifdef CONFIG_EDAC_ALTERA_SDRAM
+       { .compatible = "altr,sdram-edac-s10", .data = &s10_sdramecc_data },
+#endif
        {},
 };
 MODULE_DEVICE_TABLE(of, altr_edac_a10_device_of_match);
@@ -1866,6 +1886,7 @@ static void altr_edac_a10_irq_handler(struct irq_desc *desc)
        struct altr_arria10_edac *edac = irq_desc_get_handler_data(desc);
        struct irq_chip *chip = irq_desc_get_chip(desc);
        int irq = irq_desc_get_irq(desc);
+       unsigned long bits;
 
        dberr = (irq == edac->db_irq) ? 1 : 0;
        sm_offset = dberr ? A10_SYSMGR_ECC_INTSTAT_DERR_OFST :
@@ -1875,7 +1896,8 @@ static void altr_edac_a10_irq_handler(struct irq_desc *desc)
 
        regmap_read(edac->ecc_mgr_map, sm_offset, &irq_status);
 
-       for_each_set_bit(bit, (unsigned long *)&irq_status, 32) {
+       bits = irq_status;
+       for_each_set_bit(bit, &bits, 32) {
                irq = irq_linear_revmap(edac->domain, dberr * 32 + bit);
                if (irq)
                        generic_handle_irq(irq);
@@ -1889,6 +1911,10 @@ static int validate_parent_available(struct device_node *np)
        struct device_node *parent;
        int ret = 0;
 
+       /* SDRAM must be present for Linux (implied parent) */
+       if (of_device_is_compatible(np, "altr,sdram-edac-s10"))
+               return 0;
+
        /* Ensure parent device is enabled if parent node exists */
        parent = of_parse_phandle(np, "altr,ecc-parent", 0);
        if (parent && !of_device_is_available(parent))
@@ -1898,6 +1924,22 @@ static int validate_parent_available(struct device_node *np)
        return ret;
 }
 
+static int get_s10_sdram_edac_resource(struct device_node *np,
+                                      struct resource *res)
+{
+       struct device_node *parent;
+       int ret;
+
+       parent = of_parse_phandle(np, "altr,sdr-syscon", 0);
+       if (!parent)
+               return -ENODEV;
+
+       ret = of_address_to_resource(parent, 0, res);
+       of_node_put(parent);
+
+       return ret;
+}
+
 static int altr_edac_a10_device_add(struct altr_arria10_edac *edac,
                                    struct device_node *np)
 {
@@ -1925,7 +1967,11 @@ static int altr_edac_a10_device_add(struct altr_arria10_edac *edac,
        if (!devres_open_group(edac->dev, altr_edac_a10_device_add, GFP_KERNEL))
                return -ENOMEM;
 
-       rc = of_address_to_resource(np, 0, &res);
+       if (of_device_is_compatible(np, "altr,sdram-edac-s10"))
+               rc = get_s10_sdram_edac_resource(np, &res);
+       else
+               rc = of_address_to_resource(np, 0, &res);
+
        if (rc < 0) {
                edac_printk(KERN_ERR, EDAC_DEVICE,
                            "%s: no resource address\n", ecc_name);
@@ -2231,13 +2277,15 @@ static int altr_edac_a10_probe(struct platform_device *pdev)
                    of_device_is_compatible(child, "altr,socfpga-dma-ecc") ||
                    of_device_is_compatible(child, "altr,socfpga-usb-ecc") ||
                    of_device_is_compatible(child, "altr,socfpga-qspi-ecc") ||
+#ifdef CONFIG_EDAC_ALTERA_SDRAM
+                   of_device_is_compatible(child, "altr,sdram-edac-s10") ||
+#endif
                    of_device_is_compatible(child, "altr,socfpga-sdmmc-ecc"))
 
                        altr_edac_a10_device_add(edac, child);
 
 #ifdef CONFIG_EDAC_ALTERA_SDRAM
-               else if ((of_device_is_compatible(child, "altr,sdram-edac-a10")) ||
-                        (of_device_is_compatible(child, "altr,sdram-edac-s10")))
+               else if (of_device_is_compatible(child, "altr,sdram-edac-a10"))
                        of_platform_populate(pdev->dev.of_node,
                                             altr_sdram_ctrl_of_match,
                                             NULL, &pdev->dev);
index 55654cc..3727e72 100644 (file)
@@ -289,6 +289,29 @@ struct altr_sdram_mc_data {
 #define ALTR_A10_ECC_INIT_WATCHDOG_10US      10000
 
 /************* Stratix10 Defines **************/
+#define ALTR_S10_ECC_CTRL_SDRAM_OFST      0x00
+#define ALTR_S10_ECC_EN                   BIT(0)
+
+#define ALTR_S10_ECC_ERRINTEN_OFST        0x10
+#define ALTR_S10_ECC_ERRINTENS_OFST       0x14
+#define ALTR_S10_ECC_ERRINTENR_OFST       0x18
+#define ALTR_S10_ECC_SERRINTEN            BIT(0)
+
+#define ALTR_S10_ECC_INTMODE_OFST         0x1C
+#define ALTR_S10_ECC_INTMODE              BIT(0)
+
+#define ALTR_S10_ECC_INTSTAT_OFST         0x20
+#define ALTR_S10_ECC_SERRPENA             BIT(0)
+#define ALTR_S10_ECC_DERRPENA             BIT(8)
+#define ALTR_S10_ECC_ERRPENA_MASK         (ALTR_S10_ECC_SERRPENA | \
+                                          ALTR_S10_ECC_DERRPENA)
+
+#define ALTR_S10_ECC_INTTEST_OFST         0x24
+#define ALTR_S10_ECC_TSERRA               BIT(0)
+#define ALTR_S10_ECC_TDERRA               BIT(8)
+#define ALTR_S10_ECC_TSERRB               BIT(16)
+#define ALTR_S10_ECC_TDERRB               BIT(24)
+
 #define ALTR_S10_DERR_ADDRA_OFST          0x2C
 
 /* Stratix10 ECC Manager Defines */
@@ -300,7 +323,7 @@ struct altr_sdram_mc_data {
 #define S10_SYSMGR_UE_ADDR_OFST           0x224
 
 #define S10_DDR0_IRQ_MASK                 BIT(16)
-#define S10_DBE_IRQ_MASK                  0x3FE
+#define S10_DBE_IRQ_MASK                  0x3FFFE
 
 /* Define ECC Block Offsets for peripherals */
 #define ECC_BLK_ADDRESS_OFST              0x40
index 873437b..c1d4536 100644 (file)
@@ -788,51 +788,45 @@ static void debug_dump_dramcfg_low(struct amd64_pvt *pvt, u32 dclr, int chan)
                 (dclr & BIT(15)) ?  "yes" : "no");
 }
 
-/*
- * The Address Mask should be a contiguous set of bits in the non-interleaved
- * case. So to check for CS interleaving, find the most- and least-significant
- * bits of the mask, generate a contiguous bitmask, and compare the two.
- */
-static bool f17_cs_interleaved(struct amd64_pvt *pvt, u8 ctrl, int cs)
+#define CS_EVEN_PRIMARY                BIT(0)
+#define CS_ODD_PRIMARY         BIT(1)
+#define CS_EVEN_SECONDARY      BIT(2)
+#define CS_ODD_SECONDARY       BIT(3)
+
+#define CS_EVEN                        (CS_EVEN_PRIMARY | CS_EVEN_SECONDARY)
+#define CS_ODD                 (CS_ODD_PRIMARY | CS_ODD_SECONDARY)
+
+static int f17_get_cs_mode(int dimm, u8 ctrl, struct amd64_pvt *pvt)
 {
-       u32 mask = pvt->csels[ctrl].csmasks[cs >> 1];
-       u32 msb = fls(mask) - 1, lsb = ffs(mask) - 1;
-       u32 test_mask = GENMASK(msb, lsb);
+       int cs_mode = 0;
 
-       edac_dbg(1, "mask=0x%08x test_mask=0x%08x\n", mask, test_mask);
+       if (csrow_enabled(2 * dimm, ctrl, pvt))
+               cs_mode |= CS_EVEN_PRIMARY;
 
-       return mask ^ test_mask;
+       if (csrow_enabled(2 * dimm + 1, ctrl, pvt))
+               cs_mode |= CS_ODD_PRIMARY;
+
+       /* Asymmetric dual-rank DIMM support. */
+       if (csrow_sec_enabled(2 * dimm + 1, ctrl, pvt))
+               cs_mode |= CS_ODD_SECONDARY;
+
+       return cs_mode;
 }
 
 static void debug_display_dimm_sizes_df(struct amd64_pvt *pvt, u8 ctrl)
 {
-       int dimm, size0, size1, cs0, cs1;
+       int dimm, size0, size1, cs0, cs1, cs_mode;
 
        edac_printk(KERN_DEBUG, EDAC_MC, "UMC%d chip selects:\n", ctrl);
 
-       for (dimm = 0; dimm < 4; dimm++) {
-               size0 = 0;
+       for (dimm = 0; dimm < 2; dimm++) {
                cs0 = dimm * 2;
-
-               if (csrow_enabled(cs0, ctrl, pvt))
-                       size0 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs0);
-
-               size1 = 0;
                cs1 = dimm * 2 + 1;
 
-               if (csrow_enabled(cs1, ctrl, pvt)) {
-                       /*
-                        * CS interleaving is only supported if both CSes have
-                        * the same amount of memory. Because they are
-                        * interleaved, it will look like both CSes have the
-                        * full amount of memory. Save the size for both as
-                        * half the amount we found on CS0, if interleaved.
-                        */
-                       if (f17_cs_interleaved(pvt, ctrl, cs1))
-                               size1 = size0 = (size0 >> 1);
-                       else
-                               size1 = pvt->ops->dbam_to_cs(pvt, ctrl, 0, cs1);
-               }
+               cs_mode = f17_get_cs_mode(dimm, ctrl, pvt);
+
+               size0 = pvt->ops->dbam_to_cs(pvt, ctrl, cs_mode, cs0);
+               size1 = pvt->ops->dbam_to_cs(pvt, ctrl, cs_mode, cs1);
 
                amd64_info(EDAC_MC ": %d: %5dMB %d: %5dMB\n",
                                cs0,    size0,
@@ -942,89 +936,119 @@ static void prep_chip_selects(struct amd64_pvt *pvt)
        } else if (pvt->fam == 0x15 && pvt->model == 0x30) {
                pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 4;
                pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 2;
+       } else if (pvt->fam >= 0x17) {
+               int umc;
+
+               for_each_umc(umc) {
+                       pvt->csels[umc].b_cnt = 4;
+                       pvt->csels[umc].m_cnt = 2;
+               }
+
        } else {
                pvt->csels[0].b_cnt = pvt->csels[1].b_cnt = 8;
                pvt->csels[0].m_cnt = pvt->csels[1].m_cnt = 4;
        }
 }
 
+static void read_umc_base_mask(struct amd64_pvt *pvt)
+{
+       u32 umc_base_reg, umc_base_reg_sec;
+       u32 umc_mask_reg, umc_mask_reg_sec;
+       u32 base_reg, base_reg_sec;
+       u32 mask_reg, mask_reg_sec;
+       u32 *base, *base_sec;
+       u32 *mask, *mask_sec;
+       int cs, umc;
+
+       for_each_umc(umc) {
+               umc_base_reg = get_umc_base(umc) + UMCCH_BASE_ADDR;
+               umc_base_reg_sec = get_umc_base(umc) + UMCCH_BASE_ADDR_SEC;
+
+               for_each_chip_select(cs, umc, pvt) {
+                       base = &pvt->csels[umc].csbases[cs];
+                       base_sec = &pvt->csels[umc].csbases_sec[cs];
+
+                       base_reg = umc_base_reg + (cs * 4);
+                       base_reg_sec = umc_base_reg_sec + (cs * 4);
+
+                       if (!amd_smn_read(pvt->mc_node_id, base_reg, base))
+                               edac_dbg(0, "  DCSB%d[%d]=0x%08x reg: 0x%x\n",
+                                        umc, cs, *base, base_reg);
+
+                       if (!amd_smn_read(pvt->mc_node_id, base_reg_sec, base_sec))
+                               edac_dbg(0, "    DCSB_SEC%d[%d]=0x%08x reg: 0x%x\n",
+                                        umc, cs, *base_sec, base_reg_sec);
+               }
+
+               umc_mask_reg = get_umc_base(umc) + UMCCH_ADDR_MASK;
+               umc_mask_reg_sec = get_umc_base(umc) + UMCCH_ADDR_MASK_SEC;
+
+               for_each_chip_select_mask(cs, umc, pvt) {
+                       mask = &pvt->csels[umc].csmasks[cs];
+                       mask_sec = &pvt->csels[umc].csmasks_sec[cs];
+
+                       mask_reg = umc_mask_reg + (cs * 4);
+                       mask_reg_sec = umc_mask_reg_sec + (cs * 4);
+
+                       if (!amd_smn_read(pvt->mc_node_id, mask_reg, mask))
+                               edac_dbg(0, "  DCSM%d[%d]=0x%08x reg: 0x%x\n",
+                                        umc, cs, *mask, mask_reg);
+
+                       if (!amd_smn_read(pvt->mc_node_id, mask_reg_sec, mask_sec))
+                               edac_dbg(0, "    DCSM_SEC%d[%d]=0x%08x reg: 0x%x\n",
+                                        umc, cs, *mask_sec, mask_reg_sec);
+               }
+       }
+}
+
 /*
  * Function 2 Offset F10_DCSB0; read in the DCS Base and DCS Mask registers
  */
 static void read_dct_base_mask(struct amd64_pvt *pvt)
 {
-       int base_reg0, base_reg1, mask_reg0, mask_reg1, cs;
+       int cs;
 
        prep_chip_selects(pvt);
 
-       if (pvt->umc) {
-               base_reg0 = get_umc_base(0) + UMCCH_BASE_ADDR;
-               base_reg1 = get_umc_base(1) + UMCCH_BASE_ADDR;
-               mask_reg0 = get_umc_base(0) + UMCCH_ADDR_MASK;
-               mask_reg1 = get_umc_base(1) + UMCCH_ADDR_MASK;
-       } else {
-               base_reg0 = DCSB0;
-               base_reg1 = DCSB1;
-               mask_reg0 = DCSM0;
-               mask_reg1 = DCSM1;
-       }
+       if (pvt->umc)
+               return read_umc_base_mask(pvt);
 
        for_each_chip_select(cs, 0, pvt) {
-               int reg0   = base_reg0 + (cs * 4);
-               int reg1   = base_reg1 + (cs * 4);
+               int reg0   = DCSB0 + (cs * 4);
+               int reg1   = DCSB1 + (cs * 4);
                u32 *base0 = &pvt->csels[0].csbases[cs];
                u32 *base1 = &pvt->csels[1].csbases[cs];
 
-               if (pvt->umc) {
-                       if (!amd_smn_read(pvt->mc_node_id, reg0, base0))
-                               edac_dbg(0, "  DCSB0[%d]=0x%08x reg: 0x%x\n",
-                                        cs, *base0, reg0);
+               if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, base0))
+                       edac_dbg(0, "  DCSB0[%d]=0x%08x reg: F2x%x\n",
+                                cs, *base0, reg0);
 
-                       if (!amd_smn_read(pvt->mc_node_id, reg1, base1))
-                               edac_dbg(0, "  DCSB1[%d]=0x%08x reg: 0x%x\n",
-                                        cs, *base1, reg1);
-               } else {
-                       if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, base0))
-                               edac_dbg(0, "  DCSB0[%d]=0x%08x reg: F2x%x\n",
-                                        cs, *base0, reg0);
-
-                       if (pvt->fam == 0xf)
-                               continue;
+               if (pvt->fam == 0xf)
+                       continue;
 
-                       if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, base1))
-                               edac_dbg(0, "  DCSB1[%d]=0x%08x reg: F2x%x\n",
-                                        cs, *base1, (pvt->fam == 0x10) ? reg1
-                                                               : reg0);
-               }
+               if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, base1))
+                       edac_dbg(0, "  DCSB1[%d]=0x%08x reg: F2x%x\n",
+                                cs, *base1, (pvt->fam == 0x10) ? reg1
+                                                       : reg0);
        }
 
        for_each_chip_select_mask(cs, 0, pvt) {
-               int reg0   = mask_reg0 + (cs * 4);
-               int reg1   = mask_reg1 + (cs * 4);
+               int reg0   = DCSM0 + (cs * 4);
+               int reg1   = DCSM1 + (cs * 4);
                u32 *mask0 = &pvt->csels[0].csmasks[cs];
                u32 *mask1 = &pvt->csels[1].csmasks[cs];
 
-               if (pvt->umc) {
-                       if (!amd_smn_read(pvt->mc_node_id, reg0, mask0))
-                               edac_dbg(0, "    DCSM0[%d]=0x%08x reg: 0x%x\n",
-                                        cs, *mask0, reg0);
-
-                       if (!amd_smn_read(pvt->mc_node_id, reg1, mask1))
-                               edac_dbg(0, "    DCSM1[%d]=0x%08x reg: 0x%x\n",
-                                        cs, *mask1, reg1);
-               } else {
-                       if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, mask0))
-                               edac_dbg(0, "    DCSM0[%d]=0x%08x reg: F2x%x\n",
-                                        cs, *mask0, reg0);
+               if (!amd64_read_dct_pci_cfg(pvt, 0, reg0, mask0))
+                       edac_dbg(0, "    DCSM0[%d]=0x%08x reg: F2x%x\n",
+                                cs, *mask0, reg0);
 
-                       if (pvt->fam == 0xf)
-                               continue;
+               if (pvt->fam == 0xf)
+                       continue;
 
-                       if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, mask1))
-                               edac_dbg(0, "    DCSM1[%d]=0x%08x reg: F2x%x\n",
-                                        cs, *mask1, (pvt->fam == 0x10) ? reg1
-                                                               : reg0);
-               }
+               if (!amd64_read_dct_pci_cfg(pvt, 1, reg0, mask1))
+                       edac_dbg(0, "    DCSM1[%d]=0x%08x reg: F2x%x\n",
+                                cs, *mask1, (pvt->fam == 0x10) ? reg1
+                                                       : reg0);
        }
 }
 
@@ -1556,18 +1580,58 @@ static int f16_dbam_to_chip_select(struct amd64_pvt *pvt, u8 dct,
                return ddr3_cs_size(cs_mode, false);
 }
 
-static int f17_base_addr_to_cs_size(struct amd64_pvt *pvt, u8 umc,
+static int f17_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc,
                                    unsigned int cs_mode, int csrow_nr)
 {
-       u32 base_addr = pvt->csels[umc].csbases[csrow_nr];
+       u32 addr_mask_orig, addr_mask_deinterleaved;
+       u32 msb, weight, num_zero_bits;
+       int dimm, size = 0;
 
-       /*  Each mask is used for every two base addresses. */
-       u32 addr_mask = pvt->csels[umc].csmasks[csrow_nr >> 1];
+       /* No Chip Selects are enabled. */
+       if (!cs_mode)
+               return size;
 
-       /*  Register [31:1] = Address [39:9]. Size is in kBs here. */
-       u32 size = ((addr_mask >> 1) - (base_addr >> 1) + 1) >> 1;
+       /* Requested size of an even CS but none are enabled. */
+       if (!(cs_mode & CS_EVEN) && !(csrow_nr & 1))
+               return size;
 
-       edac_dbg(1, "BaseAddr: 0x%x, AddrMask: 0x%x\n", base_addr, addr_mask);
+       /* Requested size of an odd CS but none are enabled. */
+       if (!(cs_mode & CS_ODD) && (csrow_nr & 1))
+               return size;
+
+       /*
+        * There is one mask per DIMM, and two Chip Selects per DIMM.
+        *      CS0 and CS1 -> DIMM0
+        *      CS2 and CS3 -> DIMM1
+        */
+       dimm = csrow_nr >> 1;
+
+       /* Asymmetric dual-rank DIMM support. */
+       if ((csrow_nr & 1) && (cs_mode & CS_ODD_SECONDARY))
+               addr_mask_orig = pvt->csels[umc].csmasks_sec[dimm];
+       else
+               addr_mask_orig = pvt->csels[umc].csmasks[dimm];
+
+       /*
+        * The number of zero bits in the mask is equal to the number of bits
+        * in a full mask minus the number of bits in the current mask.
+        *
+        * The MSB is the number of bits in the full mask because BIT[0] is
+        * always 0.
+        */
+       msb = fls(addr_mask_orig) - 1;
+       weight = hweight_long(addr_mask_orig);
+       num_zero_bits = msb - weight;
+
+       /* Take the number of zero bits off from the top of the mask. */
+       addr_mask_deinterleaved = GENMASK_ULL(msb - num_zero_bits, 1);
+
+       edac_dbg(1, "CS%d DIMM%d AddrMasks:\n", csrow_nr, dimm);
+       edac_dbg(1, "  Original AddrMask: 0x%x\n", addr_mask_orig);
+       edac_dbg(1, "  Deinterleaved AddrMask: 0x%x\n", addr_mask_deinterleaved);
+
+       /* Register [31:1] = Address [39:9]. Size is in kBs here. */
+       size = (addr_mask_deinterleaved >> 2) + 1;
 
        /* Return size in MBs. */
        return size >> 10;
@@ -2232,7 +2296,7 @@ static struct amd64_family_type family_types[] = {
                .f6_id = PCI_DEVICE_ID_AMD_17H_DF_F6,
                .ops = {
                        .early_channel_count    = f17_early_channel_count,
-                       .dbam_to_cs             = f17_base_addr_to_cs_size,
+                       .dbam_to_cs             = f17_addr_mask_to_cs_size,
                }
        },
        [F17_M10H_CPUS] = {
@@ -2241,7 +2305,7 @@ static struct amd64_family_type family_types[] = {
                .f6_id = PCI_DEVICE_ID_AMD_17H_M10H_DF_F6,
                .ops = {
                        .early_channel_count    = f17_early_channel_count,
-                       .dbam_to_cs             = f17_base_addr_to_cs_size,
+                       .dbam_to_cs             = f17_addr_mask_to_cs_size,
                }
        },
        [F17_M30H_CPUS] = {
@@ -2250,7 +2314,16 @@ static struct amd64_family_type family_types[] = {
                .f6_id = PCI_DEVICE_ID_AMD_17H_M30H_DF_F6,
                .ops = {
                        .early_channel_count    = f17_early_channel_count,
-                       .dbam_to_cs             = f17_base_addr_to_cs_size,
+                       .dbam_to_cs             = f17_addr_mask_to_cs_size,
+               }
+       },
+       [F17_M70H_CPUS] = {
+               .ctl_name = "F17h_M70h",
+               .f0_id = PCI_DEVICE_ID_AMD_17H_M70H_DF_F0,
+               .f6_id = PCI_DEVICE_ID_AMD_17H_M70H_DF_F6,
+               .ops = {
+                       .early_channel_count    = f17_early_channel_count,
+                       .dbam_to_cs             = f17_addr_mask_to_cs_size,
                }
        },
 };
@@ -2537,13 +2610,6 @@ static void decode_umc_error(int node_id, struct mce *m)
 
        err.channel = find_umc_channel(m);
 
-       if (umc_normaddr_to_sysaddr(m->addr, pvt->mc_node_id, err.channel, &sys_addr)) {
-               err.err_code = ERR_NORM_ADDR;
-               goto log_error;
-       }
-
-       error_address_to_page_and_offset(sys_addr, &err);
-
        if (!(m->status & MCI_STATUS_SYNDV)) {
                err.err_code = ERR_SYND;
                goto log_error;
@@ -2560,6 +2626,13 @@ static void decode_umc_error(int node_id, struct mce *m)
 
        err.csrow = m->synd & 0x7;
 
+       if (umc_normaddr_to_sysaddr(m->addr, pvt->mc_node_id, err.channel, &sys_addr)) {
+               err.err_code = ERR_NORM_ADDR;
+               goto log_error;
+       }
+
+       error_address_to_page_and_offset(sys_addr, &err);
+
 log_error:
        __log_ecc_error(mci, &err, ecc_type);
 }
@@ -2809,10 +2882,12 @@ static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr_orig)
        int csrow_nr = csrow_nr_orig;
        u32 cs_mode, nr_pages;
 
-       if (!pvt->umc)
+       if (!pvt->umc) {
                csrow_nr >>= 1;
-
-       cs_mode = DBAM_DIMM(csrow_nr, dbam);
+               cs_mode = DBAM_DIMM(csrow_nr, dbam);
+       } else {
+               cs_mode = f17_get_cs_mode(csrow_nr >> 1, dct, pvt);
+       }
 
        nr_pages   = pvt->ops->dbam_to_cs(pvt, dct, cs_mode, csrow_nr);
        nr_pages <<= 20 - PAGE_SHIFT;
@@ -2824,6 +2899,49 @@ static u32 get_csrow_nr_pages(struct amd64_pvt *pvt, u8 dct, int csrow_nr_orig)
        return nr_pages;
 }
 
+static int init_csrows_df(struct mem_ctl_info *mci)
+{
+       struct amd64_pvt *pvt = mci->pvt_info;
+       enum edac_type edac_mode = EDAC_NONE;
+       enum dev_type dev_type = DEV_UNKNOWN;
+       struct dimm_info *dimm;
+       int empty = 1;
+       u8 umc, cs;
+
+       if (mci->edac_ctl_cap & EDAC_FLAG_S16ECD16ED) {
+               edac_mode = EDAC_S16ECD16ED;
+               dev_type = DEV_X16;
+       } else if (mci->edac_ctl_cap & EDAC_FLAG_S8ECD8ED) {
+               edac_mode = EDAC_S8ECD8ED;
+               dev_type = DEV_X8;
+       } else if (mci->edac_ctl_cap & EDAC_FLAG_S4ECD4ED) {
+               edac_mode = EDAC_S4ECD4ED;
+               dev_type = DEV_X4;
+       } else if (mci->edac_ctl_cap & EDAC_FLAG_SECDED) {
+               edac_mode = EDAC_SECDED;
+       }
+
+       for_each_umc(umc) {
+               for_each_chip_select(cs, umc, pvt) {
+                       if (!csrow_enabled(cs, umc, pvt))
+                               continue;
+
+                       empty = 0;
+                       dimm = mci->csrows[cs]->channels[umc]->dimm;
+
+                       edac_dbg(1, "MC node: %d, csrow: %d\n",
+                                       pvt->mc_node_id, cs);
+
+                       dimm->nr_pages = get_csrow_nr_pages(pvt, umc, cs);
+                       dimm->mtype = pvt->dram_type;
+                       dimm->edac_mode = edac_mode;
+                       dimm->dtype = dev_type;
+               }
+       }
+
+       return empty;
+}
+
 /*
  * Initialize the array of csrow attribute instances, based on the values
  * from pci config hardware registers.
@@ -2838,15 +2956,16 @@ static int init_csrows(struct mem_ctl_info *mci)
        int nr_pages = 0;
        u32 val;
 
-       if (!pvt->umc) {
-               amd64_read_pci_cfg(pvt->F3, NBCFG, &val);
+       if (pvt->umc)
+               return init_csrows_df(mci);
 
-               pvt->nbcfg = val;
+       amd64_read_pci_cfg(pvt->F3, NBCFG, &val);
 
-               edac_dbg(0, "node %d, NBCFG=0x%08x[ChipKillEccCap: %d|DramEccEn: %d]\n",
-                        pvt->mc_node_id, val,
-                        !!(val & NBCFG_CHIPKILL), !!(val & NBCFG_ECC_ENABLE));
-       }
+       pvt->nbcfg = val;
+
+       edac_dbg(0, "node %d, NBCFG=0x%08x[ChipKillEccCap: %d|DramEccEn: %d]\n",
+                pvt->mc_node_id, val,
+                !!(val & NBCFG_CHIPKILL), !!(val & NBCFG_ECC_ENABLE));
 
        /*
         * We iterate over DCT0 here but we look at DCT1 in parallel, if needed.
@@ -2883,13 +3002,7 @@ static int init_csrows(struct mem_ctl_info *mci)
                edac_dbg(1, "Total csrow%d pages: %u\n", i, nr_pages);
 
                /* Determine DIMM ECC mode: */
-               if (pvt->umc) {
-                       if (mci->edac_ctl_cap & EDAC_FLAG_S4ECD4ED)
-                               edac_mode = EDAC_S4ECD4ED;
-                       else if (mci->edac_ctl_cap & EDAC_FLAG_SECDED)
-                               edac_mode = EDAC_SECDED;
-
-               } else if (pvt->nbcfg & NBCFG_ECC_ENABLE) {
+               if (pvt->nbcfg & NBCFG_ECC_ENABLE) {
                        edac_mode = (pvt->nbcfg & NBCFG_CHIPKILL)
                                        ? EDAC_S4ECD4ED
                                        : EDAC_SECDED;
@@ -3137,12 +3250,15 @@ static bool ecc_enabled(struct pci_dev *F3, u16 nid)
 static inline void
 f17h_determine_edac_ctl_cap(struct mem_ctl_info *mci, struct amd64_pvt *pvt)
 {
-       u8 i, ecc_en = 1, cpk_en = 1;
+       u8 i, ecc_en = 1, cpk_en = 1, dev_x4 = 1, dev_x16 = 1;
 
        for_each_umc(i) {
                if (pvt->umc[i].sdp_ctrl & UMC_SDP_INIT) {
                        ecc_en &= !!(pvt->umc[i].umc_cap_hi & UMC_ECC_ENABLED);
                        cpk_en &= !!(pvt->umc[i].umc_cap_hi & UMC_ECC_CHIPKILL_CAP);
+
+                       dev_x4  &= !!(pvt->umc[i].dimm_cfg & BIT(6));
+                       dev_x16 &= !!(pvt->umc[i].dimm_cfg & BIT(7));
                }
        }
 
@@ -3150,8 +3266,15 @@ f17h_determine_edac_ctl_cap(struct mem_ctl_info *mci, struct amd64_pvt *pvt)
        if (ecc_en) {
                mci->edac_ctl_cap |= EDAC_FLAG_SECDED;
 
-               if (cpk_en)
+               if (!cpk_en)
+                       return;
+
+               if (dev_x4)
                        mci->edac_ctl_cap |= EDAC_FLAG_S4ECD4ED;
+               else if (dev_x16)
+                       mci->edac_ctl_cap |= EDAC_FLAG_S16ECD16ED;
+               else
+                       mci->edac_ctl_cap |= EDAC_FLAG_S8ECD8ED;
        }
 }
 
@@ -3241,6 +3364,10 @@ static struct amd64_family_type *per_family_init(struct amd64_pvt *pvt)
                        fam_type = &family_types[F17_M30H_CPUS];
                        pvt->ops = &family_types[F17_M30H_CPUS].ops;
                        break;
+               } else if (pvt->model >= 0x70 && pvt->model <= 0x7f) {
+                       fam_type = &family_types[F17_M70H_CPUS];
+                       pvt->ops = &family_types[F17_M70H_CPUS].ops;
+                       break;
                }
                /* fall through */
        case 0x18:
index 8f66472..8c3cda8 100644 (file)
@@ -96,6 +96,7 @@
 /* Hardware limit on ChipSelect rows per MC and processors per system */
 #define NUM_CHIPSELECTS                        8
 #define DRAM_RANGES                    8
+#define NUM_CONTROLLERS                        8
 
 #define ON true
 #define OFF false
 #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F6 0x15ee
 #define PCI_DEVICE_ID_AMD_17H_M30H_DF_F0 0x1490
 #define PCI_DEVICE_ID_AMD_17H_M30H_DF_F6 0x1496
+#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F0 0x1440
+#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F6 0x1446
 
 /*
  * Function 1 - Address Map
 #define DCSM0                          0x60
 #define DCSM1                          0x160
 
-#define csrow_enabled(i, dct, pvt)     ((pvt)->csels[(dct)].csbases[(i)] & DCSB_CS_ENABLE)
+#define csrow_enabled(i, dct, pvt)     ((pvt)->csels[(dct)].csbases[(i)]     & DCSB_CS_ENABLE)
+#define csrow_sec_enabled(i, dct, pvt) ((pvt)->csels[(dct)].csbases_sec[(i)] & DCSB_CS_ENABLE)
 
 #define DRAM_CONTROL                   0x78
 
 
 /* UMC CH register offsets */
 #define UMCCH_BASE_ADDR                        0x0
+#define UMCCH_BASE_ADDR_SEC            0x10
 #define UMCCH_ADDR_MASK                        0x20
+#define UMCCH_ADDR_MASK_SEC            0x28
 #define UMCCH_ADDR_CFG                 0x30
 #define UMCCH_DIMM_CFG                 0x80
 #define UMCCH_UMC_CFG                  0x100
@@ -285,6 +291,7 @@ enum amd_families {
        F17_CPUS,
        F17_M10H_CPUS,
        F17_M30H_CPUS,
+       F17_M70H_CPUS,
        NUM_FAMILIES,
 };
 
@@ -311,9 +318,11 @@ struct dram_range {
 /* A DCT chip selects collection */
 struct chip_select {
        u32 csbases[NUM_CHIPSELECTS];
+       u32 csbases_sec[NUM_CHIPSELECTS];
        u8 b_cnt;
 
        u32 csmasks[NUM_CHIPSELECTS];
+       u32 csmasks_sec[NUM_CHIPSELECTS];
        u8 m_cnt;
 };
 
@@ -351,8 +360,8 @@ struct amd64_pvt {
        u32 dbam0;              /* DRAM Base Address Mapping reg for DCT0 */
        u32 dbam1;              /* DRAM Base Address Mapping reg for DCT1 */
 
-       /* one for each DCT */
-       struct chip_select csels[2];
+       /* one for each DCT/UMC */
+       struct chip_select csels[NUM_CONTROLLERS];
 
        /* DRAM base and limit pairs F1x[78,70,68,60,58,50,48,40] */
        struct dram_range ranges[DRAM_RANGES];
diff --git a/drivers/edac/bluefield_edac.c b/drivers/edac/bluefield_edac.c
new file mode 100644 (file)
index 0000000..e4736eb
--- /dev/null
@@ -0,0 +1,356 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Bluefield-specific EDAC driver.
+ *
+ * Copyright (c) 2019 Mellanox Technologies.
+ */
+
+#include <linux/acpi.h>
+#include <linux/arm-smccc.h>
+#include <linux/bitfield.h>
+#include <linux/edac.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "edac_module.h"
+
+#define DRIVER_NAME            "bluefield-edac"
+
+/*
+ * Mellanox BlueField EMI (External Memory Interface) register definitions.
+ */
+
+#define MLXBF_ECC_CNT 0x340
+#define MLXBF_ECC_CNT__SERR_CNT GENMASK(15, 0)
+#define MLXBF_ECC_CNT__DERR_CNT GENMASK(31, 16)
+
+#define MLXBF_ECC_ERR 0x348
+#define MLXBF_ECC_ERR__SECC BIT(0)
+#define MLXBF_ECC_ERR__DECC BIT(16)
+
+#define MLXBF_ECC_LATCH_SEL 0x354
+#define MLXBF_ECC_LATCH_SEL__START BIT(24)
+
+#define MLXBF_ERR_ADDR_0 0x358
+
+#define MLXBF_ERR_ADDR_1 0x37c
+
+#define MLXBF_SYNDROM 0x35c
+#define MLXBF_SYNDROM__DERR BIT(0)
+#define MLXBF_SYNDROM__SERR BIT(1)
+#define MLXBF_SYNDROM__SYN GENMASK(25, 16)
+
+#define MLXBF_ADD_INFO 0x364
+#define MLXBF_ADD_INFO__ERR_PRANK GENMASK(9, 8)
+
+#define MLXBF_EDAC_MAX_DIMM_PER_MC     2
+#define MLXBF_EDAC_ERROR_GRAIN         8
+
+/*
+ * Request MLNX_SIP_GET_DIMM_INFO
+ *
+ * Retrieve information about DIMM on a certain slot.
+ *
+ * Call register usage:
+ * a0: MLNX_SIP_GET_DIMM_INFO
+ * a1: (Memory controller index) << 16 | (Dimm index in memory controller)
+ * a2-7: not used.
+ *
+ * Return status:
+ * a0: MLXBF_DIMM_INFO defined below describing the DIMM.
+ * a1-3: not used.
+ */
+#define MLNX_SIP_GET_DIMM_INFO         0x82000008
+
+/* Format for the SMC response about the memory information */
+#define MLXBF_DIMM_INFO__SIZE_GB GENMASK_ULL(15, 0)
+#define MLXBF_DIMM_INFO__IS_RDIMM BIT(16)
+#define MLXBF_DIMM_INFO__IS_LRDIMM BIT(17)
+#define MLXBF_DIMM_INFO__IS_NVDIMM BIT(18)
+#define MLXBF_DIMM_INFO__RANKS GENMASK_ULL(23, 21)
+#define MLXBF_DIMM_INFO__PACKAGE_X GENMASK_ULL(31, 24)
+
+struct bluefield_edac_priv {
+       int dimm_ranks[MLXBF_EDAC_MAX_DIMM_PER_MC];
+       void __iomem *emi_base;
+       int dimm_per_mc;
+};
+
+static u64 smc_call1(u64 smc_op, u64 smc_arg)
+{
+       struct arm_smccc_res res;
+
+       arm_smccc_smc(smc_op, smc_arg, 0, 0, 0, 0, 0, 0, &res);
+
+       return res.a0;
+}
+
+/*
+ * Gather the ECC information from the External Memory Interface registers
+ * and report it to the edac handler.
+ */
+static void bluefield_gather_report_ecc(struct mem_ctl_info *mci,
+                                       int error_cnt,
+                                       int is_single_ecc)
+{
+       struct bluefield_edac_priv *priv = mci->pvt_info;
+       u32 dram_additional_info, err_prank, edea0, edea1;
+       u32 ecc_latch_select, dram_syndrom, serr, derr, syndrom;
+       enum hw_event_mc_err_type ecc_type;
+       u64 ecc_dimm_addr;
+       int ecc_dimm;
+
+       ecc_type = is_single_ecc ? HW_EVENT_ERR_CORRECTED :
+                                  HW_EVENT_ERR_UNCORRECTED;
+
+       /*
+        * Tell the External Memory Interface to populate the relevant
+        * registers with information about the last ECC error occurrence.
+        */
+       ecc_latch_select = MLXBF_ECC_LATCH_SEL__START;
+       writel(ecc_latch_select, priv->emi_base + MLXBF_ECC_LATCH_SEL);
+
+       /*
+        * Verify that the ECC reported info in the registers is of the
+        * same type as the one asked to report. If not, just report the
+        * error without the detailed information.
+        */
+       dram_syndrom = readl(priv->emi_base + MLXBF_SYNDROM);
+       serr = FIELD_GET(MLXBF_SYNDROM__SERR, dram_syndrom);
+       derr = FIELD_GET(MLXBF_SYNDROM__DERR, dram_syndrom);
+       syndrom = FIELD_GET(MLXBF_SYNDROM__SYN, dram_syndrom);
+
+       if ((is_single_ecc && !serr) || (!is_single_ecc && !derr)) {
+               edac_mc_handle_error(ecc_type, mci, error_cnt, 0, 0, 0,
+                                    0, 0, -1, mci->ctl_name, "");
+               return;
+       }
+
+       dram_additional_info = readl(priv->emi_base + MLXBF_ADD_INFO);
+       err_prank = FIELD_GET(MLXBF_ADD_INFO__ERR_PRANK, dram_additional_info);
+
+       ecc_dimm = (err_prank >= 2 && priv->dimm_ranks[0] <= 2) ? 1 : 0;
+
+       edea0 = readl(priv->emi_base + MLXBF_ERR_ADDR_0);
+       edea1 = readl(priv->emi_base + MLXBF_ERR_ADDR_1);
+
+       ecc_dimm_addr = ((u64)edea1 << 32) | edea0;
+
+       edac_mc_handle_error(ecc_type, mci, error_cnt,
+                            PFN_DOWN(ecc_dimm_addr),
+                            offset_in_page(ecc_dimm_addr),
+                            syndrom, ecc_dimm, 0, 0, mci->ctl_name, "");
+}
+
+static void bluefield_edac_check(struct mem_ctl_info *mci)
+{
+       struct bluefield_edac_priv *priv = mci->pvt_info;
+       u32 ecc_count, single_error_count, double_error_count, ecc_error = 0;
+
+       /*
+        * The memory controller might not be initialized by the firmware
+        * when there isn't memory, which may lead to bad register readings.
+        */
+       if (mci->edac_cap == EDAC_FLAG_NONE)
+               return;
+
+       ecc_count = readl(priv->emi_base + MLXBF_ECC_CNT);
+       single_error_count = FIELD_GET(MLXBF_ECC_CNT__SERR_CNT, ecc_count);
+       double_error_count = FIELD_GET(MLXBF_ECC_CNT__DERR_CNT, ecc_count);
+
+       if (single_error_count) {
+               ecc_error |= MLXBF_ECC_ERR__SECC;
+
+               bluefield_gather_report_ecc(mci, single_error_count, 1);
+       }
+
+       if (double_error_count) {
+               ecc_error |= MLXBF_ECC_ERR__DECC;
+
+               bluefield_gather_report_ecc(mci, double_error_count, 0);
+       }
+
+       /* Write to clear reported errors. */
+       if (ecc_count)
+               writel(ecc_error, priv->emi_base + MLXBF_ECC_ERR);
+}
+
+/* Initialize the DIMMs information for the given memory controller. */
+static void bluefield_edac_init_dimms(struct mem_ctl_info *mci)
+{
+       struct bluefield_edac_priv *priv = mci->pvt_info;
+       int mem_ctrl_idx = mci->mc_idx;
+       struct dimm_info *dimm;
+       u64 smc_info, smc_arg;
+       int is_empty = 1, i;
+
+       for (i = 0; i < priv->dimm_per_mc; i++) {
+               dimm = mci->dimms[i];
+
+               smc_arg = mem_ctrl_idx << 16 | i;
+               smc_info = smc_call1(MLNX_SIP_GET_DIMM_INFO, smc_arg);
+
+               if (!FIELD_GET(MLXBF_DIMM_INFO__SIZE_GB, smc_info)) {
+                       dimm->mtype = MEM_EMPTY;
+                       continue;
+               }
+
+               is_empty = 0;
+
+               dimm->edac_mode = EDAC_SECDED;
+
+               if (FIELD_GET(MLXBF_DIMM_INFO__IS_NVDIMM, smc_info))
+                       dimm->mtype = MEM_NVDIMM;
+               else if (FIELD_GET(MLXBF_DIMM_INFO__IS_LRDIMM, smc_info))
+                       dimm->mtype = MEM_LRDDR4;
+               else if (FIELD_GET(MLXBF_DIMM_INFO__IS_RDIMM, smc_info))
+                       dimm->mtype = MEM_RDDR4;
+               else
+                       dimm->mtype = MEM_DDR4;
+
+               dimm->nr_pages =
+                       FIELD_GET(MLXBF_DIMM_INFO__SIZE_GB, smc_info) *
+                       (SZ_1G / PAGE_SIZE);
+               dimm->grain = MLXBF_EDAC_ERROR_GRAIN;
+
+               /* Mem controller for BlueField only supports x4, x8 and x16 */
+               switch (FIELD_GET(MLXBF_DIMM_INFO__PACKAGE_X, smc_info)) {
+               case 4:
+                       dimm->dtype = DEV_X4;
+                       break;
+               case 8:
+                       dimm->dtype = DEV_X8;
+                       break;
+               case 16:
+                       dimm->dtype = DEV_X16;
+                       break;
+               default:
+                       dimm->dtype = DEV_UNKNOWN;
+               }
+
+               priv->dimm_ranks[i] =
+                       FIELD_GET(MLXBF_DIMM_INFO__RANKS, smc_info);
+       }
+
+       if (is_empty)
+               mci->edac_cap = EDAC_FLAG_NONE;
+       else
+               mci->edac_cap = EDAC_FLAG_SECDED;
+}
+
+static int bluefield_edac_mc_probe(struct platform_device *pdev)
+{
+       struct bluefield_edac_priv *priv;
+       struct device *dev = &pdev->dev;
+       struct edac_mc_layer layers[1];
+       struct mem_ctl_info *mci;
+       struct resource *emi_res;
+       unsigned int mc_idx, dimm_count;
+       int rc, ret;
+
+       /* Read the MSS (Memory SubSystem) index from ACPI table. */
+       if (device_property_read_u32(dev, "mss_number", &mc_idx)) {
+               dev_warn(dev, "bf_edac: MSS number unknown\n");
+               return -EINVAL;
+       }
+
+       /* Read the DIMMs per MC from ACPI table. */
+       if (device_property_read_u32(dev, "dimm_per_mc", &dimm_count)) {
+               dev_warn(dev, "bf_edac: DIMMs per MC unknown\n");
+               return -EINVAL;
+       }
+
+       if (dimm_count > MLXBF_EDAC_MAX_DIMM_PER_MC) {
+               dev_warn(dev, "bf_edac: DIMMs per MC not valid\n");
+               return -EINVAL;
+       }
+
+       emi_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!emi_res)
+               return -EINVAL;
+
+       layers[0].type = EDAC_MC_LAYER_SLOT;
+       layers[0].size = dimm_count;
+       layers[0].is_virt_csrow = true;
+
+       mci = edac_mc_alloc(mc_idx, ARRAY_SIZE(layers), layers, sizeof(*priv));
+       if (!mci)
+               return -ENOMEM;
+
+       priv = mci->pvt_info;
+
+       priv->dimm_per_mc = dimm_count;
+       priv->emi_base = devm_ioremap_resource(dev, emi_res);
+       if (IS_ERR(priv->emi_base)) {
+               dev_err(dev, "failed to map EMI IO resource\n");
+               ret = PTR_ERR(priv->emi_base);
+               goto err;
+       }
+
+       mci->pdev = dev;
+       mci->mtype_cap = MEM_FLAG_DDR4 | MEM_FLAG_RDDR4 |
+                        MEM_FLAG_LRDDR4 | MEM_FLAG_NVDIMM;
+       mci->edac_ctl_cap = EDAC_FLAG_SECDED;
+
+       mci->mod_name = DRIVER_NAME;
+       mci->ctl_name = "BlueField_Memory_Controller";
+       mci->dev_name = dev_name(dev);
+       mci->edac_check = bluefield_edac_check;
+
+       /* Initialize mci with the actual populated DIMM information. */
+       bluefield_edac_init_dimms(mci);
+
+       platform_set_drvdata(pdev, mci);
+
+       /* Register with EDAC core */
+       rc = edac_mc_add_mc(mci);
+       if (rc) {
+               dev_err(dev, "failed to register with EDAC core\n");
+               ret = rc;
+               goto err;
+       }
+
+       /* Only POLL mode supported so far. */
+       edac_op_state = EDAC_OPSTATE_POLL;
+
+       return 0;
+
+err:
+       edac_mc_free(mci);
+
+       return ret;
+
+}
+
+static int bluefield_edac_mc_remove(struct platform_device *pdev)
+{
+       struct mem_ctl_info *mci = platform_get_drvdata(pdev);
+
+       edac_mc_del_mc(&pdev->dev);
+       edac_mc_free(mci);
+
+       return 0;
+}
+
+static const struct acpi_device_id bluefield_mc_acpi_ids[] = {
+       {"MLNXBF08", 0},
+       {}
+};
+
+MODULE_DEVICE_TABLE(acpi, bluefield_mc_acpi_ids);
+
+static struct platform_driver bluefield_edac_mc_driver = {
+       .driver = {
+               .name = DRIVER_NAME,
+               .acpi_match_table = bluefield_mc_acpi_ids,
+       },
+       .probe = bluefield_edac_mc_probe,
+       .remove = bluefield_edac_mc_remove,
+};
+
+module_platform_driver(bluefield_edac_mc_driver);
+
+MODULE_DESCRIPTION("Mellanox BlueField memory edac driver");
+MODULE_AUTHOR("Mellanox Technologies");
+MODULE_LICENSE("GPL v2");
index 64922c8..e6fd079 100644 (file)
@@ -114,8 +114,8 @@ static const struct kernel_param_ops edac_report_ops = {
 
 module_param_cb(edac_report, &edac_report_ops, &edac_report, 0644);
 
-unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf,
-                                unsigned len)
+unsigned int edac_dimm_info_location(struct dimm_info *dimm, char *buf,
+                                    unsigned int len)
 {
        struct mem_ctl_info *mci = dimm->mci;
        int i, n, count = 0;
@@ -236,9 +236,9 @@ EXPORT_SYMBOL_GPL(edac_mem_types);
  * At return, the pointer 'p' will be incremented to be used on a next call
  * to this function.
  */
-void *edac_align_ptr(void **p, unsigned size, int n_elems)
+void *edac_align_ptr(void **p, unsigned int size, int n_elems)
 {
-       unsigned align, r;
+       unsigned int align, r;
        void *ptr = *p;
 
        *p += size * n_elems;
@@ -275,38 +275,37 @@ void *edac_align_ptr(void **p, unsigned size, int n_elems)
 
 static void _edac_mc_free(struct mem_ctl_info *mci)
 {
-       int i, chn, row;
        struct csrow_info *csr;
-       const unsigned int tot_dimms = mci->tot_dimms;
-       const unsigned int tot_channels = mci->num_cschannel;
-       const unsigned int tot_csrows = mci->nr_csrows;
+       int i, chn, row;
 
        if (mci->dimms) {
-               for (i = 0; i < tot_dimms; i++)
+               for (i = 0; i < mci->tot_dimms; i++)
                        kfree(mci->dimms[i]);
                kfree(mci->dimms);
        }
+
        if (mci->csrows) {
-               for (row = 0; row < tot_csrows; row++) {
+               for (row = 0; row < mci->nr_csrows; row++) {
                        csr = mci->csrows[row];
-                       if (csr) {
-                               if (csr->channels) {
-                                       for (chn = 0; chn < tot_channels; chn++)
-                                               kfree(csr->channels[chn]);
-                                       kfree(csr->channels);
-                               }
-                               kfree(csr);
+                       if (!csr)
+                               continue;
+
+                       if (csr->channels) {
+                               for (chn = 0; chn < mci->num_cschannel; chn++)
+                                       kfree(csr->channels[chn]);
+                               kfree(csr->channels);
                        }
+                       kfree(csr);
                }
                kfree(mci->csrows);
        }
        kfree(mci);
 }
 
-struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
-                                  unsigned n_layers,
+struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
+                                  unsigned int n_layers,
                                   struct edac_mc_layer *layers,
-                                  unsigned sz_pvt)
+                                  unsigned int sz_pvt)
 {
        struct mem_ctl_info *mci;
        struct edac_mc_layer *layer;
@@ -314,9 +313,9 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
        struct rank_info *chan;
        struct dimm_info *dimm;
        u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
-       unsigned pos[EDAC_MAX_LAYERS];
-       unsigned size, tot_dimms = 1, count = 1;
-       unsigned tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
+       unsigned int pos[EDAC_MAX_LAYERS];
+       unsigned int size, tot_dimms = 1, count = 1;
+       unsigned int tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
        void *pvt, *p, *ptr = NULL;
        int i, j, row, chn, n, len, off;
        bool per_rank = false;
@@ -1235,9 +1234,13 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type,
        if (p > e->location)
                *(p - 1) = '\0';
 
-       /* Report the error via the trace interface */
-       grain_bits = fls_long(e->grain) + 1;
+       /* Sanity-check driver-supplied grain value. */
+       if (WARN_ON_ONCE(!e->grain))
+               e->grain = 1;
 
+       grain_bits = fls_long(e->grain - 1);
+
+       /* Report the error via the trace interface */
        if (IS_ENABLED(CONFIG_RAS))
                trace_mc_event(type, e->msg, e->label, e->error_count,
                               mci->mc_idx, e->top_layer, e->mid_layer,
index 4165e15..02aac5c 100644 (file)
@@ -122,10 +122,10 @@ do {                                                                      \
  *     On success, return a pointer to struct mem_ctl_info pointer;
  *     %NULL otherwise
  */
-struct mem_ctl_info *edac_mc_alloc(unsigned mc_num,
-                                  unsigned n_layers,
+struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
+                                  unsigned int n_layers,
                                   struct edac_mc_layer *layers,
-                                  unsigned sz_pvt);
+                                  unsigned int sz_pvt);
 
 /**
  * edac_get_owner - Return the owner's mod_name of EDAC MC
index 4386ea4..32d016f 100644 (file)
@@ -131,7 +131,7 @@ static const char * const edac_caps[] = {
 
 struct dev_ch_attribute {
        struct device_attribute attr;
-       int channel;
+       unsigned int channel;
 };
 
 #define DEVICE_CHANNEL(_name, _mode, _show, _store, _var) \
@@ -200,7 +200,7 @@ static ssize_t channel_dimm_label_show(struct device *dev,
                                       char *data)
 {
        struct csrow_info *csrow = to_csrow(dev);
-       unsigned chan = to_channel(mattr);
+       unsigned int chan = to_channel(mattr);
        struct rank_info *rank = csrow->channels[chan];
 
        /* if field has not been initialized, there is nothing to send */
@@ -216,7 +216,7 @@ static ssize_t channel_dimm_label_store(struct device *dev,
                                        const char *data, size_t count)
 {
        struct csrow_info *csrow = to_csrow(dev);
-       unsigned chan = to_channel(mattr);
+       unsigned int chan = to_channel(mattr);
        struct rank_info *rank = csrow->channels[chan];
        size_t copy_count = count;
 
@@ -240,7 +240,7 @@ static ssize_t channel_ce_count_show(struct device *dev,
                                     struct device_attribute *mattr, char *data)
 {
        struct csrow_info *csrow = to_csrow(dev);
-       unsigned chan = to_channel(mattr);
+       unsigned int chan = to_channel(mattr);
        struct rank_info *rank = csrow->channels[chan];
 
        return sprintf(data, "%u\n", rank->ce_count);
@@ -278,7 +278,7 @@ static void csrow_attr_release(struct device *dev)
 {
        struct csrow_info *csrow = container_of(dev, struct csrow_info, dev);
 
-       edac_dbg(1, "Releasing csrow device %s\n", dev_name(dev));
+       edac_dbg(1, "device %s released\n", dev_name(dev));
        kfree(csrow);
 }
 
@@ -414,14 +414,16 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci,
        dev_set_name(&csrow->dev, "csrow%d", index);
        dev_set_drvdata(&csrow->dev, csrow);
 
-       edac_dbg(0, "creating (virtual) csrow node %s\n",
-                dev_name(&csrow->dev));
-
        err = device_add(&csrow->dev);
-       if (err)
+       if (err) {
+               edac_dbg(1, "failure: create device %s\n", dev_name(&csrow->dev));
                put_device(&csrow->dev);
+               return err;
+       }
 
-       return err;
+       edac_dbg(0, "device %s created\n", dev_name(&csrow->dev));
+
+       return 0;
 }
 
 /* Create a CSROW object under specifed edac_mc_device */
@@ -435,12 +437,8 @@ static int edac_create_csrow_objects(struct mem_ctl_info *mci)
                if (!nr_pages_per_csrow(csrow))
                        continue;
                err = edac_create_csrow_object(mci, mci->csrows[i], i);
-               if (err < 0) {
-                       edac_dbg(1,
-                                "failure: create csrow objects for csrow %d\n",
-                                i);
+               if (err < 0)
                        goto error;
-               }
        }
        return 0;
 
@@ -624,7 +622,7 @@ static void dimm_attr_release(struct device *dev)
 {
        struct dimm_info *dimm = container_of(dev, struct dimm_info, dev);
 
-       edac_dbg(1, "Releasing dimm device %s\n", dev_name(dev));
+       edac_dbg(1, "device %s released\n", dev_name(dev));
        kfree(dimm);
 }
 
@@ -653,12 +651,21 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci,
        pm_runtime_forbid(&mci->dev);
 
        err = device_add(&dimm->dev);
-       if (err)
+       if (err) {
+               edac_dbg(1, "failure: create device %s\n", dev_name(&dimm->dev));
                put_device(&dimm->dev);
+               return err;
+       }
 
-       edac_dbg(0, "created rank/dimm device %s\n", dev_name(&dimm->dev));
+       if (IS_ENABLED(CONFIG_EDAC_DEBUG)) {
+               char location[80];
 
-       return err;
+               edac_dimm_info_location(dimm, location, sizeof(location));
+               edac_dbg(0, "device %s created at location %s\n",
+                       dev_name(&dimm->dev), location);
+       }
+
+       return 0;
 }
 
 /*
@@ -901,7 +908,7 @@ static void mci_attr_release(struct device *dev)
 {
        struct mem_ctl_info *mci = container_of(dev, struct mem_ctl_info, dev);
 
-       edac_dbg(1, "Releasing csrow device %s\n", dev_name(dev));
+       edac_dbg(1, "device %s released\n", dev_name(dev));
        kfree(mci);
 }
 
@@ -933,14 +940,15 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
        dev_set_drvdata(&mci->dev, mci);
        pm_runtime_forbid(&mci->dev);
 
-       edac_dbg(0, "creating device %s\n", dev_name(&mci->dev));
        err = device_add(&mci->dev);
        if (err < 0) {
                edac_dbg(1, "failure: create device %s\n", dev_name(&mci->dev));
                put_device(&mci->dev);
-               goto out;
+               return err;
        }
 
+       edac_dbg(0, "device %s created\n", dev_name(&mci->dev));
+
        /*
         * Create the dimm/rank devices
         */
@@ -950,22 +958,9 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci,
                if (!dimm->nr_pages)
                        continue;
 
-#ifdef CONFIG_EDAC_DEBUG
-               edac_dbg(1, "creating dimm%d, located at ", i);
-               if (edac_debug_level >= 1) {
-                       int lay;
-                       for (lay = 0; lay < mci->n_layers; lay++)
-                               printk(KERN_CONT "%s %d ",
-                                       edac_layer_name[mci->layers[lay].type],
-                                       dimm->location[lay]);
-                       printk(KERN_CONT "\n");
-               }
-#endif
                err = edac_create_dimm_object(mci, dimm, i);
-               if (err) {
-                       edac_dbg(1, "failure: create dimm %d obj\n", i);
+               if (err)
                        goto fail_unregister_dimm;
-               }
        }
 
 #ifdef CONFIG_EDAC_LEGACY_SYSFS
@@ -987,7 +982,6 @@ fail_unregister_dimm:
        }
        device_unregister(&mci->dev);
 
-out:
        return err;
 }
 
@@ -1011,14 +1005,14 @@ void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci)
                struct dimm_info *dimm = mci->dimms[i];
                if (dimm->nr_pages == 0)
                        continue;
-               edac_dbg(0, "removing device %s\n", dev_name(&dimm->dev));
+               edac_dbg(1, "unregistering device %s\n", dev_name(&dimm->dev));
                device_unregister(&dimm->dev);
        }
 }
 
 void edac_unregister_sysfs(struct mem_ctl_info *mci)
 {
-       edac_dbg(1, "Unregistering device %s\n", dev_name(&mci->dev));
+       edac_dbg(1, "unregistering device %s\n", dev_name(&mci->dev));
        device_unregister(&mci->dev);
 }
 
@@ -1029,7 +1023,7 @@ static void mc_attr_release(struct device *dev)
         * parent device, used to create the /sys/devices/mc sysfs node.
         * So, there are no attributes on it.
         */
-       edac_dbg(1, "Releasing device %s\n", dev_name(dev));
+       edac_dbg(1, "device %s released\n", dev_name(dev));
        kfree(dev);
 }
 
@@ -1044,10 +1038,8 @@ int __init edac_mc_sysfs_init(void)
        int err;
 
        mci_pdev = kzalloc(sizeof(*mci_pdev), GFP_KERNEL);
-       if (!mci_pdev) {
-               err = -ENOMEM;
-               goto out;
-       }
+       if (!mci_pdev)
+               return -ENOMEM;
 
        mci_pdev->bus = edac_get_sysfs_subsys();
        mci_pdev->type = &mc_attr_type;
@@ -1055,17 +1047,15 @@ int __init edac_mc_sysfs_init(void)
        dev_set_name(mci_pdev, "mc");
 
        err = device_add(mci_pdev);
-       if (err < 0)
-               goto out_put_device;
+       if (err < 0) {
+               edac_dbg(1, "failure: create device %s\n", dev_name(mci_pdev));
+               put_device(mci_pdev);
+               return err;
+       }
 
        edac_dbg(0, "device %s created\n", dev_name(mci_pdev));
 
        return 0;
-
- out_put_device:
-       put_device(mci_pdev);
- out:
-       return err;
 }
 
 void edac_mc_sysfs_exit(void)
index 7f19f1c..d413a0b 100644 (file)
@@ -68,7 +68,7 @@ struct memdev_dmi_entry {
 
 struct ghes_edac_dimm_fill {
        struct mem_ctl_info *mci;
-       unsigned count;
+       unsigned int count;
 };
 
 static void ghes_edac_count_dimms(const struct dmi_header *dh, void *arg)
index b506eef..251f2b6 100644 (file)
@@ -417,7 +417,8 @@ static const char *i5100_err_msg(unsigned err)
 }
 
 /* convert csrow index into a rank (per channel -- 0..5) */
-static int i5100_csrow_to_rank(const struct mem_ctl_info *mci, int csrow)
+static unsigned int i5100_csrow_to_rank(const struct mem_ctl_info *mci,
+                                       unsigned int csrow)
 {
        const struct i5100_priv *priv = mci->pvt_info;
 
@@ -425,7 +426,8 @@ static int i5100_csrow_to_rank(const struct mem_ctl_info *mci, int csrow)
 }
 
 /* convert csrow index into a channel (0..1) */
-static int i5100_csrow_to_chan(const struct mem_ctl_info *mci, int csrow)
+static unsigned int i5100_csrow_to_chan(const struct mem_ctl_info *mci,
+                                       unsigned int csrow)
 {
        const struct i5100_priv *priv = mci->pvt_info;
 
@@ -653,11 +655,11 @@ static struct pci_dev *pci_get_device_func(unsigned vendor,
        return ret;
 }
 
-static unsigned long i5100_npages(struct mem_ctl_info *mci, int csrow)
+static unsigned long i5100_npages(struct mem_ctl_info *mci, unsigned int csrow)
 {
        struct i5100_priv *priv = mci->pvt_info;
-       const unsigned chan_rank = i5100_csrow_to_rank(mci, csrow);
-       const unsigned chan = i5100_csrow_to_chan(mci, csrow);
+       const unsigned int chan_rank = i5100_csrow_to_rank(mci, csrow);
+       const unsigned int chan = i5100_csrow_to_chan(mci, csrow);
        unsigned addr_lines;
 
        /* dimm present? */
@@ -852,8 +854,8 @@ static void i5100_init_csrows(struct mem_ctl_info *mci)
        for (i = 0; i < mci->tot_dimms; i++) {
                struct dimm_info *dimm;
                const unsigned long npages = i5100_npages(mci, i);
-               const unsigned chan = i5100_csrow_to_chan(mci, i);
-               const unsigned rank = i5100_csrow_to_rank(mci, i);
+               const unsigned int chan = i5100_csrow_to_chan(mci, i);
+               const unsigned int rank = i5100_csrow_to_rank(mci, i);
 
                if (!npages)
                        continue;
index ca25f8f..1ad538b 100644 (file)
@@ -260,11 +260,14 @@ static u64 get_sideband_reg_base_addr(void)
        }
 }
 
+#define DNV_MCHBAR_SIZE  0x8000
+#define DNV_SB_PORT_SIZE 0x10000
 static int dnv_rd_reg(int port, int off, int op, void *data, size_t sz, char *name)
 {
        struct pci_dev *pdev;
        char *base;
        u64 addr;
+       unsigned long size;
 
        if (op == 4) {
                pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x1980, NULL);
@@ -279,15 +282,17 @@ static int dnv_rd_reg(int port, int off, int op, void *data, size_t sz, char *na
                        addr = get_mem_ctrl_hub_base_addr();
                        if (!addr)
                                return -ENODEV;
+                       size = DNV_MCHBAR_SIZE;
                } else {
                        /* MMIO via sideband register base address */
                        addr = get_sideband_reg_base_addr();
                        if (!addr)
                                return -ENODEV;
                        addr += (port << 16);
+                       size = DNV_SB_PORT_SIZE;
                }
 
-               base = ioremap((resource_size_t)addr, 0x10000);
+               base = ioremap((resource_size_t)addr, size);
                if (!base)
                        return -ENODEV;
 
index ba8d3d0..c9a827b 100644 (file)
@@ -271,6 +271,20 @@ config TRUSTED_FOUNDATIONS
 
          Choose N if you don't know what this is about.
 
+config TURRIS_MOX_RWTM
+       tristate "Turris Mox rWTM secure firmware driver"
+       depends on ARCH_MVEBU || COMPILE_TEST
+       depends on HAS_DMA && OF
+       depends on MAILBOX
+       select HW_RANDOM
+       select ARMADA_37XX_RWTM_MBOX
+       help
+         This driver communicates with the firmware on the Cortex-M3 secure
+         processor of the Turris Mox router. Enable if you are building for
+         Turris Mox, and you will be able to read the device serial number and
+         other manufacturing data and also utilize the Entropy Bit Generator
+         for hardware random number generation.
+
 config HAVE_ARM_SMCCC
        bool
 
index 3fa0b34..2b6e3a0 100644 (file)
@@ -22,6 +22,7 @@ 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-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
+obj-$(CONFIG_TURRIS_MOX_RWTM)  += turris-mox-rwtm.o
 
 obj-$(CONFIG_ARM_SCMI_PROTOCOL)        += arm_scmi/
 obj-y                          += psci/
index c47d28d..5f298f0 100644 (file)
@@ -2,5 +2,5 @@
 obj-y  = scmi-bus.o scmi-driver.o scmi-protocols.o
 scmi-bus-y = bus.o
 scmi-driver-y = driver.o
-scmi-protocols-y = base.o clock.o perf.o power.o sensors.o
+scmi-protocols-y = base.o clock.o perf.o power.o reset.o sensors.o
 obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o
index 2043902..f804e8a 100644 (file)
@@ -204,7 +204,7 @@ static int scmi_base_discover_agent_get(const struct scmi_handle *handle,
        if (ret)
                return ret;
 
-       *(__le32 *)t->tx.buf = cpu_to_le32(id);
+       put_unaligned_le32(id, t->tx.buf);
 
        ret = scmi_do_xfer(handle, t);
        if (!ret)
index 0a194af..32526a7 100644 (file)
@@ -56,7 +56,7 @@ struct scmi_msg_resp_clock_describe_rates {
 struct scmi_clock_set_rate {
        __le32 flags;
 #define CLOCK_SET_ASYNC                BIT(0)
-#define CLOCK_SET_DELAYED      BIT(1)
+#define CLOCK_SET_IGNORE_RESP  BIT(1)
 #define CLOCK_SET_ROUND_UP     BIT(2)
 #define CLOCK_SET_ROUND_AUTO   BIT(3)
        __le32 id;
@@ -67,6 +67,7 @@ struct scmi_clock_set_rate {
 struct clock_info {
        int num_clocks;
        int max_async_req;
+       atomic_t cur_async_req;
        struct scmi_clock_info *clk;
 };
 
@@ -106,7 +107,7 @@ static int scmi_clock_attributes_get(const struct scmi_handle *handle,
        if (ret)
                return ret;
 
-       *(__le32 *)t->tx.buf = cpu_to_le32(clk_id);
+       put_unaligned_le32(clk_id, t->tx.buf);
        attr = t->rx.buf;
 
        ret = scmi_do_xfer(handle, t);
@@ -203,39 +204,47 @@ scmi_clock_rate_get(const struct scmi_handle *handle, u32 clk_id, u64 *value)
        if (ret)
                return ret;
 
-       *(__le32 *)t->tx.buf = cpu_to_le32(clk_id);
+       put_unaligned_le32(clk_id, t->tx.buf);
 
        ret = scmi_do_xfer(handle, t);
-       if (!ret) {
-               __le32 *pval = t->rx.buf;
-
-               *value = le32_to_cpu(*pval);
-               *value |= (u64)le32_to_cpu(*(pval + 1)) << 32;
-       }
+       if (!ret)
+               *value = get_unaligned_le64(t->rx.buf);
 
        scmi_xfer_put(handle, t);
        return ret;
 }
 
 static int scmi_clock_rate_set(const struct scmi_handle *handle, u32 clk_id,
-                              u32 config, u64 rate)
+                              u64 rate)
 {
        int ret;
+       u32 flags = 0;
        struct scmi_xfer *t;
        struct scmi_clock_set_rate *cfg;
+       struct clock_info *ci = handle->clk_priv;
 
        ret = scmi_xfer_get_init(handle, CLOCK_RATE_SET, SCMI_PROTOCOL_CLOCK,
                                 sizeof(*cfg), 0, &t);
        if (ret)
                return ret;
 
+       if (ci->max_async_req &&
+           atomic_inc_return(&ci->cur_async_req) < ci->max_async_req)
+               flags |= CLOCK_SET_ASYNC;
+
        cfg = t->tx.buf;
-       cfg->flags = cpu_to_le32(config);
+       cfg->flags = cpu_to_le32(flags);
        cfg->id = cpu_to_le32(clk_id);
        cfg->value_low = cpu_to_le32(rate & 0xffffffff);
        cfg->value_high = cpu_to_le32(rate >> 32);
 
-       ret = scmi_do_xfer(handle, t);
+       if (flags & CLOCK_SET_ASYNC)
+               ret = scmi_do_xfer_with_response(handle, t);
+       else
+               ret = scmi_do_xfer(handle, t);
+
+       if (ci->max_async_req)
+               atomic_dec(&ci->cur_async_req);
 
        scmi_xfer_put(handle, t);
        return ret;
index 44fd4f9..5237c2f 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/scmi_protocol.h>
 #include <linux/types.h>
 
+#include <asm/unaligned.h>
+
 #define PROTOCOL_REV_MINOR_MASK        GENMASK(15, 0)
 #define PROTOCOL_REV_MAJOR_MASK        GENMASK(31, 16)
 #define PROTOCOL_REV_MAJOR(x)  (u16)(FIELD_GET(PROTOCOL_REV_MAJOR_MASK, (x)))
@@ -48,11 +50,11 @@ struct scmi_msg_resp_prot_version {
 /**
  * struct scmi_msg_hdr - Message(Tx/Rx) header
  *
- * @id: The identifier of the command being sent
- * @protocol_id: The identifier of the protocol used to send @id command
- * @seq: The token to identify the message. when a message/command returns,
- *     the platform returns the whole message header unmodified including
- *     the token
+ * @id: The identifier of the message being sent
+ * @protocol_id: The identifier of the protocol used to send @id message
+ * @seq: The token to identify the message. When a message returns, the
+ *     platform returns the whole message header unmodified including the
+ *     token
  * @status: Status of the transfer once it's complete
  * @poll_completion: Indicate if the transfer needs to be polled for
  *     completion or interrupt mode is used
@@ -84,17 +86,21 @@ struct scmi_msg {
  * @rx: Receive message, the buffer should be pre-allocated to store
  *     message. If request-ACK protocol is used, we can reuse the same
  *     buffer for the rx path as we use for the tx path.
- * @done: completion event
+ * @done: command message transmit completion event
+ * @async: pointer to delayed response message received event completion
  */
 struct scmi_xfer {
        struct scmi_msg_hdr hdr;
        struct scmi_msg tx;
        struct scmi_msg rx;
        struct completion done;
+       struct completion *async_done;
 };
 
 void scmi_xfer_put(const struct scmi_handle *h, struct scmi_xfer *xfer);
 int scmi_do_xfer(const struct scmi_handle *h, struct scmi_xfer *xfer);
+int scmi_do_xfer_with_response(const struct scmi_handle *h,
+                              struct scmi_xfer *xfer);
 int scmi_xfer_get_init(const struct scmi_handle *h, u8 msg_id, u8 prot_id,
                       size_t tx_size, size_t rx_size, struct scmi_xfer **p);
 int scmi_handle_put(const struct scmi_handle *handle);
index b5bc4c7..3eb0382 100644 (file)
 #include "common.h"
 
 #define MSG_ID_MASK            GENMASK(7, 0)
+#define MSG_XTRACT_ID(hdr)     FIELD_GET(MSG_ID_MASK, (hdr))
 #define MSG_TYPE_MASK          GENMASK(9, 8)
+#define MSG_XTRACT_TYPE(hdr)   FIELD_GET(MSG_TYPE_MASK, (hdr))
+#define MSG_TYPE_COMMAND       0
+#define MSG_TYPE_DELAYED_RESP  2
+#define MSG_TYPE_NOTIFICATION  3
 #define MSG_PROTOCOL_ID_MASK   GENMASK(17, 10)
+#define MSG_XTRACT_PROT_ID(hdr)        FIELD_GET(MSG_PROTOCOL_ID_MASK, (hdr))
 #define MSG_TOKEN_ID_MASK      GENMASK(27, 18)
 #define MSG_XTRACT_TOKEN(hdr)  FIELD_GET(MSG_TOKEN_ID_MASK, (hdr))
 #define MSG_TOKEN_MAX          (MSG_XTRACT_TOKEN(MSG_TOKEN_ID_MASK) + 1)
@@ -86,7 +92,7 @@ struct scmi_desc {
 };
 
 /**
- * struct scmi_chan_info - Structure representing a SCMI channel informfation
+ * struct scmi_chan_info - Structure representing a SCMI channel information
  *
  * @cl: Mailbox Client
  * @chan: Transmit/Receive mailbox channel
@@ -111,8 +117,9 @@ struct scmi_chan_info {
  * @handle: Instance of SCMI handle to send to clients
  * @version: SCMI revision information containing protocol version,
  *     implementation version and (sub-)vendor identification.
- * @minfo: Message info
- * @tx_idr: IDR object to map protocol id to channel info pointer
+ * @tx_minfo: Universal Transmit Message management info
+ * @tx_idr: IDR object to map protocol id to Tx channel info pointer
+ * @rx_idr: IDR object to map protocol id to Rx channel info pointer
  * @protocols_imp: List of protocols implemented, currently maximum of
  *     MAX_PROTOCOLS_IMP elements allocated by the base protocol
  * @node: List head
@@ -123,8 +130,9 @@ struct scmi_info {
        const struct scmi_desc *desc;
        struct scmi_revision_info version;
        struct scmi_handle handle;
-       struct scmi_xfers_info minfo;
+       struct scmi_xfers_info tx_minfo;
        struct idr tx_idr;
+       struct idr rx_idr;
        u8 *protocols_imp;
        struct list_head node;
        int users;
@@ -182,7 +190,7 @@ static inline int scmi_to_linux_errno(int errno)
 static inline void scmi_dump_header_dbg(struct device *dev,
                                        struct scmi_msg_hdr *hdr)
 {
-       dev_dbg(dev, "Command ID: %x Sequence ID: %x Protocol: %x\n",
+       dev_dbg(dev, "Message ID: %x Sequence ID: %x Protocol: %x\n",
                hdr->id, hdr->seq, hdr->protocol_id);
 }
 
@@ -190,7 +198,7 @@ static void scmi_fetch_response(struct scmi_xfer *xfer,
                                struct scmi_shared_mem __iomem *mem)
 {
        xfer->hdr.status = ioread32(mem->msg_payload);
-       /* Skip the length of header and statues in payload area i.e 8 bytes*/
+       /* Skip the length of header and status in payload area i.e 8 bytes */
        xfer->rx.len = min_t(size_t, xfer->rx.len, ioread32(&mem->length) - 8);
 
        /* Take a copy to the rx buffer.. */
@@ -198,56 +206,12 @@ static void scmi_fetch_response(struct scmi_xfer *xfer,
 }
 
 /**
- * scmi_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 scmi_rx_callback(struct mbox_client *cl, void *m)
-{
-       u16 xfer_id;
-       struct scmi_xfer *xfer;
-       struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
-       struct device *dev = cinfo->dev;
-       struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
-       struct scmi_xfers_info *minfo = &info->minfo;
-       struct scmi_shared_mem __iomem *mem = cinfo->payload;
-
-       xfer_id = MSG_XTRACT_TOKEN(ioread32(&mem->msg_header));
-
-       /* Are we even expecting this? */
-       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];
-
-       scmi_dump_header_dbg(dev, &xfer->hdr);
-       /* Is the message of valid length? */
-       if (xfer->rx.len > info->desc->max_msg_size) {
-               dev_err(dev, "unable to handle %zu xfer(max %d)\n",
-                       xfer->rx.len, info->desc->max_msg_size);
-               return;
-       }
-
-       scmi_fetch_response(xfer, mem);
-       complete(&xfer->done);
-}
-
-/**
  * pack_scmi_header() - packs and returns 32-bit header
  *
  * @hdr: pointer to header containing all the information on message id,
  *     protocol id and sequence id.
  *
- * Return: 32-bit packed command header to be sent to the platform.
+ * Return: 32-bit packed message header to be sent to the platform.
  */
 static inline u32 pack_scmi_header(struct scmi_msg_hdr *hdr)
 {
@@ -257,6 +221,18 @@ static inline u32 pack_scmi_header(struct scmi_msg_hdr *hdr)
 }
 
 /**
+ * unpack_scmi_header() - unpacks and records message and protocol id
+ *
+ * @msg_hdr: 32-bit packed message header sent from the platform
+ * @hdr: pointer to header to fetch message and protocol id.
+ */
+static inline void unpack_scmi_header(u32 msg_hdr, struct scmi_msg_hdr *hdr)
+{
+       hdr->id = MSG_XTRACT_ID(msg_hdr);
+       hdr->protocol_id = MSG_XTRACT_PROT_ID(msg_hdr);
+}
+
+/**
  * scmi_tx_prepare() - mailbox client callback to prepare for the transfer
  *
  * @cl: client pointer
@@ -271,6 +247,14 @@ static void scmi_tx_prepare(struct mbox_client *cl, void *m)
        struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
        struct scmi_shared_mem __iomem *mem = cinfo->payload;
 
+       /*
+        * Ideally channel must be free by now unless OS timeout last
+        * request and platform continued to process the same, wait
+        * until it releases the shared memory, otherwise we may endup
+        * overwriting its response with new message payload or vice-versa
+        */
+       spin_until_cond(ioread32(&mem->channel_status) &
+                       SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE);
        /* Mark channel busy + clear error */
        iowrite32(0x0, &mem->channel_status);
        iowrite32(t->hdr.poll_completion ? 0 : SCMI_SHMEM_FLAG_INTR_ENABLED,
@@ -285,8 +269,9 @@ static void scmi_tx_prepare(struct mbox_client *cl, void *m)
  * scmi_xfer_get() - Allocate one message
  *
  * @handle: Pointer to SCMI entity handle
+ * @minfo: Pointer to Tx/Rx Message management info based on channel type
  *
- * Helper function which is used by various command functions that are
+ * Helper function which is used by various message 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
@@ -295,13 +280,13 @@ static void scmi_tx_prepare(struct mbox_client *cl, void *m)
  *
  * Return: 0 if all went fine, else corresponding error.
  */
-static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle)
+static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle,
+                                      struct scmi_xfers_info *minfo)
 {
        u16 xfer_id;
        struct scmi_xfer *xfer;
        unsigned long flags, bit_pos;
        struct scmi_info *info = handle_to_scmi_info(handle);
-       struct scmi_xfers_info *minfo = &info->minfo;
 
        /* Keep the locked section as small as possible */
        spin_lock_irqsave(&minfo->xfer_lock, flags);
@@ -324,18 +309,17 @@ static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle)
 }
 
 /**
- * scmi_xfer_put() - Release a message
+ * __scmi_xfer_put() - Release a message
  *
- * @handle: Pointer to SCMI entity handle
+ * @minfo: Pointer to Tx/Rx Message management info based on channel type
  * @xfer: message that was reserved by scmi_xfer_get
  *
  * This holds a spinlock to maintain integrity of internal data structures.
  */
-void scmi_xfer_put(const struct scmi_handle *handle, struct scmi_xfer *xfer)
+static void
+__scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
 {
        unsigned long flags;
-       struct scmi_info *info = handle_to_scmi_info(handle);
-       struct scmi_xfers_info *minfo = &info->minfo;
 
        /*
         * Keep the locked section as small as possible
@@ -347,6 +331,68 @@ void scmi_xfer_put(const struct scmi_handle *handle, struct scmi_xfer *xfer)
        spin_unlock_irqrestore(&minfo->xfer_lock, flags);
 }
 
+/**
+ * scmi_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 scmi_rx_callback(struct mbox_client *cl, void *m)
+{
+       u8 msg_type;
+       u32 msg_hdr;
+       u16 xfer_id;
+       struct scmi_xfer *xfer;
+       struct scmi_chan_info *cinfo = client_to_scmi_chan_info(cl);
+       struct device *dev = cinfo->dev;
+       struct scmi_info *info = handle_to_scmi_info(cinfo->handle);
+       struct scmi_xfers_info *minfo = &info->tx_minfo;
+       struct scmi_shared_mem __iomem *mem = cinfo->payload;
+
+       msg_hdr = ioread32(&mem->msg_header);
+       msg_type = MSG_XTRACT_TYPE(msg_hdr);
+       xfer_id = MSG_XTRACT_TOKEN(msg_hdr);
+
+       if (msg_type == MSG_TYPE_NOTIFICATION)
+               return; /* Notifications not yet supported */
+
+       /* Are we even expecting this? */
+       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];
+
+       scmi_dump_header_dbg(dev, &xfer->hdr);
+
+       scmi_fetch_response(xfer, mem);
+
+       if (msg_type == MSG_TYPE_DELAYED_RESP)
+               complete(xfer->async_done);
+       else
+               complete(&xfer->done);
+}
+
+/**
+ * scmi_xfer_put() - Release a transmit message
+ *
+ * @handle: Pointer to SCMI entity handle
+ * @xfer: message that was reserved by scmi_xfer_get
+ */
+void scmi_xfer_put(const struct scmi_handle *handle, struct scmi_xfer *xfer)
+{
+       struct scmi_info *info = handle_to_scmi_info(handle);
+
+       __scmi_xfer_put(&info->tx_minfo, xfer);
+}
+
 static bool
 scmi_xfer_poll_done(const struct scmi_chan_info *cinfo, struct scmi_xfer *xfer)
 {
@@ -435,8 +481,36 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer)
        return ret;
 }
 
+#define SCMI_MAX_RESPONSE_TIMEOUT      (2 * MSEC_PER_SEC)
+
+/**
+ * scmi_do_xfer_with_response() - Do one transfer and wait until the delayed
+ *     response is received
+ *
+ * @handle: Pointer to SCMI entity handle
+ * @xfer: Transfer to initiate and wait for response
+ *
+ * Return: -ETIMEDOUT in case of no delayed response, if transmit error,
+ *     return corresponding error, else if all goes well, return 0.
+ */
+int scmi_do_xfer_with_response(const struct scmi_handle *handle,
+                              struct scmi_xfer *xfer)
+{
+       int ret, timeout = msecs_to_jiffies(SCMI_MAX_RESPONSE_TIMEOUT);
+       DECLARE_COMPLETION_ONSTACK(async_response);
+
+       xfer->async_done = &async_response;
+
+       ret = scmi_do_xfer(handle, xfer);
+       if (!ret && !wait_for_completion_timeout(xfer->async_done, timeout))
+               ret = -ETIMEDOUT;
+
+       xfer->async_done = NULL;
+       return ret;
+}
+
 /**
- * scmi_xfer_get_init() - Allocate and initialise one message
+ * scmi_xfer_get_init() - Allocate and initialise one message for transmit
  *
  * @handle: Pointer to SCMI entity handle
  * @msg_id: Message identifier
@@ -457,6 +531,7 @@ int scmi_xfer_get_init(const struct scmi_handle *handle, u8 msg_id, u8 prot_id,
        int ret;
        struct scmi_xfer *xfer;
        struct scmi_info *info = handle_to_scmi_info(handle);
+       struct scmi_xfers_info *minfo = &info->tx_minfo;
        struct device *dev = info->dev;
 
        /* Ensure we have sane transfer sizes */
@@ -464,7 +539,7 @@ int scmi_xfer_get_init(const struct scmi_handle *handle, u8 msg_id, u8 prot_id,
            tx_size > info->desc->max_msg_size)
                return -ERANGE;
 
-       xfer = scmi_xfer_get(handle);
+       xfer = scmi_xfer_get(handle, minfo);
        if (IS_ERR(xfer)) {
                ret = PTR_ERR(xfer);
                dev_err(dev, "failed to get free message slot(%d)\n", ret);
@@ -597,27 +672,13 @@ int scmi_handle_put(const struct scmi_handle *handle)
        return 0;
 }
 
-static const struct scmi_desc scmi_generic_desc = {
-       .max_rx_timeout_ms = 30,        /* We may increase this if required */
-       .max_msg = 20,          /* Limited by MBOX_TX_QUEUE_LEN */
-       .max_msg_size = 128,
-};
-
-/* Each compatible listed below must have descriptor associated with it */
-static const struct of_device_id scmi_of_match[] = {
-       { .compatible = "arm,scmi", .data = &scmi_generic_desc },
-       { /* Sentinel */ },
-};
-
-MODULE_DEVICE_TABLE(of, scmi_of_match);
-
 static int scmi_xfer_info_init(struct scmi_info *sinfo)
 {
        int i;
        struct scmi_xfer *xfer;
        struct device *dev = sinfo->dev;
        const struct scmi_desc *desc = sinfo->desc;
-       struct scmi_xfers_info *info = &sinfo->minfo;
+       struct scmi_xfers_info *info = &sinfo->tx_minfo;
 
        /* Pre-allocated messages, no more than what hdr.seq can support */
        if (WARN_ON(desc->max_msg >= MSG_TOKEN_MAX)) {
@@ -652,61 +713,32 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo)
        return 0;
 }
 
-static int scmi_mailbox_check(struct device_node *np)
+static int scmi_mailbox_check(struct device_node *np, int idx)
 {
-       return of_parse_phandle_with_args(np, "mboxes", "#mbox-cells", 0, NULL);
+       return of_parse_phandle_with_args(np, "mboxes", "#mbox-cells",
+                                         idx, NULL);
 }
 
-static int scmi_mbox_free_channel(int id, void *p, void *data)
+static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev,
+                               int prot_id, bool tx)
 {
-       struct scmi_chan_info *cinfo = p;
-       struct idr *idr = data;
-
-       if (!IS_ERR_OR_NULL(cinfo->chan)) {
-               mbox_free_channel(cinfo->chan);
-               cinfo->chan = NULL;
-       }
-
-       idr_remove(idr, id);
-
-       return 0;
-}
-
-static int scmi_remove(struct platform_device *pdev)
-{
-       int ret = 0;
-       struct scmi_info *info = platform_get_drvdata(pdev);
-       struct idr *idr = &info->tx_idr;
-
-       mutex_lock(&scmi_list_mutex);
-       if (info->users)
-               ret = -EBUSY;
-       else
-               list_del(&info->node);
-       mutex_unlock(&scmi_list_mutex);
-
-       if (ret)
-               return ret;
-
-       /* Safe to free channels since no more users */
-       ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
-       idr_destroy(&info->tx_idr);
-
-       return ret;
-}
-
-static inline int
-scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, int prot_id)
-{
-       int ret;
+       int ret, idx;
        struct resource res;
        resource_size_t size;
        struct device_node *shmem, *np = dev->of_node;
        struct scmi_chan_info *cinfo;
        struct mbox_client *cl;
+       struct idr *idr;
+       const char *desc = tx ? "Tx" : "Rx";
 
-       if (scmi_mailbox_check(np)) {
-               cinfo = idr_find(&info->tx_idr, SCMI_PROTOCOL_BASE);
+       /* Transmit channel is first entry i.e. index 0 */
+       idx = tx ? 0 : 1;
+       idr = tx ? &info->tx_idr : &info->rx_idr;
+
+       if (scmi_mailbox_check(np, idx)) {
+               cinfo = idr_find(idr, SCMI_PROTOCOL_BASE);
+               if (unlikely(!cinfo)) /* Possible only if platform has no Rx */
+                       return -EINVAL;
                goto idr_alloc;
        }
 
@@ -719,36 +751,36 @@ scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev, int prot_id)
        cl = &cinfo->cl;
        cl->dev = dev;
        cl->rx_callback = scmi_rx_callback;
-       cl->tx_prepare = scmi_tx_prepare;
+       cl->tx_prepare = tx ? scmi_tx_prepare : NULL;
        cl->tx_block = false;
-       cl->knows_txdone = true;
+       cl->knows_txdone = tx;
 
-       shmem = of_parse_phandle(np, "shmem", 0);
+       shmem = of_parse_phandle(np, "shmem", idx);
        ret = of_address_to_resource(shmem, 0, &res);
        of_node_put(shmem);
        if (ret) {
-               dev_err(dev, "failed to get SCMI Tx payload mem resource\n");
+               dev_err(dev, "failed to get SCMI %s payload memory\n", desc);
                return ret;
        }
 
        size = resource_size(&res);
        cinfo->payload = devm_ioremap(info->dev, res.start, size);
        if (!cinfo->payload) {
-               dev_err(dev, "failed to ioremap SCMI Tx payload\n");
+               dev_err(dev, "failed to ioremap SCMI %s payload\n", desc);
                return -EADDRNOTAVAIL;
        }
 
-       /* Transmit channel is first entry i.e. index 0 */
-       cinfo->chan = mbox_request_channel(cl, 0);
+       cinfo->chan = mbox_request_channel(cl, idx);
        if (IS_ERR(cinfo->chan)) {
                ret = PTR_ERR(cinfo->chan);
                if (ret != -EPROBE_DEFER)
-                       dev_err(dev, "failed to request SCMI Tx mailbox\n");
+                       dev_err(dev, "failed to request SCMI %s mailbox\n",
+                               desc);
                return ret;
        }
 
 idr_alloc:
-       ret = idr_alloc(&info->tx_idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
+       ret = idr_alloc(idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL);
        if (ret != prot_id) {
                dev_err(dev, "unable to allocate SCMI idr slot err %d\n", ret);
                return ret;
@@ -758,6 +790,17 @@ idr_alloc:
        return 0;
 }
 
+static inline int
+scmi_mbox_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
+{
+       int ret = scmi_mbox_chan_setup(info, dev, prot_id, true);
+
+       if (!ret) /* Rx is optional, hence no error check */
+               scmi_mbox_chan_setup(info, dev, prot_id, false);
+
+       return ret;
+}
+
 static inline void
 scmi_create_protocol_device(struct device_node *np, struct scmi_info *info,
                            int prot_id)
@@ -771,7 +814,7 @@ scmi_create_protocol_device(struct device_node *np, struct scmi_info *info,
                return;
        }
 
-       if (scmi_mbox_chan_setup(info, &sdev->dev, prot_id)) {
+       if (scmi_mbox_txrx_setup(info, &sdev->dev, prot_id)) {
                dev_err(&sdev->dev, "failed to setup transport\n");
                scmi_device_destroy(sdev);
                return;
@@ -791,7 +834,7 @@ static int scmi_probe(struct platform_device *pdev)
        struct device_node *child, *np = dev->of_node;
 
        /* Only mailbox method supported, check for the presence of one */
-       if (scmi_mailbox_check(np)) {
+       if (scmi_mailbox_check(np, 0)) {
                dev_err(dev, "no mailbox found in %pOF\n", np);
                return -EINVAL;
        }
@@ -814,12 +857,13 @@ static int scmi_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, info);
        idr_init(&info->tx_idr);
+       idr_init(&info->rx_idr);
 
        handle = &info->handle;
        handle->dev = info->dev;
        handle->version = &info->version;
 
-       ret = scmi_mbox_chan_setup(info, dev, SCMI_PROTOCOL_BASE);
+       ret = scmi_mbox_txrx_setup(info, dev, SCMI_PROTOCOL_BASE);
        if (ret)
                return ret;
 
@@ -854,6 +898,62 @@ static int scmi_probe(struct platform_device *pdev)
        return 0;
 }
 
+static int scmi_mbox_free_channel(int id, void *p, void *data)
+{
+       struct scmi_chan_info *cinfo = p;
+       struct idr *idr = data;
+
+       if (!IS_ERR_OR_NULL(cinfo->chan)) {
+               mbox_free_channel(cinfo->chan);
+               cinfo->chan = NULL;
+       }
+
+       idr_remove(idr, id);
+
+       return 0;
+}
+
+static int scmi_remove(struct platform_device *pdev)
+{
+       int ret = 0;
+       struct scmi_info *info = platform_get_drvdata(pdev);
+       struct idr *idr = &info->tx_idr;
+
+       mutex_lock(&scmi_list_mutex);
+       if (info->users)
+               ret = -EBUSY;
+       else
+               list_del(&info->node);
+       mutex_unlock(&scmi_list_mutex);
+
+       if (ret)
+               return ret;
+
+       /* Safe to free channels since no more users */
+       ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
+       idr_destroy(&info->tx_idr);
+
+       idr = &info->rx_idr;
+       ret = idr_for_each(idr, scmi_mbox_free_channel, idr);
+       idr_destroy(&info->rx_idr);
+
+       return ret;
+}
+
+static const struct scmi_desc scmi_generic_desc = {
+       .max_rx_timeout_ms = 30,        /* We may increase this if required */
+       .max_msg = 20,          /* Limited by MBOX_TX_QUEUE_LEN */
+       .max_msg_size = 128,
+};
+
+/* Each compatible listed below must have descriptor associated with it */
+static const struct of_device_id scmi_of_match[] = {
+       { .compatible = "arm,scmi", .data = &scmi_generic_desc },
+       { /* Sentinel */ },
+};
+
+MODULE_DEVICE_TABLE(of, scmi_of_match);
+
 static struct platform_driver scmi_driver = {
        .driver = {
                   .name = "arm-scmi",
index 3c8ae7c..4a8012e 100644 (file)
@@ -5,7 +5,10 @@
  * Copyright (C) 2018 ARM Ltd.
  */
 
+#include <linux/bits.h>
 #include <linux/of.h>
+#include <linux/io.h>
+#include <linux/io-64-nonatomic-hi-lo.h>
 #include <linux/platform_device.h>
 #include <linux/pm_opp.h>
 #include <linux/sort.h>
@@ -21,6 +24,7 @@ enum scmi_performance_protocol_cmd {
        PERF_LEVEL_GET = 0x8,
        PERF_NOTIFY_LIMITS = 0x9,
        PERF_NOTIFY_LEVEL = 0xa,
+       PERF_DESCRIBE_FASTCHANNEL = 0xb,
 };
 
 struct scmi_opp {
@@ -44,6 +48,7 @@ struct scmi_msg_resp_perf_domain_attributes {
 #define SUPPORTS_SET_PERF_LVL(x)       ((x) & BIT(30))
 #define SUPPORTS_PERF_LIMIT_NOTIFY(x)  ((x) & BIT(29))
 #define SUPPORTS_PERF_LEVEL_NOTIFY(x)  ((x) & BIT(28))
+#define SUPPORTS_PERF_FASTCHANNELS(x)  ((x) & BIT(27))
        __le32 rate_limit_us;
        __le32 sustained_freq_khz;
        __le32 sustained_perf_level;
@@ -87,17 +92,56 @@ struct scmi_msg_resp_perf_describe_levels {
        } opp[0];
 };
 
+struct scmi_perf_get_fc_info {
+       __le32 domain;
+       __le32 message_id;
+};
+
+struct scmi_msg_resp_perf_desc_fc {
+       __le32 attr;
+#define SUPPORTS_DOORBELL(x)           ((x) & BIT(0))
+#define DOORBELL_REG_WIDTH(x)          FIELD_GET(GENMASK(2, 1), (x))
+       __le32 rate_limit;
+       __le32 chan_addr_low;
+       __le32 chan_addr_high;
+       __le32 chan_size;
+       __le32 db_addr_low;
+       __le32 db_addr_high;
+       __le32 db_set_lmask;
+       __le32 db_set_hmask;
+       __le32 db_preserve_lmask;
+       __le32 db_preserve_hmask;
+};
+
+struct scmi_fc_db_info {
+       int width;
+       u64 set;
+       u64 mask;
+       void __iomem *addr;
+};
+
+struct scmi_fc_info {
+       void __iomem *level_set_addr;
+       void __iomem *limit_set_addr;
+       void __iomem *level_get_addr;
+       void __iomem *limit_get_addr;
+       struct scmi_fc_db_info *level_set_db;
+       struct scmi_fc_db_info *limit_set_db;
+};
+
 struct perf_dom_info {
        bool set_limits;
        bool set_perf;
        bool perf_limit_notify;
        bool perf_level_notify;
+       bool perf_fastchannels;
        u32 opp_count;
        u32 sustained_freq_khz;
        u32 sustained_perf_level;
        u32 mult_factor;
        char name[SCMI_MAX_STR_SIZE];
        struct scmi_opp opp[MAX_OPPS];
+       struct scmi_fc_info *fc_info;
 };
 
 struct scmi_perf_info {
@@ -151,7 +195,7 @@ scmi_perf_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
        if (ret)
                return ret;
 
-       *(__le32 *)t->tx.buf = cpu_to_le32(domain);
+       put_unaligned_le32(domain, t->tx.buf);
        attr = t->rx.buf;
 
        ret = scmi_do_xfer(handle, t);
@@ -162,6 +206,7 @@ scmi_perf_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
                dom_info->set_perf = SUPPORTS_SET_PERF_LVL(flags);
                dom_info->perf_limit_notify = SUPPORTS_PERF_LIMIT_NOTIFY(flags);
                dom_info->perf_level_notify = SUPPORTS_PERF_LEVEL_NOTIFY(flags);
+               dom_info->perf_fastchannels = SUPPORTS_PERF_FASTCHANNELS(flags);
                dom_info->sustained_freq_khz =
                                        le32_to_cpu(attr->sustained_freq_khz);
                dom_info->sustained_perf_level =
@@ -249,8 +294,42 @@ scmi_perf_describe_levels_get(const struct scmi_handle *handle, u32 domain,
        return ret;
 }
 
-static int scmi_perf_limits_set(const struct scmi_handle *handle, u32 domain,
-                               u32 max_perf, u32 min_perf)
+#define SCMI_PERF_FC_RING_DB(w)                                \
+do {                                                   \
+       u##w val = 0;                                   \
+                                                       \
+       if (db->mask)                                   \
+               val = ioread##w(db->addr) & db->mask;   \
+       iowrite##w((u##w)db->set | val, db->addr);      \
+} while (0)
+
+static void scmi_perf_fc_ring_db(struct scmi_fc_db_info *db)
+{
+       if (!db || !db->addr)
+               return;
+
+       if (db->width == 1)
+               SCMI_PERF_FC_RING_DB(8);
+       else if (db->width == 2)
+               SCMI_PERF_FC_RING_DB(16);
+       else if (db->width == 4)
+               SCMI_PERF_FC_RING_DB(32);
+       else /* db->width == 8 */
+#ifdef CONFIG_64BIT
+               SCMI_PERF_FC_RING_DB(64);
+#else
+       {
+               u64 val = 0;
+
+               if (db->mask)
+                       val = ioread64_hi_lo(db->addr) & db->mask;
+               iowrite64_hi_lo(db->set, db->addr);
+       }
+#endif
+}
+
+static int scmi_perf_mb_limits_set(const struct scmi_handle *handle, u32 domain,
+                                  u32 max_perf, u32 min_perf)
 {
        int ret;
        struct scmi_xfer *t;
@@ -272,8 +351,24 @@ static int scmi_perf_limits_set(const struct scmi_handle *handle, u32 domain,
        return ret;
 }
 
-static int scmi_perf_limits_get(const struct scmi_handle *handle, u32 domain,
-                               u32 *max_perf, u32 *min_perf)
+static int scmi_perf_limits_set(const struct scmi_handle *handle, u32 domain,
+                               u32 max_perf, u32 min_perf)
+{
+       struct scmi_perf_info *pi = handle->perf_priv;
+       struct perf_dom_info *dom = pi->dom_info + domain;
+
+       if (dom->fc_info && dom->fc_info->limit_set_addr) {
+               iowrite32(max_perf, dom->fc_info->limit_set_addr);
+               iowrite32(min_perf, dom->fc_info->limit_set_addr + 4);
+               scmi_perf_fc_ring_db(dom->fc_info->limit_set_db);
+               return 0;
+       }
+
+       return scmi_perf_mb_limits_set(handle, domain, max_perf, min_perf);
+}
+
+static int scmi_perf_mb_limits_get(const struct scmi_handle *handle, u32 domain,
+                                  u32 *max_perf, u32 *min_perf)
 {
        int ret;
        struct scmi_xfer *t;
@@ -284,7 +379,7 @@ static int scmi_perf_limits_get(const struct scmi_handle *handle, u32 domain,
        if (ret)
                return ret;
 
-       *(__le32 *)t->tx.buf = cpu_to_le32(domain);
+       put_unaligned_le32(domain, t->tx.buf);
 
        ret = scmi_do_xfer(handle, t);
        if (!ret) {
@@ -298,8 +393,23 @@ static int scmi_perf_limits_get(const struct scmi_handle *handle, u32 domain,
        return ret;
 }
 
-static int scmi_perf_level_set(const struct scmi_handle *handle, u32 domain,
-                              u32 level, bool poll)
+static int scmi_perf_limits_get(const struct scmi_handle *handle, u32 domain,
+                               u32 *max_perf, u32 *min_perf)
+{
+       struct scmi_perf_info *pi = handle->perf_priv;
+       struct perf_dom_info *dom = pi->dom_info + domain;
+
+       if (dom->fc_info && dom->fc_info->limit_get_addr) {
+               *max_perf = ioread32(dom->fc_info->limit_get_addr);
+               *min_perf = ioread32(dom->fc_info->limit_get_addr + 4);
+               return 0;
+       }
+
+       return scmi_perf_mb_limits_get(handle, domain, max_perf, min_perf);
+}
+
+static int scmi_perf_mb_level_set(const struct scmi_handle *handle, u32 domain,
+                                 u32 level, bool poll)
 {
        int ret;
        struct scmi_xfer *t;
@@ -321,8 +431,23 @@ static int scmi_perf_level_set(const struct scmi_handle *handle, u32 domain,
        return ret;
 }
 
-static int scmi_perf_level_get(const struct scmi_handle *handle, u32 domain,
-                              u32 *level, bool poll)
+static int scmi_perf_level_set(const struct scmi_handle *handle, u32 domain,
+                              u32 level, bool poll)
+{
+       struct scmi_perf_info *pi = handle->perf_priv;
+       struct perf_dom_info *dom = pi->dom_info + domain;
+
+       if (dom->fc_info && dom->fc_info->level_set_addr) {
+               iowrite32(level, dom->fc_info->level_set_addr);
+               scmi_perf_fc_ring_db(dom->fc_info->level_set_db);
+               return 0;
+       }
+
+       return scmi_perf_mb_level_set(handle, domain, level, poll);
+}
+
+static int scmi_perf_mb_level_get(const struct scmi_handle *handle, u32 domain,
+                                 u32 *level, bool poll)
 {
        int ret;
        struct scmi_xfer *t;
@@ -333,16 +458,128 @@ static int scmi_perf_level_get(const struct scmi_handle *handle, u32 domain,
                return ret;
 
        t->hdr.poll_completion = poll;
-       *(__le32 *)t->tx.buf = cpu_to_le32(domain);
+       put_unaligned_le32(domain, t->tx.buf);
 
        ret = scmi_do_xfer(handle, t);
        if (!ret)
-               *level = le32_to_cpu(*(__le32 *)t->rx.buf);
+               *level = get_unaligned_le32(t->rx.buf);
 
        scmi_xfer_put(handle, t);
        return ret;
 }
 
+static int scmi_perf_level_get(const struct scmi_handle *handle, u32 domain,
+                              u32 *level, bool poll)
+{
+       struct scmi_perf_info *pi = handle->perf_priv;
+       struct perf_dom_info *dom = pi->dom_info + domain;
+
+       if (dom->fc_info && dom->fc_info->level_get_addr) {
+               *level = ioread32(dom->fc_info->level_get_addr);
+               return 0;
+       }
+
+       return scmi_perf_mb_level_get(handle, domain, level, poll);
+}
+
+static bool scmi_perf_fc_size_is_valid(u32 msg, u32 size)
+{
+       if ((msg == PERF_LEVEL_GET || msg == PERF_LEVEL_SET) && size == 4)
+               return true;
+       if ((msg == PERF_LIMITS_GET || msg == PERF_LIMITS_SET) && size == 8)
+               return true;
+       return false;
+}
+
+static void
+scmi_perf_domain_desc_fc(const struct scmi_handle *handle, u32 domain,
+                        u32 message_id, void __iomem **p_addr,
+                        struct scmi_fc_db_info **p_db)
+{
+       int ret;
+       u32 flags;
+       u64 phys_addr;
+       u8 size;
+       void __iomem *addr;
+       struct scmi_xfer *t;
+       struct scmi_fc_db_info *db;
+       struct scmi_perf_get_fc_info *info;
+       struct scmi_msg_resp_perf_desc_fc *resp;
+
+       if (!p_addr)
+               return;
+
+       ret = scmi_xfer_get_init(handle, PERF_DESCRIBE_FASTCHANNEL,
+                                SCMI_PROTOCOL_PERF,
+                                sizeof(*info), sizeof(*resp), &t);
+       if (ret)
+               return;
+
+       info = t->tx.buf;
+       info->domain = cpu_to_le32(domain);
+       info->message_id = cpu_to_le32(message_id);
+
+       ret = scmi_do_xfer(handle, t);
+       if (ret)
+               goto err_xfer;
+
+       resp = t->rx.buf;
+       flags = le32_to_cpu(resp->attr);
+       size = le32_to_cpu(resp->chan_size);
+       if (!scmi_perf_fc_size_is_valid(message_id, size))
+               goto err_xfer;
+
+       phys_addr = le32_to_cpu(resp->chan_addr_low);
+       phys_addr |= (u64)le32_to_cpu(resp->chan_addr_high) << 32;
+       addr = devm_ioremap(handle->dev, phys_addr, size);
+       if (!addr)
+               goto err_xfer;
+       *p_addr = addr;
+
+       if (p_db && SUPPORTS_DOORBELL(flags)) {
+               db = devm_kzalloc(handle->dev, sizeof(*db), GFP_KERNEL);
+               if (!db)
+                       goto err_xfer;
+
+               size = 1 << DOORBELL_REG_WIDTH(flags);
+               phys_addr = le32_to_cpu(resp->db_addr_low);
+               phys_addr |= (u64)le32_to_cpu(resp->db_addr_high) << 32;
+               addr = devm_ioremap(handle->dev, phys_addr, size);
+               if (!addr)
+                       goto err_xfer;
+
+               db->addr = addr;
+               db->width = size;
+               db->set = le32_to_cpu(resp->db_set_lmask);
+               db->set |= (u64)le32_to_cpu(resp->db_set_hmask) << 32;
+               db->mask = le32_to_cpu(resp->db_preserve_lmask);
+               db->mask |= (u64)le32_to_cpu(resp->db_preserve_hmask) << 32;
+               *p_db = db;
+       }
+err_xfer:
+       scmi_xfer_put(handle, t);
+}
+
+static void scmi_perf_domain_init_fc(const struct scmi_handle *handle,
+                                    u32 domain, struct scmi_fc_info **p_fc)
+{
+       struct scmi_fc_info *fc;
+
+       fc = devm_kzalloc(handle->dev, sizeof(*fc), GFP_KERNEL);
+       if (!fc)
+               return;
+
+       scmi_perf_domain_desc_fc(handle, domain, PERF_LEVEL_SET,
+                                &fc->level_set_addr, &fc->level_set_db);
+       scmi_perf_domain_desc_fc(handle, domain, PERF_LEVEL_GET,
+                                &fc->level_get_addr, NULL);
+       scmi_perf_domain_desc_fc(handle, domain, PERF_LIMITS_SET,
+                                &fc->limit_set_addr, &fc->limit_set_db);
+       scmi_perf_domain_desc_fc(handle, domain, PERF_LIMITS_GET,
+                                &fc->limit_get_addr, NULL);
+       *p_fc = fc;
+}
+
 /* Device specific ops */
 static int scmi_dev_domain_id(struct device *dev)
 {
@@ -494,6 +731,9 @@ static int scmi_perf_protocol_init(struct scmi_handle *handle)
 
                scmi_perf_domain_attributes_get(handle, domain, dom);
                scmi_perf_describe_levels_get(handle, domain, dom);
+
+               if (dom->perf_fastchannels)
+                       scmi_perf_domain_init_fc(handle, domain, &dom->fc_info);
        }
 
        handle->perf_ops = &perf_ops;
index 62f3401..5abef70 100644 (file)
@@ -96,7 +96,7 @@ scmi_power_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
        if (ret)
                return ret;
 
-       *(__le32 *)t->tx.buf = cpu_to_le32(domain);
+       put_unaligned_le32(domain, t->tx.buf);
        attr = t->rx.buf;
 
        ret = scmi_do_xfer(handle, t);
@@ -147,11 +147,11 @@ scmi_power_state_get(const struct scmi_handle *handle, u32 domain, u32 *state)
        if (ret)
                return ret;
 
-       *(__le32 *)t->tx.buf = cpu_to_le32(domain);
+       put_unaligned_le32(domain, t->tx.buf);
 
        ret = scmi_do_xfer(handle, t);
        if (!ret)
-               *state = le32_to_cpu(*(__le32 *)t->rx.buf);
+               *state = get_unaligned_le32(t->rx.buf);
 
        scmi_xfer_put(handle, t);
        return ret;
diff --git a/drivers/firmware/arm_scmi/reset.c b/drivers/firmware/arm_scmi/reset.c
new file mode 100644 (file)
index 0000000..64cc819
--- /dev/null
@@ -0,0 +1,231 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * System Control and Management Interface (SCMI) Reset Protocol
+ *
+ * Copyright (C) 2019 ARM Ltd.
+ */
+
+#include "common.h"
+
+enum scmi_reset_protocol_cmd {
+       RESET_DOMAIN_ATTRIBUTES = 0x3,
+       RESET = 0x4,
+       RESET_NOTIFY = 0x5,
+};
+
+enum scmi_reset_protocol_notify {
+       RESET_ISSUED = 0x0,
+};
+
+#define NUM_RESET_DOMAIN_MASK  0xffff
+#define RESET_NOTIFY_ENABLE    BIT(0)
+
+struct scmi_msg_resp_reset_domain_attributes {
+       __le32 attributes;
+#define SUPPORTS_ASYNC_RESET(x)                ((x) & BIT(31))
+#define SUPPORTS_NOTIFY_RESET(x)       ((x) & BIT(30))
+       __le32 latency;
+           u8 name[SCMI_MAX_STR_SIZE];
+};
+
+struct scmi_msg_reset_domain_reset {
+       __le32 domain_id;
+       __le32 flags;
+#define AUTONOMOUS_RESET       BIT(0)
+#define EXPLICIT_RESET_ASSERT  BIT(1)
+#define ASYNCHRONOUS_RESET     BIT(2)
+       __le32 reset_state;
+#define ARCH_RESET_TYPE                BIT(31)
+#define COLD_RESET_STATE       BIT(0)
+#define ARCH_COLD_RESET                (ARCH_RESET_TYPE | COLD_RESET_STATE)
+};
+
+struct reset_dom_info {
+       bool async_reset;
+       bool reset_notify;
+       u32 latency_us;
+       char name[SCMI_MAX_STR_SIZE];
+};
+
+struct scmi_reset_info {
+       int num_domains;
+       struct reset_dom_info *dom_info;
+};
+
+static int scmi_reset_attributes_get(const struct scmi_handle *handle,
+                                    struct scmi_reset_info *pi)
+{
+       int ret;
+       struct scmi_xfer *t;
+       u32 attr;
+
+       ret = scmi_xfer_get_init(handle, PROTOCOL_ATTRIBUTES,
+                                SCMI_PROTOCOL_RESET, 0, sizeof(attr), &t);
+       if (ret)
+               return ret;
+
+       ret = scmi_do_xfer(handle, t);
+       if (!ret) {
+               attr = get_unaligned_le32(t->rx.buf);
+               pi->num_domains = attr & NUM_RESET_DOMAIN_MASK;
+       }
+
+       scmi_xfer_put(handle, t);
+       return ret;
+}
+
+static int
+scmi_reset_domain_attributes_get(const struct scmi_handle *handle, u32 domain,
+                                struct reset_dom_info *dom_info)
+{
+       int ret;
+       struct scmi_xfer *t;
+       struct scmi_msg_resp_reset_domain_attributes *attr;
+
+       ret = scmi_xfer_get_init(handle, RESET_DOMAIN_ATTRIBUTES,
+                                SCMI_PROTOCOL_RESET, sizeof(domain),
+                                sizeof(*attr), &t);
+       if (ret)
+               return ret;
+
+       put_unaligned_le32(domain, t->tx.buf);
+       attr = t->rx.buf;
+
+       ret = scmi_do_xfer(handle, t);
+       if (!ret) {
+               u32 attributes = le32_to_cpu(attr->attributes);
+
+               dom_info->async_reset = SUPPORTS_ASYNC_RESET(attributes);
+               dom_info->reset_notify = SUPPORTS_NOTIFY_RESET(attributes);
+               dom_info->latency_us = le32_to_cpu(attr->latency);
+               if (dom_info->latency_us == U32_MAX)
+                       dom_info->latency_us = 0;
+               strlcpy(dom_info->name, attr->name, SCMI_MAX_STR_SIZE);
+       }
+
+       scmi_xfer_put(handle, t);
+       return ret;
+}
+
+static int scmi_reset_num_domains_get(const struct scmi_handle *handle)
+{
+       struct scmi_reset_info *pi = handle->reset_priv;
+
+       return pi->num_domains;
+}
+
+static char *scmi_reset_name_get(const struct scmi_handle *handle, u32 domain)
+{
+       struct scmi_reset_info *pi = handle->reset_priv;
+       struct reset_dom_info *dom = pi->dom_info + domain;
+
+       return dom->name;
+}
+
+static int scmi_reset_latency_get(const struct scmi_handle *handle, u32 domain)
+{
+       struct scmi_reset_info *pi = handle->reset_priv;
+       struct reset_dom_info *dom = pi->dom_info + domain;
+
+       return dom->latency_us;
+}
+
+static int scmi_domain_reset(const struct scmi_handle *handle, u32 domain,
+                            u32 flags, u32 state)
+{
+       int ret;
+       struct scmi_xfer *t;
+       struct scmi_msg_reset_domain_reset *dom;
+       struct scmi_reset_info *pi = handle->reset_priv;
+       struct reset_dom_info *rdom = pi->dom_info + domain;
+
+       if (rdom->async_reset)
+               flags |= ASYNCHRONOUS_RESET;
+
+       ret = scmi_xfer_get_init(handle, RESET, SCMI_PROTOCOL_RESET,
+                                sizeof(*dom), 0, &t);
+       if (ret)
+               return ret;
+
+       dom = t->tx.buf;
+       dom->domain_id = cpu_to_le32(domain);
+       dom->flags = cpu_to_le32(flags);
+       dom->domain_id = cpu_to_le32(state);
+
+       if (rdom->async_reset)
+               ret = scmi_do_xfer_with_response(handle, t);
+       else
+               ret = scmi_do_xfer(handle, t);
+
+       scmi_xfer_put(handle, t);
+       return ret;
+}
+
+static int scmi_reset_domain_reset(const struct scmi_handle *handle, u32 domain)
+{
+       return scmi_domain_reset(handle, domain, AUTONOMOUS_RESET,
+                                ARCH_COLD_RESET);
+}
+
+static int
+scmi_reset_domain_assert(const struct scmi_handle *handle, u32 domain)
+{
+       return scmi_domain_reset(handle, domain, EXPLICIT_RESET_ASSERT,
+                                ARCH_COLD_RESET);
+}
+
+static int
+scmi_reset_domain_deassert(const struct scmi_handle *handle, u32 domain)
+{
+       return scmi_domain_reset(handle, domain, 0, ARCH_COLD_RESET);
+}
+
+static struct scmi_reset_ops reset_ops = {
+       .num_domains_get = scmi_reset_num_domains_get,
+       .name_get = scmi_reset_name_get,
+       .latency_get = scmi_reset_latency_get,
+       .reset = scmi_reset_domain_reset,
+       .assert = scmi_reset_domain_assert,
+       .deassert = scmi_reset_domain_deassert,
+};
+
+static int scmi_reset_protocol_init(struct scmi_handle *handle)
+{
+       int domain;
+       u32 version;
+       struct scmi_reset_info *pinfo;
+
+       scmi_version_get(handle, SCMI_PROTOCOL_RESET, &version);
+
+       dev_dbg(handle->dev, "Reset Version %d.%d\n",
+               PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));
+
+       pinfo = devm_kzalloc(handle->dev, sizeof(*pinfo), GFP_KERNEL);
+       if (!pinfo)
+               return -ENOMEM;
+
+       scmi_reset_attributes_get(handle, pinfo);
+
+       pinfo->dom_info = devm_kcalloc(handle->dev, pinfo->num_domains,
+                                      sizeof(*pinfo->dom_info), GFP_KERNEL);
+       if (!pinfo->dom_info)
+               return -ENOMEM;
+
+       for (domain = 0; domain < pinfo->num_domains; domain++) {
+               struct reset_dom_info *dom = pinfo->dom_info + domain;
+
+               scmi_reset_domain_attributes_get(handle, domain, dom);
+       }
+
+       handle->reset_ops = &reset_ops;
+       handle->reset_priv = pinfo;
+
+       return 0;
+}
+
+static int __init scmi_reset_init(void)
+{
+       return scmi_protocol_register(SCMI_PROTOCOL_RESET,
+                                     &scmi_reset_protocol_init);
+}
+subsys_initcall(scmi_reset_init);
index 0e94ab5..a400ea8 100644 (file)
@@ -9,8 +9,8 @@
 
 enum scmi_sensor_protocol_cmd {
        SENSOR_DESCRIPTION_GET = 0x3,
-       SENSOR_CONFIG_SET = 0x4,
-       SENSOR_TRIP_POINT_SET = 0x5,
+       SENSOR_TRIP_POINT_NOTIFY = 0x4,
+       SENSOR_TRIP_POINT_CONFIG = 0x5,
        SENSOR_READING_GET = 0x6,
 };
 
@@ -42,9 +42,10 @@ struct scmi_msg_resp_sensor_description {
        } desc[0];
 };
 
-struct scmi_msg_set_sensor_config {
+struct scmi_msg_sensor_trip_point_notify {
        __le32 id;
        __le32 event_control;
+#define SENSOR_TP_NOTIFY_ALL   BIT(0)
 };
 
 struct scmi_msg_set_sensor_trip_point {
@@ -119,7 +120,7 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle,
 
        do {
                /* Set the number of sensors to be skipped/already read */
-               *(__le32 *)t->tx.buf = cpu_to_le32(desc_index);
+               put_unaligned_le32(desc_index, t->tx.buf);
 
                ret = scmi_do_xfer(handle, t);
                if (ret)
@@ -135,9 +136,10 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle,
                }
 
                for (cnt = 0; cnt < num_returned; cnt++) {
-                       u32 attrh;
+                       u32 attrh, attrl;
                        struct scmi_sensor_info *s;
 
+                       attrl = le32_to_cpu(buf->desc[cnt].attributes_low);
                        attrh = le32_to_cpu(buf->desc[cnt].attributes_high);
                        s = &si->sensors[desc_index + cnt];
                        s->id = le32_to_cpu(buf->desc[cnt].id);
@@ -146,6 +148,8 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle,
                        /* Sign extend to a full s8 */
                        if (s->scale & SENSOR_SCALE_SIGN)
                                s->scale |= SENSOR_SCALE_EXTEND;
+                       s->async = SUPPORTS_ASYNC_READ(attrl);
+                       s->num_trip_points = NUM_TRIP_POINTS(attrl);
                        strlcpy(s->name, buf->desc[cnt].name, SCMI_MAX_STR_SIZE);
                }
 
@@ -160,15 +164,15 @@ static int scmi_sensor_description_get(const struct scmi_handle *handle,
        return ret;
 }
 
-static int
-scmi_sensor_configuration_set(const struct scmi_handle *handle, u32 sensor_id)
+static int scmi_sensor_trip_point_notify(const struct scmi_handle *handle,
+                                        u32 sensor_id, bool enable)
 {
        int ret;
-       u32 evt_cntl = BIT(0);
+       u32 evt_cntl = enable ? SENSOR_TP_NOTIFY_ALL : 0;
        struct scmi_xfer *t;
-       struct scmi_msg_set_sensor_config *cfg;
+       struct scmi_msg_sensor_trip_point_notify *cfg;
 
-       ret = scmi_xfer_get_init(handle, SENSOR_CONFIG_SET,
+       ret = scmi_xfer_get_init(handle, SENSOR_TRIP_POINT_NOTIFY,
                                 SCMI_PROTOCOL_SENSOR, sizeof(*cfg), 0, &t);
        if (ret)
                return ret;
@@ -183,15 +187,16 @@ scmi_sensor_configuration_set(const struct scmi_handle *handle, u32 sensor_id)
        return ret;
 }
 
-static int scmi_sensor_trip_point_set(const struct scmi_handle *handle,
-                                     u32 sensor_id, u8 trip_id, u64 trip_value)
+static int
+scmi_sensor_trip_point_config(const struct scmi_handle *handle, u32 sensor_id,
+                             u8 trip_id, u64 trip_value)
 {
        int ret;
        u32 evt_cntl = SENSOR_TP_BOTH;
        struct scmi_xfer *t;
        struct scmi_msg_set_sensor_trip_point *trip;
 
-       ret = scmi_xfer_get_init(handle, SENSOR_TRIP_POINT_SET,
+       ret = scmi_xfer_get_init(handle, SENSOR_TRIP_POINT_CONFIG,
                                 SCMI_PROTOCOL_SENSOR, sizeof(*trip), 0, &t);
        if (ret)
                return ret;
@@ -209,11 +214,13 @@ static int scmi_sensor_trip_point_set(const struct scmi_handle *handle,
 }
 
 static int scmi_sensor_reading_get(const struct scmi_handle *handle,
-                                  u32 sensor_id, bool async, u64 *value)
+                                  u32 sensor_id, u64 *value)
 {
        int ret;
        struct scmi_xfer *t;
        struct scmi_msg_sensor_reading_get *sensor;
+       struct sensors_info *si = handle->sensor_priv;
+       struct scmi_sensor_info *s = si->sensors + sensor_id;
 
        ret = scmi_xfer_get_init(handle, SENSOR_READING_GET,
                                 SCMI_PROTOCOL_SENSOR, sizeof(*sensor),
@@ -223,14 +230,18 @@ static int scmi_sensor_reading_get(const struct scmi_handle *handle,
 
        sensor = t->tx.buf;
        sensor->id = cpu_to_le32(sensor_id);
-       sensor->flags = cpu_to_le32(async ? SENSOR_READ_ASYNC : 0);
 
-       ret = scmi_do_xfer(handle, t);
-       if (!ret) {
-               __le32 *pval = t->rx.buf;
-
-               *value = le32_to_cpu(*pval);
-               *value |= (u64)le32_to_cpu(*(pval + 1)) << 32;
+       if (s->async) {
+               sensor->flags = cpu_to_le32(SENSOR_READ_ASYNC);
+               ret = scmi_do_xfer_with_response(handle, t);
+               if (!ret)
+                       *value = get_unaligned_le64((void *)
+                                                   ((__le32 *)t->rx.buf + 1));
+       } else {
+               sensor->flags = cpu_to_le32(0);
+               ret = scmi_do_xfer(handle, t);
+               if (!ret)
+                       *value = get_unaligned_le64(t->rx.buf);
        }
 
        scmi_xfer_put(handle, t);
@@ -255,8 +266,8 @@ static int scmi_sensor_count_get(const struct scmi_handle *handle)
 static struct scmi_sensor_ops sensor_ops = {
        .count_get = scmi_sensor_count_get,
        .info_get = scmi_sensor_info_get,
-       .configuration_set = scmi_sensor_configuration_set,
-       .trip_point_set = scmi_sensor_trip_point_set,
+       .trip_point_notify = scmi_sensor_trip_point_notify,
+       .trip_point_config = scmi_sensor_trip_point_config,
        .reading_get = scmi_sensor_reading_get,
 };
 
index 42b566f..0dbee32 100644 (file)
@@ -1,4 +1,15 @@
 # SPDX-License-Identifier: GPL-2.0-only
+config IMX_DSP
+       bool "IMX DSP Protocol driver"
+       depends on IMX_MBOX
+       help
+         This enables DSP IPC protocol between host AP (Linux)
+         and the firmware running on DSP.
+         DSP exists on some i.MX8 processors (e.g i.MX8QM, i.MX8QXP).
+
+         It acts like a doorbell. Client might use shared memory to
+         exchange information with DSP side.
+
 config IMX_SCU
        bool "IMX SCU Protocol driver"
        depends on IMX_MBOX
index 802c4ad..08bc9dd 100644 (file)
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_IMX_DSP)          += imx-dsp.o
 obj-$(CONFIG_IMX_SCU)          += imx-scu.o misc.o imx-scu-irq.o
 obj-$(CONFIG_IMX_SCU_PD)       += scu-pd.o
diff --git a/drivers/firmware/imx/imx-dsp.c b/drivers/firmware/imx/imx-dsp.c
new file mode 100644 (file)
index 0000000..a43d2db
--- /dev/null
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 NXP
+ *  Author: Daniel Baluta <daniel.baluta@nxp.com>
+ *
+ * Implementation of the DSP IPC interface (host side)
+ */
+
+#include <linux/firmware/imx/dsp.h>
+#include <linux/kernel.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/*
+ * imx_dsp_ring_doorbell - triggers an interrupt on the other side (DSP)
+ *
+ * @dsp: DSP IPC handle
+ * @chan_idx: index of the channel where to trigger the interrupt
+ *
+ * Returns non-negative value for success, negative value for error
+ */
+int imx_dsp_ring_doorbell(struct imx_dsp_ipc *ipc, unsigned int idx)
+{
+       int ret;
+       struct imx_dsp_chan *dsp_chan;
+
+       if (idx >= DSP_MU_CHAN_NUM)
+               return -EINVAL;
+
+       dsp_chan = &ipc->chans[idx];
+       ret = mbox_send_message(dsp_chan->ch, NULL);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+EXPORT_SYMBOL(imx_dsp_ring_doorbell);
+
+/*
+ * imx_dsp_handle_rx - rx callback used by imx mailbox
+ *
+ * @c: mbox client
+ * @msg: message received
+ *
+ * Users of DSP IPC will need to privde handle_reply and handle_request
+ * callbacks.
+ */
+static void imx_dsp_handle_rx(struct mbox_client *c, void *msg)
+{
+       struct imx_dsp_chan *chan = container_of(c, struct imx_dsp_chan, cl);
+
+       if (chan->idx == 0) {
+               chan->ipc->ops->handle_reply(chan->ipc);
+       } else {
+               chan->ipc->ops->handle_request(chan->ipc);
+               imx_dsp_ring_doorbell(chan->ipc, 1);
+       }
+}
+
+static int imx_dsp_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct imx_dsp_ipc *dsp_ipc;
+       struct imx_dsp_chan *dsp_chan;
+       struct mbox_client *cl;
+       char *chan_name;
+       int ret;
+       int i, j;
+
+       device_set_of_node_from_dev(&pdev->dev, pdev->dev.parent);
+
+       dsp_ipc = devm_kzalloc(dev, sizeof(*dsp_ipc), GFP_KERNEL);
+       if (!dsp_ipc)
+               return -ENOMEM;
+
+       for (i = 0; i < DSP_MU_CHAN_NUM; i++) {
+               if (i < 2)
+                       chan_name = kasprintf(GFP_KERNEL, "txdb%d", i);
+               else
+                       chan_name = kasprintf(GFP_KERNEL, "rxdb%d", i - 2);
+
+               if (!chan_name)
+                       return -ENOMEM;
+
+               dsp_chan = &dsp_ipc->chans[i];
+               cl = &dsp_chan->cl;
+               cl->dev = dev;
+               cl->tx_block = false;
+               cl->knows_txdone = true;
+               cl->rx_callback = imx_dsp_handle_rx;
+
+               dsp_chan->ipc = dsp_ipc;
+               dsp_chan->idx = i % 2;
+               dsp_chan->ch = mbox_request_channel_byname(cl, chan_name);
+               if (IS_ERR(dsp_chan->ch)) {
+                       ret = PTR_ERR(dsp_chan->ch);
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(dev, "Failed to request mbox chan %s ret %d\n",
+                                       chan_name, ret);
+                       goto out;
+               }
+
+               dev_dbg(dev, "request mbox chan %s\n", chan_name);
+               /* chan_name is not used anymore by framework */
+               kfree(chan_name);
+       }
+
+       dsp_ipc->dev = dev;
+
+       dev_set_drvdata(dev, dsp_ipc);
+
+       dev_info(dev, "NXP i.MX DSP IPC initialized\n");
+
+       return devm_of_platform_populate(dev);
+out:
+       kfree(chan_name);
+       for (j = 0; j < i; j++) {
+               dsp_chan = &dsp_ipc->chans[j];
+               mbox_free_channel(dsp_chan->ch);
+       }
+
+       return ret;
+}
+
+static int imx_dsp_remove(struct platform_device *pdev)
+{
+       struct imx_dsp_chan *dsp_chan;
+       struct imx_dsp_ipc *dsp_ipc;
+       int i;
+
+       dsp_ipc = dev_get_drvdata(&pdev->dev);
+
+       for (i = 0; i < DSP_MU_CHAN_NUM; i++) {
+               dsp_chan = &dsp_ipc->chans[i];
+               mbox_free_channel(dsp_chan->ch);
+       }
+
+       return 0;
+}
+
+static struct platform_driver imx_dsp_driver = {
+       .driver = {
+               .name = "imx-dsp",
+       },
+       .probe = imx_dsp_probe,
+       .remove = imx_dsp_remove,
+};
+builtin_platform_driver(imx_dsp_driver);
+
+MODULE_AUTHOR("Daniel Baluta <daniel.baluta@nxp.com>");
+MODULE_DESCRIPTION("IMX DSP IPC protocol driver");
+MODULE_LICENSE("GPL v2");
index 480cec6..b556612 100644 (file)
@@ -92,7 +92,8 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
        { "gpt", IMX_SC_R_GPT_0, 5, true, 0 },
        { "kpp", IMX_SC_R_KPP, 1, false, 0 },
        { "fspi", IMX_SC_R_FSPI_0, 2, true, 0 },
-       { "mu", IMX_SC_R_MU_0A, 14, true, 0 },
+       { "mu_a", IMX_SC_R_MU_0A, 14, true, 0 },
+       { "mu_b", IMX_SC_R_MU_13B, 1, true, 13 },
 
        /* CONN SS */
        { "usb", IMX_SC_R_USB_0, 2, true, 0 },
@@ -130,6 +131,7 @@ static const struct imx_sc_pd_range imx8qxp_scu_pd_ranges[] = {
        { "lcd0-pwm", IMX_SC_R_LCD_0_PWM_0, 1, true, 0 },
        { "lpuart", IMX_SC_R_UART_0, 4, true, 0 },
        { "lpspi", IMX_SC_R_SPI_0, 4, true, 0 },
+       { "irqstr_dsp", IMX_SC_R_IRQSTR_DSP, 1, false, 0 },
 
        /* VPU SS */
        { "vpu", IMX_SC_R_VPU, 1, false, 0 },
index f82ccd3..84f4ff3 100644 (file)
@@ -103,7 +103,7 @@ static inline bool psci_power_state_loses_context(u32 state)
        return state & mask;
 }
 
-static inline bool psci_power_state_is_valid(u32 state)
+bool psci_power_state_is_valid(u32 state)
 {
        const u32 valid_mask = psci_has_ext_power_state() ?
                               PSCI_1_0_EXT_POWER_STATE_MASK :
@@ -277,175 +277,24 @@ static int __init psci_features(u32 psci_func_id)
 }
 
 #ifdef CONFIG_CPU_IDLE
-static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
-
-static int psci_dt_parse_state_node(struct device_node *np, u32 *state)
-{
-       int err = of_property_read_u32(np, "arm,psci-suspend-param", state);
-
-       if (err) {
-               pr_warn("%pOF missing arm,psci-suspend-param property\n", np);
-               return err;
-       }
-
-       if (!psci_power_state_is_valid(*state)) {
-               pr_warn("Invalid PSCI power state %#x\n", *state);
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static int psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
-{
-       int i, ret = 0, count = 0;
-       u32 *psci_states;
-       struct device_node *state_node;
-
-       /* Count idle states */
-       while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
-                                             count))) {
-               count++;
-               of_node_put(state_node);
-       }
-
-       if (!count)
-               return -ENODEV;
-
-       psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
-       if (!psci_states)
-               return -ENOMEM;
-
-       for (i = 0; i < count; i++) {
-               state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
-               ret = psci_dt_parse_state_node(state_node, &psci_states[i]);
-               of_node_put(state_node);
-
-               if (ret)
-                       goto free_mem;
-
-               pr_debug("psci-power-state %#x index %d\n", psci_states[i], i);
-       }
-
-       /* Idle states parsed correctly, initialize per-cpu pointer */
-       per_cpu(psci_power_state, cpu) = psci_states;
-       return 0;
-
-free_mem:
-       kfree(psci_states);
-       return ret;
-}
-
-#ifdef CONFIG_ACPI
-#include <acpi/processor.h>
-
-static int __maybe_unused psci_acpi_cpu_init_idle(unsigned int cpu)
-{
-       int i, count;
-       u32 *psci_states;
-       struct acpi_lpi_state *lpi;
-       struct acpi_processor *pr = per_cpu(processors, cpu);
-
-       if (unlikely(!pr || !pr->flags.has_lpi))
-               return -EINVAL;
-
-       count = pr->power.count - 1;
-       if (count <= 0)
-               return -ENODEV;
-
-       psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
-       if (!psci_states)
-               return -ENOMEM;
-
-       for (i = 0; i < count; i++) {
-               u32 state;
-
-               lpi = &pr->power.lpi_states[i + 1];
-               /*
-                * Only bits[31:0] represent a PSCI power_state while
-                * bits[63:32] must be 0x0 as per ARM ACPI FFH Specification
-                */
-               state = lpi->address;
-               if (!psci_power_state_is_valid(state)) {
-                       pr_warn("Invalid PSCI power state %#x\n", state);
-                       kfree(psci_states);
-                       return -EINVAL;
-               }
-               psci_states[i] = state;
-       }
-       /* Idle states parsed correctly, initialize per-cpu pointer */
-       per_cpu(psci_power_state, cpu) = psci_states;
-       return 0;
-}
-#else
-static int __maybe_unused psci_acpi_cpu_init_idle(unsigned int cpu)
-{
-       return -EINVAL;
-}
-#endif
-
-int psci_cpu_init_idle(unsigned int cpu)
-{
-       struct device_node *cpu_node;
-       int ret;
-
-       /*
-        * If the PSCI cpu_suspend function hook has not been initialized
-        * idle states must not be enabled, so bail out
-        */
-       if (!psci_ops.cpu_suspend)
-               return -EOPNOTSUPP;
-
-       if (!acpi_disabled)
-               return psci_acpi_cpu_init_idle(cpu);
-
-       cpu_node = of_get_cpu_node(cpu, NULL);
-       if (!cpu_node)
-               return -ENODEV;
-
-       ret = psci_dt_cpu_init_idle(cpu_node, cpu);
-
-       of_node_put(cpu_node);
-
-       return ret;
-}
-
-static int psci_suspend_finisher(unsigned long index)
+static int psci_suspend_finisher(unsigned long state)
 {
-       u32 *state = __this_cpu_read(psci_power_state);
+       u32 power_state = state;
 
-       return psci_ops.cpu_suspend(state[index - 1],
-                                   __pa_symbol(cpu_resume));
+       return psci_ops.cpu_suspend(power_state, __pa_symbol(cpu_resume));
 }
 
-int psci_cpu_suspend_enter(unsigned long index)
+int psci_cpu_suspend_enter(u32 state)
 {
        int ret;
-       u32 *state = __this_cpu_read(psci_power_state);
-       /*
-        * idle state index 0 corresponds to wfi, should never be called
-        * from the cpu_suspend operations
-        */
-       if (WARN_ON_ONCE(!index))
-               return -EINVAL;
 
-       if (!psci_power_state_loses_context(state[index - 1]))
-               ret = psci_ops.cpu_suspend(state[index - 1], 0);
+       if (!psci_power_state_loses_context(state))
+               ret = psci_ops.cpu_suspend(state, 0);
        else
-               ret = cpu_suspend(index, psci_suspend_finisher);
+               ret = cpu_suspend(state, psci_suspend_finisher);
 
        return ret;
 }
-
-/* ARM specific CPU idle operations */
-#ifdef CONFIG_ARM
-static const struct cpuidle_ops psci_cpuidle_ops __initconst = {
-       .suspend = psci_cpu_suspend_enter,
-       .init = psci_dt_cpu_init_idle,
-};
-
-CPUIDLE_METHOD_OF_DECLARE(psci, "psci", &psci_cpuidle_ops);
-#endif
 #endif
 
 static int psci_system_suspend(unsigned long unused)
index f365944..6a44539 100644 (file)
@@ -228,8 +228,11 @@ out_free_cpus:
 
 static void dummy_callback(struct timer_list *unused) {}
 
-static int suspend_cpu(int index, bool broadcast)
+static int suspend_cpu(struct cpuidle_device *dev,
+                      struct cpuidle_driver *drv, int index)
 {
+       struct cpuidle_state *state = &drv->states[index];
+       bool broadcast = state->flags & CPUIDLE_FLAG_TIMER_STOP;
        int ret;
 
        arch_cpu_idle_enter();
@@ -254,11 +257,7 @@ static int suspend_cpu(int index, bool broadcast)
                }
        }
 
-       /*
-        * Replicate the common ARM cpuidle enter function
-        * (arm_enter_idle_state).
-        */
-       ret = CPU_PM_CPU_IDLE_ENTER(arm_cpuidle_suspend, index);
+       ret = state->enter(dev, drv, index);
 
        if (broadcast)
                tick_broadcast_exit();
@@ -301,9 +300,8 @@ static int suspend_test_thread(void *arg)
                 * 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;
+                       struct cpuidle_state *state = &drv->states[index];
 
                        /*
                         * Set the timer to wake this CPU up in some time (which
@@ -318,7 +316,7 @@ static int suspend_test_thread(void *arg)
                        /* IRQs must be disabled during suspend operations. */
                        local_irq_disable();
 
-                       ret = suspend_cpu(index, broadcast);
+                       ret = suspend_cpu(dev, drv, index);
 
                        /*
                         * We have woken up. Re-enable IRQs to handle any
index 2ddc118..4802ab1 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/init.h>
 #include <linux/cpumask.h>
 #include <linux/export.h>
+#include <linux/dma-direct.h>
 #include <linux/dma-mapping.h>
 #include <linux/module.h>
 #include <linux/types.h>
@@ -425,21 +426,23 @@ EXPORT_SYMBOL(qcom_scm_set_remote_state);
  * @mem_sz:   size of the region.
  * @srcvm:    vmid for current set of owners, each set bit in
  *            flag indicate a unique owner
- * @newvm:    array having new owners and corrsponding permission
+ * @newvm:    array having new owners and corresponding permission
  *            flags
  * @dest_cnt: number of owners in next set.
  *
- * Return negative errno on failure, 0 on success, with @srcvm updated.
+ * Return negative errno on failure or 0 on success with @srcvm updated.
  */
 int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
                        unsigned int *srcvm,
-                       struct qcom_scm_vmperm *newvm, int dest_cnt)
+                       const struct qcom_scm_vmperm *newvm,
+                       unsigned int dest_cnt)
 {
        struct qcom_scm_current_perm_info *destvm;
        struct qcom_scm_mem_map_info *mem_to_map;
        phys_addr_t mem_to_map_phys;
        phys_addr_t dest_phys;
        phys_addr_t ptr_phys;
+       dma_addr_t ptr_dma;
        size_t mem_to_map_sz;
        size_t dest_sz;
        size_t src_sz;
@@ -447,52 +450,50 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
        int next_vm;
        __le32 *src;
        void *ptr;
-       int ret;
-       int len;
-       int i;
+       int ret, i, b;
+       unsigned long srcvm_bits = *srcvm;
 
-       src_sz = hweight_long(*srcvm) * sizeof(*src);
+       src_sz = hweight_long(srcvm_bits) * sizeof(*src);
        mem_to_map_sz = sizeof(*mem_to_map);
        dest_sz = dest_cnt * sizeof(*destvm);
        ptr_sz = ALIGN(src_sz, SZ_64) + ALIGN(mem_to_map_sz, SZ_64) +
                        ALIGN(dest_sz, SZ_64);
 
-       ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_phys, GFP_KERNEL);
+       ptr = dma_alloc_coherent(__scm->dev, ptr_sz, &ptr_dma, GFP_KERNEL);
        if (!ptr)
                return -ENOMEM;
+       ptr_phys = dma_to_phys(__scm->dev, ptr_dma);
 
        /* Fill source vmid detail */
        src = ptr;
-       len = hweight_long(*srcvm);
-       for (i = 0; i < len; i++) {
-               src[i] = cpu_to_le32(ffs(*srcvm) - 1);
-               *srcvm ^= 1 << (ffs(*srcvm) - 1);
-       }
+       i = 0;
+       for_each_set_bit(b, &srcvm_bits, BITS_PER_LONG)
+               src[i++] = cpu_to_le32(b);
 
        /* Fill details of mem buff to map */
        mem_to_map = ptr + ALIGN(src_sz, SZ_64);
        mem_to_map_phys = ptr_phys + ALIGN(src_sz, SZ_64);
-       mem_to_map[0].mem_addr = cpu_to_le64(mem_addr);
-       mem_to_map[0].mem_size = cpu_to_le64(mem_sz);
+       mem_to_map->mem_addr = cpu_to_le64(mem_addr);
+       mem_to_map->mem_size = cpu_to_le64(mem_sz);
 
        next_vm = 0;
        /* Fill details of next vmid detail */
        destvm = ptr + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(src_sz, SZ_64);
        dest_phys = ptr_phys + ALIGN(mem_to_map_sz, SZ_64) + ALIGN(src_sz, SZ_64);
-       for (i = 0; i < dest_cnt; i++) {
-               destvm[i].vmid = cpu_to_le32(newvm[i].vmid);
-               destvm[i].perm = cpu_to_le32(newvm[i].perm);
-               destvm[i].ctx = 0;
-               destvm[i].ctx_size = 0;
-               next_vm |= BIT(newvm[i].vmid);
+       for (i = 0; i < dest_cnt; i++, destvm++, newvm++) {
+               destvm->vmid = cpu_to_le32(newvm->vmid);
+               destvm->perm = cpu_to_le32(newvm->perm);
+               destvm->ctx = 0;
+               destvm->ctx_size = 0;
+               next_vm |= BIT(newvm->vmid);
        }
 
        ret = __qcom_scm_assign_mem(__scm->dev, mem_to_map_phys, mem_to_map_sz,
                                    ptr_phys, src_sz, dest_phys, dest_sz);
-       dma_free_coherent(__scm->dev, ALIGN(ptr_sz, SZ_64), ptr, ptr_phys);
+       dma_free_coherent(__scm->dev, ptr_sz, ptr, ptr_dma);
        if (ret) {
                dev_err(__scm->dev,
-                       "Assign memory protection call failed %d.\n", ret);
+                       "Assign memory protection call failed %d\n", ret);
                return -EINVAL;
        }
 
index cdee0b4..4126be9 100644 (file)
@@ -635,6 +635,7 @@ fail:
 
 /**
  * ti_sci_cmd_get_device() - command to request for device managed by TISCI
+ *                          that can be shared with other hosts.
  * @handle:    Pointer to TISCI handle as retrieved by *ti_sci_get_handle
  * @id:                Device Identifier
  *
@@ -642,12 +643,30 @@ fail:
  * 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, 0,
+                                      MSG_DEVICE_SW_STATE_ON);
+}
+
+/**
+ * ti_sci_cmd_get_device_exclusive() - command to request for device managed by
+ *                                    TISCI that is exclusively owned by the
+ *                                    requesting host.
+ * @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_get_device_exclusive(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);
@@ -666,6 +685,26 @@ static int ti_sci_cmd_get_device(const struct ti_sci_handle *handle, u32 id)
  */
 static int ti_sci_cmd_idle_device(const struct ti_sci_handle *handle, u32 id)
 {
+       return ti_sci_set_device_state(handle, id, 0,
+                                      MSG_DEVICE_SW_STATE_RETENTION);
+}
+
+/**
+ * ti_sci_cmd_idle_device_exclusive() - Command to idle a device managed by
+ *                                     TISCI that is exclusively owned by
+ *                                     requesting host.
+ * @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_exclusive(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);
@@ -2894,7 +2933,9 @@ static void ti_sci_setup_ops(struct ti_sci_info *info)
        core_ops->reboot_device = ti_sci_cmd_core_reboot;
 
        dops->get_device = ti_sci_cmd_get_device;
+       dops->get_device_exclusive = ti_sci_cmd_get_device_exclusive;
        dops->idle_device = ti_sci_cmd_idle_device;
+       dops->idle_device_exclusive = ti_sci_cmd_idle_device_exclusive;
        dops->put_device = ti_sci_cmd_put_device;
 
        dops->is_valid = ti_sci_cmd_dev_is_valid;
diff --git a/drivers/firmware/turris-mox-rwtm.c b/drivers/firmware/turris-mox-rwtm.c
new file mode 100644 (file)
index 0000000..72be589
--- /dev/null
@@ -0,0 +1,384 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Turris Mox rWTM firmware driver
+ *
+ * Copyright (C) 2019 Marek Behun <marek.behun@nic.cz>
+ */
+
+#include <linux/armada-37xx-rwtm-mailbox.h>
+#include <linux/completion.h>
+#include <linux/dma-mapping.h>
+#include <linux/hw_random.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define DRIVER_NAME            "turris-mox-rwtm"
+
+/*
+ * The macros and constants below come from Turris Mox's rWTM firmware code.
+ * This firmware is open source and it's sources can be found at
+ * https://gitlab.labs.nic.cz/turris/mox-boot-builder/tree/master/wtmi.
+ */
+
+#define MBOX_STS_SUCCESS       (0 << 30)
+#define MBOX_STS_FAIL          (1 << 30)
+#define MBOX_STS_BADCMD                (2 << 30)
+#define MBOX_STS_ERROR(s)      ((s) & (3 << 30))
+#define MBOX_STS_VALUE(s)      (((s) >> 10) & 0xfffff)
+#define MBOX_STS_CMD(s)                ((s) & 0x3ff)
+
+enum mbox_cmd {
+       MBOX_CMD_GET_RANDOM     = 1,
+       MBOX_CMD_BOARD_INFO     = 2,
+       MBOX_CMD_ECDSA_PUB_KEY  = 3,
+       MBOX_CMD_HASH           = 4,
+       MBOX_CMD_SIGN           = 5,
+       MBOX_CMD_VERIFY         = 6,
+
+       MBOX_CMD_OTP_READ       = 7,
+       MBOX_CMD_OTP_WRITE      = 8,
+};
+
+struct mox_kobject;
+
+struct mox_rwtm {
+       struct device *dev;
+       struct mbox_client mbox_client;
+       struct mbox_chan *mbox;
+       struct mox_kobject *kobj;
+       struct hwrng hwrng;
+
+       struct armada_37xx_rwtm_rx_msg reply;
+
+       void *buf;
+       dma_addr_t buf_phys;
+
+       struct mutex busy;
+       struct completion cmd_done;
+
+       /* board information */
+       int has_board_info;
+       u64 serial_number;
+       int board_version, ram_size;
+       u8 mac_address1[6], mac_address2[6];
+
+       /* public key burned in eFuse */
+       int has_pubkey;
+       u8 pubkey[135];
+};
+
+struct mox_kobject {
+       struct kobject kobj;
+       struct mox_rwtm *rwtm;
+};
+
+static inline struct kobject *rwtm_to_kobj(struct mox_rwtm *rwtm)
+{
+       return &rwtm->kobj->kobj;
+}
+
+static inline struct mox_rwtm *to_rwtm(struct kobject *kobj)
+{
+       return container_of(kobj, struct mox_kobject, kobj)->rwtm;
+}
+
+static void mox_kobj_release(struct kobject *kobj)
+{
+       kfree(to_rwtm(kobj)->kobj);
+}
+
+static struct kobj_type mox_kobj_ktype = {
+       .release        = mox_kobj_release,
+       .sysfs_ops      = &kobj_sysfs_ops,
+};
+
+static int mox_kobj_create(struct mox_rwtm *rwtm)
+{
+       rwtm->kobj = kzalloc(sizeof(*rwtm->kobj), GFP_KERNEL);
+       if (!rwtm->kobj)
+               return -ENOMEM;
+
+       kobject_init(rwtm_to_kobj(rwtm), &mox_kobj_ktype);
+       if (kobject_add(rwtm_to_kobj(rwtm), firmware_kobj, "turris-mox-rwtm")) {
+               kobject_put(rwtm_to_kobj(rwtm));
+               return -ENXIO;
+       }
+
+       rwtm->kobj->rwtm = rwtm;
+
+       return 0;
+}
+
+#define MOX_ATTR_RO(name, format, cat)                         \
+static ssize_t                                                 \
+name##_show(struct kobject *kobj, struct kobj_attribute *a,    \
+           char *buf)                                          \
+{                                                              \
+       struct mox_rwtm *rwtm = to_rwtm(kobj);  \
+       if (!rwtm->has_##cat)                                   \
+               return -ENODATA;                                \
+       return sprintf(buf, format, rwtm->name);                \
+}                                                              \
+static struct kobj_attribute mox_attr_##name = __ATTR_RO(name)
+
+MOX_ATTR_RO(serial_number, "%016llX\n", board_info);
+MOX_ATTR_RO(board_version, "%i\n", board_info);
+MOX_ATTR_RO(ram_size, "%i\n", board_info);
+MOX_ATTR_RO(mac_address1, "%pM\n", board_info);
+MOX_ATTR_RO(mac_address2, "%pM\n", board_info);
+MOX_ATTR_RO(pubkey, "%s\n", pubkey);
+
+static int mox_get_status(enum mbox_cmd cmd, u32 retval)
+{
+       if (MBOX_STS_CMD(retval) != cmd ||
+           MBOX_STS_ERROR(retval) != MBOX_STS_SUCCESS)
+               return -EIO;
+       else if (MBOX_STS_ERROR(retval) == MBOX_STS_FAIL)
+               return -(int)MBOX_STS_VALUE(retval);
+       else
+               return MBOX_STS_VALUE(retval);
+}
+
+static const struct attribute *mox_rwtm_attrs[] = {
+       &mox_attr_serial_number.attr,
+       &mox_attr_board_version.attr,
+       &mox_attr_ram_size.attr,
+       &mox_attr_mac_address1.attr,
+       &mox_attr_mac_address2.attr,
+       &mox_attr_pubkey.attr,
+       NULL
+};
+
+static void mox_rwtm_rx_callback(struct mbox_client *cl, void *data)
+{
+       struct mox_rwtm *rwtm = dev_get_drvdata(cl->dev);
+       struct armada_37xx_rwtm_rx_msg *msg = data;
+
+       rwtm->reply = *msg;
+       complete(&rwtm->cmd_done);
+}
+
+static void reply_to_mac_addr(u8 *mac, u32 t1, u32 t2)
+{
+       mac[0] = t1 >> 8;
+       mac[1] = t1;
+       mac[2] = t2 >> 24;
+       mac[3] = t2 >> 16;
+       mac[4] = t2 >> 8;
+       mac[5] = t2;
+}
+
+static int mox_get_board_info(struct mox_rwtm *rwtm)
+{
+       struct armada_37xx_rwtm_tx_msg msg;
+       struct armada_37xx_rwtm_rx_msg *reply = &rwtm->reply;
+       int ret;
+
+       msg.command = MBOX_CMD_BOARD_INFO;
+       ret = mbox_send_message(rwtm->mbox, &msg);
+       if (ret < 0)
+               return ret;
+
+       ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2);
+       if (ret < 0)
+               return ret;
+
+       ret = mox_get_status(MBOX_CMD_BOARD_INFO, reply->retval);
+       if (ret < 0 && ret != -ENODATA) {
+               return ret;
+       } else if (ret == -ENODATA) {
+               dev_warn(rwtm->dev,
+                        "Board does not have manufacturing information burned!\n");
+       } else {
+               rwtm->serial_number = reply->status[1];
+               rwtm->serial_number <<= 32;
+               rwtm->serial_number |= reply->status[0];
+                       rwtm->board_version = reply->status[2];
+               rwtm->ram_size = reply->status[3];
+               reply_to_mac_addr(rwtm->mac_address1, reply->status[4],
+                                 reply->status[5]);
+               reply_to_mac_addr(rwtm->mac_address2, reply->status[6],
+                                 reply->status[7]);
+               rwtm->has_board_info = 1;
+
+               pr_info("Turris Mox serial number %016llX\n",
+                       rwtm->serial_number);
+               pr_info("           board version %i\n", rwtm->board_version);
+               pr_info("           burned RAM size %i MiB\n", rwtm->ram_size);
+       }
+
+       msg.command = MBOX_CMD_ECDSA_PUB_KEY;
+       ret = mbox_send_message(rwtm->mbox, &msg);
+       if (ret < 0)
+               return ret;
+
+       ret = wait_for_completion_timeout(&rwtm->cmd_done, HZ / 2);
+       if (ret < 0)
+               return ret;
+
+       ret = mox_get_status(MBOX_CMD_ECDSA_PUB_KEY, reply->retval);
+       if (ret < 0 && ret != -ENODATA) {
+               return ret;
+       } else if (ret == -ENODATA) {
+               dev_warn(rwtm->dev, "Board has no public key burned!\n");
+       } else {
+               u32 *s = reply->status;
+
+               rwtm->has_pubkey = 1;
+               sprintf(rwtm->pubkey,
+                       "%06x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
+                       ret, s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7],
+                       s[8], s[9], s[10], s[11], s[12], s[13], s[14], s[15]);
+       }
+
+       return 0;
+}
+
+static int mox_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+{
+       struct mox_rwtm *rwtm = (struct mox_rwtm *) rng->priv;
+       struct armada_37xx_rwtm_tx_msg msg;
+       int ret;
+
+       if (max > 4096)
+               max = 4096;
+
+       msg.command = MBOX_CMD_GET_RANDOM;
+       msg.args[0] = 1;
+       msg.args[1] = rwtm->buf_phys;
+       msg.args[2] = (max + 3) & ~3;
+
+       if (!wait) {
+               if (!mutex_trylock(&rwtm->busy))
+                       return -EBUSY;
+       } else {
+               mutex_lock(&rwtm->busy);
+       }
+
+       ret = mbox_send_message(rwtm->mbox, &msg);
+       if (ret < 0)
+               goto unlock_mutex;
+
+       ret = wait_for_completion_interruptible(&rwtm->cmd_done);
+       if (ret < 0)
+               goto unlock_mutex;
+
+       ret = mox_get_status(MBOX_CMD_GET_RANDOM, rwtm->reply.retval);
+       if (ret < 0)
+               goto unlock_mutex;
+
+       memcpy(data, rwtm->buf, max);
+       ret = max;
+
+unlock_mutex:
+       mutex_unlock(&rwtm->busy);
+       return ret;
+}
+
+static int turris_mox_rwtm_probe(struct platform_device *pdev)
+{
+       struct mox_rwtm *rwtm;
+       struct device *dev = &pdev->dev;
+       int ret;
+
+       rwtm = devm_kzalloc(dev, sizeof(*rwtm), GFP_KERNEL);
+       if (!rwtm)
+               return -ENOMEM;
+
+       rwtm->dev = dev;
+       rwtm->buf = dmam_alloc_coherent(dev, PAGE_SIZE, &rwtm->buf_phys,
+                                       GFP_KERNEL);
+       if (!rwtm->buf)
+               return -ENOMEM;
+
+       ret = mox_kobj_create(rwtm);
+       if (ret < 0) {
+               dev_err(dev, "Cannot create turris-mox-rwtm kobject!\n");
+               return ret;
+       }
+
+       ret = sysfs_create_files(rwtm_to_kobj(rwtm), mox_rwtm_attrs);
+       if (ret < 0) {
+               dev_err(dev, "Cannot create sysfs files!\n");
+               goto put_kobj;
+       }
+
+       platform_set_drvdata(pdev, rwtm);
+
+       mutex_init(&rwtm->busy);
+
+       rwtm->mbox_client.dev = dev;
+       rwtm->mbox_client.rx_callback = mox_rwtm_rx_callback;
+
+       rwtm->mbox = mbox_request_channel(&rwtm->mbox_client, 0);
+       if (IS_ERR(rwtm->mbox)) {
+               ret = PTR_ERR(rwtm->mbox);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "Cannot request mailbox channel: %i\n",
+                               ret);
+               goto remove_files;
+       }
+
+       init_completion(&rwtm->cmd_done);
+
+       ret = mox_get_board_info(rwtm);
+       if (ret < 0)
+               dev_warn(dev, "Cannot read board information: %i\n", ret);
+
+       rwtm->hwrng.name = DRIVER_NAME "_hwrng";
+       rwtm->hwrng.read = mox_hwrng_read;
+       rwtm->hwrng.priv = (unsigned long) rwtm;
+       rwtm->hwrng.quality = 1024;
+
+       ret = devm_hwrng_register(dev, &rwtm->hwrng);
+       if (ret < 0) {
+               dev_err(dev, "Cannot register HWRNG: %i\n", ret);
+               goto free_channel;
+       }
+
+       return 0;
+
+free_channel:
+       mbox_free_channel(rwtm->mbox);
+remove_files:
+       sysfs_remove_files(rwtm_to_kobj(rwtm), mox_rwtm_attrs);
+put_kobj:
+       kobject_put(rwtm_to_kobj(rwtm));
+       return ret;
+}
+
+static int turris_mox_rwtm_remove(struct platform_device *pdev)
+{
+       struct mox_rwtm *rwtm = platform_get_drvdata(pdev);
+
+       sysfs_remove_files(rwtm_to_kobj(rwtm), mox_rwtm_attrs);
+       kobject_put(rwtm_to_kobj(rwtm));
+       mbox_free_channel(rwtm->mbox);
+
+       return 0;
+}
+
+static const struct of_device_id turris_mox_rwtm_match[] = {
+       { .compatible = "cznic,turris-mox-rwtm", },
+       { },
+};
+
+MODULE_DEVICE_TABLE(of, turris_mox_rwtm_match);
+
+static struct platform_driver turris_mox_rwtm_driver = {
+       .probe  = turris_mox_rwtm_probe,
+       .remove = turris_mox_rwtm_remove,
+       .driver = {
+               .name           = DRIVER_NAME,
+               .of_match_table = turris_mox_rwtm_match,
+       },
+};
+module_platform_driver(turris_mox_rwtm_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Turris Mox rWTM firmware driver");
+MODULE_AUTHOR("Marek Behun <marek.behun@nic.cz>");
index a13f224..0221dee 100644 (file)
@@ -210,7 +210,7 @@ static int altera_ps_write_complete(struct fpga_manager *mgr,
                return -EIO;
        }
 
-       if (!IS_ERR(conf->confd)) {
+       if (conf->confd) {
                if (!gpiod_get_raw_value_cansleep(conf->confd)) {
                        dev_err(&mgr->dev, "CONF_DONE is inactive!\n");
                        return -EIO;
@@ -289,10 +289,13 @@ static int altera_ps_probe(struct spi_device *spi)
                return PTR_ERR(conf->status);
        }
 
-       conf->confd = devm_gpiod_get(&spi->dev, "confd", GPIOD_IN);
+       conf->confd = devm_gpiod_get_optional(&spi->dev, "confd", GPIOD_IN);
        if (IS_ERR(conf->confd)) {
-               dev_warn(&spi->dev, "Not using confd gpio: %ld\n",
-                        PTR_ERR(conf->confd));
+               dev_err(&spi->dev, "Failed to get confd gpio: %ld\n",
+                       PTR_ERR(conf->confd));
+               return PTR_ERR(conf->confd);
+       } else if (!conf->confd) {
+               dev_warn(&spi->dev, "Not using confd gpio");
        }
 
        /* Register manager with unique name */
index 343153d..004dc03 100644 (file)
@@ -38,8 +38,7 @@
 #define SCOM_STATUS_PIB_RESP_MASK      0x00007000
 #define SCOM_STATUS_PIB_RESP_SHIFT     12
 
-#define SCOM_STATUS_ANY_ERR            (SCOM_STATUS_ERR_SUMMARY | \
-                                        SCOM_STATUS_PROTECTION | \
+#define SCOM_STATUS_ANY_ERR            (SCOM_STATUS_PROTECTION | \
                                         SCOM_STATUS_PARITY |     \
                                         SCOM_STATUS_PIB_ABORT | \
                                         SCOM_STATUS_PIB_RESP_MASK)
@@ -251,11 +250,6 @@ static int handle_fsi2pib_status(struct scom_device *scom, uint32_t status)
        /* Return -EBUSY on PIB abort to force a retry */
        if (status & SCOM_STATUS_PIB_ABORT)
                return -EBUSY;
-       if (status & SCOM_STATUS_ERR_SUMMARY) {
-               fsi_device_write(scom->fsi_dev, SCOM_FSI2PIB_RESET_REG, &dummy,
-                                sizeof(uint32_t));
-               return -EIO;
-       }
        return 0;
 }
 
index bb13c26..38e096e 100644 (file)
@@ -275,7 +275,7 @@ config GPIO_ICH
 
 config GPIO_IOP
        tristate "Intel IOP GPIO"
-       depends on ARCH_IOP32X || ARCH_IOP33X || COMPILE_TEST
+       depends on ARCH_IOP32X || COMPILE_TEST
        select GPIO_GENERIC
        help
          Say yes here to support the GPIO functionality of a number of Intel
@@ -288,7 +288,7 @@ config GPIO_IXP4XX
        depends on ARM # For <asm/mach-types.h>
        depends on ARCH_IXP4XX
        select GPIO_GENERIC
-       select IRQ_DOMAIN
+       select GPIOLIB_IRQCHIP
        select IRQ_DOMAIN_HIERARCHY
        help
          Say yes here to support the GPIO functionality of a number of Intel
@@ -311,6 +311,13 @@ config GPIO_LPC18XX
          Select this option to enable GPIO driver for
          NXP LPC18XX/43XX devices.
 
+config GPIO_LPC32XX
+       tristate "NXP LPC32XX GPIO support"
+       depends on OF_GPIO && (ARCH_LPC32XX || COMPILE_TEST)
+       help
+         Select this option to enable GPIO driver for
+         NXP LPC32XX devices.
+
 config GPIO_LYNXPOINT
        tristate "Intel Lynxpoint GPIO support"
        depends on ACPI && X86
@@ -539,6 +546,7 @@ config GPIO_THUNDERX
        tristate "Cavium ThunderX/OCTEON-TX GPIO"
        depends on ARCH_THUNDER || (64BIT && COMPILE_TEST)
        depends on PCI_MSI
+       select GPIOLIB_IRQCHIP
        select IRQ_DOMAIN_HIERARCHY
        select IRQ_FASTEOI_HIERARCHY_HANDLERS
        help
@@ -1445,6 +1453,15 @@ config GPIO_XRA1403
        help
          GPIO driver for EXAR XRA1403 16-bit SPI-based GPIO expander.
 
+config GPIO_MOXTET
+       tristate "Turris Mox Moxtet bus GPIO expander"
+       depends on MOXTET
+       help
+         Say yes here if you are building for the Turris Mox router.
+         This is the driver needed for configuring the GPIOs via the Moxtet
+         bus. For example the Mox module with SFP cage needs this driver
+         so that phylink can use corresponding GPIOs.
+
 endmenu
 
 menu "USB GPIO expanders"
@@ -1465,7 +1482,6 @@ endmenu
 
 config GPIO_MOCKUP
        tristate "GPIO Testing Driver"
-       depends on GPIOLIB
        select IRQ_SIM
        help
          This enables GPIO Testing driver, which provides a way to test GPIO
index a4e9117..d2fd19c 100644 (file)
@@ -67,14 +67,13 @@ obj-$(CONFIG_GPIO_IT87)                     += gpio-it87.o
 obj-$(CONFIG_GPIO_IXP4XX)              += gpio-ixp4xx.o
 obj-$(CONFIG_GPIO_JANZ_TTL)            += gpio-janz-ttl.o
 obj-$(CONFIG_GPIO_KEMPLD)              += gpio-kempld.o
-obj-$(CONFIG_ARCH_KS8695)              += gpio-ks8695.o
 obj-$(CONFIG_GPIO_LOONGSON1)           += gpio-loongson1.o
 obj-$(CONFIG_GPIO_LOONGSON)            += gpio-loongson.o
 obj-$(CONFIG_GPIO_LP3943)              += gpio-lp3943.o
 obj-$(CONFIG_GPIO_LP873X)              += gpio-lp873x.o
 obj-$(CONFIG_GPIO_LP87565)             += gpio-lp87565.o
 obj-$(CONFIG_GPIO_LPC18XX)             += gpio-lpc18xx.o
-obj-$(CONFIG_ARCH_LPC32XX)             += gpio-lpc32xx.o
+obj-$(CONFIG_GPIO_LPC32XX)             += gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_LYNXPOINT)           += gpio-lynxpoint.o
 obj-$(CONFIG_GPIO_MADERA)              += gpio-madera.o
 obj-$(CONFIG_GPIO_MAX3191X)            += gpio-max3191x.o
@@ -93,6 +92,7 @@ obj-$(CONFIG_GPIO_ML_IOH)             += gpio-ml-ioh.o
 obj-$(CONFIG_GPIO_MLXBF)               += gpio-mlxbf.o
 obj-$(CONFIG_GPIO_MM_LANTIQ)           += gpio-mm-lantiq.o
 obj-$(CONFIG_GPIO_MOCKUP)              += gpio-mockup.o
+obj-$(CONFIG_GPIO_MOXTET)              += gpio-moxtet.o
 obj-$(CONFIG_GPIO_MPC5200)             += gpio-mpc5200.o
 obj-$(CONFIG_GPIO_MPC8XXX)             += gpio-mpc8xxx.o
 obj-$(CONFIG_GPIO_MSIC)                        += gpio-msic.o
index c07fad9..5640efe 100644 (file)
@@ -142,7 +142,7 @@ static const struct gpio_chip template_chip = {
 static int arizona_gpio_probe(struct platform_device *pdev)
 {
        struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
-       struct arizona_pdata *pdata = dev_get_platdata(arizona->dev);
+       struct arizona_pdata *pdata = &arizona->pdata;
        struct arizona_gpio *arizona_gpio;
        int ret;
 
@@ -177,7 +177,7 @@ static int arizona_gpio_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       if (pdata && pdata->gpio_base)
+       if (pdata->gpio_base)
                arizona_gpio->gpio_chip.base = pdata->gpio_base;
        else
                arizona_gpio->gpio_chip.base = -1;
index 13d80bf..09e53c5 100644 (file)
@@ -52,6 +52,7 @@ struct aspeed_gpio_config {
  */
 struct aspeed_gpio {
        struct gpio_chip chip;
+       struct irq_chip irqc;
        spinlock_t lock;
        void __iomem *base;
        int irq;
@@ -661,12 +662,14 @@ static void aspeed_gpio_irq_handler(struct irq_desc *desc)
        struct gpio_chip *gc = irq_desc_get_handler_data(desc);
        struct irq_chip *ic = irq_desc_get_chip(desc);
        struct aspeed_gpio *data = gpiochip_get_data(gc);
-       unsigned int i, p, girq;
+       unsigned int i, p, girq, banks;
        unsigned long reg;
+       struct aspeed_gpio *gpio = gpiochip_get_data(gc);
 
        chained_irq_enter(ic, desc);
 
-       for (i = 0; i < ARRAY_SIZE(aspeed_gpio_banks); i++) {
+       banks = DIV_ROUND_UP(gpio->chip.ngpio, 32);
+       for (i = 0; i < banks; i++) {
                const struct aspeed_gpio_bank *bank = &aspeed_gpio_banks[i];
 
                reg = ioread32(bank_reg(data, bank, reg_irq_status));
@@ -681,16 +684,11 @@ static void aspeed_gpio_irq_handler(struct irq_desc *desc)
        chained_irq_exit(ic, desc);
 }
 
-static struct irq_chip aspeed_gpio_irqchip = {
-       .name           = "aspeed-gpio",
-       .irq_ack        = aspeed_gpio_irq_ack,
-       .irq_mask       = aspeed_gpio_irq_mask,
-       .irq_unmask     = aspeed_gpio_irq_unmask,
-       .irq_set_type   = aspeed_gpio_set_type,
-};
-
-static void set_irq_valid_mask(struct aspeed_gpio *gpio)
+static void aspeed_init_irq_valid_mask(struct gpio_chip *gc,
+                                      unsigned long *valid_mask,
+                                      unsigned int ngpios)
 {
+       struct aspeed_gpio *gpio = gpiochip_get_data(gc);
        const struct aspeed_bank_props *props = gpio->config->props;
 
        while (!is_bank_props_sentinel(props)) {
@@ -701,42 +699,16 @@ static void set_irq_valid_mask(struct aspeed_gpio *gpio)
                for_each_clear_bit(offset, &input, 32) {
                        unsigned int i = props->bank * 32 + offset;
 
-                       if (i >= gpio->config->nr_gpios)
+                       if (i >= gpio->chip.ngpio)
                                break;
 
-                       clear_bit(i, gpio->chip.irq.valid_mask);
+                       clear_bit(i, valid_mask);
                }
 
                props++;
        }
 }
 
-static int aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio,
-               struct platform_device *pdev)
-{
-       int rc;
-
-       rc = platform_get_irq(pdev, 0);
-       if (rc < 0)
-               return rc;
-
-       gpio->irq = rc;
-
-       set_irq_valid_mask(gpio);
-
-       rc = gpiochip_irqchip_add(&gpio->chip, &aspeed_gpio_irqchip,
-                       0, handle_bad_irq, IRQ_TYPE_NONE);
-       if (rc) {
-               dev_info(&pdev->dev, "Could not add irqchip\n");
-               return rc;
-       }
-
-       gpiochip_set_chained_irqchip(&gpio->chip, &aspeed_gpio_irqchip,
-                                    gpio->irq, aspeed_gpio_irq_handler);
-
-       return 0;
-}
-
 static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip,
                                        unsigned int offset, bool enable)
 {
@@ -1040,10 +1012,10 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc,
        unsigned long flags;
 
        if (!gpio->cf_copro_bankmap)
-               gpio->cf_copro_bankmap = kzalloc(gpio->config->nr_gpios >> 3, GFP_KERNEL);
+               gpio->cf_copro_bankmap = kzalloc(gpio->chip.ngpio >> 3, GFP_KERNEL);
        if (!gpio->cf_copro_bankmap)
                return -ENOMEM;
-       if (offset < 0 || offset > gpio->config->nr_gpios)
+       if (offset < 0 || offset > gpio->chip.ngpio)
                return -EINVAL;
        bindex = offset >> 3;
 
@@ -1088,7 +1060,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc)
        if (!gpio->cf_copro_bankmap)
                return -ENXIO;
 
-       if (offset < 0 || offset > gpio->config->nr_gpios)
+       if (offset < 0 || offset > gpio->chip.ngpio)
                return -EINVAL;
        bindex = offset >> 3;
 
@@ -1141,9 +1113,25 @@ static const struct aspeed_gpio_config ast2500_config =
        /* 232 for simplicity, actual number is 228 (4-GPIO hole in GPIOAB) */
        { .nr_gpios = 232, .props = ast2500_bank_props, };
 
+static const struct aspeed_bank_props ast2600_bank_props[] = {
+       /*     input      output   */
+       {5, 0xffffffff,  0x0000ffff}, /* U/V/W/X */
+       {6, 0xffff0000,  0x0fff0000}, /* Y/Z */
+       { },
+};
+
+static const struct aspeed_gpio_config ast2600_config =
+       /*
+        * ast2600 has two controllers one with 208 GPIOs and one with 36 GPIOs.
+        * We expect ngpio being set in the device tree and this is a fallback
+        * option.
+        */
+       { .nr_gpios = 208, .props = ast2600_bank_props, };
+
 static const struct of_device_id aspeed_gpio_of_table[] = {
        { .compatible = "aspeed,ast2400-gpio", .data = &ast2400_config, },
        { .compatible = "aspeed,ast2500-gpio", .data = &ast2500_config, },
+       { .compatible = "aspeed,ast2600-gpio", .data = &ast2600_config, },
        {}
 };
 MODULE_DEVICE_TABLE(of, aspeed_gpio_of_table);
@@ -1152,7 +1140,8 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
 {
        const struct of_device_id *gpio_id;
        struct aspeed_gpio *gpio;
-       int rc, i, banks;
+       int rc, i, banks, err;
+       u32 ngpio;
 
        gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
        if (!gpio)
@@ -1178,7 +1167,10 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
        gpio->config = gpio_id->data;
 
        gpio->chip.parent = &pdev->dev;
-       gpio->chip.ngpio = gpio->config->nr_gpios;
+       err = of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpio);
+       gpio->chip.ngpio = (u16) ngpio;
+       if (err)
+               gpio->chip.ngpio = gpio->config->nr_gpios;
        gpio->chip.direction_input = aspeed_gpio_dir_in;
        gpio->chip.direction_output = aspeed_gpio_dir_out;
        gpio->chip.get_direction = aspeed_gpio_get_direction;
@@ -1189,10 +1181,9 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
        gpio->chip.set_config = aspeed_gpio_set_config;
        gpio->chip.label = dev_name(&pdev->dev);
        gpio->chip.base = -1;
-       gpio->chip.irq.need_valid_mask = true;
 
        /* Allocate a cache of the output registers */
-       banks = gpio->config->nr_gpios >> 5;
+       banks = DIV_ROUND_UP(gpio->chip.ngpio, 32);
        gpio->dcache = devm_kcalloc(&pdev->dev,
                                    banks, sizeof(u32), GFP_KERNEL);
        if (!gpio->dcache)
@@ -1212,16 +1203,42 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev)
                aspeed_gpio_change_cmd_source(gpio, bank, 3, GPIO_CMDSRC_ARM);
        }
 
-       rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
-       if (rc < 0)
-               return rc;
+       /* Optionally set up an irqchip if there is an IRQ */
+       rc = platform_get_irq(pdev, 0);
+       if (rc > 0) {
+               struct gpio_irq_chip *girq;
+
+               gpio->irq = rc;
+               girq = &gpio->chip.irq;
+               girq->chip = &gpio->irqc;
+               girq->chip->name = dev_name(&pdev->dev);
+               girq->chip->irq_ack = aspeed_gpio_irq_ack;
+               girq->chip->irq_mask = aspeed_gpio_irq_mask;
+               girq->chip->irq_unmask = aspeed_gpio_irq_unmask;
+               girq->chip->irq_set_type = aspeed_gpio_set_type;
+               girq->parent_handler = aspeed_gpio_irq_handler;
+               girq->num_parents = 1;
+               girq->parents = devm_kcalloc(&pdev->dev, 1,
+                                            sizeof(*girq->parents),
+                                            GFP_KERNEL);
+               if (!girq->parents)
+                       return -ENOMEM;
+               girq->parents[0] = gpio->irq;
+               girq->default_type = IRQ_TYPE_NONE;
+               girq->handler = handle_bad_irq;
+               girq->init_valid_mask = aspeed_init_irq_valid_mask;
+       }
 
        gpio->offset_timer =
                devm_kzalloc(&pdev->dev, gpio->chip.ngpio, GFP_KERNEL);
        if (!gpio->offset_timer)
                return -ENOMEM;
 
-       return aspeed_gpio_setup_irqs(gpio, pdev);
+       rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
+       if (rc < 0)
+               return rc;
+
+       return 0;
 }
 
 static struct platform_driver aspeed_gpio_driver = {
index fd85605..0c1ead1 100644 (file)
@@ -36,7 +36,7 @@ static int bd70528_set_debounce(struct bd70528_gpio *bdgpio,
                break;
        default:
                dev_err(bdgpio->chip.dev,
-                       "Invalid debouce value %u\n", debounce);
+                       "Invalid debounce value %u\n", debounce);
                return -EINVAL;
        }
        return regmap_update_bits(bdgpio->chip.regmap, GPIO_IN_REG(offset),
@@ -153,7 +153,7 @@ static int bd70528_gpio_get_i(struct bd70528_gpio *bdgpio, unsigned int offset)
 
 static int bd70528_gpio_get(struct gpio_chip *chip, unsigned int offset)
 {
-       int ret = -EINVAL;
+       int ret;
        struct bd70528_gpio *bdgpio = gpiochip_get_data(chip);
 
        /*
index af936dc..05e3f99 100644 (file)
@@ -636,10 +636,8 @@ static int brcmstb_gpio_probe(struct platform_device *pdev)
 
        if (of_property_read_bool(np, "interrupt-controller")) {
                priv->parent_irq = platform_get_irq(pdev, 0);
-               if (priv->parent_irq <= 0) {
-                       dev_err(dev, "Couldn't get IRQ");
+               if (priv->parent_irq <= 0)
                        return -ENOENT;
-               }
        } else {
                priv->parent_irq = -ENOENT;
        }
index 712ae21..a4d3239 100644 (file)
@@ -214,27 +214,33 @@ static int cdns_gpio_probe(struct platform_device *pdev)
                goto err_revert_dir;
        }
 
-       ret = devm_gpiochip_add_data(&pdev->dev, &cgpio->gc, cgpio);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
-               goto err_disable_clk;
-       }
-
        /*
-        * irq_chip support
+        * Optional irq_chip support
         */
        irq = platform_get_irq(pdev, 0);
        if (irq >= 0) {
-               ret = gpiochip_irqchip_add(&cgpio->gc, &cdns_gpio_irqchip,
-                                          0, handle_level_irq,
-                                          IRQ_TYPE_NONE);
-               if (ret) {
-                       dev_err(&pdev->dev, "Could not add irqchip, %d\n",
-                               ret);
+               struct gpio_irq_chip *girq;
+
+               girq = &cgpio->gc.irq;
+               girq->chip = &cdns_gpio_irqchip;
+               girq->parent_handler = cdns_gpio_irq_handler;
+               girq->num_parents = 1;
+               girq->parents = devm_kcalloc(&pdev->dev, 1,
+                                            sizeof(*girq->parents),
+                                            GFP_KERNEL);
+               if (!girq->parents) {
+                       ret = -ENOMEM;
                        goto err_disable_clk;
                }
-               gpiochip_set_chained_irqchip(&cgpio->gc, &cdns_gpio_irqchip,
-                                            irq, cdns_gpio_irq_handler);
+               girq->parents[0] = irq;
+               girq->default_type = IRQ_TYPE_NONE;
+               girq->handler = handle_level_irq;
+       }
+
+       ret = devm_gpiochip_add_data(&pdev->dev, &cgpio->gc, cgpio);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
+               goto err_disable_clk;
        }
 
        cgpio->bypass_orig = ioread32(cgpio->regs + CDNS_GPIO_BYPASS_MODE);
index 8cbc94d..ff19a8a 100644 (file)
@@ -137,7 +137,6 @@ static int creg_gpio_probe(struct platform_device *pdev)
        const struct of_device_id *match;
        struct device *dev = &pdev->dev;
        struct creg_gpio *hcg;
-       struct resource *mem;
        u32 ngpios;
        int ret;
 
@@ -145,8 +144,7 @@ static int creg_gpio_probe(struct platform_device *pdev)
        if (!hcg)
                return -ENOMEM;
 
-       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       hcg->regs = devm_ioremap_resource(dev, mem);
+       hcg->regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(hcg->regs))
                return PTR_ERR(hcg->regs);
 
index 3108be5..92e127e 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/slab.h>
 
 #include "gpiolib.h"
+#include "gpiolib-acpi.h"
 
 #define GPIO_SWPORTA_DR                0x00
 #define GPIO_SWPORTA_DDR       0x04
index 7b9ac4a..fe7a73f 100644 (file)
@@ -584,10 +584,8 @@ static int sprd_eic_probe(struct platform_device *pdev)
        sprd_eic->type = pdata->type;
 
        sprd_eic->irq = platform_get_irq(pdev, 0);
-       if (sprd_eic->irq < 0) {
-               dev_err(&pdev->dev, "Failed to get EIC interrupt.\n");
+       if (sprd_eic->irq < 0)
                return sprd_eic->irq;
-       }
 
        for (i = 0; i < SPRD_EIC_MAX_BANK; i++) {
                /*
index a879512..620f25b 100644 (file)
@@ -272,11 +272,12 @@ static int em_gio_probe(struct platform_device *pdev)
        struct resource *io[2], *irq[2];
        struct gpio_chip *gpio_chip;
        struct irq_chip *irq_chip;
-       const char *name = dev_name(&pdev->dev);
+       struct device *dev = &pdev->dev;
+       const char *name = dev_name(dev);
        unsigned int ngpios;
        int ret;
 
-       p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
+       p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL);
        if (!p)
                return -ENOMEM;
 
@@ -290,27 +291,27 @@ static int em_gio_probe(struct platform_device *pdev)
        irq[1] = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
 
        if (!io[0] || !io[1] || !irq[0] || !irq[1]) {
-               dev_err(&pdev->dev, "missing IRQ or IOMEM\n");
+               dev_err(dev, "missing IRQ or IOMEM\n");
                return -EINVAL;
        }
 
-       p->base0 = devm_ioremap_nocache(&pdev->dev, io[0]->start,
+       p->base0 = devm_ioremap_nocache(dev, io[0]->start,
                                        resource_size(io[0]));
        if (!p->base0)
                return -ENOMEM;
 
-       p->base1 = devm_ioremap_nocache(&pdev->dev, io[1]->start,
+       p->base1 = devm_ioremap_nocache(dev, io[1]->start,
                                   resource_size(io[1]));
        if (!p->base1)
                return -ENOMEM;
 
-       if (of_property_read_u32(pdev->dev.of_node, "ngpios", &ngpios)) {
-               dev_err(&pdev->dev, "Missing ngpios OF property\n");
+       if (of_property_read_u32(dev->of_node, "ngpios", &ngpios)) {
+               dev_err(dev, "Missing ngpios OF property\n");
                return -EINVAL;
        }
 
        gpio_chip = &p->gpio_chip;
-       gpio_chip->of_node = pdev->dev.of_node;
+       gpio_chip->of_node = dev->of_node;
        gpio_chip->direction_input = em_gio_direction_input;
        gpio_chip->get = em_gio_get;
        gpio_chip->direction_output = em_gio_direction_output;
@@ -319,7 +320,7 @@ static int em_gio_probe(struct platform_device *pdev)
        gpio_chip->request = em_gio_request;
        gpio_chip->free = em_gio_free;
        gpio_chip->label = name;
-       gpio_chip->parent = &pdev->dev;
+       gpio_chip->parent = dev;
        gpio_chip->owner = THIS_MODULE;
        gpio_chip->base = -1;
        gpio_chip->ngpio = ngpios;
@@ -333,33 +334,33 @@ static int em_gio_probe(struct platform_device *pdev)
        irq_chip->irq_release_resources = em_gio_irq_relres;
        irq_chip->flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND;
 
-       p->irq_domain = irq_domain_add_simple(pdev->dev.of_node, ngpios, 0,
+       p->irq_domain = irq_domain_add_simple(dev->of_node, ngpios, 0,
                                              &em_gio_irq_domain_ops, p);
        if (!p->irq_domain) {
-               dev_err(&pdev->dev, "cannot initialize irq domain\n");
+               dev_err(dev, "cannot initialize irq domain\n");
                return -ENXIO;
        }
 
-       ret = devm_add_action_or_reset(&pdev->dev, em_gio_irq_domain_remove,
+       ret = devm_add_action_or_reset(dev, em_gio_irq_domain_remove,
                                       p->irq_domain);
        if (ret)
                return ret;
 
-       if (devm_request_irq(&pdev->dev, irq[0]->start,
+       if (devm_request_irq(dev, irq[0]->start,
                             em_gio_irq_handler, 0, name, p)) {
-               dev_err(&pdev->dev, "failed to request low IRQ\n");
+               dev_err(dev, "failed to request low IRQ\n");
                return -ENOENT;
        }
 
-       if (devm_request_irq(&pdev->dev, irq[1]->start,
+       if (devm_request_irq(dev, irq[1]->start,
                             em_gio_irq_handler, 0, name, p)) {
-               dev_err(&pdev->dev, "failed to request high IRQ\n");
+               dev_err(dev, "failed to request high IRQ\n");
                return -ENOENT;
        }
 
-       ret = devm_gpiochip_add_data(&pdev->dev, gpio_chip, p);
+       ret = devm_gpiochip_add_data(dev, gpio_chip, p);
        if (ret) {
-               dev_err(&pdev->dev, "failed to add GPIO controller\n");
+               dev_err(dev, "failed to add GPIO controller\n");
                return ret;
        }
 
index a90870a..226da8d 100644 (file)
@@ -269,56 +269,6 @@ static struct irq_chip ep93xx_gpio_irq_chip = {
        .irq_set_type   = ep93xx_gpio_irq_type,
 };
 
-static int ep93xx_gpio_init_irq(struct platform_device *pdev,
-                               struct ep93xx_gpio *epg)
-{
-       int ab_parent_irq = platform_get_irq(pdev, 0);
-       struct device *dev = &pdev->dev;
-       int gpio_irq;
-       int ret;
-       int i;
-
-       /* The A bank */
-       ret = gpiochip_irqchip_add(&epg->gc[0], &ep93xx_gpio_irq_chip,
-                                   64, handle_level_irq,
-                                   IRQ_TYPE_NONE);
-       if (ret) {
-               dev_err(dev, "Could not add irqchip 0\n");
-               return ret;
-       }
-       gpiochip_set_chained_irqchip(&epg->gc[0], &ep93xx_gpio_irq_chip,
-                                    ab_parent_irq,
-                                    ep93xx_gpio_ab_irq_handler);
-
-       /* The B bank */
-       ret = gpiochip_irqchip_add(&epg->gc[1], &ep93xx_gpio_irq_chip,
-                                   72, handle_level_irq,
-                                   IRQ_TYPE_NONE);
-       if (ret) {
-               dev_err(dev, "Could not add irqchip 1\n");
-               return ret;
-       }
-       gpiochip_set_chained_irqchip(&epg->gc[1], &ep93xx_gpio_irq_chip,
-                                    ab_parent_irq,
-                                    ep93xx_gpio_ab_irq_handler);
-
-       /* The F bank */
-       for (i = 0; i < 8; i++) {
-               gpio_irq = EP93XX_GPIO_F_IRQ_BASE + i;
-               irq_set_chip_data(gpio_irq, &epg->gc[5]);
-               irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
-                                        handle_level_irq);
-               irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
-       }
-
-       for (i = 1; i <= 8; i++)
-               irq_set_chained_handler_and_data(platform_get_irq(pdev, i),
-                                                ep93xx_gpio_f_irq_handler,
-                                                &epg->gc[i]);
-       return 0;
-}
-
-
 /*************************************************************************
  * gpiolib interface for EP93xx on-chip GPIOs
  *************************************************************************/
@@ -328,26 +278,33 @@ struct ep93xx_gpio_bank {
        int             dir;
        int             base;
        bool            has_irq;
+       bool            has_hierarchical_irq;
+       unsigned int    irq_base;
 };
 
-#define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _has_irq) \
+#define EP93XX_GPIO_BANK(_label, _data, _dir, _base, _has_irq, _has_hier, _irq_base) \
        {                                                       \
                .label          = _label,                       \
                .data           = _data,                        \
                .dir            = _dir,                         \
                .base           = _base,                        \
                .has_irq        = _has_irq,                     \
+               .has_hierarchical_irq = _has_hier,              \
+               .irq_base       = _irq_base,                    \
        }
 
 static struct ep93xx_gpio_bank ep93xx_gpio_banks[] = {
-       EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true), /* Bank A has 8 IRQs */
-       EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true), /* Bank B has 8 IRQs */
-       EP93XX_GPIO_BANK("C", 0x08, 0x18, 40, false),
-       EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24, false),
-       EP93XX_GPIO_BANK("E", 0x20, 0x24, 32, false),
-       EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, true), /* Bank F has 8 IRQs */
-       EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48, false),
-       EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false),
+       /* Bank A has 8 IRQs */
+       EP93XX_GPIO_BANK("A", 0x00, 0x10, 0, true, false, 64),
+       /* Bank B has 8 IRQs */
+       EP93XX_GPIO_BANK("B", 0x04, 0x14, 8, true, false, 72),
+       EP93XX_GPIO_BANK("C", 0x08, 0x18, 40, false, false, 0),
+       EP93XX_GPIO_BANK("D", 0x0c, 0x1c, 24, false, false, 0),
+       EP93XX_GPIO_BANK("E", 0x20, 0x24, 32, false, false, 0),
+       /* Bank F has 8 IRQs */
+       EP93XX_GPIO_BANK("F", 0x30, 0x34, 16, false, true, 0),
+       EP93XX_GPIO_BANK("G", 0x38, 0x3c, 48, false, false, 0),
+       EP93XX_GPIO_BANK("H", 0x40, 0x44, 56, false, false, 0),
 };
 
 static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset,
@@ -369,12 +326,15 @@ static int ep93xx_gpio_f_to_irq(struct gpio_chip *gc, unsigned offset)
        return EP93XX_GPIO_F_IRQ_BASE + offset;
 }
 
-static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
+static int ep93xx_gpio_add_bank(struct gpio_chip *gc,
+                               struct platform_device *pdev,
                                struct ep93xx_gpio *epg,
                                struct ep93xx_gpio_bank *bank)
 {
        void __iomem *data = epg->base + bank->data;
        void __iomem *dir = epg->base + bank->dir;
+       struct device *dev = &pdev->dev;
+       struct gpio_irq_chip *girq;
        int err;
 
        err = bgpio_init(gc, dev, 1, data, NULL, NULL, dir, NULL, 0);
@@ -384,8 +344,59 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev,
        gc->label = bank->label;
        gc->base = bank->base;
 
-       if (bank->has_irq)
+       girq = &gc->irq;
+       if (bank->has_irq || bank->has_hierarchical_irq) {
                gc->set_config = ep93xx_gpio_set_config;
+               girq->chip = &ep93xx_gpio_irq_chip;
+       }
+
+       if (bank->has_irq) {
+               int ab_parent_irq = platform_get_irq(pdev, 0);
+
+               girq->parent_handler = ep93xx_gpio_ab_irq_handler;
+               girq->num_parents = 1;
+               girq->parents = devm_kcalloc(dev, 1,
+                                            sizeof(*girq->parents),
+                                            GFP_KERNEL);
+               if (!girq->parents)
+                       return -ENOMEM;
+               girq->default_type = IRQ_TYPE_NONE;
+               girq->handler = handle_level_irq;
+               girq->parents[0] = ab_parent_irq;
+               girq->first = bank->irq_base;
+       }
+
+       /* Only bank F has especially funky IRQ handling */
+       if (bank->has_hierarchical_irq) {
+               int gpio_irq;
+               int i;
+
+               /*
+                * FIXME: convert this to use hierarchical IRQ support!
+                * this requires fixing the root irqchip to be hierarchial.
+                */
+               girq->parent_handler = ep93xx_gpio_f_irq_handler;
+               girq->num_parents = 8;
+               girq->parents = devm_kcalloc(dev, 8,
+                                            sizeof(*girq->parents),
+                                            GFP_KERNEL);
+               if (!girq->parents)
+                       return -ENOMEM;
+               /* Pick resources 1..8 for these IRQs */
+               for (i = 1; i <= 8; i++)
+                       girq->parents[i - 1] = platform_get_irq(pdev, i);
+               for (i = 0; i < 8; i++) {
+                       gpio_irq = EP93XX_GPIO_F_IRQ_BASE + i;
+                       irq_set_chip_data(gpio_irq, &epg->gc[5]);
+                       irq_set_chip_and_handler(gpio_irq,
+                                                &ep93xx_gpio_irq_chip,
+                                                handle_level_irq);
+                       irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST);
+               }
+               girq->default_type = IRQ_TYPE_NONE;
+               girq->handler = handle_level_irq;
+               gc->to_irq = ep93xx_gpio_f_to_irq;
+       }
 
        return devm_gpiochip_add_data(dev, gc, epg);
 }
@@ -407,16 +418,11 @@ static int ep93xx_gpio_probe(struct platform_device *pdev)
                struct gpio_chip *gc = &epg->gc[i];
                struct ep93xx_gpio_bank *bank = &ep93xx_gpio_banks[i];
 
-               if (ep93xx_gpio_add_bank(gc, &pdev->dev, epg, bank))
+               if (ep93xx_gpio_add_bank(gc, pdev, epg, bank))
                        dev_warn(&pdev->dev, "Unable to add gpio bank %s\n",
                                 bank->label);
-               /* Only bank F has especially funky IRQ handling */
-               if (i == 5)
-                       gc->to_irq = ep93xx_gpio_f_to_irq;
        }
 
-       ep93xx_gpio_init_irq(pdev, epg);
-
        return 0;
 }
 
index 250e71f..fbddb16 100644 (file)
@@ -290,16 +290,14 @@ static int ftgpio_gpio_probe(struct platform_device *pdev)
        girq->num_parents = 1;
        girq->parents = devm_kcalloc(dev, 1, sizeof(*girq->parents),
                                     GFP_KERNEL);
-       if (!girq->parents)
-               return -ENOMEM;
+       if (!girq->parents) {
+               ret = -ENOMEM;
+               goto dis_clk;
+       }
        girq->default_type = IRQ_TYPE_NONE;
        girq->handler = handle_bad_irq;
        girq->parents[0] = irq;
 
-       ret = devm_gpiochip_add_data(dev, &g->gc, g);
-       if (ret)
-               goto dis_clk;
-
        /* Disable, unmask and clear all interrupts */
        writel(0x0, g->base + GPIO_INT_EN);
        writel(0x0, g->base + GPIO_INT_MASK);
@@ -308,6 +306,10 @@ static int ftgpio_gpio_probe(struct platform_device *pdev)
        /* Clear any use of debounce */
        writel(0x0, g->base + GPIO_DEBOUNCE_EN);
 
+       ret = devm_gpiochip_add_data(dev, &g->gc, g);
+       if (ret)
+               goto dis_clk;
+
        platform_set_drvdata(pdev, g);
        dev_info(dev, "FTGPIO010 @%p registered\n", g->base);
 
index 0937b60..08234e6 100644 (file)
@@ -408,8 +408,6 @@ static int grgpio_probe(struct platform_device *ofdev)
                                 * Continue without irq functionality for that
                                 * gpio line
                                 */
-                               dev_err(priv->dev,
-                                       "Failed to get irq for offset %d\n", i);
                                continue;
                        }
                        priv->uirqs[lirq->index].uirq = ret;
index e5fa00f..4a17599 100644 (file)
@@ -244,43 +244,45 @@ static int hlwd_gpio_probe(struct platform_device *pdev)
                ngpios = 32;
        hlwd->gpioc.ngpio = ngpios;
 
-       res = devm_gpiochip_add_data(&pdev->dev, &hlwd->gpioc, hlwd);
-       if (res)
-               return res;
-
        /* Mask and ack all interrupts */
        iowrite32be(0, hlwd->regs + HW_GPIOB_INTMASK);
        iowrite32be(0xffffffff, hlwd->regs + HW_GPIOB_INTFLAG);
 
        /*
         * If this GPIO controller is not marked as an interrupt controller in
-        * the DT, return.
+        * the DT, skip interrupt support.
         */
-       if (!of_property_read_bool(pdev->dev.of_node, "interrupt-controller"))
-               return 0;
-
-       hlwd->irq = platform_get_irq(pdev, 0);
-       if (hlwd->irq < 0) {
-               dev_info(&pdev->dev, "platform_get_irq returned %d\n",
-                        hlwd->irq);
-               return hlwd->irq;
+       if (of_property_read_bool(pdev->dev.of_node, "interrupt-controller")) {
+               struct gpio_irq_chip *girq;
+
+               hlwd->irq = platform_get_irq(pdev, 0);
+               if (hlwd->irq < 0) {
+                       dev_info(&pdev->dev, "platform_get_irq returned %d\n",
+                                hlwd->irq);
+                       return hlwd->irq;
+               }
+
+               hlwd->irqc.name = dev_name(&pdev->dev);
+               hlwd->irqc.irq_mask = hlwd_gpio_irq_mask;
+               hlwd->irqc.irq_unmask = hlwd_gpio_irq_unmask;
+               hlwd->irqc.irq_enable = hlwd_gpio_irq_enable;
+               hlwd->irqc.irq_set_type = hlwd_gpio_irq_set_type;
+
+               girq = &hlwd->gpioc.irq;
+               girq->chip = &hlwd->irqc;
+               girq->parent_handler = hlwd_gpio_irqhandler;
+               girq->num_parents = 1;
+               girq->parents = devm_kcalloc(&pdev->dev, 1,
+                                            sizeof(*girq->parents),
+                                            GFP_KERNEL);
+               if (!girq->parents)
+                       return -ENOMEM;
+               girq->parents[0] = hlwd->irq;
+               girq->default_type = IRQ_TYPE_NONE;
+               girq->handler = handle_level_irq;
        }
 
-       hlwd->irqc.name = dev_name(&pdev->dev);
-       hlwd->irqc.irq_mask = hlwd_gpio_irq_mask;
-       hlwd->irqc.irq_unmask = hlwd_gpio_irq_unmask;
-       hlwd->irqc.irq_enable = hlwd_gpio_irq_enable;
-       hlwd->irqc.irq_set_type = hlwd_gpio_irq_set_type;
-
-       res = gpiochip_irqchip_add(&hlwd->gpioc, &hlwd->irqc, 0,
-                                  handle_level_irq, IRQ_TYPE_NONE);
-       if (res)
-               return res;
-
-       gpiochip_set_chained_irqchip(&hlwd->gpioc, &hlwd->irqc,
-                                    hlwd->irq, hlwd_gpio_irqhandler);
-
-       return 0;
+       return devm_gpiochip_add_data(&pdev->dev, &hlwd->gpioc, hlwd);
 }
 
 static const struct of_device_id hlwd_gpio_match[] = {
index 9d3ac51..6eb56f7 100644 (file)
@@ -118,20 +118,6 @@ static void egpio_handler(struct irq_desc *desc)
        }
 }
 
-int htc_egpio_get_wakeup_irq(struct device *dev)
-{
-       struct egpio_info *ei = dev_get_drvdata(dev);
-
-       /* Read current pins. */
-       u16 readval = egpio_readw(ei, ei->ack_register);
-       /* Ack/unmask interrupts. */
-       ack_irqs(ei);
-       /* Return first set pin. */
-       readval &= ei->irqs_enabled;
-       return ei->irq_start + ffs(readval) - 1;
-}
-EXPORT_SYMBOL(htc_egpio_get_wakeup_irq);
-
 static inline int egpio_pos(struct egpio_info *ei, int bit)
 {
        return bit >> ei->reg_shift;
index 4e803ba..4d835f9 100644 (file)
@@ -329,6 +329,7 @@ static int intel_gpio_probe(struct pci_dev *pdev,
        u32 gpio_base;
        u32 irq_base;
        int retval;
+       struct gpio_irq_chip *girq;
        struct intel_mid_gpio_ddata *ddata =
                                (struct intel_mid_gpio_ddata *)id->driver_data;
 
@@ -369,6 +370,22 @@ static int intel_gpio_probe(struct pci_dev *pdev,
 
        spin_lock_init(&priv->lock);
 
+       girq = &priv->chip.irq;
+       girq->chip = &intel_mid_irqchip;
+       girq->parent_handler = intel_mid_irq_handler;
+       girq->num_parents = 1;
+       girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
+                                    sizeof(*girq->parents),
+                                    GFP_KERNEL);
+       if (!girq->parents)
+               return -ENOMEM;
+       girq->parents[0] = pdev->irq;
+       girq->first = irq_base;
+       girq->default_type = IRQ_TYPE_NONE;
+       girq->handler = handle_simple_irq;
+
+       intel_mid_irq_init_hw(priv);
+
        pci_set_drvdata(pdev, priv);
        retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv);
        if (retval) {
@@ -376,24 +393,6 @@ static int intel_gpio_probe(struct pci_dev *pdev,
                return retval;
        }
 
-       retval = gpiochip_irqchip_add(&priv->chip,
-                                     &intel_mid_irqchip,
-                                     irq_base,
-                                     handle_simple_irq,
-                                     IRQ_TYPE_NONE);
-       if (retval) {
-               dev_err(&pdev->dev,
-                       "could not connect irqchip to gpiochip\n");
-               return retval;
-       }
-
-       intel_mid_irq_init_hw(priv);
-
-       gpiochip_set_chained_irqchip(&priv->chip,
-                                    &intel_mid_irqchip,
-                                    pdev->irq,
-                                    intel_mid_irq_handler);
-
        pm_runtime_put_noidle(&pdev->dev);
        pm_runtime_allow(&pdev->dev);
 
index 670c2a8..b3b0506 100644 (file)
@@ -47,7 +47,6 @@
  * @dev: containing device for this instance
  * @fwnode: the fwnode for this GPIO chip
  * @gc: gpiochip for this instance
- * @domain: irqdomain for this chip instance
  * @base: remapped I/O-memory base
  * @irq_edge: Each bit represents an IRQ: 1: edge-triggered,
  * 0: level triggered
@@ -56,48 +55,22 @@ struct ixp4xx_gpio {
        struct device *dev;
        struct fwnode_handle *fwnode;
        struct gpio_chip gc;
-       struct irq_domain *domain;
        void __iomem *base;
        unsigned long long irq_edge;
 };
 
-/**
- * struct ixp4xx_gpio_map - IXP4 GPIO to parent IRQ map
- * @gpio_offset: offset of the IXP4 GPIO line
- * @parent_hwirq: hwirq on the parent IRQ controller
- */
-struct ixp4xx_gpio_map {
-       int gpio_offset;
-       int parent_hwirq;
-};
-
-/* GPIO lines 0..12 have corresponding IRQs, GPIOs 13..15 have no IRQs */
-const struct ixp4xx_gpio_map ixp4xx_gpiomap[] = {
-       { .gpio_offset = 0, .parent_hwirq = 6 },
-       { .gpio_offset = 1, .parent_hwirq = 7 },
-       { .gpio_offset = 2, .parent_hwirq = 19 },
-       { .gpio_offset = 3, .parent_hwirq = 20 },
-       { .gpio_offset = 4, .parent_hwirq = 21 },
-       { .gpio_offset = 5, .parent_hwirq = 22 },
-       { .gpio_offset = 6, .parent_hwirq = 23 },
-       { .gpio_offset = 7, .parent_hwirq = 24 },
-       { .gpio_offset = 8, .parent_hwirq = 25 },
-       { .gpio_offset = 9, .parent_hwirq = 26 },
-       { .gpio_offset = 10, .parent_hwirq = 27 },
-       { .gpio_offset = 11, .parent_hwirq = 28 },
-       { .gpio_offset = 12, .parent_hwirq = 29 },
-};
-
 static void ixp4xx_gpio_irq_ack(struct irq_data *d)
 {
-       struct ixp4xx_gpio *g = irq_data_get_irq_chip_data(d);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct ixp4xx_gpio *g = gpiochip_get_data(gc);
 
        __raw_writel(BIT(d->hwirq), g->base + IXP4XX_REG_GPIS);
 }
 
 static void ixp4xx_gpio_irq_unmask(struct irq_data *d)
 {
-       struct ixp4xx_gpio *g = irq_data_get_irq_chip_data(d);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct ixp4xx_gpio *g = gpiochip_get_data(gc);
 
        /* ACK when unmasking if not edge-triggered */
        if (!(g->irq_edge & BIT(d->hwirq)))
@@ -108,7 +81,8 @@ static void ixp4xx_gpio_irq_unmask(struct irq_data *d)
 
 static int ixp4xx_gpio_irq_set_type(struct irq_data *d, unsigned int type)
 {
-       struct ixp4xx_gpio *g = irq_data_get_irq_chip_data(d);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct ixp4xx_gpio *g = gpiochip_get_data(gc);
        int line = d->hwirq;
        unsigned long flags;
        u32 int_style;
@@ -187,122 +161,31 @@ static struct irq_chip ixp4xx_gpio_irqchip = {
        .irq_set_type = ixp4xx_gpio_irq_set_type,
 };
 
-static int ixp4xx_gpio_to_irq(struct gpio_chip *gc, unsigned int offset)
+static int ixp4xx_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
+                                            unsigned int child,
+                                            unsigned int child_type,
+                                            unsigned int *parent,
+                                            unsigned int *parent_type)
 {
-       struct ixp4xx_gpio *g = gpiochip_get_data(gc);
-       struct irq_fwspec fwspec;
-
-       fwspec.fwnode = g->fwnode;
-       fwspec.param_count = 2;
-       fwspec.param[0] = offset;
-       fwspec.param[1] = IRQ_TYPE_NONE;
-
-       return irq_create_fwspec_mapping(&fwspec);
-}
+       /* All these interrupts are level high in the CPU */
+       *parent_type = IRQ_TYPE_LEVEL_HIGH;
 
-static int ixp4xx_gpio_irq_domain_translate(struct irq_domain *domain,
-                                           struct irq_fwspec *fwspec,
-                                           unsigned long *hwirq,
-                                           unsigned int *type)
-{
-       int ret;
-
-       /* We support standard DT translation */
-       if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) {
-               return irq_domain_translate_twocell(domain, fwspec,
-                                                   hwirq, type);
+       /* GPIO lines 0..12 have dedicated IRQs */
+       if (child == 0) {
+               *parent = 6;
+               return 0;
        }
-
-       /* This goes away when we transition to DT */
-       if (is_fwnode_irqchip(fwspec->fwnode)) {
-               ret = irq_domain_translate_twocell(domain, fwspec,
-                                                  hwirq, type);
-               if (ret)
-                       return ret;
-               WARN_ON(*type == IRQ_TYPE_NONE);
+       if (child == 1) {
+               *parent = 7;
                return 0;
        }
-       return -EINVAL;
-}
-
-static int ixp4xx_gpio_irq_domain_alloc(struct irq_domain *d,
-                                       unsigned int irq, unsigned int nr_irqs,
-                                       void *data)
-{
-       struct ixp4xx_gpio *g = d->host_data;
-       irq_hw_number_t hwirq;
-       unsigned int type = IRQ_TYPE_NONE;
-       struct irq_fwspec *fwspec = data;
-       int ret;
-       int i;
-
-       ret = ixp4xx_gpio_irq_domain_translate(d, fwspec, &hwirq, &type);
-       if (ret)
-               return ret;
-
-       dev_dbg(g->dev, "allocate IRQ %d..%d, hwirq %lu..%lu\n",
-               irq, irq + nr_irqs - 1,
-               hwirq, hwirq + nr_irqs - 1);
-
-       for (i = 0; i < nr_irqs; i++) {
-               struct irq_fwspec parent_fwspec;
-               const struct ixp4xx_gpio_map *map;
-               int j;
-
-               /* Not all lines support IRQs */
-               for (j = 0; j < ARRAY_SIZE(ixp4xx_gpiomap); j++) {
-                       map = &ixp4xx_gpiomap[j];
-                       if (map->gpio_offset == hwirq)
-                               break;
-               }
-               if (j == ARRAY_SIZE(ixp4xx_gpiomap)) {
-                       dev_err(g->dev, "can't look up hwirq %lu\n", hwirq);
-                       return -EINVAL;
-               }
-               dev_dbg(g->dev, "found parent hwirq %u\n", map->parent_hwirq);
-
-               /*
-                * We set handle_bad_irq because the .set_type() should
-                * always be invoked and set the right type of handler.
-                */
-               irq_domain_set_info(d,
-                                   irq + i,
-                                   hwirq + i,
-                                   &ixp4xx_gpio_irqchip,
-                                   g,
-                                   handle_bad_irq,
-                                   NULL, NULL);
-               irq_set_probe(irq + i);
-
-               /*
-                * Create a IRQ fwspec to send up to the parent irqdomain:
-                * specify the hwirq we address on the parent and tie it
-                * all together up the chain.
-                */
-               parent_fwspec.fwnode = d->parent->fwnode;
-               parent_fwspec.param_count = 2;
-               parent_fwspec.param[0] = map->parent_hwirq;
-               /* This parent only handles asserted level IRQs */
-               parent_fwspec.param[1] = IRQ_TYPE_LEVEL_HIGH;
-               dev_dbg(g->dev, "alloc_irqs_parent for %d parent hwirq %d\n",
-                       irq + i, map->parent_hwirq);
-               ret = irq_domain_alloc_irqs_parent(d, irq + i, 1,
-                                                  &parent_fwspec);
-               if (ret)
-                       dev_err(g->dev,
-                               "failed to allocate parent hwirq %d for hwirq %lu\n",
-                               map->parent_hwirq, hwirq);
+       if (child >= 2 && child <= 12) {
+               *parent = child + 17;
+               return 0;
        }
-
-       return 0;
+       return -EINVAL;
 }
 
-static const struct irq_domain_ops ixp4xx_gpio_irqdomain_ops = {
-       .translate = ixp4xx_gpio_irq_domain_translate,
-       .alloc = ixp4xx_gpio_irq_domain_alloc,
-       .free = irq_domain_free_irqs_common,
-};
-
 static int ixp4xx_gpio_probe(struct platform_device *pdev)
 {
        unsigned long flags;
@@ -311,8 +194,8 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
        struct irq_domain *parent;
        struct resource *res;
        struct ixp4xx_gpio *g;
+       struct gpio_irq_chip *girq;
        int ret;
-       int i;
 
        g = devm_kzalloc(dev, sizeof(*g), GFP_KERNEL);
        if (!g)
@@ -321,9 +204,36 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        g->base = devm_ioremap_resource(dev, res);
-       if (IS_ERR(g->base)) {
-               dev_err(dev, "ioremap error\n");
+       if (IS_ERR(g->base))
                return PTR_ERR(g->base);
+
+       /*
+        * When we convert to device tree we will simply look up the
+        * parent irqdomain using irq_find_host(parent) as parent comes
+        * from IRQCHIP_DECLARE(), then use of_node_to_fwnode() to get
+        * the fwnode. For now we need this boardfile style code.
+        */
+       if (np) {
+               struct device_node *irq_parent;
+
+               irq_parent = of_irq_find_parent(np);
+               if (!irq_parent) {
+                       dev_err(dev, "no IRQ parent node\n");
+                       return -ENODEV;
+               }
+               parent = irq_find_host(irq_parent);
+               if (!parent) {
+                       dev_err(dev, "no IRQ parent domain\n");
+                       return -ENODEV;
+               }
+               g->fwnode = of_node_to_fwnode(np);
+       } else {
+               parent = ixp4xx_get_irq_domain();
+               g->fwnode = irq_domain_alloc_fwnode(&res->start);
+               if (!g->fwnode) {
+                       dev_err(dev, "no domain base\n");
+                       return -ENODEV;
+               }
        }
 
        /*
@@ -360,7 +270,6 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
                dev_err(dev, "unable to init generic GPIO\n");
                return ret;
        }
-       g->gc.to_irq = ixp4xx_gpio_to_irq;
        g->gc.ngpio = 16;
        g->gc.label = "IXP4XX_GPIO_CHIP";
        /*
@@ -372,86 +281,22 @@ static int ixp4xx_gpio_probe(struct platform_device *pdev)
        g->gc.parent = &pdev->dev;
        g->gc.owner = THIS_MODULE;
 
+       girq = &g->gc.irq;
+       girq->chip = &ixp4xx_gpio_irqchip;
+       girq->fwnode = g->fwnode;
+       girq->parent_domain = parent;
+       girq->child_to_parent_hwirq = ixp4xx_gpio_child_to_parent_hwirq;
+       girq->handler = handle_bad_irq;
+       girq->default_type = IRQ_TYPE_NONE;
+
        ret = devm_gpiochip_add_data(dev, &g->gc, g);
        if (ret) {
                dev_err(dev, "failed to add SoC gpiochip\n");
                return ret;
        }
 
-       /*
-        * When we convert to device tree we will simply look up the
-        * parent irqdomain using irq_find_host(parent) as parent comes
-        * from IRQCHIP_DECLARE(), then use of_node_to_fwnode() to get
-        * the fwnode. For now we need this boardfile style code.
-        */
-       if (np) {
-               struct device_node *irq_parent;
-
-               irq_parent = of_irq_find_parent(np);
-               if (!irq_parent) {
-                       dev_err(dev, "no IRQ parent node\n");
-                       return -ENODEV;
-               }
-               parent = irq_find_host(irq_parent);
-               if (!parent) {
-                       dev_err(dev, "no IRQ parent domain\n");
-                       return -ENODEV;
-               }
-               g->fwnode = of_node_to_fwnode(np);
-       } else {
-               parent = ixp4xx_get_irq_domain();
-               g->fwnode = irq_domain_alloc_fwnode(g->base);
-               if (!g->fwnode) {
-                       dev_err(dev, "no domain base\n");
-                       return -ENODEV;
-               }
-       }
-       g->domain = irq_domain_create_hierarchy(parent,
-                                               IRQ_DOMAIN_FLAG_HIERARCHY,
-                                               ARRAY_SIZE(ixp4xx_gpiomap),
-                                               g->fwnode,
-                                               &ixp4xx_gpio_irqdomain_ops,
-                                               g);
-       if (!g->domain) {
-               irq_domain_free_fwnode(g->fwnode);
-               dev_err(dev, "no hierarchical irq domain\n");
-               return ret;
-       }
-
-       /*
-        * After adding OF support, this is no longer needed: irqs
-        * will be allocated for the respective fwnodes.
-        */
-       if (!np) {
-               for (i = 0; i < ARRAY_SIZE(ixp4xx_gpiomap); i++) {
-                       const struct ixp4xx_gpio_map *map = &ixp4xx_gpiomap[i];
-                       struct irq_fwspec fwspec;
-
-                       fwspec.fwnode = g->fwnode;
-                       /* This is the hwirq for the GPIO line side of things */
-                       fwspec.param[0] = map->gpio_offset;
-                       fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
-                       fwspec.param_count = 2;
-                       ret = __irq_domain_alloc_irqs(g->domain,
-                                                     -1, /* just pick something */
-                                                     1,
-                                                     NUMA_NO_NODE,
-                                                     &fwspec,
-                                                     false,
-                                                     NULL);
-                       if (ret < 0) {
-                               irq_domain_free_fwnode(g->fwnode);
-                               dev_err(dev,
-                                       "can not allocate irq for GPIO line %d parent hwirq %d in hierarchy domain: %d\n",
-                                       map->gpio_offset, map->parent_hwirq,
-                                       ret);
-                               return ret;
-                       }
-               }
-       }
-
        platform_set_drvdata(pdev, g);
-       dev_info(dev, "IXP4 GPIO @%p registered\n", g->base);
+       dev_info(dev, "IXP4 GPIO registered\n");
 
        return 0;
 }
diff --git a/drivers/gpio/gpio-ks8695.c b/drivers/gpio/gpio-ks8695.c
deleted file mode 100644 (file)
index a0f87c1..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * arch/arm/mach-ks8695/gpio.c
- *
- * Copyright (C) 2006 Andrew Victor
- * Updated to GPIOLIB, Copyright 2008 Simtec Electronics
- *                     Daniel Silverstone <dsilvers@simtec.co.uk>
- */
-#include <linux/gpio/driver.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/module.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <asm/mach/irq.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/gpio-ks8695.h>
-
-/*
- * Configure a GPIO line for either GPIO function, or its internal
- * function (Interrupt, Timer, etc).
- */
-static void ks8695_gpio_mode(unsigned int pin, short gpio)
-{
-       unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN };
-       unsigned long x, flags;
-
-       if (pin > KS8695_GPIO_5)        /* only GPIO 0..5 have internal functions */
-               return;
-
-       local_irq_save(flags);
-
-       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
-       if (gpio)                       /* GPIO: set bit to 0 */
-               x &= ~enable[pin];
-       else                            /* Internal function: set bit to 1 */
-               x |= enable[pin];
-       __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPC);
-
-       local_irq_restore(flags);
-}
-
-
-static unsigned short gpio_irq[] = { KS8695_IRQ_EXTERN0, KS8695_IRQ_EXTERN1, KS8695_IRQ_EXTERN2, KS8695_IRQ_EXTERN3 };
-
-/*
- * Configure GPIO pin as external interrupt source.
- */
-int ks8695_gpio_interrupt(unsigned int pin, unsigned int type)
-{
-       unsigned long x, flags;
-
-       if (pin > KS8695_GPIO_3)        /* only GPIO 0..3 can generate IRQ */
-               return -EINVAL;
-
-       local_irq_save(flags);
-
-       /* set pin as input */
-       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
-       x &= ~IOPM(pin);
-       __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
-
-       local_irq_restore(flags);
-
-       /* Set IRQ triggering type */
-       irq_set_irq_type(gpio_irq[pin], type);
-
-       /* enable interrupt mode */
-       ks8695_gpio_mode(pin, 0);
-
-       return 0;
-}
-EXPORT_SYMBOL(ks8695_gpio_interrupt);
-
-
-
-/* .... Generic GPIO interface .............................................. */
-
-/*
- * Configure the GPIO line as an input.
- */
-static int ks8695_gpio_direction_input(struct gpio_chip *gc, unsigned int pin)
-{
-       unsigned long x, flags;
-
-       if (pin > KS8695_GPIO_15)
-               return -EINVAL;
-
-       /* set pin to GPIO mode */
-       ks8695_gpio_mode(pin, 1);
-
-       local_irq_save(flags);
-
-       /* set pin as input */
-       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
-       x &= ~IOPM(pin);
-       __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
-
-       local_irq_restore(flags);
-
-       return 0;
-}
-
-
-/*
- * Configure the GPIO line as an output, with default state.
- */
-static int ks8695_gpio_direction_output(struct gpio_chip *gc,
-                                       unsigned int pin, int state)
-{
-       unsigned long x, flags;
-
-       if (pin > KS8695_GPIO_15)
-               return -EINVAL;
-
-       /* set pin to GPIO mode */
-       ks8695_gpio_mode(pin, 1);
-
-       local_irq_save(flags);
-
-       /* set line state */
-       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
-       if (state)
-               x |= IOPD(pin);
-       else
-               x &= ~IOPD(pin);
-       __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
-
-       /* set pin as output */
-       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
-       x |= IOPM(pin);
-       __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPM);
-
-       local_irq_restore(flags);
-
-       return 0;
-}
-
-
-/*
- * Set the state of an output GPIO line.
- */
-static void ks8695_gpio_set_value(struct gpio_chip *gc,
-                                 unsigned int pin, int state)
-{
-       unsigned long x, flags;
-
-       if (pin > KS8695_GPIO_15)
-               return;
-
-       local_irq_save(flags);
-
-       /* set output line state */
-       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
-       if (state)
-               x |= IOPD(pin);
-       else
-               x &= ~IOPD(pin);
-       __raw_writel(x, KS8695_GPIO_VA + KS8695_IOPD);
-
-       local_irq_restore(flags);
-}
-
-
-/*
- * Read the state of a GPIO line.
- */
-static int ks8695_gpio_get_value(struct gpio_chip *gc, unsigned int pin)
-{
-       unsigned long x;
-
-       if (pin > KS8695_GPIO_15)
-               return -EINVAL;
-
-       x = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
-       return (x & IOPD(pin)) != 0;
-}
-
-
-/*
- * Map GPIO line to IRQ number.
- */
-static int ks8695_gpio_to_irq(struct gpio_chip *gc, unsigned int pin)
-{
-       if (pin > KS8695_GPIO_3)        /* only GPIO 0..3 can generate IRQ */
-               return -EINVAL;
-
-       return gpio_irq[pin];
-}
-
-/* GPIOLIB interface */
-
-static struct gpio_chip ks8695_gpio_chip = {
-       .label                  = "KS8695",
-       .direction_input        = ks8695_gpio_direction_input,
-       .direction_output       = ks8695_gpio_direction_output,
-       .get                    = ks8695_gpio_get_value,
-       .set                    = ks8695_gpio_set_value,
-       .to_irq                 = ks8695_gpio_to_irq,
-       .base                   = 0,
-       .ngpio                  = 16,
-       .can_sleep              = false,
-};
-
-/* Register the GPIOs */
-void ks8695_register_gpios(void)
-{
-       if (gpiochip_add_data(&ks8695_gpio_chip, NULL))
-               printk(KERN_ERR "Unable to register core GPIOs\n");
-}
-
-/* .... Debug interface ..................................................... */
-
-#ifdef CONFIG_DEBUG_FS
-
-static int ks8695_gpio_show(struct seq_file *s, void *unused)
-{
-       unsigned int enable[] = { IOPC_IOEINT0EN, IOPC_IOEINT1EN, IOPC_IOEINT2EN, IOPC_IOEINT3EN, IOPC_IOTIM0EN, IOPC_IOTIM1EN };
-       unsigned int intmask[] = { IOPC_IOEINT0TM, IOPC_IOEINT1TM, IOPC_IOEINT2TM, IOPC_IOEINT3TM };
-       unsigned long mode, ctrl, data;
-       int i;
-
-       mode = __raw_readl(KS8695_GPIO_VA + KS8695_IOPM);
-       ctrl = __raw_readl(KS8695_GPIO_VA + KS8695_IOPC);
-       data = __raw_readl(KS8695_GPIO_VA + KS8695_IOPD);
-
-       seq_printf(s, "Pin\tI/O\tFunction\tState\n\n");
-
-       for (i = KS8695_GPIO_0; i <= KS8695_GPIO_15 ; i++) {
-               seq_printf(s, "%i:\t", i);
-
-               seq_printf(s, "%s\t", (mode & IOPM(i)) ? "Output" : "Input");
-
-               if (i <= KS8695_GPIO_3) {
-                       if (ctrl & enable[i]) {
-                               seq_printf(s, "EXT%i ", i);
-
-                               switch ((ctrl & intmask[i]) >> (4 * i)) {
-                               case IOPC_TM_LOW:
-                                       seq_printf(s, "(Low)");         break;
-                               case IOPC_TM_HIGH:
-                                       seq_printf(s, "(High)");        break;
-                               case IOPC_TM_RISING:
-                                       seq_printf(s, "(Rising)");      break;
-                               case IOPC_TM_FALLING:
-                                       seq_printf(s, "(Falling)");     break;
-                               case IOPC_TM_EDGE:
-                                       seq_printf(s, "(Edges)");       break;
-                               }
-                       } else
-                               seq_printf(s, "GPIO\t");
-               } else if (i <= KS8695_GPIO_5) {
-                       if (ctrl & enable[i])
-                               seq_printf(s, "TOUT%i\t", i - KS8695_GPIO_4);
-                       else
-                               seq_printf(s, "GPIO\t");
-               } else {
-                       seq_printf(s, "GPIO\t");
-               }
-
-               seq_printf(s, "\t");
-
-               seq_printf(s, "%i\n", (data & IOPD(i)) ? 1 : 0);
-       }
-       return 0;
-}
-
-DEFINE_SHOW_ATTRIBUTE(ks8695_gpio);
-
-static int __init ks8695_gpio_debugfs_init(void)
-{
-       /* /sys/kernel/debug/ks8695_gpio */
-       debugfs_create_file("ks8695_gpio", S_IFREG | S_IRUGO, NULL, NULL,
-                               &ks8695_gpio_fops);
-       return 0;
-}
-postcore_initcall(ks8695_gpio_debugfs_init);
-
-#endif
index 24885b3..4e626c4 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/module.h>
 
-#include <mach/hardware.h>
-#include <mach/platform.h>
-
-#define LPC32XX_GPIO_P3_INP_STATE              _GPREG(0x000)
-#define LPC32XX_GPIO_P3_OUTP_SET               _GPREG(0x004)
-#define LPC32XX_GPIO_P3_OUTP_CLR               _GPREG(0x008)
-#define LPC32XX_GPIO_P3_OUTP_STATE             _GPREG(0x00C)
-#define LPC32XX_GPIO_P2_DIR_SET                        _GPREG(0x010)
-#define LPC32XX_GPIO_P2_DIR_CLR                        _GPREG(0x014)
-#define LPC32XX_GPIO_P2_DIR_STATE              _GPREG(0x018)
-#define LPC32XX_GPIO_P2_INP_STATE              _GPREG(0x01C)
-#define LPC32XX_GPIO_P2_OUTP_SET               _GPREG(0x020)
-#define LPC32XX_GPIO_P2_OUTP_CLR               _GPREG(0x024)
-#define LPC32XX_GPIO_P2_MUX_SET                        _GPREG(0x028)
-#define LPC32XX_GPIO_P2_MUX_CLR                        _GPREG(0x02C)
-#define LPC32XX_GPIO_P2_MUX_STATE              _GPREG(0x030)
-#define LPC32XX_GPIO_P0_INP_STATE              _GPREG(0x040)
-#define LPC32XX_GPIO_P0_OUTP_SET               _GPREG(0x044)
-#define LPC32XX_GPIO_P0_OUTP_CLR               _GPREG(0x048)
-#define LPC32XX_GPIO_P0_OUTP_STATE             _GPREG(0x04C)
-#define LPC32XX_GPIO_P0_DIR_SET                        _GPREG(0x050)
-#define LPC32XX_GPIO_P0_DIR_CLR                        _GPREG(0x054)
-#define LPC32XX_GPIO_P0_DIR_STATE              _GPREG(0x058)
-#define LPC32XX_GPIO_P1_INP_STATE              _GPREG(0x060)
-#define LPC32XX_GPIO_P1_OUTP_SET               _GPREG(0x064)
-#define LPC32XX_GPIO_P1_OUTP_CLR               _GPREG(0x068)
-#define LPC32XX_GPIO_P1_OUTP_STATE             _GPREG(0x06C)
-#define LPC32XX_GPIO_P1_DIR_SET                        _GPREG(0x070)
-#define LPC32XX_GPIO_P1_DIR_CLR                        _GPREG(0x074)
-#define LPC32XX_GPIO_P1_DIR_STATE              _GPREG(0x078)
+#define LPC32XX_GPIO_P3_INP_STATE              (0x000)
+#define LPC32XX_GPIO_P3_OUTP_SET               (0x004)
+#define LPC32XX_GPIO_P3_OUTP_CLR               (0x008)
+#define LPC32XX_GPIO_P3_OUTP_STATE             (0x00C)
+#define LPC32XX_GPIO_P2_DIR_SET                        (0x010)
+#define LPC32XX_GPIO_P2_DIR_CLR                        (0x014)
+#define LPC32XX_GPIO_P2_DIR_STATE              (0x018)
+#define LPC32XX_GPIO_P2_INP_STATE              (0x01C)
+#define LPC32XX_GPIO_P2_OUTP_SET               (0x020)
+#define LPC32XX_GPIO_P2_OUTP_CLR               (0x024)
+#define LPC32XX_GPIO_P2_MUX_SET                        (0x028)
+#define LPC32XX_GPIO_P2_MUX_CLR                        (0x02C)
+#define LPC32XX_GPIO_P2_MUX_STATE              (0x030)
+#define LPC32XX_GPIO_P0_INP_STATE              (0x040)
+#define LPC32XX_GPIO_P0_OUTP_SET               (0x044)
+#define LPC32XX_GPIO_P0_OUTP_CLR               (0x048)
+#define LPC32XX_GPIO_P0_OUTP_STATE             (0x04C)
+#define LPC32XX_GPIO_P0_DIR_SET                        (0x050)
+#define LPC32XX_GPIO_P0_DIR_CLR                        (0x054)
+#define LPC32XX_GPIO_P0_DIR_STATE              (0x058)
+#define LPC32XX_GPIO_P1_INP_STATE              (0x060)
+#define LPC32XX_GPIO_P1_OUTP_SET               (0x064)
+#define LPC32XX_GPIO_P1_OUTP_CLR               (0x068)
+#define LPC32XX_GPIO_P1_OUTP_STATE             (0x06C)
+#define LPC32XX_GPIO_P1_DIR_SET                        (0x070)
+#define LPC32XX_GPIO_P1_DIR_CLR                        (0x074)
+#define LPC32XX_GPIO_P1_DIR_STATE              (0x078)
 
 #define GPIO012_PIN_TO_BIT(x)                  (1 << (x))
 #define GPIO3_PIN_TO_BIT(x)                    (1 << ((x) + 25))
 #define LPC32XX_GPO_P3_GRP     (LPC32XX_GPI_P3_GRP + LPC32XX_GPI_P3_MAX)
 
 struct gpio_regs {
-       void __iomem *inp_state;
-       void __iomem *outp_state;
-       void __iomem *outp_set;
-       void __iomem *outp_clr;
-       void __iomem *dir_set;
-       void __iomem *dir_clr;
+       unsigned long inp_state;
+       unsigned long outp_state;
+       unsigned long outp_set;
+       unsigned long outp_clr;
+       unsigned long dir_set;
+       unsigned long dir_clr;
 };
 
 /*
@@ -165,16 +162,27 @@ static struct gpio_regs gpio_grp_regs_p3 = {
 struct lpc32xx_gpio_chip {
        struct gpio_chip        chip;
        struct gpio_regs        *gpio_grp;
+       void __iomem            *reg_base;
 };
 
+static inline u32 gpreg_read(struct lpc32xx_gpio_chip *group, unsigned long offset)
+{
+       return __raw_readl(group->reg_base + offset);
+}
+
+static inline void gpreg_write(struct lpc32xx_gpio_chip *group, u32 val, unsigned long offset)
+{
+       __raw_writel(val, group->reg_base + offset);
+}
+
 static void __set_gpio_dir_p012(struct lpc32xx_gpio_chip *group,
        unsigned pin, int input)
 {
        if (input)
-               __raw_writel(GPIO012_PIN_TO_BIT(pin),
+               gpreg_write(group, GPIO012_PIN_TO_BIT(pin),
                        group->gpio_grp->dir_clr);
        else
-               __raw_writel(GPIO012_PIN_TO_BIT(pin),
+               gpreg_write(group, GPIO012_PIN_TO_BIT(pin),
                        group->gpio_grp->dir_set);
 }
 
@@ -184,19 +192,19 @@ static void __set_gpio_dir_p3(struct lpc32xx_gpio_chip *group,
        u32 u = GPIO3_PIN_TO_BIT(pin);
 
        if (input)
-               __raw_writel(u, group->gpio_grp->dir_clr);
+               gpreg_write(group, u, group->gpio_grp->dir_clr);
        else
-               __raw_writel(u, group->gpio_grp->dir_set);
+               gpreg_write(group, u, group->gpio_grp->dir_set);
 }
 
 static void __set_gpio_level_p012(struct lpc32xx_gpio_chip *group,
        unsigned pin, int high)
 {
        if (high)
-               __raw_writel(GPIO012_PIN_TO_BIT(pin),
+               gpreg_write(group, GPIO012_PIN_TO_BIT(pin),
                        group->gpio_grp->outp_set);
        else
-               __raw_writel(GPIO012_PIN_TO_BIT(pin),
+               gpreg_write(group, GPIO012_PIN_TO_BIT(pin),
                        group->gpio_grp->outp_clr);
 }
 
@@ -206,31 +214,31 @@ static void __set_gpio_level_p3(struct lpc32xx_gpio_chip *group,
        u32 u = GPIO3_PIN_TO_BIT(pin);
 
        if (high)
-               __raw_writel(u, group->gpio_grp->outp_set);
+               gpreg_write(group, u, group->gpio_grp->outp_set);
        else
-               __raw_writel(u, group->gpio_grp->outp_clr);
+               gpreg_write(group, u, group->gpio_grp->outp_clr);
 }
 
 static void __set_gpo_level_p3(struct lpc32xx_gpio_chip *group,
        unsigned pin, int high)
 {
        if (high)
-               __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set);
+               gpreg_write(group, GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_set);
        else
-               __raw_writel(GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr);
+               gpreg_write(group, GPO3_PIN_TO_BIT(pin), group->gpio_grp->outp_clr);
 }
 
 static int __get_gpio_state_p012(struct lpc32xx_gpio_chip *group,
        unsigned pin)
 {
-       return GPIO012_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state),
+       return GPIO012_PIN_IN_SEL(gpreg_read(group, group->gpio_grp->inp_state),
                pin);
 }
 
 static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group,
        unsigned pin)
 {
-       int state = __raw_readl(group->gpio_grp->inp_state);
+       int state = gpreg_read(group, group->gpio_grp->inp_state);
 
        /*
         * P3 GPIO pin input mapping is not contiguous, GPIOP3-0..4 is mapped
@@ -242,13 +250,13 @@ static int __get_gpio_state_p3(struct lpc32xx_gpio_chip *group,
 static int __get_gpi_state_p3(struct lpc32xx_gpio_chip *group,
        unsigned pin)
 {
-       return GPI3_PIN_IN_SEL(__raw_readl(group->gpio_grp->inp_state), pin);
+       return GPI3_PIN_IN_SEL(gpreg_read(group, group->gpio_grp->inp_state), pin);
 }
 
 static int __get_gpo_state_p3(struct lpc32xx_gpio_chip *group,
        unsigned pin)
 {
-       return GPO3_PIN_IN_SEL(__raw_readl(group->gpio_grp->outp_state), pin);
+       return GPO3_PIN_IN_SEL(gpreg_read(group, group->gpio_grp->outp_state), pin);
 }
 
 /*
@@ -497,12 +505,18 @@ static int lpc32xx_of_xlate(struct gpio_chip *gc,
 static int lpc32xx_gpio_probe(struct platform_device *pdev)
 {
        int i;
+       void __iomem *reg_base;
+
+       reg_base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(reg_base))
+               return PTR_ERR(reg_base);
 
        for (i = 0; i < ARRAY_SIZE(lpc32xx_gpiochip); i++) {
                if (pdev->dev.of_node) {
                        lpc32xx_gpiochip[i].chip.of_xlate = lpc32xx_of_xlate;
                        lpc32xx_gpiochip[i].chip.of_gpio_n_cells = 3;
                        lpc32xx_gpiochip[i].chip.of_node = pdev->dev.of_node;
+                       lpc32xx_gpiochip[i].reg_base = reg_base;
                }
                devm_gpiochip_add_data(&pdev->dev, &lpc32xx_gpiochip[i].chip,
                                  &lpc32xx_gpiochip[i]);
@@ -527,3 +541,7 @@ static struct platform_driver lpc32xx_gpio_driver = {
 };
 
 module_platform_driver(lpc32xx_gpio_driver);
+
+MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("GPIO driver for LPC32xx SoC");
index 31b4a09..6bb9741 100644 (file)
@@ -358,25 +358,30 @@ static int lp_gpio_probe(struct platform_device *pdev)
        gc->can_sleep = false;
        gc->parent = dev;
 
-       ret = devm_gpiochip_add_data(dev, gc, lg);
-       if (ret) {
-               dev_err(dev, "failed adding lp-gpio chip\n");
-               return ret;
-       }
-
        /* set up interrupts  */
        if (irq_rc && irq_rc->start) {
+               struct gpio_irq_chip *girq;
+
+               girq = &gc->irq;
+               girq->chip = &lp_irqchip;
+               girq->parent_handler = lp_gpio_irq_handler;
+               girq->num_parents = 1;
+               girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
+                                            sizeof(*girq->parents),
+                                            GFP_KERNEL);
+               if (!girq->parents)
+                       return -ENOMEM;
+               girq->parents[0] = (unsigned)irq_rc->start;
+               girq->default_type = IRQ_TYPE_NONE;
+               girq->handler = handle_simple_irq;
+
                lp_gpio_irq_init_hw(lg);
-               ret = gpiochip_irqchip_add(gc, &lp_irqchip, 0,
-                                          handle_simple_irq, IRQ_TYPE_NONE);
-               if (ret) {
-                       dev_err(dev, "failed to add irqchip\n");
-                       return ret;
-               }
+       }
 
-               gpiochip_set_chained_irqchip(gc, &lp_irqchip,
-                                            (unsigned)irq_rc->start,
-                                            lp_gpio_irq_handler);
+       ret = devm_gpiochip_add_data(dev, gc, lg);
+       if (ret) {
+               dev_err(dev, "failed adding lp-gpio chip\n");
+               return ret;
        }
 
        pm_runtime_enable(dev);
index 4dbc837..7086f8b 100644 (file)
@@ -120,7 +120,7 @@ static const struct gpio_chip madera_gpio_chip = {
 static int madera_gpio_probe(struct platform_device *pdev)
 {
        struct madera *madera = dev_get_drvdata(pdev->dev.parent);
-       struct madera_pdata *pdata = dev_get_platdata(madera->dev);
+       struct madera_pdata *pdata = &madera->pdata;
        struct madera_gpio *madera_gpio;
        int ret;
 
@@ -136,6 +136,9 @@ static int madera_gpio_probe(struct platform_device *pdev)
        madera_gpio->gpio_chip.parent = pdev->dev.parent;
 
        switch (madera->type) {
+       case CS47L15:
+               madera_gpio->gpio_chip.ngpio = CS47L15_NUM_GPIOS;
+               break;
        case CS47L35:
                madera_gpio->gpio_chip.ngpio = CS47L35_NUM_GPIOS;
                break;
@@ -147,13 +150,18 @@ static int madera_gpio_probe(struct platform_device *pdev)
        case CS47L91:
                madera_gpio->gpio_chip.ngpio = CS47L90_NUM_GPIOS;
                break;
+       case CS42L92:
+       case CS47L92:
+       case CS47L93:
+               madera_gpio->gpio_chip.ngpio = CS47L92_NUM_GPIOS;
+               break;
        default:
                dev_err(&pdev->dev, "Unknown chip variant %d\n", madera->type);
                return -EINVAL;
        }
 
        /* We want to be usable on systems that don't use devicetree or acpi */
-       if (pdata && pdata->gpio_base)
+       if (pdata->gpio_base)
                madera_gpio->gpio_chip.base = pdata->gpio_base;
        else
                madera_gpio->gpio_chip.base = -1;
index b7d89e3..47d05e3 100644 (file)
@@ -270,10 +270,8 @@ static int max77620_gpio_probe(struct platform_device *pdev)
        int ret;
 
        gpio_irq = platform_get_irq(pdev, 0);
-       if (gpio_irq <= 0) {
-               dev_err(&pdev->dev, "GPIO irq not available %d\n", gpio_irq);
+       if (gpio_irq <= 0)
                return -ENODEV;
-       }
 
        mgpio = devm_kzalloc(&pdev->dev, sizeof(*mgpio), GFP_KERNEL);
        if (!mgpio)
index 3f03f4e..3075f25 100644 (file)
@@ -188,3 +188,4 @@ module_platform_driver(max77650_gpio_driver);
 MODULE_DESCRIPTION("MAXIM 77650/77651 GPIO driver");
 MODULE_AUTHOR("Bartosz Golaszewski <bgolaszewski@baylibre.com>");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:max77650-gpio");
index 8f46699..501e895 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/slab.h>
 
 #include "gpiolib.h"
+#include "gpiolib-acpi.h"
 
 /*
  * Only first 8bits of a register correspond to each pin,
index 3302125..4f27ddf 100644 (file)
@@ -397,6 +397,7 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
 {
        const struct mrfld_gpio_pinrange *range;
        const char *pinctrl_dev_name;
+       struct gpio_irq_chip *girq;
        struct mrfld_gpio *priv;
        u32 gpio_base, irq_base;
        void __iomem *base;
@@ -444,6 +445,21 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
 
        raw_spin_lock_init(&priv->lock);
 
+       girq = &priv->chip.irq;
+       girq->chip = &mrfld_irqchip;
+       girq->parent_handler = mrfld_irq_handler;
+       girq->num_parents = 1;
+       girq->parents = devm_kcalloc(&pdev->dev, girq->num_parents,
+                                    sizeof(*girq->parents),
+                                    GFP_KERNEL);
+       if (!girq->parents)
+               return -ENOMEM;
+       girq->parents[0] = pdev->irq;
+       girq->default_type = IRQ_TYPE_NONE;
+       girq->handler = handle_bad_irq;
+
+       mrfld_irq_init_hw(priv);
+
        pci_set_drvdata(pdev, priv);
        retval = devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv);
        if (retval) {
@@ -465,18 +481,6 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id
                }
        }
 
-       retval = gpiochip_irqchip_add(&priv->chip, &mrfld_irqchip, irq_base,
-                                     handle_bad_irq, IRQ_TYPE_NONE);
-       if (retval) {
-               dev_err(&pdev->dev, "could not connect irqchip to gpiochip\n");
-               return retval;
-       }
-
-       mrfld_irq_init_hw(priv);
-
-       gpiochip_set_chained_irqchip(&priv->chip, &mrfld_irqchip, pdev->irq,
-                                    mrfld_irq_handler);
-
        return 0;
 }
 
index f1a9c05..213aedc 100644 (file)
@@ -309,6 +309,7 @@ static const struct file_operations gpio_mockup_debugfs_ops = {
        .read = gpio_mockup_debugfs_read,
        .write = gpio_mockup_debugfs_write,
        .llseek = no_llseek,
+       .release = single_release,
 };
 
 static void gpio_mockup_debugfs_setup(struct device *dev,
diff --git a/drivers/gpio/gpio-moxtet.c b/drivers/gpio/gpio-moxtet.c
new file mode 100644 (file)
index 0000000..3fd7299
--- /dev/null
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  Turris Mox Moxtet GPIO expander
+ *
+ *  Copyright (C) 2018 Marek Behun <marek.behun@nic.cz>
+ */
+
+#include <linux/bitops.h>
+#include <linux/gpio/driver.h>
+#include <linux/moxtet.h>
+#include <linux/module.h>
+
+#define MOXTET_GPIO_NGPIOS     12
+#define MOXTET_GPIO_INPUTS     4
+
+struct moxtet_gpio_desc {
+       u16 in_mask;
+       u16 out_mask;
+};
+
+static const struct moxtet_gpio_desc descs[] = {
+       [TURRIS_MOX_MODULE_SFP] = {
+               .in_mask = GENMASK(2, 0),
+               .out_mask = GENMASK(5, 4),
+       },
+};
+
+struct moxtet_gpio_chip {
+       struct device                   *dev;
+       struct gpio_chip                gpio_chip;
+       const struct moxtet_gpio_desc   *desc;
+};
+
+static int moxtet_gpio_get_value(struct gpio_chip *gc, unsigned int offset)
+{
+       struct moxtet_gpio_chip *chip = gpiochip_get_data(gc);
+       int ret;
+
+       if (chip->desc->in_mask & BIT(offset)) {
+               ret = moxtet_device_read(chip->dev);
+       } else if (chip->desc->out_mask & BIT(offset)) {
+               ret = moxtet_device_written(chip->dev);
+               if (ret >= 0)
+                       ret <<= MOXTET_GPIO_INPUTS;
+       } else {
+               return -EINVAL;
+       }
+
+       if (ret < 0)
+               return ret;
+
+       return !!(ret & BIT(offset));
+}
+
+static void moxtet_gpio_set_value(struct gpio_chip *gc, unsigned int offset,
+                                 int val)
+{
+       struct moxtet_gpio_chip *chip = gpiochip_get_data(gc);
+       int state;
+
+       state = moxtet_device_written(chip->dev);
+       if (state < 0)
+               return;
+
+       offset -= MOXTET_GPIO_INPUTS;
+
+       if (val)
+               state |= BIT(offset);
+       else
+               state &= ~BIT(offset);
+
+       moxtet_device_write(chip->dev, state);
+}
+
+static int moxtet_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
+{
+       struct moxtet_gpio_chip *chip = gpiochip_get_data(gc);
+
+       /* All lines are hard wired to be either input or output, not both. */
+       if (chip->desc->in_mask & BIT(offset))
+               return 1;
+       else if (chip->desc->out_mask & BIT(offset))
+               return 0;
+       else
+               return -EINVAL;
+}
+
+static int moxtet_gpio_direction_input(struct gpio_chip *gc,
+                                      unsigned int offset)
+{
+       struct moxtet_gpio_chip *chip = gpiochip_get_data(gc);
+
+       if (chip->desc->in_mask & BIT(offset))
+               return 0;
+       else if (chip->desc->out_mask & BIT(offset))
+               return -ENOTSUPP;
+       else
+               return -EINVAL;
+}
+
+static int moxtet_gpio_direction_output(struct gpio_chip *gc,
+                                       unsigned int offset, int val)
+{
+       struct moxtet_gpio_chip *chip = gpiochip_get_data(gc);
+
+       if (chip->desc->out_mask & BIT(offset))
+               moxtet_gpio_set_value(gc, offset, val);
+       else if (chip->desc->in_mask & BIT(offset))
+               return -ENOTSUPP;
+       else
+               return -EINVAL;
+
+       return 0;
+}
+
+static int moxtet_gpio_probe(struct device *dev)
+{
+       struct moxtet_gpio_chip *chip;
+       struct device_node *nc = dev->of_node;
+       int id;
+
+       id = to_moxtet_device(dev)->id;
+
+       if (id >= ARRAY_SIZE(descs)) {
+               dev_err(dev, "%pOF Moxtet device id 0x%x is not supported by gpio-moxtet driver\n",
+                       nc, id);
+               return -ENOTSUPP;
+       }
+
+       chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+
+       chip->dev = dev;
+       chip->gpio_chip.parent = dev;
+       chip->desc = &descs[id];
+
+       dev_set_drvdata(dev, chip);
+
+       chip->gpio_chip.label = dev_name(dev);
+       chip->gpio_chip.get_direction = moxtet_gpio_get_direction;
+       chip->gpio_chip.direction_input = moxtet_gpio_direction_input;
+       chip->gpio_chip.direction_output = moxtet_gpio_direction_output;
+       chip->gpio_chip.get = moxtet_gpio_get_value;
+       chip->gpio_chip.set = moxtet_gpio_set_value;
+       chip->gpio_chip.base = -1;
+
+       chip->gpio_chip.ngpio = MOXTET_GPIO_NGPIOS;
+
+       chip->gpio_chip.can_sleep = true;
+       chip->gpio_chip.owner = THIS_MODULE;
+
+       return devm_gpiochip_add_data(dev, &chip->gpio_chip, chip);
+}
+
+static const struct of_device_id moxtet_gpio_dt_ids[] = {
+       { .compatible = "cznic,moxtet-gpio", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, moxtet_gpio_dt_ids);
+
+static const enum turris_mox_module_id moxtet_gpio_module_table[] = {
+       TURRIS_MOX_MODULE_SFP,
+       0,
+};
+
+static struct moxtet_driver moxtet_gpio_driver = {
+       .driver = {
+               .name           = "moxtet-gpio",
+               .of_match_table = moxtet_gpio_dt_ids,
+               .probe          = moxtet_gpio_probe,
+       },
+       .id_table = moxtet_gpio_module_table,
+};
+module_moxtet_driver(moxtet_gpio_driver);
+
+MODULE_AUTHOR("Marek Behun <marek.behun@nic.cz>");
+MODULE_DESCRIPTION("Turris Mox Moxtet GPIO expander");
+MODULE_LICENSE("GPL v2");
index c8673a5..16a47de 100644 (file)
@@ -32,6 +32,7 @@
 #define GPIO_IMR               0x10
 #define GPIO_ICR               0x14
 #define GPIO_ICR2              0x18
+#define GPIO_IBE               0x18
 
 struct mpc8xxx_gpio_chip {
        struct gpio_chip        gc;
@@ -45,6 +46,27 @@ struct mpc8xxx_gpio_chip {
        unsigned int irqn;
 };
 
+/* The GPIO Input Buffer Enable register(GPIO_IBE) is used to
+ * control the input enable of each individual GPIO port.
+ * When an individual GPIO port’s direction is set to
+ * input (GPIO_GPDIR[DRn=0]), the associated input enable must be
+ * set (GPIOxGPIE[IEn]=1) to propagate the port value to the GPIO
+ * Data Register.
+ */
+static int ls1028a_gpio_dir_in_init(struct gpio_chip *gc)
+{
+       unsigned long flags;
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = gpiochip_get_data(gc);
+
+       spin_lock_irqsave(&gc->bgpio_lock, flags);
+
+       gc->write_reg(mpc8xxx_gc->regs + GPIO_IBE, 0xffffffff);
+
+       spin_unlock_irqrestore(&gc->bgpio_lock, flags);
+
+       return 0;
+}
+
 /*
  * This hardware has a big endian bit assignment such that GPIO line 0 is
  * connected to bit 31, line 1 to bit 30 ... line 31 to bit 0.
@@ -261,6 +283,7 @@ static const struct irq_domain_ops mpc8xxx_gpio_irq_ops = {
 };
 
 struct mpc8xxx_gpio_devtype {
+       int (*gpio_dir_in_init)(struct gpio_chip *chip);
        int (*gpio_dir_out)(struct gpio_chip *, unsigned int, int);
        int (*gpio_get)(struct gpio_chip *, unsigned int);
        int (*irq_set_type)(struct irq_data *, unsigned int);
@@ -271,6 +294,10 @@ static const struct mpc8xxx_gpio_devtype mpc512x_gpio_devtype = {
        .irq_set_type = mpc512x_irq_set_type,
 };
 
+static const struct mpc8xxx_gpio_devtype ls1028a_gpio_devtype = {
+       .gpio_dir_in_init = ls1028a_gpio_dir_in_init,
+};
+
 static const struct mpc8xxx_gpio_devtype mpc5125_gpio_devtype = {
        .gpio_dir_out = mpc5125_gpio_dir_out,
        .irq_set_type = mpc512x_irq_set_type,
@@ -291,6 +318,8 @@ static const struct of_device_id mpc8xxx_gpio_ids[] = {
        { .compatible = "fsl,mpc5121-gpio", .data = &mpc512x_gpio_devtype, },
        { .compatible = "fsl,mpc5125-gpio", .data = &mpc5125_gpio_devtype, },
        { .compatible = "fsl,pq3-gpio",     },
+       { .compatible = "fsl,ls1028a-gpio", .data = &ls1028a_gpio_devtype, },
+       { .compatible = "fsl,ls1088a-gpio", .data = &ls1028a_gpio_devtype, },
        { .compatible = "fsl,qoriq-gpio",   },
        {}
 };
@@ -376,6 +405,9 @@ static int mpc8xxx_probe(struct platform_device *pdev)
        /* ack and mask all irqs */
        gc->write_reg(mpc8xxx_gc->regs + GPIO_IER, 0xffffffff);
        gc->write_reg(mpc8xxx_gc->regs + GPIO_IMR, 0);
+       /* enable input buffer  */
+       if (devtype->gpio_dir_in_init)
+               devtype->gpio_dir_in_init(gc);
 
        irq_set_chained_handler_and_data(mpc8xxx_gc->irqn,
                                         mpc8xxx_gpio_irq_cascade, mpc8xxx_gc);
index 79654fb..d1d785f 100644 (file)
@@ -241,13 +241,6 @@ mediatek_gpio_bank_probe(struct device *dev,
        if (!rg->chip.label)
                return -ENOMEM;
 
-       ret = devm_gpiochip_add_data(dev, &rg->chip, mtk);
-       if (ret < 0) {
-               dev_err(dev, "Could not register gpio %d, ret=%d\n",
-                       rg->chip.ngpio, ret);
-               return ret;
-       }
-
        rg->irq_chip.name = dev_name(dev);
        rg->irq_chip.parent_device = dev;
        rg->irq_chip.irq_unmask = mediatek_gpio_irq_unmask;
@@ -256,8 +249,10 @@ mediatek_gpio_bank_probe(struct device *dev,
        rg->irq_chip.irq_set_type = mediatek_gpio_irq_type;
 
        if (mtk->gpio_irq) {
+               struct gpio_irq_chip *girq;
+
                /*
-                * Manually request the irq here instead of passing
+                * Directly request the irq here instead of passing
                 * a flow-handler to gpiochip_set_chained_irqchip,
                 * because the irq is shared.
                 */
@@ -271,15 +266,21 @@ mediatek_gpio_bank_probe(struct device *dev,
                        return ret;
                }
 
-               ret = gpiochip_irqchip_add(&rg->chip, &rg->irq_chip,
-                                          0, handle_simple_irq, IRQ_TYPE_NONE);
-               if (ret) {
-                       dev_err(dev, "failed to add gpiochip_irqchip\n");
-                       return ret;
-               }
+               girq = &rg->chip.irq;
+               girq->chip = &rg->irq_chip;
+               /* This will let us handle the parent IRQ in the driver */
+               girq->parent_handler = NULL;
+               girq->num_parents = 0;
+               girq->parents = NULL;
+               girq->default_type = IRQ_TYPE_NONE;
+               girq->handler = handle_simple_irq;
+       }
 
-               gpiochip_set_chained_irqchip(&rg->chip, &rg->irq_chip,
-                                            mtk->gpio_irq, NULL);
+       ret = devm_gpiochip_add_data(dev, &rg->chip, mtk);
+       if (ret < 0) {
+               dev_err(dev, "Could not register gpio %d, ret=%d\n",
+                       rg->chip.ngpio, ret);
+               return ret;
        }
 
        /* set polarity to low for all gpios */
index b281358..7907a87 100644 (file)
@@ -435,12 +435,9 @@ static int mxc_gpio_probe(struct platform_device *pdev)
                return port->irq;
 
        /* the controller clock is optional */
-       port->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(port->clk)) {
-               if (PTR_ERR(port->clk) == -EPROBE_DEFER)
-                       return -EPROBE_DEFER;
-               port->clk = NULL;
-       }
+       port->clk = devm_clk_get_optional(&pdev->dev, NULL);
+       if (IS_ERR(port->clk))
+               return PTR_ERR(port->clk);
 
        err = clk_prepare_enable(port->clk);
        if (err) {
index 378b206..de5d138 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/bits.h>
 #include <linux/gpio/driver.h>
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
@@ -28,9 +29,9 @@
 #define PCA953X_INVERT         0x02
 #define PCA953X_DIRECTION      0x03
 
-#define REG_ADDR_MASK          0x3f
-#define REG_ADDR_EXT           0x40
-#define REG_ADDR_AI            0x80
+#define REG_ADDR_MASK          GENMASK(5, 0)
+#define REG_ADDR_EXT           BIT(6)
+#define REG_ADDR_AI            BIT(7)
 
 #define PCA957X_IN             0x00
 #define PCA957X_INVRT          0x01
 #define PCAL6524_OUT_INDCONF   0x2c
 #define PCAL6524_DEBOUNCE      0x2d
 
-#define PCA_GPIO_MASK          0x00FF
+#define PCA_GPIO_MASK          GENMASK(7, 0)
 
-#define PCAL_GPIO_MASK         0x1f
-#define PCAL_PINCTRL_MASK      0x60
+#define PCAL_GPIO_MASK         GENMASK(4, 0)
+#define PCAL_PINCTRL_MASK      GENMASK(6, 5)
 
-#define PCA_INT                        0x0100
-#define PCA_PCAL               0x0200
+#define PCA_INT                        BIT(8)
+#define PCA_PCAL               BIT(9)
 #define PCA_LATCH_INT          (PCA_PCAL | PCA_INT)
-#define PCA953X_TYPE           0x1000
-#define PCA957X_TYPE           0x2000
-#define PCA_TYPE_MASK          0xF000
+#define PCA953X_TYPE           BIT(12)
+#define PCA957X_TYPE           BIT(13)
+#define PCA_TYPE_MASK          GENMASK(15, 12)
 
 #define PCA_CHIP_TYPE(x)       ((x) & PCA_TYPE_MASK)
 
@@ -565,7 +566,7 @@ static void pca953x_irq_mask(struct irq_data *d)
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct pca953x_chip *chip = gpiochip_get_data(gc);
 
-       chip->irq_mask[d->hwirq / BANK_SZ] &= ~(1 << (d->hwirq % BANK_SZ));
+       chip->irq_mask[d->hwirq / BANK_SZ] &= ~BIT(d->hwirq % BANK_SZ);
 }
 
 static void pca953x_irq_unmask(struct irq_data *d)
@@ -573,7 +574,7 @@ static void pca953x_irq_unmask(struct irq_data *d)
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct pca953x_chip *chip = gpiochip_get_data(gc);
 
-       chip->irq_mask[d->hwirq / BANK_SZ] |= 1 << (d->hwirq % BANK_SZ);
+       chip->irq_mask[d->hwirq / BANK_SZ] |= BIT(d->hwirq % BANK_SZ);
 }
 
 static int pca953x_irq_set_wake(struct irq_data *d, unsigned int on)
@@ -604,10 +605,9 @@ static void pca953x_irq_bus_sync_unlock(struct irq_data *d)
        u8 new_irqs;
        int level, i;
        u8 invert_irq_mask[MAX_BANK];
-       int reg_direction[MAX_BANK];
+       u8 reg_direction[MAX_BANK];
 
-       regmap_bulk_read(chip->regmap, chip->regs->direction, reg_direction,
-                        NBANK(chip));
+       pca953x_read_regs(chip, chip->regs->direction, reg_direction);
 
        if (chip->driver_data & PCA_PCAL) {
                /* Enable latch on interrupt-enabled inputs */
@@ -641,7 +641,7 @@ static int pca953x_irq_set_type(struct irq_data *d, unsigned int type)
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct pca953x_chip *chip = gpiochip_get_data(gc);
        int bank_nb = d->hwirq / BANK_SZ;
-       u8 mask = 1 << (d->hwirq % BANK_SZ);
+       u8 mask = BIT(d->hwirq % BANK_SZ);
 
        if (!(type & IRQ_TYPE_EDGE_BOTH)) {
                dev_err(&chip->client->dev, "irq %d: unsupported type %d\n",
@@ -666,7 +666,7 @@ static void pca953x_irq_shutdown(struct irq_data *d)
 {
        struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
        struct pca953x_chip *chip = gpiochip_get_data(gc);
-       u8 mask = 1 << (d->hwirq % BANK_SZ);
+       u8 mask = BIT(d->hwirq % BANK_SZ);
 
        chip->irq_trig_raise[d->hwirq / BANK_SZ] &= ~mask;
        chip->irq_trig_fall[d->hwirq / BANK_SZ] &= ~mask;
@@ -679,7 +679,7 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
        bool pending_seen = false;
        bool trigger_seen = false;
        u8 trigger[MAX_BANK];
-       int reg_direction[MAX_BANK];
+       u8 reg_direction[MAX_BANK];
        int ret, i;
 
        if (chip->driver_data & PCA_PCAL) {
@@ -710,8 +710,7 @@ static bool pca953x_irq_pending(struct pca953x_chip *chip, u8 *pending)
                return false;
 
        /* Remove output pins from the equation */
-       regmap_bulk_read(chip->regmap, chip->regs->direction, reg_direction,
-                        NBANK(chip));
+       pca953x_read_regs(chip, chip->regs->direction, reg_direction);
        for (i = 0; i < NBANK(chip); i++)
                cur_stat[i] &= reg_direction[i];
 
@@ -768,7 +767,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
 {
        struct i2c_client *client = chip->client;
        struct irq_chip *irq_chip = &chip->irq_chip;
-       int reg_direction[MAX_BANK];
+       u8 reg_direction[MAX_BANK];
        int ret, i;
 
        if (!client->irq)
@@ -789,8 +788,7 @@ static int pca953x_irq_setup(struct pca953x_chip *chip,
         * interrupt.  We have to rely on the previous read for
         * this purpose.
         */
-       regmap_bulk_read(chip->regmap, chip->regs->direction, reg_direction,
-                        NBANK(chip));
+       pca953x_read_regs(chip, chip->regs->direction, reg_direction);
        for (i = 0; i < NBANK(chip); i++)
                chip->irq_stat[i] &= reg_direction[i];
        mutex_init(&chip->irq_lock);
@@ -849,12 +847,12 @@ static int device_pca95xx_init(struct pca953x_chip *chip, u32 invert)
 
        ret = regcache_sync_region(chip->regmap, chip->regs->output,
                                   chip->regs->output + NBANK(chip));
-       if (ret != 0)
+       if (ret)
                goto out;
 
        ret = regcache_sync_region(chip->regmap, chip->regs->direction,
                                   chip->regs->direction + NBANK(chip));
-       if (ret != 0)
+       if (ret)
                goto out;
 
        /* set platform specific polarity inversion */
@@ -949,19 +947,15 @@ static int pca953x_probe(struct i2c_client *client,
        if (i2c_id) {
                chip->driver_data = i2c_id->driver_data;
        } else {
-               const struct acpi_device_id *acpi_id;
-               struct device *dev = &client->dev;
-
-               chip->driver_data = (uintptr_t)of_device_get_match_data(dev);
-               if (!chip->driver_data) {
-                       acpi_id = acpi_match_device(pca953x_acpi_ids, dev);
-                       if (!acpi_id) {
-                               ret = -ENODEV;
-                               goto err_exit;
-                       }
-
-                       chip->driver_data = acpi_id->driver_data;
+               const void *match;
+
+               match = device_get_match_data(&client->dev);
+               if (!match) {
+                       ret = -ENODEV;
+                       goto err_exit;
                }
+
+               chip->driver_data = (uintptr_t)match;
        }
 
        i2c_set_clientdata(client, chip);
@@ -1041,8 +1035,7 @@ static int pca953x_remove(struct i2c_client *client)
                ret = pdata->teardown(client, chip->gpio_chip.base,
                                chip->gpio_chip.ngpio, pdata->context);
                if (ret < 0)
-                       dev_err(&client->dev, "%s failed, %d\n",
-                                       "teardown", ret);
+                       dev_err(&client->dev, "teardown failed, %d\n", ret);
        } else {
                ret = 0;
        }
@@ -1064,14 +1057,14 @@ static int pca953x_regcache_sync(struct device *dev)
         */
        ret = regcache_sync_region(chip->regmap, chip->regs->direction,
                                   chip->regs->direction + NBANK(chip));
-       if (ret != 0) {
+       if (ret) {
                dev_err(dev, "Failed to sync GPIO dir registers: %d\n", ret);
                return ret;
        }
 
        ret = regcache_sync_region(chip->regmap, chip->regs->output,
                                   chip->regs->output + NBANK(chip));
-       if (ret != 0) {
+       if (ret) {
                dev_err(dev, "Failed to sync GPIO out registers: %d\n", ret);
                return ret;
        }
@@ -1080,7 +1073,7 @@ static int pca953x_regcache_sync(struct device *dev)
        if (chip->driver_data & PCA_PCAL) {
                ret = regcache_sync_region(chip->regmap, PCAL953X_IN_LATCH,
                                           PCAL953X_IN_LATCH + NBANK(chip));
-               if (ret != 0) {
+               if (ret) {
                        dev_err(dev, "Failed to sync INT latch registers: %d\n",
                                ret);
                        return ret;
@@ -1088,7 +1081,7 @@ static int pca953x_regcache_sync(struct device *dev)
 
                ret = regcache_sync_region(chip->regmap, PCAL953X_INT_MASK,
                                           PCAL953X_INT_MASK + NBANK(chip));
-               if (ret != 0) {
+               if (ret) {
                        dev_err(dev, "Failed to sync INT mask registers: %d\n",
                                ret);
                        return ret;
@@ -1120,7 +1113,7 @@ static int pca953x_resume(struct device *dev)
 
        if (!atomic_read(&chip->wakeup_path)) {
                ret = regulator_enable(chip->regulator);
-               if (ret != 0) {
+               if (ret) {
                        dev_err(dev, "Failed to enable regulator: %d\n", ret);
                        return 0;
                }
@@ -1133,7 +1126,7 @@ static int pca953x_resume(struct device *dev)
                return ret;
 
        ret = regcache_sync(chip->regmap);
-       if (ret != 0) {
+       if (ret) {
                dev_err(dev, "Failed to restore register map: %d\n", ret);
                return ret;
        }
index 1d99293..3f3d9a9 100644 (file)
@@ -409,8 +409,7 @@ static int pch_gpio_probe(struct pci_dev *pdev,
 
 static int __maybe_unused pch_gpio_suspend(struct device *dev)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct pch_gpio *chip = pci_get_drvdata(pdev);
+       struct pch_gpio *chip = dev_get_drvdata(dev);
        unsigned long flags;
 
        spin_lock_irqsave(&chip->spinlock, flags);
@@ -422,8 +421,7 @@ static int __maybe_unused pch_gpio_suspend(struct device *dev)
 
 static int __maybe_unused pch_gpio_resume(struct device *dev)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct pch_gpio *chip = pci_get_drvdata(pdev);
+       struct pch_gpio *chip = dev_get_drvdata(dev);
        unsigned long flags;
 
        spin_lock_irqsave(&chip->spinlock, flags);
index 24228cf..05000ca 100644 (file)
@@ -305,10 +305,8 @@ static int sprd_pmic_eic_probe(struct platform_device *pdev)
        mutex_init(&pmic_eic->buslock);
 
        pmic_eic->irq = platform_get_irq(pdev, 0);
-       if (pmic_eic->irq < 0) {
-               dev_err(&pdev->dev, "Failed to get PMIC EIC interrupt.\n");
+       if (pmic_eic->irq < 0)
                return pmic_eic->irq;
-       }
 
        pmic_eic->map = dev_get_regmap(pdev->dev.parent, NULL);
        if (!pmic_eic->map)
index f5c8b3a..d7314d3 100644 (file)
@@ -226,10 +226,8 @@ static int sprd_gpio_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        sprd_gpio->irq = platform_get_irq(pdev, 0);
-       if (sprd_gpio->irq < 0) {
-               dev_err(&pdev->dev, "Failed to get GPIO interrupt.\n");
+       if (sprd_gpio->irq < 0)
                return sprd_gpio->irq;
-       }
 
        sprd_gpio->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(sprd_gpio->base))
index dbf9cbe..994d542 100644 (file)
@@ -429,6 +429,23 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)
        return IRQ_HANDLED;
 }
 
+static void stmpe_init_irq_valid_mask(struct gpio_chip *gc,
+                                     unsigned long *valid_mask,
+                                     unsigned int ngpios)
+{
+       struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc);
+       int i;
+
+       if (!stmpe_gpio->norequest_mask)
+               return;
+
+       /* Forbid unused lines to be mapped as IRQs */
+       for (i = 0; i < sizeof(u32); i++) {
+               if (stmpe_gpio->norequest_mask & BIT(i))
+                       clear_bit(i, valid_mask);
+       }
+}
+
 static int stmpe_gpio_probe(struct platform_device *pdev)
 {
        struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
@@ -454,14 +471,21 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
        stmpe_gpio->chip.parent = &pdev->dev;
        stmpe_gpio->chip.of_node = np;
        stmpe_gpio->chip.base = -1;
+       /*
+        * REVISIT: this makes sure the valid mask gets allocated and
+        * filled in when adding the gpio_chip, but the rest of the
+        * gpio_irqchip is still filled in using the old method
+        * in gpiochip_irqchip_add_nested() so clean this up once we
+        * get the gpio_irqchip to initialize while adding the
+        * gpio_chip also for threaded irqchips.
+        */
+       stmpe_gpio->chip.irq.init_valid_mask = stmpe_init_irq_valid_mask;
 
        if (IS_ENABLED(CONFIG_DEBUG_FS))
                 stmpe_gpio->chip.dbg_show = stmpe_dbg_show;
 
        of_property_read_u32(np, "st,norequest-mask",
                        &stmpe_gpio->norequest_mask);
-       if (stmpe_gpio->norequest_mask)
-               stmpe_gpio->chip.irq.need_valid_mask = true;
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
@@ -487,14 +511,6 @@ static int stmpe_gpio_probe(struct platform_device *pdev)
                        dev_err(&pdev->dev, "unable to get irq: %d\n", ret);
                        goto out_disable;
                }
-               if (stmpe_gpio->norequest_mask) {
-                       int i;
-
-                       /* Forbid unused lines to be mapped as IRQs */
-                       for (i = 0; i < sizeof(u32); i++)
-                               if (stmpe_gpio->norequest_mask & BIT(i))
-                                       clear_bit(i, stmpe_gpio->chip.irq.valid_mask);
-               }
                ret =  gpiochip_irqchip_add_nested(&stmpe_gpio->chip,
                                                   &stmpe_gpio_irq_chip,
                                                   0,
index bd1f3f7..5e37518 100644 (file)
@@ -171,10 +171,8 @@ static int tb10x_gpio_probe(struct platform_device *pdev)
                struct irq_chip_generic *gc;
 
                ret = platform_get_irq(pdev, 0);
-               if (ret < 0) {
-                       dev_err(dev, "No interrupt specified.\n");
+               if (ret < 0)
                        return ret;
-               }
 
                tb10x_gpio->gc.to_irq   = tb10x_gpio_to_irq;
                tb10x_gpio->irq         = ret;
index 0f59161..8a01d36 100644 (file)
@@ -624,10 +624,8 @@ static int tegra_gpio_probe(struct platform_device *pdev)
 
        for (i = 0; i < tgi->bank_count; i++) {
                ret = platform_get_irq(pdev, i);
-               if (ret < 0) {
-                       dev_err(&pdev->dev, "Missing IRQ resource: %d\n", ret);
+               if (ret < 0)
                        return ret;
-               }
 
                bank = &tgi->bank_info[i];
                bank->bank = i;
index 715371b..ddad5c7 100644 (file)
@@ -53,7 +53,6 @@ struct thunderx_line {
 struct thunderx_gpio {
        struct gpio_chip        chip;
        u8 __iomem              *register_base;
-       struct irq_domain       *irqd;
        struct msix_entry       *msix_entries;  /* per line MSI-X */
        struct thunderx_line    *line_entries;  /* per line irq info */
        raw_spinlock_t          lock;
@@ -283,54 +282,60 @@ static void thunderx_gpio_set_multiple(struct gpio_chip *chip,
        }
 }
 
-static void thunderx_gpio_irq_ack(struct irq_data *data)
+static void thunderx_gpio_irq_ack(struct irq_data *d)
 {
-       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
 
        writeq(GPIO_INTR_INTR,
-              txline->txgpio->register_base + intr_reg(txline->line));
+              txgpio->register_base + intr_reg(irqd_to_hwirq(d)));
 }
 
-static void thunderx_gpio_irq_mask(struct irq_data *data)
+static void thunderx_gpio_irq_mask(struct irq_data *d)
 {
-       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
 
        writeq(GPIO_INTR_ENA_W1C,
-              txline->txgpio->register_base + intr_reg(txline->line));
+              txgpio->register_base + intr_reg(irqd_to_hwirq(d)));
 }
 
-static void thunderx_gpio_irq_mask_ack(struct irq_data *data)
+static void thunderx_gpio_irq_mask_ack(struct irq_data *d)
 {
-       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
 
        writeq(GPIO_INTR_ENA_W1C | GPIO_INTR_INTR,
-              txline->txgpio->register_base + intr_reg(txline->line));
+              txgpio->register_base + intr_reg(irqd_to_hwirq(d)));
 }
 
-static void thunderx_gpio_irq_unmask(struct irq_data *data)
+static void thunderx_gpio_irq_unmask(struct irq_data *d)
 {
-       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
 
        writeq(GPIO_INTR_ENA_W1S,
-              txline->txgpio->register_base + intr_reg(txline->line));
+              txgpio->register_base + intr_reg(irqd_to_hwirq(d)));
 }
 
-static int thunderx_gpio_irq_set_type(struct irq_data *data,
+static int thunderx_gpio_irq_set_type(struct irq_data *d,
                                      unsigned int flow_type)
 {
-       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
-       struct thunderx_gpio *txgpio = txline->txgpio;
+       struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+       struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
+       struct thunderx_line *txline =
+               &txgpio->line_entries[irqd_to_hwirq(d)];
        u64 bit_cfg;
 
-       irqd_set_trigger_type(data, flow_type);
+       irqd_set_trigger_type(d, flow_type);
 
        bit_cfg = txline->fil_bits | GPIO_BIT_CFG_INT_EN;
 
        if (flow_type & IRQ_TYPE_EDGE_BOTH) {
-               irq_set_handler_locked(data, handle_fasteoi_ack_irq);
+               irq_set_handler_locked(d, handle_fasteoi_ack_irq);
                bit_cfg |= GPIO_BIT_CFG_INT_TYPE;
        } else {
-               irq_set_handler_locked(data, handle_fasteoi_mask_irq);
+               irq_set_handler_locked(d, handle_fasteoi_mask_irq);
        }
 
        raw_spin_lock(&txgpio->lock);
@@ -359,33 +364,6 @@ static void thunderx_gpio_irq_disable(struct irq_data *data)
        irq_chip_disable_parent(data);
 }
 
-static int thunderx_gpio_irq_request_resources(struct irq_data *data)
-{
-       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
-       struct thunderx_gpio *txgpio = txline->txgpio;
-       int r;
-
-       r = gpiochip_lock_as_irq(&txgpio->chip, txline->line);
-       if (r)
-               return r;
-
-       r = irq_chip_request_resources_parent(data);
-       if (r)
-               gpiochip_unlock_as_irq(&txgpio->chip, txline->line);
-
-       return r;
-}
-
-static void thunderx_gpio_irq_release_resources(struct irq_data *data)
-{
-       struct thunderx_line *txline = irq_data_get_irq_chip_data(data);
-       struct thunderx_gpio *txgpio = txline->txgpio;
-
-       irq_chip_release_resources_parent(data);
-
-       gpiochip_unlock_as_irq(&txgpio->chip, txline->line);
-}
-
 /*
  * Interrupts are chained from underlying MSI-X vectors.  We have
  * these irq_chip functions to be able to handle level triggering
@@ -402,48 +380,22 @@ static struct irq_chip thunderx_gpio_irq_chip = {
        .irq_unmask             = thunderx_gpio_irq_unmask,
        .irq_eoi                = irq_chip_eoi_parent,
        .irq_set_affinity       = irq_chip_set_affinity_parent,
-       .irq_request_resources  = thunderx_gpio_irq_request_resources,
-       .irq_release_resources  = thunderx_gpio_irq_release_resources,
        .irq_set_type           = thunderx_gpio_irq_set_type,
 
        .flags                  = IRQCHIP_SET_TYPE_MASKED
 };
 
-static int thunderx_gpio_irq_translate(struct irq_domain *d,
-                                      struct irq_fwspec *fwspec,
-                                      irq_hw_number_t *hwirq,
-                                      unsigned int *type)
+static int thunderx_gpio_child_to_parent_hwirq(struct gpio_chip *gc,
+                                              unsigned int child,
+                                              unsigned int child_type,
+                                              unsigned int *parent,
+                                              unsigned int *parent_type)
 {
-       struct thunderx_gpio *txgpio = d->host_data;
-
-       if (WARN_ON(fwspec->param_count < 2))
-               return -EINVAL;
-       if (fwspec->param[0] >= txgpio->chip.ngpio)
-               return -EINVAL;
-       *hwirq = fwspec->param[0];
-       *type = fwspec->param[1] & IRQ_TYPE_SENSE_MASK;
-       return 0;
-}
-
-static int thunderx_gpio_irq_alloc(struct irq_domain *d, unsigned int virq,
-                                  unsigned int nr_irqs, void *arg)
-{
-       struct thunderx_line *txline = arg;
+       struct thunderx_gpio *txgpio = gpiochip_get_data(gc);
 
-       return irq_domain_set_hwirq_and_chip(d, virq, txline->line,
-                                            &thunderx_gpio_irq_chip, txline);
-}
-
-static const struct irq_domain_ops thunderx_gpio_irqd_ops = {
-       .alloc          = thunderx_gpio_irq_alloc,
-       .translate      = thunderx_gpio_irq_translate
-};
-
-static int thunderx_gpio_to_irq(struct gpio_chip *chip, unsigned int offset)
-{
-       struct thunderx_gpio *txgpio = gpiochip_get_data(chip);
-
-       return irq_find_mapping(txgpio->irqd, offset);
+       *parent = txgpio->base_msi + (2 * child);
+       *parent_type = IRQ_TYPE_LEVEL_HIGH;
+       return 0;
 }
 
 static int thunderx_gpio_probe(struct pci_dev *pdev,
@@ -453,6 +405,7 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
        struct device *dev = &pdev->dev;
        struct thunderx_gpio *txgpio;
        struct gpio_chip *chip;
+       struct gpio_irq_chip *girq;
        int ngpio, i;
        int err = 0;
 
@@ -497,8 +450,8 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
        }
 
        txgpio->msix_entries = devm_kcalloc(dev,
-                                         ngpio, sizeof(struct msix_entry),
-                                         GFP_KERNEL);
+                                           ngpio, sizeof(struct msix_entry),
+                                           GFP_KERNEL);
        if (!txgpio->msix_entries) {
                err = -ENOMEM;
                goto out;
@@ -539,27 +492,6 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
        if (err < 0)
                goto out;
 
-       /*
-        * Push GPIO specific irqdomain on hierarchy created as a side
-        * effect of the pci_enable_msix()
-        */
-       txgpio->irqd = irq_domain_create_hierarchy(irq_get_irq_data(txgpio->msix_entries[0].vector)->domain,
-                                                  0, 0, of_node_to_fwnode(dev->of_node),
-                                                  &thunderx_gpio_irqd_ops, txgpio);
-       if (!txgpio->irqd) {
-               err = -ENOMEM;
-               goto out;
-       }
-
-       /* Push on irq_data and the domain for each line. */
-       for (i = 0; i < ngpio; i++) {
-               err = irq_domain_push_irq(txgpio->irqd,
-                                         txgpio->msix_entries[i].vector,
-                                         &txgpio->line_entries[i]);
-               if (err < 0)
-                       dev_err(dev, "irq_domain_push_irq: %d\n", err);
-       }
-
        chip->label = KBUILD_MODNAME;
        chip->parent = dev;
        chip->owner = THIS_MODULE;
@@ -574,11 +506,28 @@ static int thunderx_gpio_probe(struct pci_dev *pdev,
        chip->set = thunderx_gpio_set;
        chip->set_multiple = thunderx_gpio_set_multiple;
        chip->set_config = thunderx_gpio_set_config;
-       chip->to_irq = thunderx_gpio_to_irq;
+       girq = &chip->irq;
+       girq->chip = &thunderx_gpio_irq_chip;
+       girq->fwnode = of_node_to_fwnode(dev->of_node);
+       girq->parent_domain =
+               irq_get_irq_data(txgpio->msix_entries[0].vector)->domain;
+       girq->child_to_parent_hwirq = thunderx_gpio_child_to_parent_hwirq;
+       girq->handler = handle_bad_irq;
+       girq->default_type = IRQ_TYPE_NONE;
+
        err = devm_gpiochip_add_data(dev, chip, txgpio);
        if (err)
                goto out;
 
+       /* Push on irq_data and the domain for each line. */
+       for (i = 0; i < ngpio; i++) {
+               err = irq_domain_push_irq(chip->irq.domain,
+                                         txgpio->msix_entries[i].vector,
+                                         chip);
+               if (err < 0)
+                       dev_err(dev, "irq_domain_push_irq: %d\n", err);
+       }
+
        dev_info(dev, "ThunderX GPIO: %d lines with base %d.\n",
                 ngpio, chip->base);
        return 0;
@@ -593,10 +542,10 @@ static void thunderx_gpio_remove(struct pci_dev *pdev)
        struct thunderx_gpio *txgpio = pci_get_drvdata(pdev);
 
        for (i = 0; i < txgpio->chip.ngpio; i++)
-               irq_domain_pop_irq(txgpio->irqd,
+               irq_domain_pop_irq(txgpio->chip.irq.domain,
                                   txgpio->msix_entries[i].vector);
 
-       irq_domain_remove(txgpio->irqd);
+       irq_domain_remove(txgpio->chip.irq.domain);
 
        pci_set_drvdata(pdev, NULL);
 }
index d5880db..a3109bc 100644 (file)
@@ -214,11 +214,23 @@ static const struct dev_pm_ops tqmx86_gpio_dev_pm_ops = {
                           tqmx86_gpio_runtime_resume, NULL)
 };
 
+static void tqmx86_init_irq_valid_mask(struct gpio_chip *chip,
+                                      unsigned long *valid_mask,
+                                      unsigned int ngpios)
+{
+       /* Only GPIOs 4-7 are valid for interrupts. Clear the others */
+       clear_bit(0, valid_mask);
+       clear_bit(1, valid_mask);
+       clear_bit(2, valid_mask);
+       clear_bit(3, valid_mask);
+}
+
 static int tqmx86_gpio_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct tqmx86_gpio_data *gpio;
        struct gpio_chip *chip;
+       struct gpio_irq_chip *girq;
        void __iomem *io_base;
        struct resource *res;
        int ret, irq;
@@ -259,17 +271,10 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
        chip->get = tqmx86_gpio_get;
        chip->set = tqmx86_gpio_set;
        chip->ngpio = TQMX86_NGPIO;
-       chip->irq.need_valid_mask = true;
        chip->parent = pdev->dev.parent;
 
        pm_runtime_enable(&pdev->dev);
 
-       ret = devm_gpiochip_add_data(dev, chip, gpio);
-       if (ret) {
-               dev_err(dev, "Could not register GPIO chip\n");
-               goto out_pm_dis;
-       }
-
        if (irq) {
                struct irq_chip *irq_chip = &gpio->irq_chip;
                u8 irq_status;
@@ -287,23 +292,28 @@ static int tqmx86_gpio_probe(struct platform_device *pdev)
                irq_status = tqmx86_gpio_read(gpio, TQMX86_GPIIS);
                tqmx86_gpio_write(gpio, irq_status, TQMX86_GPIIS);
 
-               ret = gpiochip_irqchip_add(chip, irq_chip,
-                                          0, handle_simple_irq,
-                                          IRQ_TYPE_EDGE_BOTH);
-               if (ret) {
-                       dev_err(dev, "Could not add irq chip\n");
+               girq = &chip->irq;
+               girq->chip = irq_chip;
+               girq->parent_handler = tqmx86_gpio_irq_handler;
+               girq->num_parents = 1;
+               girq->parents = devm_kcalloc(&pdev->dev, 1,
+                                            sizeof(*girq->parents),
+                                            GFP_KERNEL);
+               if (!girq->parents) {
+                       ret = -ENOMEM;
                        goto out_pm_dis;
                }
-
-               gpiochip_set_chained_irqchip(chip, irq_chip,
-                                            irq, tqmx86_gpio_irq_handler);
+               girq->parents[0] = irq;
+               girq->default_type = IRQ_TYPE_NONE;
+               girq->handler = handle_simple_irq;
+               girq->init_valid_mask = tqmx86_init_irq_valid_mask;
        }
 
-       /* Only GPIOs 4-7 are valid for interrupts. Clear the others */
-       clear_bit(0, chip->irq.valid_mask);
-       clear_bit(1, chip->irq.valid_mask);
-       clear_bit(2, chip->irq.valid_mask);
-       clear_bit(3, chip->irq.valid_mask);
+       ret = devm_gpiochip_add_data(dev, chip, gpio);
+       if (ret) {
+               dev_err(dev, "Could not register GPIO chip\n");
+               goto out_pm_dis;
+       }
 
        dev_info(dev, "GPIO functionality initialized with %d pins\n",
                 chip->ngpio);
index 7ba668d..58776f2 100644 (file)
@@ -243,6 +243,7 @@ static int vf610_gpio_probe(struct platform_device *pdev)
        struct device_node *np = dev->of_node;
        struct vf610_gpio_port *port;
        struct gpio_chip *gc;
+       struct gpio_irq_chip *girq;
        struct irq_chip *ic;
        int i;
        int ret;
@@ -318,10 +319,6 @@ static int vf610_gpio_probe(struct platform_device *pdev)
        ic->irq_set_type = vf610_gpio_irq_set_type;
        ic->irq_set_wake = vf610_gpio_irq_set_wake;
 
-       ret = devm_gpiochip_add_data(dev, gc, port);
-       if (ret < 0)
-               return ret;
-
        /* Mask all GPIO interrupts */
        for (i = 0; i < gc->ngpio; i++)
                vf610_gpio_writel(0, port->base + PORT_PCR(i));
@@ -329,15 +326,20 @@ static int vf610_gpio_probe(struct platform_device *pdev)
        /* Clear the interrupt status register for all GPIO's */
        vf610_gpio_writel(~0, port->base + PORT_ISFR);
 
-       ret = gpiochip_irqchip_add(gc, ic, 0, handle_edge_irq, IRQ_TYPE_NONE);
-       if (ret) {
-               dev_err(dev, "failed to add irqchip\n");
-               return ret;
-       }
-       gpiochip_set_chained_irqchip(gc, ic, port->irq,
-                                    vf610_gpio_irq_handler);
+       girq = &gc->irq;
+       girq->chip = ic;
+       girq->parent_handler = vf610_gpio_irq_handler;
+       girq->num_parents = 1;
+       girq->parents = devm_kcalloc(&pdev->dev, 1,
+                                    sizeof(*girq->parents),
+                                    GFP_KERNEL);
+       if (!girq->parents)
+               return -ENOMEM;
+       girq->parents[0] = port->irq;
+       girq->default_type = IRQ_TYPE_NONE;
+       girq->handler = handle_edge_irq;
 
-       return 0;
+       return devm_gpiochip_add_data(dev, gc, port);
 }
 
 static struct platform_driver vf610_gpio_driver = {
index 9b604f1..c301c1d 100644 (file)
@@ -79,7 +79,7 @@ MODULE_PARM_DESC(gpioa_freq,
 /* ----- begin of gipo a chip -------------------------------------------- */
 
 static int vprbrd_gpioa_get(struct gpio_chip *chip,
-               unsigned offset)
+               unsigned int offset)
 {
        int ret, answer, error = 0;
        struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
@@ -129,7 +129,7 @@ static int vprbrd_gpioa_get(struct gpio_chip *chip,
 }
 
 static void vprbrd_gpioa_set(struct gpio_chip *chip,
-               unsigned offset, int value)
+               unsigned int offset, int value)
 {
        int ret;
        struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
@@ -170,7 +170,7 @@ static void vprbrd_gpioa_set(struct gpio_chip *chip,
 }
 
 static int vprbrd_gpioa_direction_input(struct gpio_chip *chip,
-                       unsigned offset)
+                       unsigned int offset)
 {
        int ret;
        struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
@@ -207,7 +207,7 @@ static int vprbrd_gpioa_direction_input(struct gpio_chip *chip,
 }
 
 static int vprbrd_gpioa_direction_output(struct gpio_chip *chip,
-                       unsigned offset, int value)
+                       unsigned int offset, int value)
 {
        int ret;
        struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
@@ -251,8 +251,8 @@ static int vprbrd_gpioa_direction_output(struct gpio_chip *chip,
 
 /* ----- begin of gipo b chip -------------------------------------------- */
 
-static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned offset,
-       unsigned dir)
+static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned int offset,
+       unsigned int dir)
 {
        struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
        int ret;
@@ -273,7 +273,7 @@ static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned offset,
 }
 
 static int vprbrd_gpiob_get(struct gpio_chip *chip,
-               unsigned offset)
+               unsigned int offset)
 {
        int ret;
        u16 val;
@@ -305,7 +305,7 @@ static int vprbrd_gpiob_get(struct gpio_chip *chip,
 }
 
 static void vprbrd_gpiob_set(struct gpio_chip *chip,
-               unsigned offset, int value)
+               unsigned int offset, int value)
 {
        int ret;
        struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
@@ -338,7 +338,7 @@ static void vprbrd_gpiob_set(struct gpio_chip *chip,
 }
 
 static int vprbrd_gpiob_direction_input(struct gpio_chip *chip,
-                       unsigned offset)
+                       unsigned int offset)
 {
        int ret;
        struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
@@ -359,7 +359,7 @@ static int vprbrd_gpiob_direction_input(struct gpio_chip *chip,
 }
 
 static int vprbrd_gpiob_direction_output(struct gpio_chip *chip,
-                       unsigned offset, int value)
+                       unsigned int offset, int value)
 {
        int ret;
        struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
index 38c0191..25d8644 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/acpi.h>
 
 #include "gpiolib.h"
+#include "gpiolib-acpi.h"
 
 /* Common property names */
 #define XGENE_NIRQ_PROPERTY            "apm,nr-irqs"
index 54d3359..d7b16bb 100644 (file)
@@ -290,6 +290,7 @@ MODULE_DEVICE_TABLE(of, xlp_gpio_of_ids);
 static int xlp_gpio_probe(struct platform_device *pdev)
 {
        struct gpio_chip *gc;
+       struct gpio_irq_chip *girq;
        struct xlp_gpio_priv *priv;
        void __iomem *gpio_base;
        int irq_base, irq, err;
@@ -395,27 +396,27 @@ static int xlp_gpio_probe(struct platform_device *pdev)
                irq_base = 0;
        }
 
+       girq = &gc->irq;
+       girq->chip = &xlp_gpio_irq_chip;
+       girq->parent_handler = xlp_gpio_generic_handler;
+       girq->num_parents = 1;
+       girq->parents = devm_kcalloc(&pdev->dev, 1,
+                                    sizeof(*girq->parents),
+                                    GFP_KERNEL);
+       if (!girq->parents)
+               return -ENOMEM;
+       girq->parents[0] = irq;
+       girq->first = irq_base;
+       girq->default_type = IRQ_TYPE_NONE;
+       girq->handler = handle_level_irq;
+
        err = gpiochip_add_data(gc, priv);
        if (err < 0)
                return err;
 
-       err = gpiochip_irqchip_add(gc, &xlp_gpio_irq_chip, irq_base,
-                               handle_level_irq, IRQ_TYPE_NONE);
-       if (err) {
-               dev_err(&pdev->dev, "Could not connect irqchip to gpiochip!\n");
-               goto out_gpio_remove;
-       }
-
-       gpiochip_set_chained_irqchip(gc, &xlp_gpio_irq_chip, irq,
-                       xlp_gpio_generic_handler);
-
        dev_info(&pdev->dev, "registered %d GPIOs\n", gc->ngpio);
 
        return 0;
-
-out_gpio_remove:
-       gpiochip_remove(gc);
-       return err;
 }
 
 #ifdef CONFIG_ACPI
index 8637adb..98cbaf0 100644 (file)
@@ -215,6 +215,7 @@ static int zx_gpio_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct zx_gpio *chip;
+       struct gpio_irq_chip *girq;
        int irq, id, ret;
 
        chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
@@ -242,32 +243,30 @@ static int zx_gpio_probe(struct platform_device *pdev)
        chip->gc.parent = dev;
        chip->gc.owner = THIS_MODULE;
 
-       ret = gpiochip_add_data(&chip->gc, chip);
-       if (ret)
-               return ret;
-
        /*
         * irq_chip support
         */
        writew_relaxed(0xffff, chip->base + ZX_GPIO_IM);
        writew_relaxed(0, chip->base + ZX_GPIO_IE);
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(dev, "invalid IRQ\n");
-               gpiochip_remove(&chip->gc);
-               return -ENODEV;
-       }
+       if (irq < 0)
+               return irq;
+       girq = &chip->gc.irq;
+       girq->chip = &zx_irqchip;
+       girq->parent_handler = zx_irq_handler;
+       girq->num_parents = 1;
+       girq->parents = devm_kcalloc(&pdev->dev, 1,
+                                    sizeof(*girq->parents),
+                                    GFP_KERNEL);
+       if (!girq->parents)
+               return -ENOMEM;
+       girq->parents[0] = irq;
+       girq->default_type = IRQ_TYPE_NONE;
+       girq->handler = handle_simple_irq;
 
-       ret = gpiochip_irqchip_add(&chip->gc, &zx_irqchip,
-                                  0, handle_simple_irq,
-                                  IRQ_TYPE_NONE);
-       if (ret) {
-               dev_err(dev, "could not add irqchip\n");
-               gpiochip_remove(&chip->gc);
+       ret = gpiochip_add_data(&chip->gc, chip);
+       if (ret)
                return ret;
-       }
-       gpiochip_set_chained_irqchip(&chip->gc, &zx_irqchip,
-                                    irq, zx_irq_handler);
 
        platform_set_drvdata(pdev, chip);
        dev_info(dev, "ZX GPIO chip registered\n");
index f241b6c..cd475ff 100644 (file)
@@ -830,6 +830,7 @@ static int zynq_gpio_probe(struct platform_device *pdev)
        int ret, bank_num;
        struct zynq_gpio *gpio;
        struct gpio_chip *chip;
+       struct gpio_irq_chip *girq;
        const struct of_device_id *match;
 
        gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
@@ -849,10 +850,8 @@ static int zynq_gpio_probe(struct platform_device *pdev)
                return PTR_ERR(gpio->base_addr);
 
        gpio->irq = platform_get_irq(pdev, 0);
-       if (gpio->irq < 0) {
-               dev_err(&pdev->dev, "invalid IRQ\n");
+       if (gpio->irq < 0)
                return gpio->irq;
-       }
 
        /* configure the gpio chip */
        chip = &gpio->chip;
@@ -887,34 +886,38 @@ static int zynq_gpio_probe(struct platform_device *pdev)
        if (ret < 0)
                goto err_pm_dis;
 
-       /* report a bug if gpio chip registration fails */
-       ret = gpiochip_add_data(chip, gpio);
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to add gpio chip\n");
-               goto err_pm_put;
-       }
-
        /* disable interrupts for all banks */
        for (bank_num = 0; bank_num < gpio->p_data->max_bank; bank_num++)
                writel_relaxed(ZYNQ_GPIO_IXR_DISABLE_ALL, gpio->base_addr +
                               ZYNQ_GPIO_INTDIS_OFFSET(bank_num));
 
-       ret = gpiochip_irqchip_add(chip, &zynq_gpio_edge_irqchip, 0,
-                                  handle_level_irq, IRQ_TYPE_NONE);
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to add irq chip\n");
-               goto err_rm_gpiochip;
+       /* Set up the GPIO irqchip */
+       girq = &chip->irq;
+       girq->chip = &zynq_gpio_edge_irqchip;
+       girq->parent_handler = zynq_gpio_irqhandler;
+       girq->num_parents = 1;
+       girq->parents = devm_kcalloc(&pdev->dev, 1,
+                                    sizeof(*girq->parents),
+                                    GFP_KERNEL);
+       if (!girq->parents) {
+               ret = -ENOMEM;
+               goto err_pm_put;
        }
+       girq->parents[0] = gpio->irq;
+       girq->default_type = IRQ_TYPE_NONE;
+       girq->handler = handle_level_irq;
 
-       gpiochip_set_chained_irqchip(chip, &zynq_gpio_edge_irqchip, gpio->irq,
-                                    zynq_gpio_irqhandler);
+       /* report a bug if gpio chip registration fails */
+       ret = gpiochip_add_data(chip, gpio);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to add gpio chip\n");
+               goto err_pm_put;
+       }
 
        pm_runtime_put(&pdev->dev);
 
        return 0;
 
-err_rm_gpiochip:
-       gpiochip_remove(chip);
 err_pm_put:
        pm_runtime_put(&pdev->dev);
 err_pm_dis:
index 39f2f90..609ed16 100644 (file)
@@ -7,6 +7,7 @@
  *          Mika Westerberg <mika.westerberg@linux.intel.com>
  */
 
+#include <linux/dmi.h>
 #include <linux/errno.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio/driver.h>
 #include <linux/pinctrl/pinctrl.h>
 
 #include "gpiolib.h"
+#include "gpiolib-acpi.h"
+
+static int run_edge_events_on_boot = -1;
+module_param(run_edge_events_on_boot, int, 0444);
+MODULE_PARM_DESC(run_edge_events_on_boot,
+                "Run edge _AEI event-handlers at boot: 0=no, 1=yes, -1=auto");
 
 /**
  * struct acpi_gpio_event - ACPI GPIO event handler data
@@ -170,10 +177,13 @@ static void acpi_gpiochip_request_irq(struct acpi_gpio_chip *acpi_gpio,
        event->irq_requested = true;
 
        /* Make sure we trigger the initial state of edge-triggered IRQs */
-       value = gpiod_get_raw_value_cansleep(event->desc);
-       if (((event->irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
-           ((event->irqflags & IRQF_TRIGGER_FALLING) && value == 0))
-               event->handler(event->irq, event);
+       if (run_edge_events_on_boot &&
+           (event->irqflags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))) {
+               value = gpiod_get_raw_value_cansleep(event->desc);
+               if (((event->irqflags & IRQF_TRIGGER_RISING) && value == 1) ||
+                   ((event->irqflags & IRQF_TRIGGER_FALLING) && value == 0))
+                       event->handler(event->irq, event);
+       }
 }
 
 static void acpi_gpiochip_request_irqs(struct acpi_gpio_chip *acpi_gpio)
@@ -382,6 +392,13 @@ int acpi_dev_add_driver_gpios(struct acpi_device *adev,
 }
 EXPORT_SYMBOL_GPL(acpi_dev_add_driver_gpios);
 
+void acpi_dev_remove_driver_gpios(struct acpi_device *adev)
+{
+       if (adev)
+               adev->driver_gpios = NULL;
+}
+EXPORT_SYMBOL_GPL(acpi_dev_remove_driver_gpios);
+
 static void devm_acpi_dev_release_driver_gpios(struct device *dev, void *res)
 {
        acpi_dev_remove_driver_gpios(ACPI_COMPANION(dev));
@@ -720,6 +737,16 @@ static struct gpio_desc *acpi_get_gpiod_by_index(struct acpi_device *adev,
        return ret ? ERR_PTR(ret) : lookup.desc;
 }
 
+static bool acpi_can_fallback_to_crs(struct acpi_device *adev,
+                                    const char *con_id)
+{
+       /* Never allow fallback if the device has properties */
+       if (acpi_dev_has_props(adev) || adev->driver_gpios)
+               return false;
+
+       return con_id == NULL;
+}
+
 struct gpio_desc *acpi_find_gpio(struct device *dev,
                                 const char *con_id,
                                 unsigned int idx,
@@ -1256,15 +1283,6 @@ int acpi_gpio_count(struct device *dev, const char *con_id)
        return count ? count : -ENOENT;
 }
 
-bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id)
-{
-       /* Never allow fallback if the device has properties */
-       if (acpi_dev_has_props(adev) || adev->driver_gpios)
-               return false;
-
-       return con_id == NULL;
-}
-
 /* Run deferred acpi_gpiochip_request_irqs() */
 static int acpi_gpio_handle_deferred_request_irqs(void)
 {
@@ -1283,3 +1301,28 @@ static int acpi_gpio_handle_deferred_request_irqs(void)
 }
 /* We must use _sync so that this runs after the first deferred_probe run */
 late_initcall_sync(acpi_gpio_handle_deferred_request_irqs);
+
+static const struct dmi_system_id run_edge_events_on_boot_blacklist[] = {
+       {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "MINIX"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"),
+               }
+       },
+       {} /* Terminating entry */
+};
+
+static int acpi_gpio_setup_params(void)
+{
+       if (run_edge_events_on_boot < 0) {
+               if (dmi_check_system(run_edge_events_on_boot_blacklist))
+                       run_edge_events_on_boot = 0;
+               else
+                       run_edge_events_on_boot = 1;
+       }
+
+       return 0;
+}
+
+/* Directly after dmi_setup() which runs as core_initcall() */
+postcore_initcall(acpi_gpio_setup_params);
diff --git a/drivers/gpio/gpiolib-acpi.h b/drivers/gpio/gpiolib-acpi.h
new file mode 100644 (file)
index 0000000..1c6d65c
--- /dev/null
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * ACPI helpers for GPIO API
+ *
+ * Copyright (C) 2012,2019 Intel Corporation
+ */
+
+#ifndef GPIOLIB_ACPI_H
+#define GPIOLIB_ACPI_H
+
+struct acpi_device;
+
+/**
+ * struct acpi_gpio_info - ACPI GPIO specific information
+ * @adev: reference to ACPI device which consumes GPIO resource
+ * @flags: GPIO initialization flags
+ * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo
+ * @pin_config: pin bias as provided by ACPI
+ * @polarity: interrupt polarity as provided by ACPI
+ * @triggering: triggering type as provided by ACPI
+ * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping
+ */
+struct acpi_gpio_info {
+       struct acpi_device *adev;
+       enum gpiod_flags flags;
+       bool gpioint;
+       int pin_config;
+       int polarity;
+       int triggering;
+       unsigned int quirks;
+};
+
+#ifdef CONFIG_ACPI
+void acpi_gpiochip_add(struct gpio_chip *chip);
+void acpi_gpiochip_remove(struct gpio_chip *chip);
+
+void acpi_gpiochip_request_interrupts(struct gpio_chip *chip);
+void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
+
+int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags,
+                                struct acpi_gpio_info *info);
+int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
+                                       struct acpi_gpio_info *info);
+
+struct gpio_desc *acpi_find_gpio(struct device *dev,
+                                const char *con_id,
+                                unsigned int idx,
+                                enum gpiod_flags *dflags,
+                                unsigned long *lookupflags);
+struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
+                                     const char *propname, int index,
+                                     struct acpi_gpio_info *info);
+
+int acpi_gpio_count(struct device *dev, const char *con_id);
+#else
+static inline void acpi_gpiochip_add(struct gpio_chip *chip) { }
+static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { }
+
+static inline void
+acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { }
+
+static inline void
+acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { }
+
+static inline int
+acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *info)
+{
+       return 0;
+}
+static inline int
+acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
+                                   struct acpi_gpio_info *info)
+{
+       return 0;
+}
+
+static inline struct gpio_desc *
+acpi_find_gpio(struct device *dev, const char *con_id,
+              unsigned int idx, enum gpiod_flags *dflags,
+              unsigned long *lookupflags)
+{
+       return ERR_PTR(-ENOENT);
+}
+static inline struct gpio_desc *
+acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname,
+                   int index, struct acpi_gpio_info *info)
+{
+       return ERR_PTR(-ENXIO);
+}
+static inline int acpi_gpio_count(struct device *dev, const char *con_id)
+{
+       return -ENODEV;
+}
+#endif
+
+#endif /* GPIOLIB_ACPI_H */
index 0acc2cc..98e3c20 100644 (file)
@@ -59,7 +59,7 @@ struct gpio_desc *__must_check devm_gpiod_get(struct device *dev,
 {
        return devm_gpiod_get_index(dev, con_id, 0, flags);
 }
-EXPORT_SYMBOL(devm_gpiod_get);
+EXPORT_SYMBOL_GPL(devm_gpiod_get);
 
 /**
  * devm_gpiod_get_optional - Resource-managed gpiod_get_optional()
@@ -77,7 +77,7 @@ struct gpio_desc *__must_check devm_gpiod_get_optional(struct device *dev,
 {
        return devm_gpiod_get_index_optional(dev, con_id, 0, flags);
 }
-EXPORT_SYMBOL(devm_gpiod_get_optional);
+EXPORT_SYMBOL_GPL(devm_gpiod_get_optional);
 
 /**
  * devm_gpiod_get_index - Resource-managed gpiod_get_index()
@@ -127,7 +127,7 @@ struct gpio_desc *__must_check devm_gpiod_get_index(struct device *dev,
 
        return desc;
 }
-EXPORT_SYMBOL(devm_gpiod_get_index);
+EXPORT_SYMBOL_GPL(devm_gpiod_get_index);
 
 /**
  * devm_gpiod_get_from_of_node() - obtain a GPIO from an OF node
@@ -182,7 +182,7 @@ struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev,
 
        return desc;
 }
-EXPORT_SYMBOL(devm_gpiod_get_from_of_node);
+EXPORT_SYMBOL_GPL(devm_gpiod_get_from_of_node);
 
 /**
  * devm_fwnode_get_index_gpiod_from_child - get a GPIO descriptor from a
@@ -239,7 +239,7 @@ struct gpio_desc *devm_fwnode_get_index_gpiod_from_child(struct device *dev,
 
        return desc;
 }
-EXPORT_SYMBOL(devm_fwnode_get_index_gpiod_from_child);
+EXPORT_SYMBOL_GPL(devm_fwnode_get_index_gpiod_from_child);
 
 /**
  * devm_gpiod_get_index_optional - Resource-managed gpiod_get_index_optional()
@@ -268,7 +268,7 @@ struct gpio_desc *__must_check devm_gpiod_get_index_optional(struct device *dev,
 
        return desc;
 }
-EXPORT_SYMBOL(devm_gpiod_get_index_optional);
+EXPORT_SYMBOL_GPL(devm_gpiod_get_index_optional);
 
 /**
  * devm_gpiod_get_array - Resource-managed gpiod_get_array()
@@ -303,7 +303,7 @@ struct gpio_descs *__must_check devm_gpiod_get_array(struct device *dev,
 
        return descs;
 }
-EXPORT_SYMBOL(devm_gpiod_get_array);
+EXPORT_SYMBOL_GPL(devm_gpiod_get_array);
 
 /**
  * devm_gpiod_get_array_optional - Resource-managed gpiod_get_array_optional()
@@ -328,7 +328,7 @@ devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
 
        return descs;
 }
-EXPORT_SYMBOL(devm_gpiod_get_array_optional);
+EXPORT_SYMBOL_GPL(devm_gpiod_get_array_optional);
 
 /**
  * devm_gpiod_put - Resource-managed gpiod_put()
@@ -344,7 +344,7 @@ void devm_gpiod_put(struct device *dev, struct gpio_desc *desc)
        WARN_ON(devres_release(dev, devm_gpiod_release, devm_gpiod_match,
                &desc));
 }
-EXPORT_SYMBOL(devm_gpiod_put);
+EXPORT_SYMBOL_GPL(devm_gpiod_put);
 
 /**
  * devm_gpiod_unhinge - Remove resource management from a gpio descriptor
@@ -374,7 +374,7 @@ void devm_gpiod_unhinge(struct device *dev, struct gpio_desc *desc)
        /* Anything else we should warn about */
        WARN_ON(ret);
 }
-EXPORT_SYMBOL(devm_gpiod_unhinge);
+EXPORT_SYMBOL_GPL(devm_gpiod_unhinge);
 
 /**
  * devm_gpiod_put_array - Resource-managed gpiod_put_array()
@@ -390,7 +390,7 @@ void devm_gpiod_put_array(struct device *dev, struct gpio_descs *descs)
        WARN_ON(devres_release(dev, devm_gpiod_release_array,
                               devm_gpiod_match_array, &descs));
 }
-EXPORT_SYMBOL(devm_gpiod_put_array);
+EXPORT_SYMBOL_GPL(devm_gpiod_put_array);
 
 
 
@@ -444,7 +444,7 @@ int devm_gpio_request(struct device *dev, unsigned gpio, const char *label)
 
        return 0;
 }
-EXPORT_SYMBOL(devm_gpio_request);
+EXPORT_SYMBOL_GPL(devm_gpio_request);
 
 /**
  *     devm_gpio_request_one - request a single GPIO with initial setup
@@ -474,7 +474,7 @@ int devm_gpio_request_one(struct device *dev, unsigned gpio,
 
        return 0;
 }
-EXPORT_SYMBOL(devm_gpio_request_one);
+EXPORT_SYMBOL_GPL(devm_gpio_request_one);
 
 /**
  *      devm_gpio_free - free a GPIO
@@ -492,4 +492,4 @@ void devm_gpio_free(struct device *dev, unsigned int gpio)
        WARN_ON(devres_release(dev, devm_gpio_release, devm_gpio_match,
                &gpio));
 }
-EXPORT_SYMBOL(devm_gpio_free);
+EXPORT_SYMBOL_GPL(devm_gpio_free);
index 9762dd6..1eea2c6 100644 (file)
 #include <linux/gpio/machine.h>
 
 #include "gpiolib.h"
+#include "gpiolib-of.h"
+
+/*
+ * This is used by external users of of_gpio_count() from <linux/of_gpio.h>
+ *
+ * FIXME: get rid of those external users by converting them to GPIO
+ * descriptors and let them all use gpiod_get_count()
+ */
+int of_gpio_get_count(struct device *dev, const char *con_id)
+{
+       int ret;
+       char propname[32];
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
+               if (con_id)
+                       snprintf(propname, sizeof(propname), "%s-%s",
+                                con_id, gpio_suffixes[i]);
+               else
+                       snprintf(propname, sizeof(propname), "%s",
+                                gpio_suffixes[i]);
+
+               ret = of_gpio_named_count(dev->of_node, propname);
+               if (ret > 0)
+                       break;
+       }
+       return ret ? ret : -ENOENT;
+}
 
 static int of_gpiochip_match_node_and_xlate(struct gpio_chip *chip, void *data)
 {
@@ -53,6 +81,23 @@ static struct gpio_desc *of_xlate_and_get_gpiod_flags(struct gpio_chip *chip,
        return gpiochip_get_desc(chip, ret);
 }
 
+/**
+ * of_gpio_need_valid_mask() - figure out if the OF GPIO driver needs
+ * to set the .valid_mask
+ * @dev: the device for the GPIO provider
+ * @return: true if the valid mask needs to be set
+ */
+bool of_gpio_need_valid_mask(const struct gpio_chip *gc)
+{
+       int size;
+       struct device_node *np = gc->of_node;
+
+       size = of_property_count_u32_elems(np,  "gpio-reserved-ranges");
+       if (size > 0 && size % 2 == 0)
+               return true;
+       return false;
+}
+
 static void of_gpio_flags_quirks(struct device_node *np,
                                 const char *propname,
                                 enum of_gpio_flags *flags,
@@ -178,7 +223,7 @@ static void of_gpio_flags_quirks(struct device_node *np,
  * value on the error condition. If @flags is not NULL the function also fills
  * in flags for the GPIO.
  */
-struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
+static struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
                     const char *propname, int index, enum of_gpio_flags *flags)
 {
        struct of_phandle_args gpiospec;
@@ -229,7 +274,76 @@ int of_get_named_gpio_flags(struct device_node *np, const char *list_name,
        else
                return desc_to_gpio(desc);
 }
-EXPORT_SYMBOL(of_get_named_gpio_flags);
+EXPORT_SYMBOL_GPL(of_get_named_gpio_flags);
+
+/**
+ * gpiod_get_from_of_node() - obtain a GPIO from an OF node
+ * @node:      handle of the OF node
+ * @propname:  name of the DT property representing the GPIO
+ * @index:     index of the GPIO to obtain for the consumer
+ * @dflags:    GPIO initialization flags
+ * @label:     label to attach to the requested GPIO
+ *
+ * Returns:
+ * On successful request the GPIO pin is configured in accordance with
+ * provided @dflags.
+ *
+ * In case of error an ERR_PTR() is returned.
+ */
+struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
+                                        const char *propname, int index,
+                                        enum gpiod_flags dflags,
+                                        const char *label)
+{
+       unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
+       struct gpio_desc *desc;
+       enum of_gpio_flags flags;
+       bool active_low = false;
+       bool single_ended = false;
+       bool open_drain = false;
+       bool transitory = false;
+       int ret;
+
+       desc = of_get_named_gpiod_flags(node, propname,
+                                       index, &flags);
+
+       if (!desc || IS_ERR(desc)) {
+               return desc;
+       }
+
+       active_low = flags & OF_GPIO_ACTIVE_LOW;
+       single_ended = flags & OF_GPIO_SINGLE_ENDED;
+       open_drain = flags & OF_GPIO_OPEN_DRAIN;
+       transitory = flags & OF_GPIO_TRANSITORY;
+
+       ret = gpiod_request(desc, label);
+       if (ret == -EBUSY && (flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE))
+               return desc;
+       if (ret)
+               return ERR_PTR(ret);
+
+       if (active_low)
+               lflags |= GPIO_ACTIVE_LOW;
+
+       if (single_ended) {
+               if (open_drain)
+                       lflags |= GPIO_OPEN_DRAIN;
+               else
+                       lflags |= GPIO_OPEN_SOURCE;
+       }
+
+       if (transitory)
+               lflags |= GPIO_TRANSITORY;
+
+       ret = gpiod_configure_flags(desc, propname, lflags, dflags);
+       if (ret < 0) {
+               gpiod_put(desc);
+               return ERR_PTR(ret);
+       }
+
+       return desc;
+}
+EXPORT_SYMBOL_GPL(gpiod_get_from_of_node);
 
 /*
  * The SPI GPIO bindings happened before we managed to establish that GPIO
@@ -324,6 +438,19 @@ static struct gpio_desc *of_find_regulator_gpio(struct device *dev, const char *
        return desc;
 }
 
+static struct gpio_desc *of_find_arizona_gpio(struct device *dev,
+                                             const char *con_id,
+                                             enum of_gpio_flags *of_flags)
+{
+       if (!IS_ENABLED(CONFIG_MFD_ARIZONA))
+               return ERR_PTR(-ENOENT);
+
+       if (!con_id || strcmp(con_id, "wlf,reset"))
+               return ERR_PTR(-ENOENT);
+
+       return of_get_named_gpiod_flags(dev->of_node, con_id, 0, of_flags);
+}
+
 struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
                               unsigned int idx, unsigned long *flags)
 {
@@ -343,36 +470,30 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
 
                desc = of_get_named_gpiod_flags(dev->of_node, prop_name, idx,
                                                &of_flags);
-               /*
-                * -EPROBE_DEFER in our case means that we found a
-                * valid GPIO property, but no controller has been
-                * registered so far.
-                *
-                * This means we don't need to look any further for
-                * alternate name conventions, and we should really
-                * preserve the return code for our user to be able to
-                * retry probing later.
-                */
-               if (IS_ERR(desc) && PTR_ERR(desc) == -EPROBE_DEFER)
-                       return desc;
 
-               if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT))
+               if (!IS_ERR(desc) || PTR_ERR(desc) != -ENOENT)
                        break;
        }
 
-       /* Special handling for SPI GPIOs if used */
-       if (IS_ERR(desc))
+       if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
+               /* Special handling for SPI GPIOs if used */
                desc = of_find_spi_gpio(dev, con_id, &of_flags);
-       if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER) {
+       }
+
+       if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
                /* This quirk looks up flags and all */
                desc = of_find_spi_cs_gpio(dev, con_id, idx, flags);
                if (!IS_ERR(desc))
                        return desc;
        }
 
-       /* Special handling for regulator GPIOs if used */
-       if (IS_ERR(desc) && PTR_ERR(desc) != -EPROBE_DEFER)
+       if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
+               /* Special handling for regulator GPIOs if used */
                desc = of_find_regulator_gpio(dev, con_id, &of_flags);
+       }
+
+       if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT)
+               desc = of_find_arizona_gpio(dev, con_id, &of_flags);
 
        if (IS_ERR(desc))
                return desc;
@@ -523,8 +644,9 @@ static int of_gpiochip_scan_gpios(struct gpio_chip *chip)
  * GPIO chips. This function performs only one sanity check: whether GPIO
  * is less than ngpios (that is specified in the gpio_chip).
  */
-int of_gpio_simple_xlate(struct gpio_chip *gc,
-                        const struct of_phandle_args *gpiospec, u32 *flags)
+static int of_gpio_simple_xlate(struct gpio_chip *gc,
+                               const struct of_phandle_args *gpiospec,
+                               u32 *flags)
 {
        /*
         * We're discouraging gpio_cells < 2, since that way you'll have to
@@ -548,7 +670,6 @@ int of_gpio_simple_xlate(struct gpio_chip *gc,
 
        return gpiospec->args[0];
 }
-EXPORT_SYMBOL(of_gpio_simple_xlate);
 
 /**
  * of_mm_gpiochip_add_data - Add memory mapped GPIO chip (bank)
@@ -605,7 +726,7 @@ err0:
        pr_err("%pOF: GPIO chip registration failed with status %d\n", np, ret);
        return ret;
 }
-EXPORT_SYMBOL(of_mm_gpiochip_add_data);
+EXPORT_SYMBOL_GPL(of_mm_gpiochip_add_data);
 
 /**
  * of_mm_gpiochip_remove - Remove memory mapped GPIO chip (bank)
@@ -622,7 +743,7 @@ void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc)
        iounmap(mm_gc->regs);
        kfree(gc->label);
 }
-EXPORT_SYMBOL(of_mm_gpiochip_remove);
+EXPORT_SYMBOL_GPL(of_mm_gpiochip_remove);
 
 static void of_gpiochip_init_valid_mask(struct gpio_chip *chip)
 {
@@ -734,7 +855,7 @@ static int of_gpiochip_add_pin_range(struct gpio_chip *chip) { return 0; }
 
 int of_gpiochip_add(struct gpio_chip *chip)
 {
-       int status;
+       int ret;
 
        if (!chip->of_node)
                return 0;
@@ -749,9 +870,9 @@ int of_gpiochip_add(struct gpio_chip *chip)
 
        of_gpiochip_init_valid_mask(chip);
 
-       status = of_gpiochip_add_pin_range(chip);
-       if (status)
-               return status;
+       ret = of_gpiochip_add_pin_range(chip);
+       if (ret)
+               return ret;
 
        /* If the chip defines names itself, these take precedence */
        if (!chip->names)
@@ -760,13 +881,13 @@ int of_gpiochip_add(struct gpio_chip *chip)
 
        of_node_get(chip->of_node);
 
-       status = of_gpiochip_scan_gpios(chip);
-       if (status) {
+       ret = of_gpiochip_scan_gpios(chip);
+       if (ret) {
                of_node_put(chip->of_node);
                gpiochip_remove_pin_ranges(chip);
        }
 
-       return status;
+       return ret;
 }
 
 void of_gpiochip_remove(struct gpio_chip *chip)
diff --git a/drivers/gpio/gpiolib-of.h b/drivers/gpio/gpiolib-of.h
new file mode 100644 (file)
index 0000000..9768831
--- /dev/null
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef GPIOLIB_OF_H
+#define GPIOLIB_OF_H
+
+struct gpio_chip;
+enum of_gpio_flags;
+
+#ifdef CONFIG_OF_GPIO
+struct gpio_desc *of_find_gpio(struct device *dev,
+                              const char *con_id,
+                              unsigned int idx,
+                              unsigned long *lookupflags);
+int of_gpiochip_add(struct gpio_chip *gc);
+void of_gpiochip_remove(struct gpio_chip *gc);
+int of_gpio_get_count(struct device *dev, const char *con_id);
+bool of_gpio_need_valid_mask(const struct gpio_chip *gc);
+#else
+static inline struct gpio_desc *of_find_gpio(struct device *dev,
+                                            const char *con_id,
+                                            unsigned int idx,
+                                            unsigned long *lookupflags)
+{
+       return ERR_PTR(-ENOENT);
+}
+static inline int of_gpiochip_add(struct gpio_chip *gc) { return 0; }
+static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
+static inline int of_gpio_get_count(struct device *dev, const char *con_id)
+{
+       return 0;
+}
+static inline bool of_gpio_need_valid_mask(const struct gpio_chip *gc)
+{
+       return false;
+}
+#endif /* CONFIG_OF_GPIO */
+
+#endif /* GPIOLIB_OF_H */
index cca7490..8229888 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/gpio.h>
-#include <linux/of_gpio.h>
 #include <linux/idr.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
@@ -30,6 +29,8 @@
 #include <uapi/linux/gpio.h>
 
 #include "gpiolib.h"
+#include "gpiolib-of.h"
+#include "gpiolib-acpi.h"
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/gpio.h>
@@ -213,7 +214,7 @@ int gpiod_get_direction(struct gpio_desc *desc)
 {
        struct gpio_chip *chip;
        unsigned offset;
-       int status;
+       int ret;
 
        chip = gpiod_to_chip(desc);
        offset = gpio_chip_hwgpio(desc);
@@ -221,17 +222,17 @@ int gpiod_get_direction(struct gpio_desc *desc)
        if (!chip->get_direction)
                return -ENOTSUPP;
 
-       status = chip->get_direction(chip, offset);
-       if (status > 0) {
+       ret = chip->get_direction(chip, offset);
+       if (ret > 0) {
                /* GPIOF_DIR_IN, or other positive */
-               status = 1;
+               ret = 1;
                clear_bit(FLAG_IS_OUT, &desc->flags);
        }
-       if (status == 0) {
+       if (ret == 0) {
                /* GPIOF_DIR_OUT */
                set_bit(FLAG_IS_OUT, &desc->flags);
        }
-       return status;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(gpiod_get_direction);
 
@@ -350,7 +351,7 @@ static unsigned long *gpiochip_allocate_mask(struct gpio_chip *chip)
 {
        unsigned long *p;
 
-       p = kmalloc_array(BITS_TO_LONGS(chip->ngpio), sizeof(*p), GFP_KERNEL);
+       p = bitmap_alloc(chip->ngpio, GFP_KERNEL);
        if (!p)
                return NULL;
 
@@ -360,38 +361,31 @@ static unsigned long *gpiochip_allocate_mask(struct gpio_chip *chip)
        return p;
 }
 
-static int gpiochip_alloc_valid_mask(struct gpio_chip *gpiochip)
+static int gpiochip_alloc_valid_mask(struct gpio_chip *gc)
 {
-#ifdef CONFIG_OF_GPIO
-       int size;
-       struct device_node *np = gpiochip->of_node;
-
-       size = of_property_count_u32_elems(np,  "gpio-reserved-ranges");
-       if (size > 0 && size % 2 == 0)
-               gpiochip->need_valid_mask = true;
-#endif
-
-       if (!gpiochip->need_valid_mask)
+       if (!(of_gpio_need_valid_mask(gc) || gc->init_valid_mask))
                return 0;
 
-       gpiochip->valid_mask = gpiochip_allocate_mask(gpiochip);
-       if (!gpiochip->valid_mask)
+       gc->valid_mask = gpiochip_allocate_mask(gc);
+       if (!gc->valid_mask)
                return -ENOMEM;
 
        return 0;
 }
 
-static int gpiochip_init_valid_mask(struct gpio_chip *gpiochip)
+static int gpiochip_init_valid_mask(struct gpio_chip *gc)
 {
-       if (gpiochip->init_valid_mask)
-               return gpiochip->init_valid_mask(gpiochip);
+       if (gc->init_valid_mask)
+               return gc->init_valid_mask(gc,
+                                          gc->valid_mask,
+                                          gc->ngpio);
 
        return 0;
 }
 
 static void gpiochip_free_valid_mask(struct gpio_chip *gpiochip)
 {
-       kfree(gpiochip->valid_mask);
+       bitmap_free(gpiochip->valid_mask);
        gpiochip->valid_mask = NULL;
 }
 
@@ -536,6 +530,14 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
                return -EINVAL;
 
        /*
+        * Do not allow both INPUT & OUTPUT flags to be set as they are
+        * contradictory.
+        */
+       if ((lflags & GPIOHANDLE_REQUEST_INPUT) &&
+           (lflags & GPIOHANDLE_REQUEST_OUTPUT))
+               return -EINVAL;
+
+       /*
         * Do not allow OPEN_SOURCE & OPEN_DRAIN flags in a single request. If
         * the hardware actually supports enabling both at the same time the
         * electrical result would be disastrous.
@@ -857,7 +859,7 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p)
        }
 
        ret = kfifo_put(&le->events, ge);
-       if (ret != 0)
+       if (ret)
                wake_up_poll(&le->wait, EPOLLIN);
 
        return IRQ_HANDLED;
@@ -926,7 +928,9 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
        }
 
        /* This is just wrong: we don't look for events on output lines */
-       if (lflags & GPIOHANDLE_REQUEST_OUTPUT) {
+       if ((lflags & GPIOHANDLE_REQUEST_OUTPUT) ||
+           (lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN) ||
+           (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)) {
                ret = -EINVAL;
                goto out_free_label;
        }
@@ -940,10 +944,6 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
 
        if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW)
                set_bit(FLAG_ACTIVE_LOW, &desc->flags);
-       if (lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN)
-               set_bit(FLAG_OPEN_DRAIN, &desc->flags);
-       if (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE)
-               set_bit(FLAG_OPEN_SOURCE, &desc->flags);
 
        ret = gpiod_direction_input(desc);
        if (ret)
@@ -1176,21 +1176,21 @@ static void gpiodevice_release(struct device *dev)
 
 static int gpiochip_setup_dev(struct gpio_device *gdev)
 {
-       int status;
+       int ret;
 
        cdev_init(&gdev->chrdev, &gpio_fileops);
        gdev->chrdev.owner = THIS_MODULE;
        gdev->dev.devt = MKDEV(MAJOR(gpio_devt), gdev->id);
 
-       status = cdev_device_add(&gdev->chrdev, &gdev->dev);
-       if (status)
-               return status;
+       ret = cdev_device_add(&gdev->chrdev, &gdev->dev);
+       if (ret)
+               return ret;
 
        chip_dbg(gdev->chip, "added GPIO chardev (%d:%d)\n",
                 MAJOR(gpio_devt), gdev->id);
 
-       status = gpiochip_sysfs_register(gdev);
-       if (status)
+       ret = gpiochip_sysfs_register(gdev);
+       if (ret)
                goto err_remove_device;
 
        /* From this point, the .release() function cleans up gpio_device */
@@ -1203,7 +1203,7 @@ static int gpiochip_setup_dev(struct gpio_device *gdev)
 
 err_remove_device:
        cdev_device_del(&gdev->chrdev, &gdev->dev);
-       return status;
+       return ret;
 }
 
 static void gpiochip_machine_hog(struct gpio_chip *chip, struct gpiod_hog *hog)
@@ -1244,13 +1244,13 @@ static void machine_gpiochip_add(struct gpio_chip *chip)
 static void gpiochip_setup_devs(void)
 {
        struct gpio_device *gdev;
-       int err;
+       int ret;
 
        list_for_each_entry(gdev, &gpio_devices, list) {
-               err = gpiochip_setup_dev(gdev);
-               if (err)
+               ret = gpiochip_setup_dev(gdev);
+               if (ret)
                        pr_err("%s: Failed to initialize gpio device (%d)\n",
-                              dev_name(&gdev->dev), err);
+                              dev_name(&gdev->dev), ret);
        }
 }
 
@@ -1259,7 +1259,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
                               struct lock_class_key *request_key)
 {
        unsigned long   flags;
-       int             status = 0;
+       int             ret = 0;
        unsigned        i;
        int             base = chip->base;
        struct gpio_device *gdev;
@@ -1289,7 +1289,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
 
        gdev->id = ida_simple_get(&gpio_ida, 0, 0, GFP_KERNEL);
        if (gdev->id < 0) {
-               status = gdev->id;
+               ret = gdev->id;
                goto err_free_gdev;
        }
        dev_set_name(&gdev->dev, "gpiochip%d", gdev->id);
@@ -1305,13 +1305,13 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
 
        gdev->descs = kcalloc(chip->ngpio, sizeof(gdev->descs[0]), GFP_KERNEL);
        if (!gdev->descs) {
-               status = -ENOMEM;
+               ret = -ENOMEM;
                goto err_free_ida;
        }
 
        if (chip->ngpio == 0) {
                chip_err(chip, "tried to insert a GPIO chip with zero lines\n");
-               status = -EINVAL;
+               ret = -EINVAL;
                goto err_free_descs;
        }
 
@@ -1321,7 +1321,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
 
        gdev->label = kstrdup_const(chip->label ?: "unknown", GFP_KERNEL);
        if (!gdev->label) {
-               status = -ENOMEM;
+               ret = -ENOMEM;
                goto err_free_descs;
        }
 
@@ -1340,7 +1340,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
        if (base < 0) {
                base = gpiochip_find_base(chip->ngpio);
                if (base < 0) {
-                       status = base;
+                       ret = base;
                        spin_unlock_irqrestore(&gpio_lock, flags);
                        goto err_free_label;
                }
@@ -1354,8 +1354,8 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
        }
        gdev->base = base;
 
-       status = gpiodev_add_to_list(gdev);
-       if (status) {
+       ret = gpiodev_add_to_list(gdev);
+       if (ret) {
                spin_unlock_irqrestore(&gpio_lock, flags);
                goto err_free_label;
        }
@@ -1369,20 +1369,20 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
        INIT_LIST_HEAD(&gdev->pin_ranges);
 #endif
 
-       status = gpiochip_set_desc_names(chip);
-       if (status)
+       ret = gpiochip_set_desc_names(chip);
+       if (ret)
                goto err_remove_from_list;
 
-       status = gpiochip_alloc_valid_mask(chip);
-       if (status)
+       ret = gpiochip_alloc_valid_mask(chip);
+       if (ret)
                goto err_remove_from_list;
 
-       status = of_gpiochip_add(chip);
-       if (status)
+       ret = of_gpiochip_add(chip);
+       if (ret)
                goto err_free_gpiochip_mask;
 
-       status = gpiochip_init_valid_mask(chip);
-       if (status)
+       ret = gpiochip_init_valid_mask(chip);
+       if (ret)
                goto err_remove_of_chip;
 
        for (i = 0; i < chip->ngpio; i++) {
@@ -1405,12 +1405,12 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
 
        machine_gpiochip_add(chip);
 
-       status = gpiochip_irqchip_init_valid_mask(chip);
-       if (status)
+       ret = gpiochip_irqchip_init_valid_mask(chip);
+       if (ret)
                goto err_remove_acpi_chip;
 
-       status = gpiochip_add_irqchip(chip, lock_key, request_key);
-       if (status)
+       ret = gpiochip_add_irqchip(chip, lock_key, request_key);
+       if (ret)
                goto err_remove_irqchip_mask;
 
        /*
@@ -1422,8 +1422,8 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data,
         * Otherwise, defer until later.
         */
        if (gpiolib_initialized) {
-               status = gpiochip_setup_dev(gdev);
-               if (status)
+               ret = gpiochip_setup_dev(gdev);
+               if (ret)
                        goto err_remove_irqchip;
        }
        return 0;
@@ -1453,9 +1453,9 @@ err_free_gdev:
        /* failures here can mean systems won't boot... */
        pr_err("%s: GPIOs %d..%d (%s) failed to register, %d\n", __func__,
               gdev->base, gdev->base + gdev->ngpio - 1,
-              chip->label ? : "generic", status);
+              chip->label ? : "generic", ret);
        kfree(gdev);
-       return status;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(gpiochip_add_data_with_key);
 
@@ -1621,21 +1621,25 @@ static struct gpio_chip *find_chip_by_name(const char *name)
  * The following is irqchip helper code for gpiochips.
  */
 
-static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip)
+static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gc)
 {
-       if (!gpiochip->irq.need_valid_mask)
+       struct gpio_irq_chip *girq = &gc->irq;
+
+       if (!girq->init_valid_mask)
                return 0;
 
-       gpiochip->irq.valid_mask = gpiochip_allocate_mask(gpiochip);
-       if (!gpiochip->irq.valid_mask)
+       girq->valid_mask = gpiochip_allocate_mask(gc);
+       if (!girq->valid_mask)
                return -ENOMEM;
 
+       girq->init_valid_mask(gc, girq->valid_mask, gc->ngpio);
+
        return 0;
 }
 
 static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip)
 {
-       kfree(gpiochip->irq.valid_mask);
+       bitmap_free(gpiochip->irq.valid_mask);
        gpiochip->irq.valid_mask = NULL;
 }
 
@@ -1735,6 +1739,273 @@ void gpiochip_set_nested_irqchip(struct gpio_chip *gpiochip,
 }
 EXPORT_SYMBOL_GPL(gpiochip_set_nested_irqchip);
 
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+
+/**
+ * gpiochip_set_hierarchical_irqchip() - connects a hierarchical irqchip
+ * to a gpiochip
+ * @gc: the gpiochip to set the irqchip hierarchical handler to
+ * @irqchip: the irqchip to handle this level of the hierarchy, the interrupt
+ * will then percolate up to the parent
+ */
+static void gpiochip_set_hierarchical_irqchip(struct gpio_chip *gc,
+                                             struct irq_chip *irqchip)
+{
+       /* DT will deal with mapping each IRQ as we go along */
+       if (is_of_node(gc->irq.fwnode))
+               return;
+
+       /*
+        * This is for legacy and boardfile "irqchip" fwnodes: allocate
+        * irqs upfront instead of dynamically since we don't have the
+        * dynamic type of allocation that hardware description languages
+        * provide. Once all GPIO drivers using board files are gone from
+        * the kernel we can delete this code, but for a transitional period
+        * it is necessary to keep this around.
+        */
+       if (is_fwnode_irqchip(gc->irq.fwnode)) {
+               int i;
+               int ret;
+
+               for (i = 0; i < gc->ngpio; i++) {
+                       struct irq_fwspec fwspec;
+                       unsigned int parent_hwirq;
+                       unsigned int parent_type;
+                       struct gpio_irq_chip *girq = &gc->irq;
+
+                       /*
+                        * We call the child to parent translation function
+                        * only to check if the child IRQ is valid or not.
+                        * Just pick the rising edge type here as that is what
+                        * we likely need to support.
+                        */
+                       ret = girq->child_to_parent_hwirq(gc, i,
+                                                         IRQ_TYPE_EDGE_RISING,
+                                                         &parent_hwirq,
+                                                         &parent_type);
+                       if (ret) {
+                               chip_err(gc, "skip set-up on hwirq %d\n",
+                                        i);
+                               continue;
+                       }
+
+                       fwspec.fwnode = gc->irq.fwnode;
+                       /* This is the hwirq for the GPIO line side of things */
+                       fwspec.param[0] = girq->child_offset_to_irq(gc, i);
+                       /* Just pick something */
+                       fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
+                       fwspec.param_count = 2;
+                       ret = __irq_domain_alloc_irqs(gc->irq.domain,
+                                                     /* just pick something */
+                                                     -1,
+                                                     1,
+                                                     NUMA_NO_NODE,
+                                                     &fwspec,
+                                                     false,
+                                                     NULL);
+                       if (ret < 0) {
+                               chip_err(gc,
+                                        "can not allocate irq for GPIO line %d parent hwirq %d in hierarchy domain: %d\n",
+                                        i, parent_hwirq,
+                                        ret);
+                       }
+               }
+       }
+
+       chip_err(gc, "%s unknown fwnode type proceed anyway\n", __func__);
+
+       return;
+}
+
+static int gpiochip_hierarchy_irq_domain_translate(struct irq_domain *d,
+                                                  struct irq_fwspec *fwspec,
+                                                  unsigned long *hwirq,
+                                                  unsigned int *type)
+{
+       /* We support standard DT translation */
+       if (is_of_node(fwspec->fwnode) && fwspec->param_count == 2) {
+               return irq_domain_translate_twocell(d, fwspec, hwirq, type);
+       }
+
+       /* This is for board files and others not using DT */
+       if (is_fwnode_irqchip(fwspec->fwnode)) {
+               int ret;
+
+               ret = irq_domain_translate_twocell(d, fwspec, hwirq, type);
+               if (ret)
+                       return ret;
+               WARN_ON(*type == IRQ_TYPE_NONE);
+               return 0;
+       }
+       return -EINVAL;
+}
+
+static int gpiochip_hierarchy_irq_domain_alloc(struct irq_domain *d,
+                                              unsigned int irq,
+                                              unsigned int nr_irqs,
+                                              void *data)
+{
+       struct gpio_chip *gc = d->host_data;
+       irq_hw_number_t hwirq;
+       unsigned int type = IRQ_TYPE_NONE;
+       struct irq_fwspec *fwspec = data;
+       struct irq_fwspec parent_fwspec;
+       unsigned int parent_hwirq;
+       unsigned int parent_type;
+       struct gpio_irq_chip *girq = &gc->irq;
+       int ret;
+
+       /*
+        * The nr_irqs parameter is always one except for PCI multi-MSI
+        * so this should not happen.
+        */
+       WARN_ON(nr_irqs != 1);
+
+       ret = gc->irq.child_irq_domain_ops.translate(d, fwspec, &hwirq, &type);
+       if (ret)
+               return ret;
+
+       chip_info(gc, "allocate IRQ %d, hwirq %lu\n", irq,  hwirq);
+
+       ret = girq->child_to_parent_hwirq(gc, hwirq, type,
+                                         &parent_hwirq, &parent_type);
+       if (ret) {
+               chip_err(gc, "can't look up hwirq %lu\n", hwirq);
+               return ret;
+       }
+       chip_info(gc, "found parent hwirq %u\n", parent_hwirq);
+
+       /*
+        * We set handle_bad_irq because the .set_type() should
+        * always be invoked and set the right type of handler.
+        */
+       irq_domain_set_info(d,
+                           irq,
+                           hwirq,
+                           gc->irq.chip,
+                           gc,
+                           girq->handler,
+                           NULL, NULL);
+       irq_set_probe(irq);
+
+       /*
+        * Create a IRQ fwspec to send up to the parent irqdomain:
+        * specify the hwirq we address on the parent and tie it
+        * all together up the chain.
+        */
+       parent_fwspec.fwnode = d->parent->fwnode;
+       /* This parent only handles asserted level IRQs */
+       girq->populate_parent_fwspec(gc, &parent_fwspec, parent_hwirq,
+                                    parent_type);
+       chip_info(gc, "alloc_irqs_parent for %d parent hwirq %d\n",
+                 irq, parent_hwirq);
+       ret = irq_domain_alloc_irqs_parent(d, irq, 1, &parent_fwspec);
+       if (ret)
+               chip_err(gc,
+                        "failed to allocate parent hwirq %d for hwirq %lu\n",
+                        parent_hwirq, hwirq);
+
+       return ret;
+}
+
+static unsigned int gpiochip_child_offset_to_irq_noop(struct gpio_chip *chip,
+                                                     unsigned int offset)
+{
+       return offset;
+}
+
+static void gpiochip_hierarchy_setup_domain_ops(struct irq_domain_ops *ops)
+{
+       ops->activate = gpiochip_irq_domain_activate;
+       ops->deactivate = gpiochip_irq_domain_deactivate;
+       ops->alloc = gpiochip_hierarchy_irq_domain_alloc;
+       ops->free = irq_domain_free_irqs_common;
+
+       /*
+        * We only allow overriding the translate() function for
+        * hierarchical chips, and this should only be done if the user
+        * really need something other than 1:1 translation.
+        */
+       if (!ops->translate)
+               ops->translate = gpiochip_hierarchy_irq_domain_translate;
+}
+
+static int gpiochip_hierarchy_add_domain(struct gpio_chip *gc)
+{
+       if (!gc->irq.child_to_parent_hwirq ||
+           !gc->irq.fwnode) {
+               chip_err(gc, "missing irqdomain vital data\n");
+               return -EINVAL;
+       }
+
+       if (!gc->irq.child_offset_to_irq)
+               gc->irq.child_offset_to_irq = gpiochip_child_offset_to_irq_noop;
+
+       if (!gc->irq.populate_parent_fwspec)
+               gc->irq.populate_parent_fwspec =
+                       gpiochip_populate_parent_fwspec_twocell;
+
+       gpiochip_hierarchy_setup_domain_ops(&gc->irq.child_irq_domain_ops);
+
+       gc->irq.domain = irq_domain_create_hierarchy(
+               gc->irq.parent_domain,
+               0,
+               gc->ngpio,
+               gc->irq.fwnode,
+               &gc->irq.child_irq_domain_ops,
+               gc);
+
+       if (!gc->irq.domain)
+               return -ENOMEM;
+
+       gpiochip_set_hierarchical_irqchip(gc, gc->irq.chip);
+
+       return 0;
+}
+
+static bool gpiochip_hierarchy_is_hierarchical(struct gpio_chip *gc)
+{
+       return !!gc->irq.parent_domain;
+}
+
+void gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
+                                            struct irq_fwspec *fwspec,
+                                            unsigned int parent_hwirq,
+                                            unsigned int parent_type)
+{
+       fwspec->param_count = 2;
+       fwspec->param[0] = parent_hwirq;
+       fwspec->param[1] = parent_type;
+}
+EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_twocell);
+
+void gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
+                                             struct irq_fwspec *fwspec,
+                                             unsigned int parent_hwirq,
+                                             unsigned int parent_type)
+{
+       fwspec->param_count = 4;
+       fwspec->param[0] = 0;
+       fwspec->param[1] = parent_hwirq;
+       fwspec->param[2] = 0;
+       fwspec->param[3] = parent_type;
+}
+EXPORT_SYMBOL_GPL(gpiochip_populate_parent_fwspec_fourcell);
+
+#else
+
+static int gpiochip_hierarchy_add_domain(struct gpio_chip *gc)
+{
+       return -EINVAL;
+}
+
+static bool gpiochip_hierarchy_is_hierarchical(struct gpio_chip *gc)
+{
+       return false;
+}
+
+#endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */
+
 /**
  * gpiochip_irq_map() - maps an IRQ into a GPIO irqchip
  * @d: the irqdomain used by this irqchip
@@ -1749,7 +2020,7 @@ int gpiochip_irq_map(struct irq_domain *d, unsigned int irq,
                     irq_hw_number_t hwirq)
 {
        struct gpio_chip *chip = d->host_data;
-       int err = 0;
+       int ret = 0;
 
        if (!gpiochip_irqchip_irq_valid(chip, hwirq))
                return -ENXIO;
@@ -1767,12 +2038,12 @@ int gpiochip_irq_map(struct irq_domain *d, unsigned int irq,
        irq_set_noprobe(irq);
 
        if (chip->irq.num_parents == 1)
-               err = irq_set_parent(irq, chip->irq.parents[0]);
+               ret = irq_set_parent(irq, chip->irq.parents[0]);
        else if (chip->irq.map)
-               err = irq_set_parent(irq, chip->irq.map[hwirq]);
+               ret = irq_set_parent(irq, chip->irq.map[hwirq]);
 
-       if (err < 0)
-               return err;
+       if (ret < 0)
+               return ret;
 
        /*
         * No set-up of the hardware will happen if IRQ_TYPE_NONE
@@ -1803,6 +2074,11 @@ static const struct irq_domain_ops gpiochip_domain_ops = {
        .xlate  = irq_domain_xlate_twocell,
 };
 
+/*
+ * TODO: move these activate/deactivate in under the hierarchicial
+ * irqchip implementation as static once SPMI and SSBI (all external
+ * users) are phased over.
+ */
 /**
  * gpiochip_irq_domain_activate() - Lock a GPIO to be used as an IRQ
  * @domain: The IRQ domain used by this IRQ chip
@@ -1842,10 +2118,25 @@ EXPORT_SYMBOL_GPL(gpiochip_irq_domain_deactivate);
 
 static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset)
 {
+       struct irq_domain *domain = chip->irq.domain;
+
        if (!gpiochip_irqchip_irq_valid(chip, offset))
                return -ENXIO;
 
-       return irq_create_mapping(chip->irq.domain, offset);
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+       if (irq_domain_is_hierarchy(domain)) {
+               struct irq_fwspec spec;
+
+               spec.fwnode = domain->fwnode;
+               spec.param_count = 2;
+               spec.param[0] = chip->irq.child_offset_to_irq(chip, offset);
+               spec.param[1] = IRQ_TYPE_NONE;
+
+               return irq_create_fwspec_mapping(&spec);
+       }
+#endif
+
+       return irq_create_mapping(domain, offset);
 }
 
 static int gpiochip_irq_reqres(struct irq_data *d)
@@ -1922,7 +2213,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip,
                                struct lock_class_key *request_key)
 {
        struct irq_chip *irqchip = gpiochip->irq.chip;
-       const struct irq_domain_ops *ops;
+       const struct irq_domain_ops *ops = NULL;
        struct device_node *np;
        unsigned int type;
        unsigned int i;
@@ -1958,16 +2249,25 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip,
        gpiochip->irq.lock_key = lock_key;
        gpiochip->irq.request_key = request_key;
 
-       if (gpiochip->irq.domain_ops)
-               ops = gpiochip->irq.domain_ops;
-       else
-               ops = &gpiochip_domain_ops;
-
-       gpiochip->irq.domain = irq_domain_add_simple(np, gpiochip->ngpio,
-                                                    gpiochip->irq.first,
-                                                    ops, gpiochip);
-       if (!gpiochip->irq.domain)
-               return -EINVAL;
+       /* If a parent irqdomain is provided, let's build a hierarchy */
+       if (gpiochip_hierarchy_is_hierarchical(gpiochip)) {
+               int ret = gpiochip_hierarchy_add_domain(gpiochip);
+               if (ret)
+                       return ret;
+       } else {
+               /* Some drivers provide custom irqdomain ops */
+               if (gpiochip->irq.domain_ops)
+                       ops = gpiochip->irq.domain_ops;
+
+               if (!ops)
+                       ops = &gpiochip_domain_ops;
+               gpiochip->irq.domain = irq_domain_add_simple(np,
+                       gpiochip->ngpio,
+                       gpiochip->irq.first,
+                       ops, gpiochip);
+               if (!gpiochip->irq.domain)
+                       return -EINVAL;
+       }
 
        if (gpiochip->irq.parent_handler) {
                void *data = gpiochip->irq.parent_handler_data ?: gpiochip;
@@ -2330,7 +2630,7 @@ EXPORT_SYMBOL_GPL(gpiochip_remove_pin_ranges);
 static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
 {
        struct gpio_chip        *chip = desc->gdev->chip;
-       int                     status;
+       int                     ret;
        unsigned long           flags;
        unsigned                offset;
 
@@ -2348,10 +2648,10 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
 
        if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
                desc_set_label(desc, label ? : "?");
-               status = 0;
+               ret = 0;
        } else {
                kfree_const(label);
-               status = -EBUSY;
+               ret = -EBUSY;
                goto done;
        }
 
@@ -2360,12 +2660,12 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
                spin_unlock_irqrestore(&gpio_lock, flags);
                offset = gpio_chip_hwgpio(desc);
                if (gpiochip_line_is_valid(chip, offset))
-                       status = chip->request(chip, offset);
+                       ret = chip->request(chip, offset);
                else
-                       status = -EINVAL;
+                       ret = -EINVAL;
                spin_lock_irqsave(&gpio_lock, flags);
 
-               if (status < 0) {
+               if (ret < 0) {
                        desc_set_label(desc, NULL);
                        kfree_const(label);
                        clear_bit(FLAG_REQUESTED, &desc->flags);
@@ -2380,7 +2680,7 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
        }
 done:
        spin_unlock_irqrestore(&gpio_lock, flags);
-       return status;
+       return ret;
 }
 
 /*
@@ -2423,24 +2723,24 @@ static int validate_desc(const struct gpio_desc *desc, const char *func)
 
 int gpiod_request(struct gpio_desc *desc, const char *label)
 {
-       int status = -EPROBE_DEFER;
+       int ret = -EPROBE_DEFER;
        struct gpio_device *gdev;
 
        VALIDATE_DESC(desc);
        gdev = desc->gdev;
 
        if (try_module_get(gdev->owner)) {
-               status = gpiod_request_commit(desc, label);
-               if (status < 0)
+               ret = gpiod_request_commit(desc, label);
+               if (ret < 0)
                        module_put(gdev->owner);
                else
                        get_device(&gdev->dev);
        }
 
-       if (status)
-               gpiod_dbg(desc, "%s: status %d\n", __func__, status);
+       if (ret)
+               gpiod_dbg(desc, "%s: status %d\n", __func__, ret);
 
-       return status;
+       return ret;
 }
 
 static bool gpiod_free_commit(struct gpio_desc *desc)
@@ -2542,22 +2842,22 @@ struct gpio_desc *gpiochip_request_own_desc(struct gpio_chip *chip, u16 hwnum,
                                            enum gpiod_flags dflags)
 {
        struct gpio_desc *desc = gpiochip_get_desc(chip, hwnum);
-       int err;
+       int ret;
 
        if (IS_ERR(desc)) {
                chip_err(chip, "failed to get GPIO descriptor\n");
                return desc;
        }
 
-       err = gpiod_request_commit(desc, label);
-       if (err < 0)
-               return ERR_PTR(err);
+       ret = gpiod_request_commit(desc, label);
+       if (ret < 0)
+               return ERR_PTR(ret);
 
-       err = gpiod_configure_flags(desc, label, lflags, dflags);
-       if (err) {
+       ret = gpiod_configure_flags(desc, label, lflags, dflags);
+       if (ret) {
                chip_err(chip, "setup of own GPIO %s failed\n", label);
                gpiod_free_commit(desc);
-               return ERR_PTR(err);
+               return ERR_PTR(ret);
        }
 
        return desc;
@@ -2620,7 +2920,7 @@ static int gpio_set_config(struct gpio_chip *gc, unsigned offset,
 int gpiod_direction_input(struct gpio_desc *desc)
 {
        struct gpio_chip        *chip;
-       int                     status = 0;
+       int                     ret = 0;
 
        VALIDATE_DESC(desc);
        chip = desc->gdev->chip;
@@ -2644,7 +2944,7 @@ int gpiod_direction_input(struct gpio_desc *desc)
         * assume we are in input mode after this.
         */
        if (chip->direction_input) {
-               status = chip->direction_input(chip, gpio_chip_hwgpio(desc));
+               ret = chip->direction_input(chip, gpio_chip_hwgpio(desc));
        } else if (chip->get_direction &&
                  (chip->get_direction(chip, gpio_chip_hwgpio(desc)) != 1)) {
                gpiod_warn(desc,
@@ -2652,7 +2952,7 @@ int gpiod_direction_input(struct gpio_desc *desc)
                           __func__);
                return -EIO;
        }
-       if (status == 0)
+       if (ret == 0)
                clear_bit(FLAG_IS_OUT, &desc->flags);
 
        if (test_bit(FLAG_PULL_UP, &desc->flags))
@@ -2662,9 +2962,9 @@ int gpiod_direction_input(struct gpio_desc *desc)
                gpio_set_config(chip, gpio_chip_hwgpio(desc),
                                PIN_CONFIG_BIAS_PULL_DOWN);
 
-       trace_gpio_direction(desc_to_gpio(desc), 1, status);
+       trace_gpio_direction(desc_to_gpio(desc), 1, ret);
 
-       return status;
+       return ret;
 }
 EXPORT_SYMBOL_GPL(gpiod_direction_input);
 
@@ -2936,7 +3236,7 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
                                  struct gpio_array *array_info,
                                  unsigned long *value_bitmap)
 {
-       int err, i = 0;
+       int ret, i = 0;
 
        /*
         * Validate array_info against desc_array and its size.
@@ -2949,11 +3249,11 @@ int gpiod_get_array_value_complex(bool raw, bool can_sleep,
                if (!can_sleep)
                        WARN_ON(array_info->chip->can_sleep);
 
-               err = gpio_chip_get_multiple(array_info->chip,
+               ret = gpio_chip_get_multiple(array_info->chip,
                                             array_info->get_mask,
                                             value_bitmap);
-               if (err)
-                       return err;
+               if (ret)
+                       return ret;
 
                if (!raw && !bitmap_empty(array_info->invert_mask, array_size))
                        bitmap_xor(value_bitmap, value_bitmap,
@@ -3141,24 +3441,24 @@ EXPORT_SYMBOL_GPL(gpiod_get_array_value);
  */
 static void gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool value)
 {
-       int err = 0;
+       int ret = 0;
        struct gpio_chip *chip = desc->gdev->chip;
        int offset = gpio_chip_hwgpio(desc);
 
        if (value) {
-               err = chip->direction_input(chip, offset);
-               if (!err)
+               ret = chip->direction_input(chip, offset);
+               if (!ret)
                        clear_bit(FLAG_IS_OUT, &desc->flags);
        } else {
-               err = chip->direction_output(chip, offset, 0);
-               if (!err)
+               ret = chip->direction_output(chip, offset, 0);
+               if (!ret)
                        set_bit(FLAG_IS_OUT, &desc->flags);
        }
-       trace_gpio_direction(desc_to_gpio(desc), value, err);
-       if (err < 0)
+       trace_gpio_direction(desc_to_gpio(desc), value, ret);
+       if (ret < 0)
                gpiod_err(desc,
                          "%s: Error in set_value for open drain err %d\n",
-                         __func__, err);
+                         __func__, ret);
 }
 
 /*
@@ -3168,24 +3468,24 @@ static void gpio_set_open_drain_value_commit(struct gpio_desc *desc, bool value)
  */
 static void gpio_set_open_source_value_commit(struct gpio_desc *desc, bool value)
 {
-       int err = 0;
+       int ret = 0;
        struct gpio_chip *chip = desc->gdev->chip;
        int offset = gpio_chip_hwgpio(desc);
 
        if (value) {
-               err = chip->direction_output(chip, offset, 1);
-               if (!err)
+               ret = chip->direction_output(chip, offset, 1);
+               if (!ret)
                        set_bit(FLAG_IS_OUT, &desc->flags);
        } else {
-               err = chip->direction_input(chip, offset);
-               if (!err)
+               ret = chip->direction_input(chip, offset);
+               if (!ret)
                        clear_bit(FLAG_IS_OUT, &desc->flags);
        }
-       trace_gpio_direction(desc_to_gpio(desc), !value, err);
-       if (err < 0)
+       trace_gpio_direction(desc_to_gpio(desc), !value, ret);
+       if (ret < 0)
                gpiod_err(desc,
                          "%s: Error in set_value for open source err %d\n",
-                         __func__, err);
+                         __func__, ret);
 }
 
 static void gpiod_set_raw_value_commit(struct gpio_desc *desc, bool value)
@@ -4002,27 +4302,6 @@ static struct gpio_desc *gpiod_find(struct device *dev, const char *con_id,
        return desc;
 }
 
-static int dt_gpio_count(struct device *dev, const char *con_id)
-{
-       int ret;
-       char propname[32];
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(gpio_suffixes); i++) {
-               if (con_id)
-                       snprintf(propname, sizeof(propname), "%s-%s",
-                                con_id, gpio_suffixes[i]);
-               else
-                       snprintf(propname, sizeof(propname), "%s",
-                                gpio_suffixes[i]);
-
-               ret = of_gpio_named_count(dev->of_node, propname);
-               if (ret > 0)
-                       break;
-       }
-       return ret ? ret : -ENOENT;
-}
-
 static int platform_gpio_count(struct device *dev, const char *con_id)
 {
        struct gpiod_lookup_table *table;
@@ -4055,7 +4334,7 @@ int gpiod_count(struct device *dev, const char *con_id)
        int count = -ENOENT;
 
        if (IS_ENABLED(CONFIG_OF) && dev && dev->of_node)
-               count = dt_gpio_count(dev, con_id);
+               count = of_gpio_get_count(dev, con_id);
        else if (IS_ENABLED(CONFIG_ACPI) && dev && ACPI_HANDLE(dev))
                count = acpi_gpio_count(dev, con_id);
 
@@ -4117,7 +4396,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_optional);
 int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
                unsigned long lflags, enum gpiod_flags dflags)
 {
-       int status;
+       int ret;
 
        if (lflags & GPIO_ACTIVE_LOW)
                set_bit(FLAG_ACTIVE_LOW, &desc->flags);
@@ -4150,9 +4429,9 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
        else if (lflags & GPIO_PULL_DOWN)
                set_bit(FLAG_PULL_DOWN, &desc->flags);
 
-       status = gpiod_set_transitory(desc, (lflags & GPIO_TRANSITORY));
-       if (status < 0)
-               return status;
+       ret = gpiod_set_transitory(desc, (lflags & GPIO_TRANSITORY));
+       if (ret < 0)
+               return ret;
 
        /* No particular flag request, return here... */
        if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) {
@@ -4162,12 +4441,12 @@ int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
 
        /* Process flags */
        if (dflags & GPIOD_FLAGS_BIT_DIR_OUT)
-               status = gpiod_direction_output(desc,
+               ret = gpiod_direction_output(desc,
                                !!(dflags & GPIOD_FLAGS_BIT_DIR_VAL));
        else
-               status = gpiod_direction_input(desc);
+               ret = gpiod_direction_input(desc);
 
-       return status;
+       return ret;
 }
 
 /**
@@ -4191,7 +4470,7 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
 {
        unsigned long lookupflags = GPIO_LOOKUP_FLAGS_DEFAULT;
        struct gpio_desc *desc = NULL;
-       int status;
+       int ret;
        /* Maybe we have a device name, maybe not */
        const char *devname = dev ? dev_name(dev) : "?";
 
@@ -4226,9 +4505,9 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
         * If a connection label was passed use that, else attempt to use
         * the device name as label
         */
-       status = gpiod_request(desc, con_id ? con_id : devname);
-       if (status < 0) {
-               if (status == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) {
+       ret = gpiod_request(desc, con_id ? con_id : devname);
+       if (ret < 0) {
+               if (ret == -EBUSY && flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE) {
                        /*
                         * This happens when there are several consumers for
                         * the same GPIO line: we just return here without
@@ -4241,89 +4520,20 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
                                 con_id ? con_id : devname);
                        return desc;
                } else {
-                       return ERR_PTR(status);
+                       return ERR_PTR(ret);
                }
        }
 
-       status = gpiod_configure_flags(desc, con_id, lookupflags, flags);
-       if (status < 0) {
-               dev_dbg(dev, "setup of GPIO %s failed\n", con_id);
-               gpiod_put(desc);
-               return ERR_PTR(status);
-       }
-
-       return desc;
-}
-EXPORT_SYMBOL_GPL(gpiod_get_index);
-
-/**
- * gpiod_get_from_of_node() - obtain a GPIO from an OF node
- * @node:      handle of the OF node
- * @propname:  name of the DT property representing the GPIO
- * @index:     index of the GPIO to obtain for the consumer
- * @dflags:    GPIO initialization flags
- * @label:     label to attach to the requested GPIO
- *
- * Returns:
- * On successful request the GPIO pin is configured in accordance with
- * provided @dflags.
- *
- * In case of error an ERR_PTR() is returned.
- */
-struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
-                                        const char *propname, int index,
-                                        enum gpiod_flags dflags,
-                                        const char *label)
-{
-       unsigned long lflags = GPIO_LOOKUP_FLAGS_DEFAULT;
-       struct gpio_desc *desc;
-       enum of_gpio_flags flags;
-       bool active_low = false;
-       bool single_ended = false;
-       bool open_drain = false;
-       bool transitory = false;
-       int ret;
-
-       desc = of_get_named_gpiod_flags(node, propname,
-                                       index, &flags);
-
-       if (!desc || IS_ERR(desc)) {
-               return desc;
-       }
-
-       active_low = flags & OF_GPIO_ACTIVE_LOW;
-       single_ended = flags & OF_GPIO_SINGLE_ENDED;
-       open_drain = flags & OF_GPIO_OPEN_DRAIN;
-       transitory = flags & OF_GPIO_TRANSITORY;
-
-       ret = gpiod_request(desc, label);
-       if (ret == -EBUSY && (flags & GPIOD_FLAGS_BIT_NONEXCLUSIVE))
-               return desc;
-       if (ret)
-               return ERR_PTR(ret);
-
-       if (active_low)
-               lflags |= GPIO_ACTIVE_LOW;
-
-       if (single_ended) {
-               if (open_drain)
-                       lflags |= GPIO_OPEN_DRAIN;
-               else
-                       lflags |= GPIO_OPEN_SOURCE;
-       }
-
-       if (transitory)
-               lflags |= GPIO_TRANSITORY;
-
-       ret = gpiod_configure_flags(desc, propname, lflags, dflags);
+       ret = gpiod_configure_flags(desc, con_id, lookupflags, flags);
        if (ret < 0) {
+               dev_dbg(dev, "setup of GPIO %s failed\n", con_id);
                gpiod_put(desc);
                return ERR_PTR(ret);
        }
 
        return desc;
 }
-EXPORT_SYMBOL(gpiod_get_from_of_node);
+EXPORT_SYMBOL_GPL(gpiod_get_index);
 
 /**
  * fwnode_get_named_gpiod - obtain a GPIO from firmware node
@@ -4433,7 +4643,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
        struct gpio_chip *chip;
        struct gpio_desc *local_desc;
        int hwnum;
-       int status;
+       int ret;
 
        chip = gpiod_to_chip(desc);
        hwnum = gpio_chip_hwgpio(desc);
@@ -4441,10 +4651,10 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
        local_desc = gpiochip_request_own_desc(chip, hwnum, name,
                                               lflags, dflags);
        if (IS_ERR(local_desc)) {
-               status = PTR_ERR(local_desc);
+               ret = PTR_ERR(local_desc);
                pr_err("requesting hog GPIO %s (chip %s, offset %d) failed, %d\n",
-                      name, chip->label, hwnum, status);
-               return status;
+                      name, chip->label, hwnum, ret);
+               return ret;
        }
 
        /* Mark GPIO as hogged so it can be identified and removed later */
index 7c52c24..b8b10a4 100644 (file)
@@ -16,9 +16,6 @@
 #include <linux/module.h>
 #include <linux/cdev.h>
 
-enum of_gpio_flags;
-struct acpi_device;
-
 /**
  * struct gpio_device - internal state container for GPIO devices
  * @id: numerical ID number for the GPIO chip
@@ -69,126 +66,9 @@ struct gpio_device {
 #endif
 };
 
-/**
- * struct acpi_gpio_info - ACPI GPIO specific information
- * @adev: reference to ACPI device which consumes GPIO resource
- * @flags: GPIO initialization flags
- * @gpioint: if %true this GPIO is of type GpioInt otherwise type is GpioIo
- * @pin_config: pin bias as provided by ACPI
- * @polarity: interrupt polarity as provided by ACPI
- * @triggering: triggering type as provided by ACPI
- * @quirks: Linux specific quirks as provided by struct acpi_gpio_mapping
- */
-struct acpi_gpio_info {
-       struct acpi_device *adev;
-       enum gpiod_flags flags;
-       bool gpioint;
-       int pin_config;
-       int polarity;
-       int triggering;
-       unsigned int quirks;
-};
-
 /* gpio suffixes used for ACPI and device tree lookup */
 static __maybe_unused const char * const gpio_suffixes[] = { "gpios", "gpio" };
 
-#ifdef CONFIG_OF_GPIO
-struct gpio_desc *of_find_gpio(struct device *dev,
-                              const char *con_id,
-                              unsigned int idx,
-                              unsigned long *lookupflags);
-struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
-                  const char *list_name, int index, enum of_gpio_flags *flags);
-int of_gpiochip_add(struct gpio_chip *gc);
-void of_gpiochip_remove(struct gpio_chip *gc);
-#else
-static inline struct gpio_desc *of_find_gpio(struct device *dev,
-                                            const char *con_id,
-                                            unsigned int idx,
-                                            unsigned long *lookupflags)
-{
-       return ERR_PTR(-ENOENT);
-}
-static inline struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
-                  const char *list_name, int index, enum of_gpio_flags *flags)
-{
-       return ERR_PTR(-ENOENT);
-}
-static inline int of_gpiochip_add(struct gpio_chip *gc) { return 0; }
-static inline void of_gpiochip_remove(struct gpio_chip *gc) { }
-#endif /* CONFIG_OF_GPIO */
-
-#ifdef CONFIG_ACPI
-void acpi_gpiochip_add(struct gpio_chip *chip);
-void acpi_gpiochip_remove(struct gpio_chip *chip);
-
-void acpi_gpiochip_request_interrupts(struct gpio_chip *chip);
-void acpi_gpiochip_free_interrupts(struct gpio_chip *chip);
-
-int acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags,
-                                struct acpi_gpio_info *info);
-int acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
-                                       struct acpi_gpio_info *info);
-
-struct gpio_desc *acpi_find_gpio(struct device *dev,
-                                const char *con_id,
-                                unsigned int idx,
-                                enum gpiod_flags *dflags,
-                                unsigned long *lookupflags);
-struct gpio_desc *acpi_node_get_gpiod(struct fwnode_handle *fwnode,
-                                     const char *propname, int index,
-                                     struct acpi_gpio_info *info);
-
-int acpi_gpio_count(struct device *dev, const char *con_id);
-
-bool acpi_can_fallback_to_crs(struct acpi_device *adev, const char *con_id);
-#else
-static inline void acpi_gpiochip_add(struct gpio_chip *chip) { }
-static inline void acpi_gpiochip_remove(struct gpio_chip *chip) { }
-
-static inline void
-acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { }
-
-static inline void
-acpi_gpiochip_free_interrupts(struct gpio_chip *chip) { }
-
-static inline int
-acpi_gpio_update_gpiod_flags(enum gpiod_flags *flags, struct acpi_gpio_info *info)
-{
-       return 0;
-}
-static inline int
-acpi_gpio_update_gpiod_lookup_flags(unsigned long *lookupflags,
-                                   struct acpi_gpio_info *info)
-{
-       return 0;
-}
-
-static inline struct gpio_desc *
-acpi_find_gpio(struct device *dev, const char *con_id,
-              unsigned int idx, enum gpiod_flags *dflags,
-              unsigned long *lookupflags)
-{
-       return ERR_PTR(-ENOENT);
-}
-static inline struct gpio_desc *
-acpi_node_get_gpiod(struct fwnode_handle *fwnode, const char *propname,
-                   int index, struct acpi_gpio_info *info)
-{
-       return ERR_PTR(-ENXIO);
-}
-static inline int acpi_gpio_count(struct device *dev, const char *con_id)
-{
-       return -ENODEV;
-}
-
-static inline bool acpi_can_fallback_to_crs(struct acpi_device *adev,
-                                           const char *con_id)
-{
-       return false;
-}
-#endif
-
 struct gpio_array {
        struct gpio_desc        **desc;
        unsigned int            size;
diff --git a/drivers/gpio/sgpio-aspeed.c b/drivers/gpio/sgpio-aspeed.c
new file mode 100644 (file)
index 0000000..7e99860
--- /dev/null
@@ -0,0 +1,533 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2019 American Megatrends International LLC.
+ *
+ * Author: Karthikeyan Mani <karthikeyanm@amiindia.co.in>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/gpio/driver.h>
+#include <linux/hashtable.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+
+#define MAX_NR_SGPIO                   80
+
+#define ASPEED_SGPIO_CTRL              0x54
+
+#define ASPEED_SGPIO_PINS_MASK         GENMASK(9, 6)
+#define ASPEED_SGPIO_CLK_DIV_MASK      GENMASK(31, 16)
+#define ASPEED_SGPIO_ENABLE            BIT(0)
+
+struct aspeed_sgpio {
+       struct gpio_chip chip;
+       struct clk *pclk;
+       spinlock_t lock;
+       void __iomem *base;
+       uint32_t dir_in[3];
+       int irq;
+};
+
+struct aspeed_sgpio_bank {
+       uint16_t    val_regs;
+       uint16_t    rdata_reg;
+       uint16_t    irq_regs;
+       const char  names[4][3];
+};
+
+/*
+ * Note: The "value" register returns the input value when the GPIO is
+ *      configured as an input.
+ *
+ *      The "rdata" register returns the output value when the GPIO is
+ *      configured as an output.
+ */
+static const struct aspeed_sgpio_bank aspeed_sgpio_banks[] = {
+       {
+               .val_regs = 0x0000,
+               .rdata_reg = 0x0070,
+               .irq_regs = 0x0004,
+               .names = { "A", "B", "C", "D" },
+       },
+       {
+               .val_regs = 0x001C,
+               .rdata_reg = 0x0074,
+               .irq_regs = 0x0020,
+               .names = { "E", "F", "G", "H" },
+       },
+       {
+               .val_regs = 0x0038,
+               .rdata_reg = 0x0078,
+               .irq_regs = 0x003C,
+               .names = { "I", "J" },
+       },
+};
+
+enum aspeed_sgpio_reg {
+       reg_val,
+       reg_rdata,
+       reg_irq_enable,
+       reg_irq_type0,
+       reg_irq_type1,
+       reg_irq_type2,
+       reg_irq_status,
+};
+
+#define GPIO_VAL_VALUE      0x00
+#define GPIO_IRQ_ENABLE     0x00
+#define GPIO_IRQ_TYPE0      0x04
+#define GPIO_IRQ_TYPE1      0x08
+#define GPIO_IRQ_TYPE2      0x0C
+#define GPIO_IRQ_STATUS     0x10
+
+static void __iomem *bank_reg(struct aspeed_sgpio *gpio,
+                                    const struct aspeed_sgpio_bank *bank,
+                                    const enum aspeed_sgpio_reg reg)
+{
+       switch (reg) {
+       case reg_val:
+               return gpio->base + bank->val_regs + GPIO_VAL_VALUE;
+       case reg_rdata:
+               return gpio->base + bank->rdata_reg;
+       case reg_irq_enable:
+               return gpio->base + bank->irq_regs + GPIO_IRQ_ENABLE;
+       case reg_irq_type0:
+               return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE0;
+       case reg_irq_type1:
+               return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE1;
+       case reg_irq_type2:
+               return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE2;
+       case reg_irq_status:
+               return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS;
+       default:
+               /* acturally if code runs to here, it's an error case */
+               BUG_ON(1);
+       }
+}
+
+#define GPIO_BANK(x)    ((x) >> 5)
+#define GPIO_OFFSET(x)  ((x) & 0x1f)
+#define GPIO_BIT(x)     BIT(GPIO_OFFSET(x))
+
+static const struct aspeed_sgpio_bank *to_bank(unsigned int offset)
+{
+       unsigned int bank = GPIO_BANK(offset);
+
+       WARN_ON(bank >= ARRAY_SIZE(aspeed_sgpio_banks));
+       return &aspeed_sgpio_banks[bank];
+}
+
+static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset)
+{
+       struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
+       const struct aspeed_sgpio_bank *bank = to_bank(offset);
+       unsigned long flags;
+       enum aspeed_sgpio_reg reg;
+       bool is_input;
+       int rc = 0;
+
+       spin_lock_irqsave(&gpio->lock, flags);
+
+       is_input = gpio->dir_in[GPIO_BANK(offset)] & GPIO_BIT(offset);
+       reg = is_input ? reg_val : reg_rdata;
+       rc = !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset));
+
+       spin_unlock_irqrestore(&gpio->lock, flags);
+
+       return rc;
+}
+
+static void sgpio_set_value(struct gpio_chip *gc, unsigned int offset, int val)
+{
+       struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
+       const struct aspeed_sgpio_bank *bank = to_bank(offset);
+       void __iomem *addr;
+       u32 reg = 0;
+
+       addr = bank_reg(gpio, bank, reg_val);
+       reg = ioread32(addr);
+
+       if (val)
+               reg |= GPIO_BIT(offset);
+       else
+               reg &= ~GPIO_BIT(offset);
+
+       iowrite32(reg, addr);
+}
+
+static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val)
+{
+       struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
+       unsigned long flags;
+
+       spin_lock_irqsave(&gpio->lock, flags);
+
+       sgpio_set_value(gc, offset, val);
+
+       spin_unlock_irqrestore(&gpio->lock, flags);
+}
+
+static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset)
+{
+       struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
+       unsigned long flags;
+
+       spin_lock_irqsave(&gpio->lock, flags);
+       gpio->dir_in[GPIO_BANK(offset)] |= GPIO_BIT(offset);
+       spin_unlock_irqrestore(&gpio->lock, flags);
+
+       return 0;
+}
+
+static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, int val)
+{
+       struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
+       unsigned long flags;
+
+       spin_lock_irqsave(&gpio->lock, flags);
+
+       gpio->dir_in[GPIO_BANK(offset)] &= ~GPIO_BIT(offset);
+       sgpio_set_value(gc, offset, val);
+
+       spin_unlock_irqrestore(&gpio->lock, flags);
+
+       return 0;
+}
+
+static int aspeed_sgpio_get_direction(struct gpio_chip *gc, unsigned int offset)
+{
+       int dir_status;
+       struct aspeed_sgpio *gpio = gpiochip_get_data(gc);
+       unsigned long flags;
+
+       spin_lock_irqsave(&gpio->lock, flags);
+       dir_status = gpio->dir_in[GPIO_BANK(offset)] & GPIO_BIT(offset);
+       spin_unlock_irqrestore(&gpio->lock, flags);
+
+       return dir_status;
+
+}
+
+static void irqd_to_aspeed_sgpio_data(struct irq_data *d,
+                                       struct aspeed_sgpio **gpio,
+                                       const struct aspeed_sgpio_bank **bank,
+                                       u32 *bit, int *offset)
+{
+       struct aspeed_sgpio *internal;
+
+       *offset = irqd_to_hwirq(d);
+       internal = irq_data_get_irq_chip_data(d);
+       WARN_ON(!internal);
+
+       *gpio = internal;
+       *bank = to_bank(*offset);
+       *bit = GPIO_BIT(*offset);
+}
+
+static void aspeed_sgpio_irq_ack(struct irq_data *d)
+{
+       const struct aspeed_sgpio_bank *bank;
+       struct aspeed_sgpio *gpio;
+       unsigned long flags;
+       void __iomem *status_addr;
+       int offset;
+       u32 bit;
+
+       irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
+
+       status_addr = bank_reg(gpio, bank, reg_irq_status);
+
+       spin_lock_irqsave(&gpio->lock, flags);
+
+       iowrite32(bit, status_addr);
+
+       spin_unlock_irqrestore(&gpio->lock, flags);
+}
+
+static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set)
+{
+       const struct aspeed_sgpio_bank *bank;
+       struct aspeed_sgpio *gpio;
+       unsigned long flags;
+       u32 reg, bit;
+       void __iomem *addr;
+       int offset;
+
+       irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
+       addr = bank_reg(gpio, bank, reg_irq_enable);
+
+       spin_lock_irqsave(&gpio->lock, flags);
+
+       reg = ioread32(addr);
+       if (set)
+               reg |= bit;
+       else
+               reg &= ~bit;
+
+       iowrite32(reg, addr);
+
+       spin_unlock_irqrestore(&gpio->lock, flags);
+}
+
+static void aspeed_sgpio_irq_mask(struct irq_data *d)
+{
+       aspeed_sgpio_irq_set_mask(d, false);
+}
+
+static void aspeed_sgpio_irq_unmask(struct irq_data *d)
+{
+       aspeed_sgpio_irq_set_mask(d, true);
+}
+
+static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type)
+{
+       u32 type0 = 0;
+       u32 type1 = 0;
+       u32 type2 = 0;
+       u32 bit, reg;
+       const struct aspeed_sgpio_bank *bank;
+       irq_flow_handler_t handler;
+       struct aspeed_sgpio *gpio;
+       unsigned long flags;
+       void __iomem *addr;
+       int offset;
+
+       irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset);
+
+       switch (type & IRQ_TYPE_SENSE_MASK) {
+       case IRQ_TYPE_EDGE_BOTH:
+               type2 |= bit;
+               /* fall through */
+       case IRQ_TYPE_EDGE_RISING:
+               type0 |= bit;
+               /* fall through */
+       case IRQ_TYPE_EDGE_FALLING:
+               handler = handle_edge_irq;
+               break;
+       case IRQ_TYPE_LEVEL_HIGH:
+               type0 |= bit;
+               /* fall through */
+       case IRQ_TYPE_LEVEL_LOW:
+               type1 |= bit;
+               handler = handle_level_irq;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       spin_lock_irqsave(&gpio->lock, flags);
+
+       addr = bank_reg(gpio, bank, reg_irq_type0);
+       reg = ioread32(addr);
+       reg = (reg & ~bit) | type0;
+       iowrite32(reg, addr);
+
+       addr = bank_reg(gpio, bank, reg_irq_type1);
+       reg = ioread32(addr);
+       reg = (reg & ~bit) | type1;
+       iowrite32(reg, addr);
+
+       addr = bank_reg(gpio, bank, reg_irq_type2);
+       reg = ioread32(addr);
+       reg = (reg & ~bit) | type2;
+       iowrite32(reg, addr);
+
+       spin_unlock_irqrestore(&gpio->lock, flags);
+
+       irq_set_handler_locked(d, handler);
+
+       return 0;
+}
+
+static void aspeed_sgpio_irq_handler(struct irq_desc *desc)
+{
+       struct gpio_chip *gc = irq_desc_get_handler_data(desc);
+       struct irq_chip *ic = irq_desc_get_chip(desc);
+       struct aspeed_sgpio *data = gpiochip_get_data(gc);
+       unsigned int i, p, girq;
+       unsigned long reg;
+
+       chained_irq_enter(ic, desc);
+
+       for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
+               const struct aspeed_sgpio_bank *bank = &aspeed_sgpio_banks[i];
+
+               reg = ioread32(bank_reg(data, bank, reg_irq_status));
+
+               for_each_set_bit(p, &reg, 32) {
+                       girq = irq_find_mapping(gc->irq.domain, i * 32 + p);
+                       generic_handle_irq(girq);
+               }
+
+       }
+
+       chained_irq_exit(ic, desc);
+}
+
+static struct irq_chip aspeed_sgpio_irqchip = {
+       .name       = "aspeed-sgpio",
+       .irq_ack    = aspeed_sgpio_irq_ack,
+       .irq_mask   = aspeed_sgpio_irq_mask,
+       .irq_unmask = aspeed_sgpio_irq_unmask,
+       .irq_set_type   = aspeed_sgpio_set_type,
+};
+
+static int aspeed_sgpio_setup_irqs(struct aspeed_sgpio *gpio,
+                                  struct platform_device *pdev)
+{
+       int rc, i;
+       const struct aspeed_sgpio_bank *bank;
+       struct gpio_irq_chip *irq;
+
+       rc = platform_get_irq(pdev, 0);
+       if (rc < 0)
+               return rc;
+
+       gpio->irq = rc;
+
+       /* Disable IRQ and clear Interrupt status registers for all SPGIO Pins. */
+       for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
+               bank =  &aspeed_sgpio_banks[i];
+               /* disable irq enable bits */
+               iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_enable));
+               /* clear status bits */
+               iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_status));
+       }
+
+       irq = &gpio->chip.irq;
+       irq->chip = &aspeed_sgpio_irqchip;
+       irq->handler = handle_bad_irq;
+       irq->default_type = IRQ_TYPE_NONE;
+       irq->parent_handler = aspeed_sgpio_irq_handler;
+       irq->parent_handler_data = gpio;
+       irq->parents = &gpio->irq;
+       irq->num_parents = 1;
+
+       /* set IRQ settings and Enable Interrupt */
+       for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) {
+               bank = &aspeed_sgpio_banks[i];
+               /* set falling or level-low irq */
+               iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type0));
+               /* trigger type is edge */
+               iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type1));
+               /* dual edge trigger mode. */
+               iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_type2));
+               /* enable irq */
+               iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_enable));
+       }
+
+       return 0;
+}
+
+static const struct of_device_id aspeed_sgpio_of_table[] = {
+       { .compatible = "aspeed,ast2400-sgpio" },
+       { .compatible = "aspeed,ast2500-sgpio" },
+       {}
+};
+
+MODULE_DEVICE_TABLE(of, aspeed_sgpio_of_table);
+
+static int __init aspeed_sgpio_probe(struct platform_device *pdev)
+{
+       struct aspeed_sgpio *gpio;
+       u32 nr_gpios, sgpio_freq, sgpio_clk_div;
+       int rc;
+       unsigned long apb_freq;
+
+       gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL);
+       if (!gpio)
+               return -ENOMEM;
+
+       gpio->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(gpio->base))
+               return PTR_ERR(gpio->base);
+
+       rc = of_property_read_u32(pdev->dev.of_node, "ngpios", &nr_gpios);
+       if (rc < 0) {
+               dev_err(&pdev->dev, "Could not read ngpios property\n");
+               return -EINVAL;
+       } else if (nr_gpios > MAX_NR_SGPIO) {
+               dev_err(&pdev->dev, "Number of GPIOs exceeds the maximum of %d: %d\n",
+                       MAX_NR_SGPIO, nr_gpios);
+               return -EINVAL;
+       }
+
+       rc = of_property_read_u32(pdev->dev.of_node, "bus-frequency", &sgpio_freq);
+       if (rc < 0) {
+               dev_err(&pdev->dev, "Could not read bus-frequency property\n");
+               return -EINVAL;
+       }
+
+       gpio->pclk = devm_clk_get(&pdev->dev, NULL);
+       if (IS_ERR(gpio->pclk)) {
+               dev_err(&pdev->dev, "devm_clk_get failed\n");
+               return PTR_ERR(gpio->pclk);
+       }
+
+       apb_freq = clk_get_rate(gpio->pclk);
+
+       /*
+        * From the datasheet,
+        *      SGPIO period = 1/PCLK * 2 * (GPIO254[31:16] + 1)
+        *      period = 2 * (GPIO254[31:16] + 1) / PCLK
+        *      frequency = 1 / (2 * (GPIO254[31:16] + 1) / PCLK)
+        *      frequency = PCLK / (2 * (GPIO254[31:16] + 1))
+        *      frequency * 2 * (GPIO254[31:16] + 1) = PCLK
+        *      GPIO254[31:16] = PCLK / (frequency * 2) - 1
+        */
+       if (sgpio_freq == 0)
+               return -EINVAL;
+
+       sgpio_clk_div = (apb_freq / (sgpio_freq * 2)) - 1;
+
+       if (sgpio_clk_div > (1 << 16) - 1)
+               return -EINVAL;
+
+       iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) |
+                 FIELD_PREP(ASPEED_SGPIO_PINS_MASK, (nr_gpios / 8)) |
+                 ASPEED_SGPIO_ENABLE,
+                 gpio->base + ASPEED_SGPIO_CTRL);
+
+       spin_lock_init(&gpio->lock);
+
+       gpio->chip.parent = &pdev->dev;
+       gpio->chip.ngpio = nr_gpios;
+       gpio->chip.direction_input = aspeed_sgpio_dir_in;
+       gpio->chip.direction_output = aspeed_sgpio_dir_out;
+       gpio->chip.get_direction = aspeed_sgpio_get_direction;
+       gpio->chip.request = NULL;
+       gpio->chip.free = NULL;
+       gpio->chip.get = aspeed_sgpio_get;
+       gpio->chip.set = aspeed_sgpio_set;
+       gpio->chip.set_config = NULL;
+       gpio->chip.label = dev_name(&pdev->dev);
+       gpio->chip.base = -1;
+
+       /* set all SGPIO pins as input (1). */
+       memset(gpio->dir_in, 0xff, sizeof(gpio->dir_in));
+
+       aspeed_sgpio_setup_irqs(gpio, pdev);
+
+       rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio);
+       if (rc < 0)
+               return rc;
+
+       return 0;
+}
+
+static struct platform_driver aspeed_sgpio_driver = {
+       .driver = {
+               .name = KBUILD_MODNAME,
+               .of_match_table = aspeed_sgpio_of_table,
+       },
+};
+
+module_platform_driver_probe(aspeed_sgpio_driver, aspeed_sgpio_probe);
+MODULE_DESCRIPTION("Aspeed Serial GPIO Driver");
+MODULE_LICENSE("GPL");
index 9b384a9..3e35a8f 100644 (file)
@@ -574,6 +574,7 @@ static const struct amdgpu_px_quirk amdgpu_px_quirk_list[] = {
        { 0x1002, 0x6900, 0x1002, 0x0124, AMDGPU_PX_QUIRK_FORCE_ATPX },
        { 0x1002, 0x6900, 0x1028, 0x0812, AMDGPU_PX_QUIRK_FORCE_ATPX },
        { 0x1002, 0x6900, 0x1028, 0x0813, AMDGPU_PX_QUIRK_FORCE_ATPX },
+       { 0x1002, 0x699f, 0x1028, 0x0814, AMDGPU_PX_QUIRK_FORCE_ATPX },
        { 0x1002, 0x6900, 0x1025, 0x125A, AMDGPU_PX_QUIRK_FORCE_ATPX },
        { 0x1002, 0x6900, 0x17AA, 0x3806, AMDGPU_PX_QUIRK_FORCE_ATPX },
        { 0, 0, 0, 0, 0 },
index f539a2a..7398b48 100644 (file)
@@ -534,21 +534,24 @@ int amdgpu_ctx_wait_prev_fence(struct amdgpu_ctx *ctx,
                               struct drm_sched_entity *entity)
 {
        struct amdgpu_ctx_entity *centity = to_amdgpu_ctx_entity(entity);
-       unsigned idx = centity->sequence & (amdgpu_sched_jobs - 1);
-       struct dma_fence *other = centity->fences[idx];
+       struct dma_fence *other;
+       unsigned idx;
+       long r;
 
-       if (other) {
-               signed long r;
-               r = dma_fence_wait(other, true);
-               if (r < 0) {
-                       if (r != -ERESTARTSYS)
-                               DRM_ERROR("Error (%ld) waiting for fence!\n", r);
+       spin_lock(&ctx->ring_lock);
+       idx = centity->sequence & (amdgpu_sched_jobs - 1);
+       other = dma_fence_get(centity->fences[idx]);
+       spin_unlock(&ctx->ring_lock);
 
-                       return r;
-               }
-       }
+       if (!other)
+               return 0;
 
-       return 0;
+       r = dma_fence_wait(other, true);
+       if (r < 0 && r != -ERESTARTSYS)
+               DRM_ERROR("Error (%ld) waiting for fence!\n", r);
+
+       dma_fence_put(other);
+       return r;
 }
 
 void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
index 4ea67f9..c066e1d 100644 (file)
@@ -596,14 +596,14 @@ static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev)
        case CHIP_VEGA20:
                break;
        case CHIP_RAVEN:
-               if (adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8)
-                       break;
-               if ((adev->gfx.rlc_fw_version != 106 &&
-                    adev->gfx.rlc_fw_version < 531) ||
-                   (adev->gfx.rlc_fw_version == 53815) ||
-                   (adev->gfx.rlc_feature_version < 1) ||
-                   !adev->gfx.rlc.is_rlc_v2_1)
+               if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8)
+                       &&((adev->gfx.rlc_fw_version != 106 &&
+                            adev->gfx.rlc_fw_version < 531) ||
+                           (adev->gfx.rlc_fw_version == 53815) ||
+                           (adev->gfx.rlc_feature_version < 1) ||
+                           !adev->gfx.rlc.is_rlc_v2_1))
                        adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
+
                if (adev->pm.pp_feature & PP_GFXOFF_MASK)
                        adev->pg_flags |= AMD_PG_SUPPORT_GFX_PG |
                                AMD_PG_SUPPORT_CP |
index f27c6fb..90c4e87 100644 (file)
@@ -2101,7 +2101,11 @@ static int vega20_get_gpu_power(struct pp_hwmgr *hwmgr,
        if (ret)
                return ret;
 
-       *query = metrics_table.CurrSocketPower << 8;
+       /* For the 40.46 release, they changed the value name */
+       if (hwmgr->smu_version == 0x282e00)
+               *query = metrics_table.AverageSocketPower << 8;
+       else
+               *query = metrics_table.CurrSocketPower << 8;
 
        return ret;
 }
@@ -2349,12 +2353,16 @@ static int vega20_force_dpm_highest(struct pp_hwmgr *hwmgr)
                data->dpm_table.soc_table.dpm_state.soft_max_level =
                data->dpm_table.soc_table.dpm_levels[soft_level].value;
 
-       ret = vega20_upload_dpm_min_level(hwmgr, 0xFFFFFFFF);
+       ret = vega20_upload_dpm_min_level(hwmgr, FEATURE_DPM_GFXCLK_MASK |
+                                                FEATURE_DPM_UCLK_MASK |
+                                                FEATURE_DPM_SOCCLK_MASK);
        PP_ASSERT_WITH_CODE(!ret,
                        "Failed to upload boot level to highest!",
                        return ret);
 
-       ret = vega20_upload_dpm_max_level(hwmgr, 0xFFFFFFFF);
+       ret = vega20_upload_dpm_max_level(hwmgr, FEATURE_DPM_GFXCLK_MASK |
+                                                FEATURE_DPM_UCLK_MASK |
+                                                FEATURE_DPM_SOCCLK_MASK);
        PP_ASSERT_WITH_CODE(!ret,
                        "Failed to upload dpm max level to highest!",
                        return ret);
@@ -2387,12 +2395,16 @@ static int vega20_force_dpm_lowest(struct pp_hwmgr *hwmgr)
                data->dpm_table.soc_table.dpm_state.soft_max_level =
                data->dpm_table.soc_table.dpm_levels[soft_level].value;
 
-       ret = vega20_upload_dpm_min_level(hwmgr, 0xFFFFFFFF);
+       ret = vega20_upload_dpm_min_level(hwmgr, FEATURE_DPM_GFXCLK_MASK |
+                                                FEATURE_DPM_UCLK_MASK |
+                                                FEATURE_DPM_SOCCLK_MASK);
        PP_ASSERT_WITH_CODE(!ret,
                        "Failed to upload boot level to highest!",
                        return ret);
 
-       ret = vega20_upload_dpm_max_level(hwmgr, 0xFFFFFFFF);
+       ret = vega20_upload_dpm_max_level(hwmgr, FEATURE_DPM_GFXCLK_MASK |
+                                                FEATURE_DPM_UCLK_MASK |
+                                                FEATURE_DPM_SOCCLK_MASK);
        PP_ASSERT_WITH_CODE(!ret,
                        "Failed to upload dpm max level to highest!",
                        return ret);
@@ -2403,14 +2415,54 @@ static int vega20_force_dpm_lowest(struct pp_hwmgr *hwmgr)
 
 static int vega20_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
 {
+       struct vega20_hwmgr *data =
+                       (struct vega20_hwmgr *)(hwmgr->backend);
+       uint32_t soft_min_level, soft_max_level;
        int ret = 0;
 
-       ret = vega20_upload_dpm_min_level(hwmgr, 0xFFFFFFFF);
+       /* gfxclk soft min/max settings */
+       soft_min_level =
+               vega20_find_lowest_dpm_level(&(data->dpm_table.gfx_table));
+       soft_max_level =
+               vega20_find_highest_dpm_level(&(data->dpm_table.gfx_table));
+
+       data->dpm_table.gfx_table.dpm_state.soft_min_level =
+               data->dpm_table.gfx_table.dpm_levels[soft_min_level].value;
+       data->dpm_table.gfx_table.dpm_state.soft_max_level =
+               data->dpm_table.gfx_table.dpm_levels[soft_max_level].value;
+
+       /* uclk soft min/max settings */
+       soft_min_level =
+               vega20_find_lowest_dpm_level(&(data->dpm_table.mem_table));
+       soft_max_level =
+               vega20_find_highest_dpm_level(&(data->dpm_table.mem_table));
+
+       data->dpm_table.mem_table.dpm_state.soft_min_level =
+               data->dpm_table.mem_table.dpm_levels[soft_min_level].value;
+       data->dpm_table.mem_table.dpm_state.soft_max_level =
+               data->dpm_table.mem_table.dpm_levels[soft_max_level].value;
+
+       /* socclk soft min/max settings */
+       soft_min_level =
+               vega20_find_lowest_dpm_level(&(data->dpm_table.soc_table));
+       soft_max_level =
+               vega20_find_highest_dpm_level(&(data->dpm_table.soc_table));
+
+       data->dpm_table.soc_table.dpm_state.soft_min_level =
+               data->dpm_table.soc_table.dpm_levels[soft_min_level].value;
+       data->dpm_table.soc_table.dpm_state.soft_max_level =
+               data->dpm_table.soc_table.dpm_levels[soft_max_level].value;
+
+       ret = vega20_upload_dpm_min_level(hwmgr, FEATURE_DPM_GFXCLK_MASK |
+                                                FEATURE_DPM_UCLK_MASK |
+                                                FEATURE_DPM_SOCCLK_MASK);
        PP_ASSERT_WITH_CODE(!ret,
                        "Failed to upload DPM Bootup Levels!",
                        return ret);
 
-       ret = vega20_upload_dpm_max_level(hwmgr, 0xFFFFFFFF);
+       ret = vega20_upload_dpm_max_level(hwmgr, FEATURE_DPM_GFXCLK_MASK |
+                                                FEATURE_DPM_UCLK_MASK |
+                                                FEATURE_DPM_SOCCLK_MASK);
        PP_ASSERT_WITH_CODE(!ret,
                        "Failed to upload DPM Max Levels!",
                        return ret);
index dd6fd1c..6a14497 100644 (file)
@@ -3050,6 +3050,7 @@ static int vega20_get_fan_speed_percent(struct smu_context *smu,
 
 static int vega20_get_gpu_power(struct smu_context *smu, uint32_t *value)
 {
+       uint32_t smu_version;
        int ret = 0;
        SmuMetrics_t metrics;
 
@@ -3060,7 +3061,15 @@ static int vega20_get_gpu_power(struct smu_context *smu, uint32_t *value)
        if (ret)
                return ret;
 
-       *value = metrics.CurrSocketPower << 8;
+       ret = smu_get_smc_version(smu, NULL, &smu_version);
+       if (ret)
+               return ret;
+
+       /* For the 40.46 release, they changed the value name */
+       if (smu_version == 0x282e00)
+               *value = metrics.AverageSocketPower << 8;
+       else
+               *value = metrics.CurrSocketPower << 8;
 
        return 0;
 }
index a0eabc1..9d4d507 100644 (file)
@@ -127,7 +127,7 @@ static int komeda_parse_pipe_dt(struct komeda_dev *mdev, struct device_node *np)
        pipe->of_output_port =
                of_graph_get_port_by_id(np, KOMEDA_OF_PORT_OUTPUT);
 
-       pipe->of_node = np;
+       pipe->of_node = of_node_get(np);
 
        return 0;
 }
index d50e75f..69d9e26 100644 (file)
@@ -14,8 +14,8 @@
 #include <drm/drm_gem_cma_helper.h>
 #include <drm/drm_gem_framebuffer_helper.h>
 #include <drm/drm_irq.h>
-#include <drm/drm_vblank.h>
 #include <drm/drm_probe_helper.h>
+#include <drm/drm_vblank.h>
 
 #include "komeda_dev.h"
 #include "komeda_framebuffer.h"
@@ -147,7 +147,6 @@ static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc,
        struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc_st);
        struct komeda_plane_state *kplane_st;
        struct drm_plane_state *plane_st;
-       struct drm_framebuffer *fb;
        struct drm_plane *plane;
        struct list_head zorder_list;
        int order = 0, err;
@@ -173,7 +172,6 @@ static int komeda_crtc_normalize_zpos(struct drm_crtc *crtc,
 
        list_for_each_entry(kplane_st, &zorder_list, zlist_node) {
                plane_st = &kplane_st->base;
-               fb = plane_st->fb;
                plane = plane_st->plane;
 
                plane_st->normalized_zpos = order++;
@@ -206,7 +204,7 @@ static int komeda_kms_check(struct drm_device *dev,
                            struct drm_atomic_state *state)
 {
        struct drm_crtc *crtc;
-       struct drm_crtc_state *old_crtc_st, *new_crtc_st;
+       struct drm_crtc_state *new_crtc_st;
        int i, err;
 
        err = drm_atomic_helper_check_modeset(dev, state);
@@ -217,7 +215,7 @@ static int komeda_kms_check(struct drm_device *dev,
         * so need to add all affected_planes (even unchanged) to
         * drm_atomic_state.
         */
-       for_each_oldnew_crtc_in_state(state, crtc, old_crtc_st, new_crtc_st, i) {
+       for_each_new_crtc_in_state(state, crtc, new_crtc_st, i) {
                err = drm_atomic_add_affected_planes(state, crtc);
                if (err)
                        return err;
@@ -308,11 +306,11 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
                               komeda_kms_irq_handler, IRQF_SHARED,
                               drm->driver->name, drm);
        if (err)
-               goto cleanup_mode_config;
+               goto free_component_binding;
 
        err = mdev->funcs->enable_irq(mdev);
        if (err)
-               goto cleanup_mode_config;
+               goto free_component_binding;
 
        drm->irq_enabled = true;
 
@@ -320,15 +318,21 @@ struct komeda_kms_dev *komeda_kms_attach(struct komeda_dev *mdev)
 
        err = drm_dev_register(drm, 0);
        if (err)
-               goto cleanup_mode_config;
+               goto free_interrupts;
 
        return kms;
 
-cleanup_mode_config:
+free_interrupts:
        drm_kms_helper_poll_fini(drm);
        drm->irq_enabled = false;
+       mdev->funcs->disable_irq(mdev);
+free_component_binding:
+       component_unbind_all(mdev->dev, drm);
+cleanup_mode_config:
        drm_mode_config_cleanup(drm);
        komeda_kms_cleanup_private_objs(kms);
+       drm->dev_private = NULL;
+       drm_dev_put(drm);
 free_kms:
        kfree(kms);
        return ERR_PTR(err);
@@ -339,13 +343,14 @@ void komeda_kms_detach(struct komeda_kms_dev *kms)
        struct drm_device *drm = &kms->base;
        struct komeda_dev *mdev = drm->dev_private;
 
-       drm->irq_enabled = false;
-       mdev->funcs->disable_irq(mdev);
        drm_dev_unregister(drm);
        drm_kms_helper_poll_fini(drm);
+       drm_atomic_helper_shutdown(drm);
+       drm->irq_enabled = false;
+       mdev->funcs->disable_irq(mdev);
        component_unbind_all(mdev->dev, drm);
-       komeda_kms_cleanup_private_objs(kms);
        drm_mode_config_cleanup(drm);
+       komeda_kms_cleanup_private_objs(kms);
        drm->dev_private = NULL;
        drm_dev_put(drm);
 }
index a90bcbb..14b6831 100644 (file)
@@ -480,6 +480,7 @@ void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,
                                   struct seq_file *sf);
 
 /* component APIs */
+extern __printf(10, 11)
 struct komeda_component *
 komeda_component_add(struct komeda_pipeline *pipe,
                     size_t comp_sz, u32 id, u32 hw_id,
index 617e1f7..2851cac 100644 (file)
@@ -148,7 +148,7 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms,
        if (!kcrtc->master->wb_layer)
                return 0;
 
-       kwb_conn = kzalloc(sizeof(*wb_conn), GFP_KERNEL);
+       kwb_conn = kzalloc(sizeof(*kwb_conn), GFP_KERNEL);
        if (!kwb_conn)
                return -ENOMEM;
 
index b0369e6..c814bce 100644 (file)
@@ -1454,6 +1454,7 @@ static int drm_mode_parse_cmdline_refresh(const char *str, char **end_ptr,
 }
 
 static int drm_mode_parse_cmdline_extra(const char *str, int length,
+                                       bool freestanding,
                                        const struct drm_connector *connector,
                                        struct drm_cmdline_mode *mode)
 {
@@ -1462,9 +1463,15 @@ static int drm_mode_parse_cmdline_extra(const char *str, int length,
        for (i = 0; i < length; i++) {
                switch (str[i]) {
                case 'i':
+                       if (freestanding)
+                               return -EINVAL;
+
                        mode->interlace = true;
                        break;
                case 'm':
+                       if (freestanding)
+                               return -EINVAL;
+
                        mode->margins = true;
                        break;
                case 'D':
@@ -1542,6 +1549,7 @@ static int drm_mode_parse_cmdline_res_mode(const char *str, unsigned int length,
                        if (extras) {
                                int ret = drm_mode_parse_cmdline_extra(end_ptr + i,
                                                                       1,
+                                                                      false,
                                                                       connector,
                                                                       mode);
                                if (ret)
@@ -1669,6 +1677,22 @@ static int drm_mode_parse_cmdline_options(char *str, size_t len,
        return 0;
 }
 
+static const char * const drm_named_modes_whitelist[] = {
+       "NTSC",
+       "PAL",
+};
+
+static bool drm_named_mode_is_in_whitelist(const char *mode, unsigned int size)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(drm_named_modes_whitelist); i++)
+               if (!strncmp(mode, drm_named_modes_whitelist[i], size))
+                       return true;
+
+       return false;
+}
+
 /**
  * drm_mode_parse_command_line_for_connector - parse command line modeline for connector
  * @mode_option: optional per connector mode option
@@ -1725,16 +1749,30 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
         * bunch of things:
         *   - We need to make sure that the first character (which
         *     would be our resolution in X) is a digit.
-        *   - However, if the X resolution is missing, then we end up
-        *     with something like x<yres>, with our first character
-        *     being an alpha-numerical character, which would be
-        *     considered a named mode.
+        *   - If not, then it's either a named mode or a force on/off.
+        *     To distinguish between the two, we need to run the
+        *     extra parsing function, and if not, then we consider it
+        *     a named mode.
         *
         * If this isn't enough, we should add more heuristics here,
         * and matching unit-tests.
         */
-       if (!isdigit(name[0]) && name[0] != 'x')
+       if (!isdigit(name[0]) && name[0] != 'x') {
+               unsigned int namelen = strlen(name);
+
+               /*
+                * Only the force on/off options can be in that case,
+                * and they all take a single character.
+                */
+               if (namelen == 1) {
+                       ret = drm_mode_parse_cmdline_extra(name, namelen, true,
+                                                          connector, mode);
+                       if (!ret)
+                               return true;
+               }
+
                named_mode = true;
+       }
 
        /* Try to locate the bpp and refresh specifiers, if any */
        bpp_ptr = strchr(name, '-');
@@ -1772,6 +1810,10 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
        if (named_mode) {
                if (mode_end + 1 > DRM_DISPLAY_MODE_LEN)
                        return false;
+
+               if (!drm_named_mode_is_in_whitelist(name, mode_end))
+                       return false;
+
                strscpy(mode->name, name, mode_end + 1);
        } else {
                ret = drm_mode_parse_cmdline_res_mode(name, mode_end,
@@ -1811,7 +1853,7 @@ bool drm_mode_parse_command_line_for_connector(const char *mode_option,
            extra_ptr != options_ptr) {
                int len = strlen(name) - (extra_ptr - name);
 
-               ret = drm_mode_parse_cmdline_extra(extra_ptr, len,
+               ret = drm_mode_parse_cmdline_extra(extra_ptr, len, false,
                                                   connector, mode);
                if (ret)
                        return false;
index 60652eb..8aa6a31 100644 (file)
@@ -128,7 +128,15 @@ static int intel_dp_mst_compute_config(struct intel_encoder *encoder,
        limits.max_lane_count = intel_dp_max_lane_count(intel_dp);
 
        limits.min_bpp = intel_dp_min_bpp(pipe_config);
-       limits.max_bpp = pipe_config->pipe_bpp;
+       /*
+        * FIXME: If all the streams can't fit into the link with
+        * their current pipe_bpp we should reduce pipe_bpp across
+        * the board until things start to fit. Until then we
+        * limit to <= 8bpc since that's what was hardcoded for all
+        * MST streams previously. This hack should be removed once
+        * we have the proper retry logic in place.
+        */
+       limits.max_bpp = min(pipe_config->pipe_bpp, 24);
 
        intel_dp_adjust_compliance_config(intel_dp, pipe_config, &limits);
 
@@ -539,7 +547,15 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo
 
        intel_attach_force_audio_property(connector);
        intel_attach_broadcast_rgb_property(connector);
-       drm_connector_attach_max_bpc_property(connector, 6, 12);
+
+       /*
+        * Reuse the prop from the SST connector because we're
+        * not allowed to create new props after device registration.
+        */
+       connector->max_bpc_property =
+               intel_dp->attached_connector->base.max_bpc_property;
+       if (connector->max_bpc_property)
+               drm_connector_attach_max_bpc_property(connector, 6, 12);
 
        return connector;
 
index ffec807..f413904 100644 (file)
@@ -541,7 +541,7 @@ static void intel_configure_pps_for_dsc_encoder(struct intel_encoder *encoder,
        pps_val |= DSC_PIC_HEIGHT(vdsc_cfg->pic_height) |
                DSC_PIC_WIDTH(vdsc_cfg->pic_width / num_vdsc_instances);
        DRM_INFO("PPS2 = 0x%08x\n", pps_val);
-       if (encoder->type == INTEL_OUTPUT_EDP) {
+       if (cpu_transcoder == TRANSCODER_EDP) {
                I915_WRITE(DSCA_PICTURE_PARAMETER_SET_2, pps_val);
                /*
                 * If 2 VDSC instances are needed, configure PPS for second
index 2caa594..528b616 100644 (file)
@@ -664,15 +664,7 @@ i915_gem_userptr_put_pages(struct drm_i915_gem_object *obj,
 
        for_each_sgt_page(page, sgt_iter, pages) {
                if (obj->mm.dirty)
-                       /*
-                        * As this may not be anonymous memory (e.g. shmem)
-                        * but exist on a real mapping, we have to lock
-                        * the page in order to dirty it -- holding
-                        * the page reference is not sufficient to
-                        * prevent the inode from being truncated.
-                        * Play safe and take the lock.
-                        */
-                       set_page_dirty_lock(page);
+                       set_page_dirty(page);
 
                mark_page_accessed(page);
                put_page(page);
index 98dfb08..99e8242 100644 (file)
@@ -308,11 +308,6 @@ static void gen9_ctx_workarounds_init(struct intel_engine_cs *engine,
                          FLOW_CONTROL_ENABLE |
                          PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
 
-       /* Syncing dependencies between camera and graphics:skl,bxt,kbl */
-       if (!IS_COFFEELAKE(i915))
-               WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
-                                 GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC);
-
        /* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl,glk,cfl */
        /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl,cfl */
        WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
index f62e339..bac1ee9 100644 (file)
@@ -1598,6 +1598,12 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
 
        pci_set_master(pdev);
 
+       /*
+        * We don't have a max segment size, so set it to the max so sg's
+        * debugging layer doesn't complain
+        */
+       dma_set_max_seg_size(&pdev->dev, UINT_MAX);
+
        /* overlay on gen2 is broken and can't address above 1G */
        if (IS_GEN(dev_priv, 2)) {
                ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(30));
index 94d3992..724627a 100644 (file)
@@ -101,6 +101,9 @@ static struct _balloon_info_ bl_info;
 static void vgt_deballoon_space(struct i915_ggtt *ggtt,
                                struct drm_mm_node *node)
 {
+       if (!drm_mm_node_allocated(node))
+               return;
+
        DRM_DEBUG_DRIVER("deballoon space: range [0x%llx - 0x%llx] %llu KiB.\n",
                         node->start,
                         node->start + node->size,
index e9f9e9f..6381652 100644 (file)
@@ -656,10 +656,9 @@ static int ingenic_drm_probe(struct platform_device *pdev)
                return ret;
        }
 
-       if (panel) {
+       if (panel)
                bridge = devm_drm_panel_bridge_add(dev, panel,
-                                                  DRM_MODE_CONNECTOR_Unknown);
-       }
+                                                  DRM_MODE_CONNECTOR_DPI);
 
        priv->dma_hwdesc = dma_alloc_coherent(dev, sizeof(*priv->dma_hwdesc),
                                              &priv->dma_hwdesc_phys,
index 477c0f7..b609dc0 100644 (file)
@@ -342,7 +342,7 @@ int lima_gem_wait(struct drm_file *file, u32 handle, u32 op, s64 timeout_ns)
        timeout = drm_timeout_abs_to_jiffies(timeout_ns);
 
        ret = drm_gem_reservation_object_wait(file, handle, write, timeout);
-       if (ret == 0)
+       if (ret == -ETIME)
                ret = timeout ? -ETIMEDOUT : -EBUSY;
 
        return ret;
index 84a2f24..4695f1c 100644 (file)
@@ -190,6 +190,9 @@ MODULE_FIRMWARE("nvidia/gp102/nvdec/scrubber.bin");
 MODULE_FIRMWARE("nvidia/gp102/sec2/desc.bin");
 MODULE_FIRMWARE("nvidia/gp102/sec2/image.bin");
 MODULE_FIRMWARE("nvidia/gp102/sec2/sig.bin");
+MODULE_FIRMWARE("nvidia/gp102/sec2/desc-1.bin");
+MODULE_FIRMWARE("nvidia/gp102/sec2/image-1.bin");
+MODULE_FIRMWARE("nvidia/gp102/sec2/sig-1.bin");
 MODULE_FIRMWARE("nvidia/gp104/acr/bl.bin");
 MODULE_FIRMWARE("nvidia/gp104/acr/unload_bl.bin");
 MODULE_FIRMWARE("nvidia/gp104/acr/ucode_load.bin");
@@ -210,6 +213,9 @@ MODULE_FIRMWARE("nvidia/gp104/nvdec/scrubber.bin");
 MODULE_FIRMWARE("nvidia/gp104/sec2/desc.bin");
 MODULE_FIRMWARE("nvidia/gp104/sec2/image.bin");
 MODULE_FIRMWARE("nvidia/gp104/sec2/sig.bin");
+MODULE_FIRMWARE("nvidia/gp104/sec2/desc-1.bin");
+MODULE_FIRMWARE("nvidia/gp104/sec2/image-1.bin");
+MODULE_FIRMWARE("nvidia/gp104/sec2/sig-1.bin");
 MODULE_FIRMWARE("nvidia/gp106/acr/bl.bin");
 MODULE_FIRMWARE("nvidia/gp106/acr/unload_bl.bin");
 MODULE_FIRMWARE("nvidia/gp106/acr/ucode_load.bin");
@@ -230,6 +236,9 @@ MODULE_FIRMWARE("nvidia/gp106/nvdec/scrubber.bin");
 MODULE_FIRMWARE("nvidia/gp106/sec2/desc.bin");
 MODULE_FIRMWARE("nvidia/gp106/sec2/image.bin");
 MODULE_FIRMWARE("nvidia/gp106/sec2/sig.bin");
+MODULE_FIRMWARE("nvidia/gp106/sec2/desc-1.bin");
+MODULE_FIRMWARE("nvidia/gp106/sec2/image-1.bin");
+MODULE_FIRMWARE("nvidia/gp106/sec2/sig-1.bin");
 MODULE_FIRMWARE("nvidia/gp107/acr/bl.bin");
 MODULE_FIRMWARE("nvidia/gp107/acr/unload_bl.bin");
 MODULE_FIRMWARE("nvidia/gp107/acr/ucode_load.bin");
@@ -250,3 +259,6 @@ MODULE_FIRMWARE("nvidia/gp107/nvdec/scrubber.bin");
 MODULE_FIRMWARE("nvidia/gp107/sec2/desc.bin");
 MODULE_FIRMWARE("nvidia/gp107/sec2/image.bin");
 MODULE_FIRMWARE("nvidia/gp107/sec2/sig.bin");
+MODULE_FIRMWARE("nvidia/gp107/sec2/desc-1.bin");
+MODULE_FIRMWARE("nvidia/gp107/sec2/image-1.bin");
+MODULE_FIRMWARE("nvidia/gp107/sec2/sig-1.bin");
index de0f882..14b41de 100644 (file)
@@ -4,6 +4,7 @@
  * Author: Archit Taneja <archit@ti.com>
  */
 
+#include <linux/bitops.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
@@ -20,7 +21,8 @@ int omapdss_device_init_output(struct omap_dss_device *out)
 {
        struct device_node *remote_node;
 
-       remote_node = of_graph_get_remote_node(out->dev->of_node, 0, 0);
+       remote_node = of_graph_get_remote_node(out->dev->of_node,
+                                              ffs(out->of_ports) - 1, 0);
        if (!remote_node) {
                dev_dbg(out->dev, "failed to find video sink\n");
                return 0;
index 92ac995..6e8145c 100644 (file)
@@ -222,7 +222,7 @@ void panfrost_mmu_unmap(struct panfrost_gem_object *bo)
                size_t unmapped_page;
                size_t pgsize = get_pgsize(iova, len - unmapped_len);
 
-               unmapped_page = ops->unmap(ops, iova, pgsize);
+               unmapped_page = ops->unmap(ops, iova, pgsize, NULL);
                if (!unmapped_page)
                        break;
 
@@ -247,20 +247,28 @@ static void mmu_tlb_inv_context_s1(void *cookie)
        mmu_hw_do_operation(pfdev, 0, 0, ~0UL, AS_COMMAND_FLUSH_MEM);
 }
 
-static void mmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
-                                    size_t granule, bool leaf, void *cookie)
-{}
-
 static void mmu_tlb_sync_context(void *cookie)
 {
        //struct panfrost_device *pfdev = cookie;
        // TODO: Wait 1000 GPU cycles for HW_ISSUE_6367/T60X
 }
 
-static const struct iommu_gather_ops mmu_tlb_ops = {
+static void mmu_tlb_flush_walk(unsigned long iova, size_t size, size_t granule,
+                              void *cookie)
+{
+       mmu_tlb_sync_context(cookie);
+}
+
+static void mmu_tlb_flush_leaf(unsigned long iova, size_t size, size_t granule,
+                              void *cookie)
+{
+       mmu_tlb_sync_context(cookie);
+}
+
+static const struct iommu_flush_ops mmu_tlb_ops = {
        .tlb_flush_all  = mmu_tlb_inv_context_s1,
-       .tlb_add_flush  = mmu_tlb_inv_range_nosync,
-       .tlb_sync       = mmu_tlb_sync_context,
+       .tlb_flush_walk = mmu_tlb_flush_walk,
+       .tlb_flush_leaf = mmu_tlb_flush_leaf,
 };
 
 static const char *access_type_name(struct panfrost_device *pfdev,
index f33e349..952201c 100644 (file)
@@ -59,6 +59,11 @@ module_param_named(num_heads, qxl_num_crtc, int, 0400);
 static struct drm_driver qxl_driver;
 static struct pci_driver qxl_pci_driver;
 
+static bool is_vga(struct pci_dev *pdev)
+{
+       return pdev->class == PCI_CLASS_DISPLAY_VGA << 8;
+}
+
 static int
 qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -83,9 +88,17 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (ret)
                goto disable_pci;
 
+       if (is_vga(pdev)) {
+               ret = vga_get_interruptible(pdev, VGA_RSRC_LEGACY_IO);
+               if (ret) {
+                       DRM_ERROR("can't get legacy vga ioports\n");
+                       goto disable_pci;
+               }
+       }
+
        ret = qxl_device_init(qdev, &qxl_driver, pdev);
        if (ret)
-               goto disable_pci;
+               goto put_vga;
 
        ret = qxl_modeset_init(qdev);
        if (ret)
@@ -105,6 +118,9 @@ modeset_cleanup:
        qxl_modeset_fini(qdev);
 unload:
        qxl_device_fini(qdev);
+put_vga:
+       if (is_vga(pdev))
+               vga_put(pdev, VGA_RSRC_LEGACY_IO);
 disable_pci:
        pci_disable_device(pdev);
 free_dev:
@@ -122,6 +138,8 @@ qxl_pci_remove(struct pci_dev *pdev)
 
        qxl_modeset_fini(qdev);
        qxl_device_fini(qdev);
+       if (is_vga(pdev))
+               vga_put(pdev, VGA_RSRC_LEGACY_IO);
 
        dev->dev_private = NULL;
        kfree(qdev);
index b45824e..6d61a0e 100644 (file)
@@ -9,6 +9,13 @@
 
 #define cmdline_test(test)     selftest(test, test)
 
+cmdline_test(drm_cmdline_test_force_d_only)
+cmdline_test(drm_cmdline_test_force_D_only_dvi)
+cmdline_test(drm_cmdline_test_force_D_only_hdmi)
+cmdline_test(drm_cmdline_test_force_D_only_not_digital)
+cmdline_test(drm_cmdline_test_force_e_only)
+cmdline_test(drm_cmdline_test_margin_only)
+cmdline_test(drm_cmdline_test_interlace_only)
 cmdline_test(drm_cmdline_test_res)
 cmdline_test(drm_cmdline_test_res_missing_x)
 cmdline_test(drm_cmdline_test_res_missing_y)
index 14c96ed..013de9d 100644 (file)
 
 static const struct drm_connector no_connector = {};
 
+static int drm_cmdline_test_force_e_only(void *ignored)
+{
+       struct drm_cmdline_mode mode = { };
+
+       FAIL_ON(!drm_mode_parse_command_line_for_connector("e",
+                                                          &no_connector,
+                                                          &mode));
+       FAIL_ON(mode.specified);
+       FAIL_ON(mode.refresh_specified);
+       FAIL_ON(mode.bpp_specified);
+
+       FAIL_ON(mode.rb);
+       FAIL_ON(mode.cvt);
+       FAIL_ON(mode.interlace);
+       FAIL_ON(mode.margins);
+       FAIL_ON(mode.force != DRM_FORCE_ON);
+
+       return 0;
+}
+
+static int drm_cmdline_test_force_D_only_not_digital(void *ignored)
+{
+       struct drm_cmdline_mode mode = { };
+
+       FAIL_ON(!drm_mode_parse_command_line_for_connector("D",
+                                                          &no_connector,
+                                                          &mode));
+       FAIL_ON(mode.specified);
+       FAIL_ON(mode.refresh_specified);
+       FAIL_ON(mode.bpp_specified);
+
+       FAIL_ON(mode.rb);
+       FAIL_ON(mode.cvt);
+       FAIL_ON(mode.interlace);
+       FAIL_ON(mode.margins);
+       FAIL_ON(mode.force != DRM_FORCE_ON);
+
+       return 0;
+}
+
+static const struct drm_connector connector_hdmi = {
+       .connector_type = DRM_MODE_CONNECTOR_HDMIB,
+};
+
+static int drm_cmdline_test_force_D_only_hdmi(void *ignored)
+{
+       struct drm_cmdline_mode mode = { };
+
+       FAIL_ON(!drm_mode_parse_command_line_for_connector("D",
+                                                          &connector_hdmi,
+                                                          &mode));
+       FAIL_ON(mode.specified);
+       FAIL_ON(mode.refresh_specified);
+       FAIL_ON(mode.bpp_specified);
+
+       FAIL_ON(mode.rb);
+       FAIL_ON(mode.cvt);
+       FAIL_ON(mode.interlace);
+       FAIL_ON(mode.margins);
+       FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL);
+
+       return 0;
+}
+
+static const struct drm_connector connector_dvi = {
+       .connector_type = DRM_MODE_CONNECTOR_DVII,
+};
+
+static int drm_cmdline_test_force_D_only_dvi(void *ignored)
+{
+       struct drm_cmdline_mode mode = { };
+
+       FAIL_ON(!drm_mode_parse_command_line_for_connector("D",
+                                                          &connector_dvi,
+                                                          &mode));
+       FAIL_ON(mode.specified);
+       FAIL_ON(mode.refresh_specified);
+       FAIL_ON(mode.bpp_specified);
+
+       FAIL_ON(mode.rb);
+       FAIL_ON(mode.cvt);
+       FAIL_ON(mode.interlace);
+       FAIL_ON(mode.margins);
+       FAIL_ON(mode.force != DRM_FORCE_ON_DIGITAL);
+
+       return 0;
+}
+
+static int drm_cmdline_test_force_d_only(void *ignored)
+{
+       struct drm_cmdline_mode mode = { };
+
+       FAIL_ON(!drm_mode_parse_command_line_for_connector("d",
+                                                          &no_connector,
+                                                          &mode));
+       FAIL_ON(mode.specified);
+       FAIL_ON(mode.refresh_specified);
+       FAIL_ON(mode.bpp_specified);
+
+       FAIL_ON(mode.rb);
+       FAIL_ON(mode.cvt);
+       FAIL_ON(mode.interlace);
+       FAIL_ON(mode.margins);
+       FAIL_ON(mode.force != DRM_FORCE_OFF);
+
+       return 0;
+}
+
+static int drm_cmdline_test_margin_only(void *ignored)
+{
+       struct drm_cmdline_mode mode = { };
+
+       FAIL_ON(drm_mode_parse_command_line_for_connector("m",
+                                                         &no_connector,
+                                                         &mode));
+
+       return 0;
+}
+
+static int drm_cmdline_test_interlace_only(void *ignored)
+{
+       struct drm_cmdline_mode mode = { };
+
+       FAIL_ON(drm_mode_parse_command_line_for_connector("i",
+                                                         &no_connector,
+                                                         &mode));
+
+       return 0;
+}
+
 static int drm_cmdline_test_res(void *ignored)
 {
        struct drm_cmdline_mode mode = { };
index b2da313..09b5265 100644 (file)
@@ -204,6 +204,7 @@ int virtio_gpu_object_get_sg_table(struct virtio_gpu_device *qdev,
                .interruptible = false,
                .no_wait_gpu = false
        };
+       size_t max_segment;
 
        /* wtf swapping */
        if (bo->pages)
@@ -215,8 +216,13 @@ int virtio_gpu_object_get_sg_table(struct virtio_gpu_device *qdev,
        if (!bo->pages)
                goto out;
 
-       ret = sg_alloc_table_from_pages(bo->pages, pages, nr_pages, 0,
-                                       nr_pages << PAGE_SHIFT, GFP_KERNEL);
+       max_segment = virtio_max_dma_size(qdev->vdev);
+       max_segment &= PAGE_MASK;
+       if (max_segment > SCATTERLIST_MAX_SEGMENT)
+               max_segment = SCATTERLIST_MAX_SEGMENT;
+       ret = __sg_alloc_table_from_pages(bo->pages, pages, nr_pages, 0,
+                                         nr_pages << PAGE_SHIFT,
+                                         max_segment, GFP_KERNEL);
        if (ret)
                goto out;
        return 0;
index 59e9d05..0af048d 100644 (file)
@@ -353,7 +353,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
                                     !!(HIGH_WORD(ecx) & MESSAGE_STATUS_HB));
                if ((HIGH_WORD(ebx) & MESSAGE_STATUS_SUCCESS) == 0) {
                        kfree(reply);
-
+                       reply = NULL;
                        if ((HIGH_WORD(ebx) & MESSAGE_STATUS_CPT) != 0) {
                                /* A checkpoint occurred. Retry. */
                                continue;
@@ -377,7 +377,7 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
 
                if ((HIGH_WORD(ecx) & MESSAGE_STATUS_SUCCESS) == 0) {
                        kfree(reply);
-
+                       reply = NULL;
                        if ((HIGH_WORD(ecx) & MESSAGE_STATUS_CPT) != 0) {
                                /* A checkpoint occurred. Retry. */
                                continue;
@@ -389,10 +389,8 @@ static int vmw_recv_msg(struct rpc_channel *channel, void **msg,
                break;
        }
 
-       if (retries == RETRIES) {
-               kfree(reply);
+       if (!reply)
                return -EINVAL;
-       }
 
        *msg_len = reply_len;
        *msg     = reply;
index 650dd71..2ca5668 100644 (file)
@@ -246,6 +246,16 @@ config SENSORS_ADT7475
          This driver can also be built as a module. If so, the module
          will be called adt7475.
 
+config SENSORS_AS370
+       tristate "Synaptics AS370 SoC hardware monitoring driver"
+       help
+         If you say yes here you get support for the PVT sensors of
+         the Synaptics AS370 SoC
+
+         This driver can also be built as a module. If so, the module
+         will be called as370-hwmon.
+
+
 config SENSORS_ASC7621
        tristate "Andigilog aSC7621"
        depends on I2C
@@ -1382,8 +1392,8 @@ config SENSORS_SHTC1
        tristate "Sensiron humidity and temperature sensors. SHTC1 and compat."
        depends on I2C
        help
-         If you say yes here you get support for the Sensiron SHTC1 and SHTW1
-         humidity and temperature sensors.
+         If you say yes here you get support for the Sensiron SHTC1, SHTW1,
+         and SHTC3 humidity and temperature sensors.
 
          This driver can also be built as a module. If so, the module
          will be called shtc1.
@@ -1570,16 +1580,6 @@ config SENSORS_ADC128D818
          This driver can also be built as a module. If so, the module
          will be called adc128d818.
 
-config SENSORS_ADS1015
-       tristate "Texas Instruments ADS1015"
-       depends on I2C
-       help
-         If you say yes here you get support for Texas Instruments
-         ADS1015/ADS1115 12/16-bit 4-input ADC device.
-
-         This driver can also be built as a module. If so, the module
-         will be called ads1015.
-
 config SENSORS_ADS7828
        tristate "Texas Instruments ADS7828 and compatibles"
        depends on I2C
@@ -1834,17 +1834,12 @@ config SENSORS_W83795
          will be called w83795.
 
 config SENSORS_W83795_FANCTRL
-       bool "Include automatic fan control support (DANGEROUS)"
+       bool "Include automatic fan control support"
        depends on SENSORS_W83795
        help
          If you say yes here, support for automatic fan speed control
          will be included in the driver.
 
-         This part of the code wasn't carefully reviewed and tested yet,
-         so enabling this option is strongly discouraged on production
-         servers. Only developers and testers should enable it for the
-         time being.
-
          Please also note that this option will create sysfs attribute
          files which may change in the future, so you shouldn't rely
          on them being stable.
index 8db472e..c86ce4d 100644 (file)
@@ -35,7 +35,6 @@ obj-$(CONFIG_SENSORS_ADM1026) += adm1026.o
 obj-$(CONFIG_SENSORS_ADM1029)  += adm1029.o
 obj-$(CONFIG_SENSORS_ADM1031)  += adm1031.o
 obj-$(CONFIG_SENSORS_ADM9240)  += adm9240.o
-obj-$(CONFIG_SENSORS_ADS1015)  += ads1015.o
 obj-$(CONFIG_SENSORS_ADS7828)  += ads7828.o
 obj-$(CONFIG_SENSORS_ADS7871)  += ads7871.o
 obj-$(CONFIG_SENSORS_ADT7X10)  += adt7x10.o
@@ -48,6 +47,7 @@ obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o
 obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
 obj-$(CONFIG_SENSORS_ARM_SCMI) += scmi-hwmon.o
 obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o
+obj-$(CONFIG_SENSORS_AS370)    += as370-hwmon.o
 obj-$(CONFIG_SENSORS_ASC7621)  += asc7621.o
 obj-$(CONFIG_SENSORS_ASPEED)   += aspeed-pwm-tacho.o
 obj-$(CONFIG_SENSORS_ATXP1)    += atxp1.o
index 6ba1a08..4cf2545 100644 (file)
@@ -681,8 +681,8 @@ static int setup_attrs(struct acpi_power_meter_resource *resource)
 
        if (resource->caps.flags & POWER_METER_CAN_CAP) {
                if (!can_cap_in_hardware()) {
-                       dev_err(&resource->acpi_dev->dev,
-                               "Ignoring unsafe software power cap!\n");
+                       dev_warn(&resource->acpi_dev->dev,
+                                "Ignoring unsafe software power cap!\n");
                        goto skip_unsafe_cap;
                }
 
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c
deleted file mode 100644 (file)
index 3727a37..0000000
+++ /dev/null
@@ -1,324 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * ads1015.c - lm_sensors driver for ads1015 12-bit 4-input ADC
- * (C) Copyright 2010
- * Dirk Eibach, Guntermann & Drunck GmbH <eibach@gdsys.de>
- *
- * Based on the ads7828 driver by Steve Hardy.
- *
- * Datasheet available at: http://focus.ti.com/lit/ds/symlink/ads1015.pdf
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/hwmon.h>
-#include <linux/hwmon-sysfs.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-#include <linux/of_device.h>
-#include <linux/of.h>
-
-#include <linux/platform_data/ads1015.h>
-
-/* ADS1015 registers */
-enum {
-       ADS1015_CONVERSION = 0,
-       ADS1015_CONFIG = 1,
-};
-
-/* PGA fullscale voltages in mV */
-static const unsigned int fullscale_table[8] = {
-       6144, 4096, 2048, 1024, 512, 256, 256, 256 };
-
-/* Data rates in samples per second */
-static const unsigned int data_rate_table_1015[8] = {
-       128, 250, 490, 920, 1600, 2400, 3300, 3300
-};
-
-static const unsigned int data_rate_table_1115[8] = {
-       8, 16, 32, 64, 128, 250, 475, 860
-};
-
-#define ADS1015_DEFAULT_CHANNELS 0xff
-#define ADS1015_DEFAULT_PGA 2
-#define ADS1015_DEFAULT_DATA_RATE 4
-
-enum ads1015_chips {
-       ads1015,
-       ads1115,
-};
-
-struct ads1015_data {
-       struct device *hwmon_dev;
-       struct mutex update_lock; /* mutex protect updates */
-       struct ads1015_channel_data channel_data[ADS1015_CHANNELS];
-       enum ads1015_chips id;
-};
-
-static int ads1015_read_adc(struct i2c_client *client, unsigned int channel)
-{
-       u16 config;
-       struct ads1015_data *data = i2c_get_clientdata(client);
-       unsigned int pga = data->channel_data[channel].pga;
-       unsigned int data_rate = data->channel_data[channel].data_rate;
-       unsigned int conversion_time_ms;
-       const unsigned int * const rate_table = data->id == ads1115 ?
-               data_rate_table_1115 : data_rate_table_1015;
-       int res;
-
-       mutex_lock(&data->update_lock);
-
-       /* get channel parameters */
-       res = i2c_smbus_read_word_swapped(client, ADS1015_CONFIG);
-       if (res < 0)
-               goto err_unlock;
-       config = res;
-       conversion_time_ms = DIV_ROUND_UP(1000, rate_table[data_rate]);
-
-       /* setup and start single conversion */
-       config &= 0x001f;
-       config |= (1 << 15) | (1 << 8);
-       config |= (channel & 0x0007) << 12;
-       config |= (pga & 0x0007) << 9;
-       config |= (data_rate & 0x0007) << 5;
-
-       res = i2c_smbus_write_word_swapped(client, ADS1015_CONFIG, config);
-       if (res < 0)
-               goto err_unlock;
-
-       /* wait until conversion finished */
-       msleep(conversion_time_ms);
-       res = i2c_smbus_read_word_swapped(client, ADS1015_CONFIG);
-       if (res < 0)
-               goto err_unlock;
-       config = res;
-       if (!(config & (1 << 15))) {
-               /* conversion not finished in time */
-               res = -EIO;
-               goto err_unlock;
-       }
-
-       res = i2c_smbus_read_word_swapped(client, ADS1015_CONVERSION);
-
-err_unlock:
-       mutex_unlock(&data->update_lock);
-       return res;
-}
-
-static int ads1015_reg_to_mv(struct i2c_client *client, unsigned int channel,
-                            s16 reg)
-{
-       struct ads1015_data *data = i2c_get_clientdata(client);
-       unsigned int pga = data->channel_data[channel].pga;
-       int fullscale = fullscale_table[pga];
-       const int mask = data->id == ads1115 ? 0x7fff : 0x7ff0;
-
-       return DIV_ROUND_CLOSEST(reg * fullscale, mask);
-}
-
-/* sysfs callback function */
-static ssize_t in_show(struct device *dev, struct device_attribute *da,
-                      char *buf)
-{
-       struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
-       struct i2c_client *client = to_i2c_client(dev);
-       int res;
-       int index = attr->index;
-
-       res = ads1015_read_adc(client, index);
-       if (res < 0)
-               return res;
-
-       return sprintf(buf, "%d\n", ads1015_reg_to_mv(client, index, res));
-}
-
-static const struct sensor_device_attribute ads1015_in[] = {
-       SENSOR_ATTR_RO(in0_input, in, 0),
-       SENSOR_ATTR_RO(in1_input, in, 1),
-       SENSOR_ATTR_RO(in2_input, in, 2),
-       SENSOR_ATTR_RO(in3_input, in, 3),
-       SENSOR_ATTR_RO(in4_input, in, 4),
-       SENSOR_ATTR_RO(in5_input, in, 5),
-       SENSOR_ATTR_RO(in6_input, in, 6),
-       SENSOR_ATTR_RO(in7_input, in, 7),
-};
-
-/*
- * Driver interface
- */
-
-static int ads1015_remove(struct i2c_client *client)
-{
-       struct ads1015_data *data = i2c_get_clientdata(client);
-       int k;
-
-       hwmon_device_unregister(data->hwmon_dev);
-       for (k = 0; k < ADS1015_CHANNELS; ++k)
-               device_remove_file(&client->dev, &ads1015_in[k].dev_attr);
-       return 0;
-}
-
-#ifdef CONFIG_OF
-static int ads1015_get_channels_config_of(struct i2c_client *client)
-{
-       struct ads1015_data *data = i2c_get_clientdata(client);
-       struct device_node *node;
-
-       if (!client->dev.of_node
-           || !of_get_next_child(client->dev.of_node, NULL))
-               return -EINVAL;
-
-       for_each_child_of_node(client->dev.of_node, node) {
-               u32 pval;
-               unsigned int channel;
-               unsigned int pga = ADS1015_DEFAULT_PGA;
-               unsigned int data_rate = ADS1015_DEFAULT_DATA_RATE;
-
-               if (of_property_read_u32(node, "reg", &pval)) {
-                       dev_err(&client->dev, "invalid reg on %pOF\n", node);
-                       continue;
-               }
-
-               channel = pval;
-               if (channel >= ADS1015_CHANNELS) {
-                       dev_err(&client->dev,
-                               "invalid channel index %d on %pOF\n",
-                               channel, node);
-                       continue;
-               }
-
-               if (!of_property_read_u32(node, "ti,gain", &pval)) {
-                       pga = pval;
-                       if (pga > 6) {
-                               dev_err(&client->dev, "invalid gain on %pOF\n",
-                                       node);
-                               return -EINVAL;
-                       }
-               }
-
-               if (!of_property_read_u32(node, "ti,datarate", &pval)) {
-                       data_rate = pval;
-                       if (data_rate > 7) {
-                               dev_err(&client->dev,
-                                       "invalid data_rate on %pOF\n", node);
-                               return -EINVAL;
-                       }
-               }
-
-               data->channel_data[channel].enabled = true;
-               data->channel_data[channel].pga = pga;
-               data->channel_data[channel].data_rate = data_rate;
-       }
-
-       return 0;
-}
-#endif
-
-static void ads1015_get_channels_config(struct i2c_client *client)
-{
-       unsigned int k;
-       struct ads1015_data *data = i2c_get_clientdata(client);
-       struct ads1015_platform_data *pdata = dev_get_platdata(&client->dev);
-
-       /* prefer platform data */
-       if (pdata) {
-               memcpy(data->channel_data, pdata->channel_data,
-                      sizeof(data->channel_data));
-               return;
-       }
-
-#ifdef CONFIG_OF
-       if (!ads1015_get_channels_config_of(client))
-               return;
-#endif
-
-       /* fallback on default configuration */
-       for (k = 0; k < ADS1015_CHANNELS; ++k) {
-               data->channel_data[k].enabled = true;
-               data->channel_data[k].pga = ADS1015_DEFAULT_PGA;
-               data->channel_data[k].data_rate = ADS1015_DEFAULT_DATA_RATE;
-       }
-}
-
-static int ads1015_probe(struct i2c_client *client,
-                        const struct i2c_device_id *id)
-{
-       struct ads1015_data *data;
-       int err;
-       unsigned int k;
-
-       data = devm_kzalloc(&client->dev, sizeof(struct ads1015_data),
-                           GFP_KERNEL);
-       if (!data)
-               return -ENOMEM;
-
-       if (client->dev.of_node)
-               data->id = (enum ads1015_chips)
-                       of_device_get_match_data(&client->dev);
-       else
-               data->id = id->driver_data;
-       i2c_set_clientdata(client, data);
-       mutex_init(&data->update_lock);
-
-       /* build sysfs attribute group */
-       ads1015_get_channels_config(client);
-       for (k = 0; k < ADS1015_CHANNELS; ++k) {
-               if (!data->channel_data[k].enabled)
-                       continue;
-               err = device_create_file(&client->dev, &ads1015_in[k].dev_attr);
-               if (err)
-                       goto exit_remove;
-       }
-
-       data->hwmon_dev = hwmon_device_register(&client->dev);
-       if (IS_ERR(data->hwmon_dev)) {
-               err = PTR_ERR(data->hwmon_dev);
-               goto exit_remove;
-       }
-
-       return 0;
-
-exit_remove:
-       for (k = 0; k < ADS1015_CHANNELS; ++k)
-               device_remove_file(&client->dev, &ads1015_in[k].dev_attr);
-       return err;
-}
-
-static const struct i2c_device_id ads1015_id[] = {
-       { "ads1015",  ads1015},
-       { "ads1115",  ads1115},
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, ads1015_id);
-
-static const struct of_device_id __maybe_unused ads1015_of_match[] = {
-       {
-               .compatible = "ti,ads1015",
-               .data = (void *)ads1015
-       },
-       {
-               .compatible = "ti,ads1115",
-               .data = (void *)ads1115
-       },
-       { },
-};
-MODULE_DEVICE_TABLE(of, ads1015_of_match);
-
-static struct i2c_driver ads1015_driver = {
-       .driver = {
-               .name = "ads1015",
-               .of_match_table = of_match_ptr(ads1015_of_match),
-       },
-       .probe = ads1015_probe,
-       .remove = ads1015_remove,
-       .id_table = ads1015_id,
-};
-
-module_i2c_driver(ads1015_driver);
-
-MODULE_AUTHOR("Dirk Eibach <eibach@gdsys.de>");
-MODULE_DESCRIPTION("ADS1015 driver");
-MODULE_LICENSE("GPL");
index c3c6031..6c64d50 100644 (file)
@@ -187,7 +187,7 @@ static const struct of_device_id __maybe_unused adt7475_of_match[] = {
 MODULE_DEVICE_TABLE(of, adt7475_of_match);
 
 struct adt7475_data {
-       struct device *hwmon_dev;
+       struct i2c_client *client;
        struct mutex lock;
 
        unsigned long measure_updated;
@@ -212,6 +212,7 @@ struct adt7475_data {
 
        u8 vid;
        u8 vrm;
+       const struct attribute_group *groups[9];
 };
 
 static struct i2c_driver adt7475_driver;
@@ -346,8 +347,8 @@ static ssize_t voltage_store(struct device *dev,
 {
 
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned char reg;
        long val;
 
@@ -440,8 +441,8 @@ static ssize_t temp_store(struct device *dev, struct device_attribute *attr,
                          const char *buf, size_t count)
 {
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned char reg = 0;
        u8 out;
        int temp;
@@ -542,8 +543,7 @@ static ssize_t temp_st_show(struct device *dev, struct device_attribute *attr,
                            char *buf)
 {
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
        long val;
 
        switch (sattr->index) {
@@ -570,8 +570,8 @@ static ssize_t temp_st_store(struct device *dev,
                             size_t count)
 {
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned char reg;
        int shift, idx;
        ulong val;
@@ -647,8 +647,8 @@ static ssize_t point2_show(struct device *dev, struct device_attribute *attr,
 static ssize_t point2_store(struct device *dev, struct device_attribute *attr,
                            const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
        int temp;
        long val;
@@ -710,8 +710,8 @@ static ssize_t tach_store(struct device *dev, struct device_attribute *attr,
 {
 
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned long val;
 
        if (kstrtoul(buf, 10, &val))
@@ -769,8 +769,8 @@ static ssize_t pwm_store(struct device *dev, struct device_attribute *attr,
 {
 
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        unsigned char reg = 0;
        long val;
 
@@ -818,8 +818,8 @@ static ssize_t stall_disable_show(struct device *dev,
                                  struct device_attribute *attr, char *buf)
 {
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+
        u8 mask = BIT(5 + sattr->index);
 
        return sprintf(buf, "%d\n", !!(data->enh_acoustics[0] & mask));
@@ -830,8 +830,8 @@ static ssize_t stall_disable_store(struct device *dev,
                                   const char *buf, size_t count)
 {
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        long val;
        u8 mask = BIT(5 + sattr->index);
 
@@ -914,8 +914,8 @@ static ssize_t pwmchan_store(struct device *dev,
                             size_t count)
 {
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        int r;
        long val;
 
@@ -938,8 +938,8 @@ static ssize_t pwmctrl_store(struct device *dev,
                             size_t count)
 {
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        int r;
        long val;
 
@@ -982,8 +982,8 @@ static ssize_t pwmfreq_store(struct device *dev,
                             size_t count)
 {
        struct sensor_device_attribute_2 *sattr = to_sensor_dev_attr_2(attr);
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        int out;
        long val;
 
@@ -1022,8 +1022,8 @@ static ssize_t pwm_use_point2_pwm_at_crit_store(struct device *dev,
                                        struct device_attribute *devattr,
                                        const char *buf, size_t count)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        long val;
 
        if (kstrtol(buf, 10, &val))
@@ -1342,26 +1342,6 @@ static int adt7475_detect(struct i2c_client *client,
        return 0;
 }
 
-static void adt7475_remove_files(struct i2c_client *client,
-                                struct adt7475_data *data)
-{
-       sysfs_remove_group(&client->dev.kobj, &adt7475_attr_group);
-       if (data->has_fan4)
-               sysfs_remove_group(&client->dev.kobj, &fan4_attr_group);
-       if (data->has_pwm2)
-               sysfs_remove_group(&client->dev.kobj, &pwm2_attr_group);
-       if (data->has_voltage & (1 << 0))
-               sysfs_remove_group(&client->dev.kobj, &in0_attr_group);
-       if (data->has_voltage & (1 << 3))
-               sysfs_remove_group(&client->dev.kobj, &in3_attr_group);
-       if (data->has_voltage & (1 << 4))
-               sysfs_remove_group(&client->dev.kobj, &in4_attr_group);
-       if (data->has_voltage & (1 << 5))
-               sysfs_remove_group(&client->dev.kobj, &in5_attr_group);
-       if (data->has_vid)
-               sysfs_remove_group(&client->dev.kobj, &vid_attr_group);
-}
-
 static int adt7475_update_limits(struct i2c_client *client)
 {
        struct adt7475_data *data = i2c_get_clientdata(client);
@@ -1489,7 +1469,8 @@ static int adt7475_probe(struct i2c_client *client,
        };
 
        struct adt7475_data *data;
-       int i, ret = 0, revision;
+       struct device *hwmon_dev;
+       int i, ret = 0, revision, group_num = 0;
        u8 config2, config3;
 
        data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
@@ -1497,6 +1478,7 @@ static int adt7475_probe(struct i2c_client *client,
                return -ENOMEM;
 
        mutex_init(&data->lock);
+       data->client = client;
        i2c_set_clientdata(client, data);
 
        if (client->dev.of_node)
@@ -1590,52 +1572,40 @@ static int adt7475_probe(struct i2c_client *client,
                break;
        }
 
-       ret = sysfs_create_group(&client->dev.kobj, &adt7475_attr_group);
-       if (ret)
-               return ret;
+       data->groups[group_num++] = &adt7475_attr_group;
 
        /* Features that can be disabled individually */
        if (data->has_fan4) {
-               ret = sysfs_create_group(&client->dev.kobj, &fan4_attr_group);
-               if (ret)
-                       goto eremove;
+               data->groups[group_num++] = &fan4_attr_group;
        }
        if (data->has_pwm2) {
-               ret = sysfs_create_group(&client->dev.kobj, &pwm2_attr_group);
-               if (ret)
-                       goto eremove;
+               data->groups[group_num++] = &pwm2_attr_group;
        }
        if (data->has_voltage & (1 << 0)) {
-               ret = sysfs_create_group(&client->dev.kobj, &in0_attr_group);
-               if (ret)
-                       goto eremove;
+               data->groups[group_num++] = &in0_attr_group;
        }
        if (data->has_voltage & (1 << 3)) {
-               ret = sysfs_create_group(&client->dev.kobj, &in3_attr_group);
-               if (ret)
-                       goto eremove;
+               data->groups[group_num++] = &in3_attr_group;
        }
        if (data->has_voltage & (1 << 4)) {
-               ret = sysfs_create_group(&client->dev.kobj, &in4_attr_group);
-               if (ret)
-                       goto eremove;
+               data->groups[group_num++] = &in4_attr_group;
        }
        if (data->has_voltage & (1 << 5)) {
-               ret = sysfs_create_group(&client->dev.kobj, &in5_attr_group);
-               if (ret)
-                       goto eremove;
+               data->groups[group_num++] = &in5_attr_group;
        }
        if (data->has_vid) {
                data->vrm = vid_which_vrm();
-               ret = sysfs_create_group(&client->dev.kobj, &vid_attr_group);
-               if (ret)
-                       goto eremove;
+               data->groups[group_num] = &vid_attr_group;
        }
 
-       data->hwmon_dev = hwmon_device_register(&client->dev);
-       if (IS_ERR(data->hwmon_dev)) {
-               ret = PTR_ERR(data->hwmon_dev);
-               goto eremove;
+       /* register device with all the acquired attributes */
+       hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
+                                                          client->name, data,
+                                                          data->groups);
+
+       if (IS_ERR(hwmon_dev)) {
+               ret = PTR_ERR(hwmon_dev);
+               return ret;
        }
 
        dev_info(&client->dev, "%s device, revision %d\n",
@@ -1657,21 +1627,7 @@ static int adt7475_probe(struct i2c_client *client,
        /* Limits and settings, should never change update more than once */
        ret = adt7475_update_limits(client);
        if (ret)
-               goto eremove;
-
-       return 0;
-
-eremove:
-       adt7475_remove_files(client, data);
-       return ret;
-}
-
-static int adt7475_remove(struct i2c_client *client)
-{
-       struct adt7475_data *data = i2c_get_clientdata(client);
-
-       hwmon_device_unregister(data->hwmon_dev);
-       adt7475_remove_files(client, data);
+               return ret;
 
        return 0;
 }
@@ -1683,7 +1639,6 @@ static struct i2c_driver adt7475_driver = {
                .of_match_table = of_match_ptr(adt7475_of_match),
        },
        .probe          = adt7475_probe,
-       .remove         = adt7475_remove,
        .id_table       = adt7475_id,
        .detect         = adt7475_detect,
        .address_list   = normal_i2c,
@@ -1757,8 +1712,8 @@ static void adt7475_read_pwm(struct i2c_client *client, int index)
 
 static int adt7475_update_measure(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
        u16 ext;
        int i;
        int ret;
@@ -1854,8 +1809,7 @@ static int adt7475_update_measure(struct device *dev)
 
 static struct adt7475_data *adt7475_update_device(struct device *dev)
 {
-       struct i2c_client *client = to_i2c_client(dev);
-       struct adt7475_data *data = i2c_get_clientdata(client);
+       struct adt7475_data *data = dev_get_drvdata(dev);
        int ret;
 
        mutex_lock(&data->lock);
diff --git a/drivers/hwmon/as370-hwmon.c b/drivers/hwmon/as370-hwmon.c
new file mode 100644 (file)
index 0000000..464244b
--- /dev/null
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Synaptics AS370 SoC Hardware Monitoring Driver
+ *
+ * Copyright (C) 2018 Synaptics Incorporated
+ * Author: Jisheng Zhang <jszhang@kernel.org>
+ */
+
+#include <linux/bitops.h>
+#include <linux/hwmon.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+
+#define CTRL           0x0
+#define  PD            BIT(0)
+#define  EN            BIT(1)
+#define  T_SEL         BIT(2)
+#define  V_SEL         BIT(3)
+#define  NMOS_SEL      BIT(8)
+#define  PMOS_SEL      BIT(9)
+#define STS            0x4
+#define  BN_MASK       GENMASK(11, 0)
+#define  EOC           BIT(12)
+
+struct as370_hwmon {
+       void __iomem *base;
+};
+
+static void init_pvt(struct as370_hwmon *hwmon)
+{
+       u32 val;
+       void __iomem *addr = hwmon->base + CTRL;
+
+       val = PD;
+       writel_relaxed(val, addr);
+       val |= T_SEL;
+       writel_relaxed(val, addr);
+       val |= EN;
+       writel_relaxed(val, addr);
+       val &= ~PD;
+       writel_relaxed(val, addr);
+}
+
+static int as370_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
+                           u32 attr, int channel, long *temp)
+{
+       int val;
+       struct as370_hwmon *hwmon = dev_get_drvdata(dev);
+
+       switch (attr) {
+       case hwmon_temp_input:
+               val = readl_relaxed(hwmon->base + STS) & BN_MASK;
+               *temp = DIV_ROUND_CLOSEST(val * 251802, 4096) - 85525;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       return 0;
+}
+
+static umode_t
+as370_hwmon_is_visible(const void *data, enum hwmon_sensor_types type,
+                      u32 attr, int channel)
+{
+       if (type != hwmon_temp)
+               return 0;
+
+       switch (attr) {
+       case hwmon_temp_input:
+               return 0444;
+       default:
+               return 0;
+       }
+}
+
+static const u32 as370_hwmon_temp_config[] = {
+       HWMON_T_INPUT,
+       0
+};
+
+static const struct hwmon_channel_info as370_hwmon_temp = {
+       .type = hwmon_temp,
+       .config = as370_hwmon_temp_config,
+};
+
+static const struct hwmon_channel_info *as370_hwmon_info[] = {
+       &as370_hwmon_temp,
+       NULL
+};
+
+static const struct hwmon_ops as370_hwmon_ops = {
+       .is_visible = as370_hwmon_is_visible,
+       .read = as370_hwmon_read,
+};
+
+static const struct hwmon_chip_info as370_chip_info = {
+       .ops = &as370_hwmon_ops,
+       .info = as370_hwmon_info,
+};
+
+static int as370_hwmon_probe(struct platform_device *pdev)
+{
+       struct device *hwmon_dev;
+       struct as370_hwmon *hwmon;
+       struct device *dev = &pdev->dev;
+
+       hwmon = devm_kzalloc(dev, sizeof(*hwmon), GFP_KERNEL);
+       if (!hwmon)
+               return -ENOMEM;
+
+       hwmon->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(hwmon->base))
+               return PTR_ERR(hwmon->base);
+
+       init_pvt(hwmon);
+
+       hwmon_dev = devm_hwmon_device_register_with_info(dev,
+                                                        "as370",
+                                                        hwmon,
+                                                        &as370_chip_info,
+                                                        NULL);
+       return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct of_device_id as370_hwmon_match[] = {
+       { .compatible = "syna,as370-hwmon" },
+       {},
+};
+MODULE_DEVICE_TABLE(of, as370_hwmon_match);
+
+static struct platform_driver as370_hwmon_driver = {
+       .probe = as370_hwmon_probe,
+       .driver = {
+               .name = "as370-hwmon",
+               .of_match_table = as370_hwmon_match,
+       },
+};
+module_platform_driver(as370_hwmon_driver);
+
+MODULE_AUTHOR("Jisheng Zhang<jszhang@kernel.org>");
+MODULE_DESCRIPTION("Synaptics AS370 SoC hardware monitor");
+MODULE_LICENSE("GPL v2");
index c9fa84b..4c609e2 100644 (file)
@@ -706,21 +706,21 @@ static int asb100_detect_subclients(struct i2c_client *client)
                goto ERROR_SC_2;
        }
 
-       data->lm75[0] = i2c_new_dummy(adapter, sc_addr[0]);
-       if (!data->lm75[0]) {
+       data->lm75[0] = i2c_new_dummy_device(adapter, sc_addr[0]);
+       if (IS_ERR(data->lm75[0])) {
                dev_err(&client->dev,
                        "subclient %d registration at address 0x%x failed.\n",
                        1, sc_addr[0]);
-               err = -ENOMEM;
+               err = PTR_ERR(data->lm75[0]);
                goto ERROR_SC_2;
        }
 
-       data->lm75[1] = i2c_new_dummy(adapter, sc_addr[1]);
-       if (!data->lm75[1]) {
+       data->lm75[1] = i2c_new_dummy_device(adapter, sc_addr[1]);
+       if (IS_ERR(data->lm75[1])) {
                dev_err(&client->dev,
                        "subclient %d registration at address 0x%x failed.\n",
                        2, sc_addr[1]);
-               err = -ENOMEM;
+               err = PTR_ERR(data->lm75[1]);
                goto ERROR_SC_3;
        }
 
index fe6618e..d855c78 100644 (file)
@@ -736,7 +736,7 @@ static int __init coretemp_init(void)
 
        err = platform_driver_register(&coretemp_driver);
        if (err)
-               return err;
+               goto outzone;
 
        err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "hwmon/coretemp:online",
                                coretemp_cpu_online, coretemp_cpu_offline);
@@ -747,6 +747,7 @@ static int __init coretemp_init(void)
 
 outdrv:
        platform_driver_unregister(&coretemp_driver);
+outzone:
        kfree(zone_devices);
        return err;
 }
index f1c2d5f..b85a125 100644 (file)
@@ -44,12 +44,20 @@ static ssize_t iio_hwmon_read_val(struct device *dev,
        int ret;
        struct sensor_device_attribute *sattr = to_sensor_dev_attr(attr);
        struct iio_hwmon_state *state = dev_get_drvdata(dev);
+       struct iio_channel *chan = &state->channels[sattr->index];
+       enum iio_chan_type type;
+
+       ret = iio_read_channel_processed(chan, &result);
+       if (ret < 0)
+               return ret;
 
-       ret = iio_read_channel_processed(&state->channels[sattr->index],
-                                       &result);
+       ret = iio_get_channel_type(chan, &type);
        if (ret < 0)
                return ret;
 
+       if (type == IIO_POWER)
+               result *= 1000; /* mili-Watts to micro-Watts conversion */
+
        return sprintf(buf, "%d\n", result);
 }
 
@@ -59,7 +67,7 @@ static int iio_hwmon_probe(struct platform_device *pdev)
        struct iio_hwmon_state *st;
        struct sensor_device_attribute *a;
        int ret, i;
-       int in_i = 1, temp_i = 1, curr_i = 1, humidity_i = 1;
+       int in_i = 1, temp_i = 1, curr_i = 1, humidity_i = 1, power_i = 1;
        enum iio_chan_type type;
        struct iio_channel *channels;
        struct device *hwmon_dev;
@@ -114,6 +122,10 @@ static int iio_hwmon_probe(struct platform_device *pdev)
                        n = curr_i++;
                        prefix = "curr";
                        break;
+               case IIO_POWER:
+                       n = power_i++;
+                       prefix = "power";
+                       break;
                case IIO_HUMIDITYRELATIVE:
                        n = humidity_i++;
                        prefix = "humidity";
index c77e892..5c1dddd 100644 (file)
@@ -349,6 +349,7 @@ static const struct pci_device_id k10temp_id_table[] = {
        { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) },
        { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) },
        { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) },
+       { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) },
        { PCI_VDEVICE(HYGON, PCI_DEVICE_ID_AMD_17H_DF_F3) },
        {}
 };
index 4994c90..f73bd4e 100644 (file)
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/slab.h>
-#include <linux/jiffies.h>
 #include <linux/pci.h>
 #include <linux/hwmon.h>
-#include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <asm/processor.h>
 #define SEL_CORE       0x04
 
 struct k8temp_data {
-       struct device *hwmon_dev;
        struct mutex update_lock;
-       const char *name;
-       char valid;             /* zero until following fields are valid */
-       unsigned long last_updated;     /* in jiffies */
 
        /* registers values */
        u8 sensorsp;            /* sensor presence bits - SEL_CORE, SEL_PLACE */
-       u32 temp[2][2];         /* core, place */
        u8 swap_core_select;    /* meaning of SEL_CORE is inverted */
        u32 temp_offset;
 };
 
-static struct k8temp_data *k8temp_update_device(struct device *dev)
-{
-       struct k8temp_data *data = dev_get_drvdata(dev);
-       struct pci_dev *pdev = to_pci_dev(dev);
-       u8 tmp;
-
-       mutex_lock(&data->update_lock);
-
-       if (!data->valid
-           || time_after(jiffies, data->last_updated + HZ)) {
-               pci_read_config_byte(pdev, REG_TEMP, &tmp);
-               tmp &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */
-               pci_write_config_byte(pdev, REG_TEMP, tmp);
-               pci_read_config_dword(pdev, REG_TEMP, &data->temp[0][0]);
-
-               if (data->sensorsp & SEL_PLACE) {
-                       tmp |= SEL_PLACE;       /* Select sensor 1, core0 */
-                       pci_write_config_byte(pdev, REG_TEMP, tmp);
-                       pci_read_config_dword(pdev, REG_TEMP,
-                                             &data->temp[0][1]);
-               }
-
-               if (data->sensorsp & SEL_CORE) {
-                       tmp &= ~SEL_PLACE;      /* Select sensor 0, core1 */
-                       tmp |= SEL_CORE;
-                       pci_write_config_byte(pdev, REG_TEMP, tmp);
-                       pci_read_config_dword(pdev, REG_TEMP,
-                                             &data->temp[1][0]);
-
-                       if (data->sensorsp & SEL_PLACE) {
-                               tmp |= SEL_PLACE; /* Select sensor 1, core1 */
-                               pci_write_config_byte(pdev, REG_TEMP, tmp);
-                               pci_read_config_dword(pdev, REG_TEMP,
-                                                     &data->temp[1][1]);
-                       }
-               }
-
-               data->last_updated = jiffies;
-               data->valid = 1;
-       }
-
-       mutex_unlock(&data->update_lock);
-       return data;
-}
-
-/*
- * Sysfs stuff
- */
-
-static ssize_t name_show(struct device *dev, struct device_attribute
-                        *devattr, char *buf)
-{
-       struct k8temp_data *data = dev_get_drvdata(dev);
-
-       return sprintf(buf, "%s\n", data->name);
-}
-
-
-static ssize_t temp_show(struct device *dev, struct device_attribute *devattr,
-                        char *buf)
-{
-       struct sensor_device_attribute_2 *attr =
-           to_sensor_dev_attr_2(devattr);
-       int core = attr->nr;
-       int place = attr->index;
-       int temp;
-       struct k8temp_data *data = k8temp_update_device(dev);
-
-       if (data->swap_core_select && (data->sensorsp & SEL_CORE))
-               core = core ? 0 : 1;
-
-       temp = TEMP_FROM_REG(data->temp[core][place]) + data->temp_offset;
-
-       return sprintf(buf, "%d\n", temp);
-}
-
-/* core, place */
-
-static SENSOR_DEVICE_ATTR_2_RO(temp1_input, temp, 0, 0);
-static SENSOR_DEVICE_ATTR_2_RO(temp2_input, temp, 0, 1);
-static SENSOR_DEVICE_ATTR_2_RO(temp3_input, temp, 1, 0);
-static SENSOR_DEVICE_ATTR_2_RO(temp4_input, temp, 1, 1);
-static DEVICE_ATTR_RO(name);
-
 static const struct pci_device_id k8temp_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) },
        { 0 },
 };
-
 MODULE_DEVICE_TABLE(pci, k8temp_ids);
 
 static int is_rev_g_desktop(u8 model)
@@ -159,14 +67,76 @@ static int is_rev_g_desktop(u8 model)
        return 1;
 }
 
+static umode_t
+k8temp_is_visible(const void *drvdata, enum hwmon_sensor_types type,
+                 u32 attr, int channel)
+{
+       const struct k8temp_data *data = drvdata;
+
+       if ((channel & 1) && !(data->sensorsp & SEL_PLACE))
+               return 0;
+
+       if ((channel & 2) && !(data->sensorsp & SEL_CORE))
+               return 0;
+
+       return 0444;
+}
+
+static int
+k8temp_read(struct device *dev, enum hwmon_sensor_types type,
+           u32 attr, int channel, long *val)
+{
+       struct k8temp_data *data = dev_get_drvdata(dev);
+       struct pci_dev *pdev = to_pci_dev(dev->parent);
+       int core, place;
+       u32 temp;
+       u8 tmp;
+
+       core = (channel >> 1) & 1;
+       place = channel & 1;
+
+       core ^= data->swap_core_select;
+
+       mutex_lock(&data->update_lock);
+       pci_read_config_byte(pdev, REG_TEMP, &tmp);
+       tmp &= ~(SEL_PLACE | SEL_CORE);
+       if (core)
+               tmp |= SEL_CORE;
+       if (place)
+               tmp |= SEL_PLACE;
+       pci_write_config_byte(pdev, REG_TEMP, tmp);
+       pci_read_config_dword(pdev, REG_TEMP, &temp);
+       mutex_unlock(&data->update_lock);
+
+       *val = TEMP_FROM_REG(temp) + data->temp_offset;
+
+       return 0;
+}
+
+static const struct hwmon_ops k8temp_ops = {
+       .is_visible = k8temp_is_visible,
+       .read = k8temp_read,
+};
+
+static const struct hwmon_channel_info *k8temp_info[] = {
+       HWMON_CHANNEL_INFO(temp,
+               HWMON_T_INPUT, HWMON_T_INPUT, HWMON_T_INPUT, HWMON_T_INPUT),
+       NULL
+};
+
+static const struct hwmon_chip_info k8temp_chip_info = {
+       .ops = &k8temp_ops,
+       .info = k8temp_info,
+};
+
 static int k8temp_probe(struct pci_dev *pdev,
                                  const struct pci_device_id *id)
 {
-       int err;
        u8 scfg;
        u32 temp;
        u8 model, stepping;
        struct k8temp_data *data;
+       struct device *hwmon_dev;
 
        data = devm_kzalloc(&pdev->dev, sizeof(struct k8temp_data), GFP_KERNEL);
        if (!data)
@@ -231,86 +201,21 @@ static int k8temp_probe(struct pci_dev *pdev,
                        data->sensorsp &= ~SEL_CORE;
        }
 
-       data->name = "k8temp";
        mutex_init(&data->update_lock);
-       pci_set_drvdata(pdev, data);
-
-       /* Register sysfs hooks */
-       err = device_create_file(&pdev->dev,
-                          &sensor_dev_attr_temp1_input.dev_attr);
-       if (err)
-               goto exit_remove;
-
-       /* sensor can be changed and reports something */
-       if (data->sensorsp & SEL_PLACE) {
-               err = device_create_file(&pdev->dev,
-                                  &sensor_dev_attr_temp2_input.dev_attr);
-               if (err)
-                       goto exit_remove;
-       }
-
-       /* core can be changed and reports something */
-       if (data->sensorsp & SEL_CORE) {
-               err = device_create_file(&pdev->dev,
-                                  &sensor_dev_attr_temp3_input.dev_attr);
-               if (err)
-                       goto exit_remove;
-               if (data->sensorsp & SEL_PLACE) {
-                       err = device_create_file(&pdev->dev,
-                                          &sensor_dev_attr_temp4_input.
-                                          dev_attr);
-                       if (err)
-                               goto exit_remove;
-               }
-       }
-
-       err = device_create_file(&pdev->dev, &dev_attr_name);
-       if (err)
-               goto exit_remove;
 
-       data->hwmon_dev = hwmon_device_register(&pdev->dev);
+       hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev,
+                                                        "k8temp",
+                                                        data,
+                                                        &k8temp_chip_info,
+                                                        NULL);
 
-       if (IS_ERR(data->hwmon_dev)) {
-               err = PTR_ERR(data->hwmon_dev);
-               goto exit_remove;
-       }
-
-       return 0;
-
-exit_remove:
-       device_remove_file(&pdev->dev,
-                          &sensor_dev_attr_temp1_input.dev_attr);
-       device_remove_file(&pdev->dev,
-                          &sensor_dev_attr_temp2_input.dev_attr);
-       device_remove_file(&pdev->dev,
-                          &sensor_dev_attr_temp3_input.dev_attr);
-       device_remove_file(&pdev->dev,
-                          &sensor_dev_attr_temp4_input.dev_attr);
-       device_remove_file(&pdev->dev, &dev_attr_name);
-       return err;
-}
-
-static void k8temp_remove(struct pci_dev *pdev)
-{
-       struct k8temp_data *data = pci_get_drvdata(pdev);
-
-       hwmon_device_unregister(data->hwmon_dev);
-       device_remove_file(&pdev->dev,
-                          &sensor_dev_attr_temp1_input.dev_attr);
-       device_remove_file(&pdev->dev,
-                          &sensor_dev_attr_temp2_input.dev_attr);
-       device_remove_file(&pdev->dev,
-                          &sensor_dev_attr_temp3_input.dev_attr);
-       device_remove_file(&pdev->dev,
-                          &sensor_dev_attr_temp4_input.dev_attr);
-       device_remove_file(&pdev->dev, &dev_attr_name);
+       return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 
 static struct pci_driver k8temp_driver = {
        .name = "k8temp",
        .id_table = k8temp_ids,
        .probe = k8temp_probe,
-       .remove = k8temp_remove,
 };
 
 module_pci_driver(k8temp_driver);
index ce5ec40..5e63922 100644 (file)
@@ -16,9 +16,9 @@
 #include <linux/of_device.h>
 #include <linux/of.h>
 #include <linux/regmap.h>
+#include <linux/util_macros.h>
 #include "lm75.h"
 
-
 /*
  * This driver handles the LM75 and compatible digital temperature sensors.
  */
@@ -36,6 +36,7 @@ enum lm75_type {              /* keep sorted in alphabetical order */
        max6626,
        max31725,
        mcp980x,
+       pct2075,
        stds75,
        stlm75,
        tcn75,
@@ -50,6 +51,41 @@ enum lm75_type {             /* keep sorted in alphabetical order */
        tmp75c,
 };
 
+/**
+ * struct lm75_params - lm75 configuration parameters.
+ * @set_mask:          Bits to set in configuration register when configuring
+ *                     the chip.
+ * @clr_mask:          Bits to clear in configuration register when configuring
+ *                     the chip.
+ * @default_resolution:        Default number of bits to represent the temperature
+ *                     value.
+ * @resolution_limits: Limit register resolution. Optional. Should be set if
+ *                     the resolution of limit registers does not match the
+ *                     resolution of the temperature register.
+ * @resolutions:       List of resolutions associated with sample times.
+ *                     Optional. Should be set if num_sample_times is larger
+ *                     than 1, and if the resolution changes with sample times.
+ *                     If set, number of entries must match num_sample_times.
+ * @default_sample_time:Sample time to be set by default.
+ * @num_sample_times:  Number of possible sample times to be set. Optional.
+ *                     Should be set if the number of sample times is larger
+ *                     than one.
+ * @sample_times:      All the possible sample times to be set. Mandatory if
+ *                     num_sample_times is larger than 1. If set, number of
+ *                     entries must match num_sample_times.
+ */
+
+struct lm75_params {
+       u8                      set_mask;
+       u8                      clr_mask;
+       u8                      default_resolution;
+       u8                      resolution_limits;
+       const u8                *resolutions;
+       unsigned int            default_sample_time;
+       u8                      num_sample_times;
+       const unsigned int      *sample_times;
+};
+
 /* Addresses scanned */
 static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
                                        0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
@@ -59,24 +95,231 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
 #define LM75_REG_CONF          0x01
 #define LM75_REG_HYST          0x02
 #define LM75_REG_MAX           0x03
+#define PCT2075_REG_IDLE       0x04
 
 /* Each client has this additional data */
 struct lm75_data {
-       struct i2c_client       *client;
-       struct regmap           *regmap;
-       u8                      orig_conf;
-       u8                      resolution;     /* In bits, between 9 and 16 */
-       u8                      resolution_limits;
-       unsigned int            sample_time;    /* In ms */
+       struct i2c_client               *client;
+       struct regmap                   *regmap;
+       u8                              orig_conf;
+       u8                              current_conf;
+       u8                              resolution;     /* In bits, 9 to 16 */
+       unsigned int                    sample_time;    /* In ms */
+       enum lm75_type                  kind;
+       const struct lm75_params        *params;
 };
 
 /*-----------------------------------------------------------------------*/
 
+static const u8 lm75_sample_set_masks[] = { 0 << 5, 1 << 5, 2 << 5, 3 << 5 };
+
+#define LM75_SAMPLE_CLEAR_MASK (3 << 5)
+
+/* The structure below stores the configuration values of the supported devices.
+ * In case of being supported multiple configurations, the default one must
+ * always be the first element of the array
+ */
+static const struct lm75_params device_params[] = {
+       [adt75] = {
+               .clr_mask = 1 << 5,     /* not one-shot mode */
+               .default_resolution = 12,
+               .default_sample_time = MSEC_PER_SEC / 10,
+       },
+       [ds1775] = {
+               .clr_mask = 3 << 5,
+               .set_mask = 2 << 5,     /* 11-bit mode */
+               .default_resolution = 11,
+               .default_sample_time = 500,
+               .num_sample_times = 4,
+               .sample_times = (unsigned int []){ 125, 250, 500, 1000 },
+               .resolutions = (u8 []) {9, 10, 11, 12 },
+       },
+       [ds75] = {
+               .clr_mask = 3 << 5,
+               .set_mask = 2 << 5,     /* 11-bit mode */
+               .default_resolution = 11,
+               .default_sample_time = 600,
+               .num_sample_times = 4,
+               .sample_times = (unsigned int []){ 150, 300, 600, 1200 },
+               .resolutions = (u8 []) {9, 10, 11, 12 },
+       },
+       [stds75] = {
+               .clr_mask = 3 << 5,
+               .set_mask = 2 << 5,     /* 11-bit mode */
+               .default_resolution = 11,
+               .default_sample_time = 600,
+               .num_sample_times = 4,
+               .sample_times = (unsigned int []){ 150, 300, 600, 1200 },
+               .resolutions = (u8 []) {9, 10, 11, 12 },
+       },
+       [stlm75] = {
+               .default_resolution = 9,
+               .default_sample_time = MSEC_PER_SEC / 6,
+       },
+       [ds7505] = {
+               .set_mask = 3 << 5,     /* 12-bit mode*/
+               .default_resolution = 12,
+               .default_sample_time = 200,
+               .num_sample_times = 4,
+               .sample_times = (unsigned int []){ 25, 50, 100, 200 },
+               .resolutions = (u8 []) {9, 10, 11, 12 },
+       },
+       [g751] = {
+               .default_resolution = 9,
+               .default_sample_time = MSEC_PER_SEC / 10,
+       },
+       [lm75] = {
+               .default_resolution = 9,
+               .default_sample_time = MSEC_PER_SEC / 10,
+       },
+       [lm75a] = {
+               .default_resolution = 9,
+               .default_sample_time = MSEC_PER_SEC / 10,
+       },
+       [lm75b] = {
+               .default_resolution = 11,
+               .default_sample_time = MSEC_PER_SEC / 10,
+       },
+       [max6625] = {
+               .default_resolution = 9,
+               .default_sample_time = MSEC_PER_SEC / 7,
+       },
+       [max6626] = {
+               .default_resolution = 12,
+               .default_sample_time = MSEC_PER_SEC / 7,
+               .resolution_limits = 9,
+       },
+       [max31725] = {
+               .default_resolution = 16,
+               .default_sample_time = MSEC_PER_SEC / 20,
+       },
+       [tcn75] = {
+               .default_resolution = 9,
+               .default_sample_time = MSEC_PER_SEC / 18,
+       },
+       [pct2075] = {
+               .default_resolution = 11,
+               .default_sample_time = MSEC_PER_SEC / 10,
+               .num_sample_times = 31,
+               .sample_times = (unsigned int []){ 100, 200, 300, 400, 500, 600,
+               700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700,
+               1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500, 2600, 2700,
+               2800, 2900, 3000, 3100 },
+       },
+       [mcp980x] = {
+               .set_mask = 3 << 5,     /* 12-bit mode */
+               .clr_mask = 1 << 7,     /* not one-shot mode */
+               .default_resolution = 12,
+               .resolution_limits = 9,
+               .default_sample_time = 240,
+               .num_sample_times = 4,
+               .sample_times = (unsigned int []){ 30, 60, 120, 240 },
+               .resolutions = (u8 []) {9, 10, 11, 12 },
+       },
+       [tmp100] = {
+               .set_mask = 3 << 5,     /* 12-bit mode */
+               .clr_mask = 1 << 7,     /* not one-shot mode */
+               .default_resolution = 12,
+               .default_sample_time = 320,
+               .num_sample_times = 4,
+               .sample_times = (unsigned int []){ 40, 80, 160, 320 },
+               .resolutions = (u8 []) {9, 10, 11, 12 },
+       },
+       [tmp101] = {
+               .set_mask = 3 << 5,     /* 12-bit mode */
+               .clr_mask = 1 << 7,     /* not one-shot mode */
+               .default_resolution = 12,
+               .default_sample_time = 320,
+               .num_sample_times = 4,
+               .sample_times = (unsigned int []){ 40, 80, 160, 320 },
+               .resolutions = (u8 []) {9, 10, 11, 12 },
+       },
+       [tmp105] = {
+               .set_mask = 3 << 5,     /* 12-bit mode */
+               .clr_mask = 1 << 7,     /* not one-shot mode*/
+               .default_resolution = 12,
+               .default_sample_time = 220,
+               .num_sample_times = 4,
+               .sample_times = (unsigned int []){ 28, 55, 110, 220 },
+               .resolutions = (u8 []) {9, 10, 11, 12 },
+       },
+       [tmp112] = {
+               .set_mask = 3 << 5,     /* 8 samples / second */
+               .clr_mask = 1 << 7,     /* no one-shot mode*/
+               .default_resolution = 12,
+               .default_sample_time = 125,
+               .num_sample_times = 4,
+               .sample_times = (unsigned int []){ 125, 250, 1000, 4000 },
+       },
+       [tmp175] = {
+               .set_mask = 3 << 5,     /* 12-bit mode */
+               .clr_mask = 1 << 7,     /* not one-shot mode*/
+               .default_resolution = 12,
+               .default_sample_time = 220,
+               .num_sample_times = 4,
+               .sample_times = (unsigned int []){ 28, 55, 110, 220 },
+               .resolutions = (u8 []) {9, 10, 11, 12 },
+       },
+       [tmp275] = {
+               .set_mask = 3 << 5,     /* 12-bit mode */
+               .clr_mask = 1 << 7,     /* not one-shot mode*/
+               .default_resolution = 12,
+               .default_sample_time = 220,
+               .num_sample_times = 4,
+               .sample_times = (unsigned int []){ 28, 55, 110, 220 },
+               .resolutions = (u8 []) {9, 10, 11, 12 },
+       },
+       [tmp75] = {
+               .set_mask = 3 << 5,     /* 12-bit mode */
+               .clr_mask = 1 << 7,     /* not one-shot mode*/
+               .default_resolution = 12,
+               .default_sample_time = 220,
+               .num_sample_times = 4,
+               .sample_times = (unsigned int []){ 28, 55, 110, 220 },
+               .resolutions = (u8 []) {9, 10, 11, 12 },
+       },
+       [tmp75b] = { /* not one-shot mode, Conversion rate 37Hz */
+               .clr_mask = 1 << 7 | 3 << 5,
+               .default_resolution = 12,
+               .default_sample_time = MSEC_PER_SEC / 37,
+               .sample_times = (unsigned int []){ MSEC_PER_SEC / 37,
+                       MSEC_PER_SEC / 18,
+                       MSEC_PER_SEC / 9, MSEC_PER_SEC / 4 },
+               .num_sample_times = 4,
+       },
+       [tmp75c] = {
+               .clr_mask = 1 << 5,     /*not one-shot mode*/
+               .default_resolution = 12,
+               .default_sample_time = MSEC_PER_SEC / 12,
+       }
+};
+
 static inline long lm75_reg_to_mc(s16 temp, u8 resolution)
 {
        return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8);
 }
 
+static int lm75_write_config(struct lm75_data *data, u8 set_mask,
+                            u8 clr_mask)
+{
+       u8 value;
+
+       clr_mask |= LM75_SHUTDOWN;
+       value = data->current_conf & ~clr_mask;
+       value |= set_mask;
+
+       if (data->current_conf != value) {
+               s32 err;
+
+               err = i2c_smbus_write_byte_data(data->client, LM75_REG_CONF,
+                                               value);
+               if (err)
+                       return err;
+               data->current_conf = value;
+       }
+       return 0;
+}
+
 static int lm75_read(struct device *dev, enum hwmon_sensor_types type,
                     u32 attr, int channel, long *val)
 {
@@ -120,16 +363,12 @@ static int lm75_read(struct device *dev, enum hwmon_sensor_types type,
        return 0;
 }
 
-static int lm75_write(struct device *dev, enum hwmon_sensor_types type,
-                     u32 attr, int channel, long temp)
+static int lm75_write_temp(struct device *dev, u32 attr, long temp)
 {
        struct lm75_data *data = dev_get_drvdata(dev);
        u8 resolution;
        int reg;
 
-       if (type != hwmon_temp)
-               return -EINVAL;
-
        switch (attr) {
        case hwmon_temp_max:
                reg = LM75_REG_MAX;
@@ -145,8 +384,8 @@ static int lm75_write(struct device *dev, enum hwmon_sensor_types type,
         * Resolution of limit registers is assumed to be the same as the
         * temperature input register resolution unless given explicitly.
         */
-       if (data->resolution_limits)
-               resolution = data->resolution_limits;
+       if (data->params->resolution_limits)
+               resolution = data->params->resolution_limits;
        else
                resolution = data->resolution;
 
@@ -154,16 +393,88 @@ static int lm75_write(struct device *dev, enum hwmon_sensor_types type,
        temp = DIV_ROUND_CLOSEST(temp  << (resolution - 8),
                                 1000) << (16 - resolution);
 
-       return regmap_write(data->regmap, reg, temp);
+       return regmap_write(data->regmap, reg, (u16)temp);
+}
+
+static int lm75_update_interval(struct device *dev, long val)
+{
+       struct lm75_data *data = dev_get_drvdata(dev);
+       unsigned int reg;
+       u8 index;
+       s32 err;
+
+       index = find_closest(val, data->params->sample_times,
+                            (int)data->params->num_sample_times);
+
+       switch (data->kind) {
+       default:
+               err = lm75_write_config(data, lm75_sample_set_masks[index],
+                                       LM75_SAMPLE_CLEAR_MASK);
+               if (err)
+                       return err;
+
+               data->sample_time = data->params->sample_times[index];
+               if (data->params->resolutions)
+                       data->resolution = data->params->resolutions[index];
+               break;
+       case tmp112:
+               err = regmap_read(data->regmap, LM75_REG_CONF, &reg);
+               if (err < 0)
+                       return err;
+               reg &= ~0x00c0;
+               reg |= (3 - index) << 6;
+               err = regmap_write(data->regmap, LM75_REG_CONF, reg);
+               if (err < 0)
+                       return err;
+               data->sample_time = data->params->sample_times[index];
+               break;
+       case pct2075:
+               err = i2c_smbus_write_byte_data(data->client, PCT2075_REG_IDLE,
+                                               index + 1);
+               if (err)
+                       return err;
+               data->sample_time = data->params->sample_times[index];
+               break;
+       }
+       return 0;
+}
+
+static int lm75_write_chip(struct device *dev, u32 attr, long val)
+{
+       switch (attr) {
+       case hwmon_chip_update_interval:
+               return lm75_update_interval(dev, val);
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int lm75_write(struct device *dev, enum hwmon_sensor_types type,
+                     u32 attr, int channel, long val)
+{
+       switch (type) {
+       case hwmon_chip:
+               return lm75_write_chip(dev, attr, val);
+       case hwmon_temp:
+               return lm75_write_temp(dev, attr, val);
+       default:
+               return -EINVAL;
+       }
+       return 0;
 }
 
 static umode_t lm75_is_visible(const void *data, enum hwmon_sensor_types type,
                               u32 attr, int channel)
 {
+       const struct lm75_data *config_data = data;
+
        switch (type) {
        case hwmon_chip:
                switch (attr) {
                case hwmon_chip_update_interval:
+                       if (config_data->params->num_sample_times > 1)
+                               return 0644;
                        return 0444;
                }
                break;
@@ -208,13 +519,13 @@ static bool lm75_is_writeable_reg(struct device *dev, unsigned int reg)
 
 static bool lm75_is_volatile_reg(struct device *dev, unsigned int reg)
 {
-       return reg == LM75_REG_TEMP;
+       return reg == LM75_REG_TEMP || reg == LM75_REG_CONF;
 }
 
 static const struct regmap_config lm75_regmap_config = {
        .reg_bits = 8,
        .val_bits = 16,
-       .max_register = LM75_REG_MAX,
+       .max_register = PCT2075_REG_IDLE,
        .writeable_reg = lm75_is_writeable_reg,
        .volatile_reg = lm75_is_volatile_reg,
        .val_format_endian = REGMAP_ENDIAN_BIG,
@@ -238,8 +549,6 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
        struct device *hwmon_dev;
        struct lm75_data *data;
        int status, err;
-       u8 set_mask, clr_mask;
-       int new;
        enum lm75_type kind;
 
        if (client->dev.of_node)
@@ -256,6 +565,7 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
                return -ENOMEM;
 
        data->client = client;
+       data->kind = kind;
 
        data->regmap = devm_regmap_init_i2c(client, &lm75_regmap_config);
        if (IS_ERR(data->regmap))
@@ -264,113 +574,30 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
        /* Set to LM75 resolution (9 bits, 1/2 degree C) and range.
         * Then tweak to be more precise when appropriate.
         */
-       set_mask = 0;
-       clr_mask = LM75_SHUTDOWN;               /* continuous conversions */
-
-       switch (kind) {
-       case adt75:
-               clr_mask |= 1 << 5;             /* not one-shot mode */
-               data->resolution = 12;
-               data->sample_time = MSEC_PER_SEC / 8;
-               break;
-       case ds1775:
-       case ds75:
-       case stds75:
-               clr_mask |= 3 << 5;
-               set_mask |= 2 << 5;             /* 11-bit mode */
-               data->resolution = 11;
-               data->sample_time = MSEC_PER_SEC;
-               break;
-       case stlm75:
-               data->resolution = 9;
-               data->sample_time = MSEC_PER_SEC / 5;
-               break;
-       case ds7505:
-               set_mask |= 3 << 5;             /* 12-bit mode */
-               data->resolution = 12;
-               data->sample_time = MSEC_PER_SEC / 4;
-               break;
-       case g751:
-       case lm75:
-       case lm75a:
-               data->resolution = 9;
-               data->sample_time = MSEC_PER_SEC / 2;
-               break;
-       case lm75b:
-               data->resolution = 11;
-               data->sample_time = MSEC_PER_SEC / 4;
-               break;
-       case max6625:
-               data->resolution = 9;
-               data->sample_time = MSEC_PER_SEC / 4;
-               break;
-       case max6626:
-               data->resolution = 12;
-               data->resolution_limits = 9;
-               data->sample_time = MSEC_PER_SEC / 4;
-               break;
-       case max31725:
-               data->resolution = 16;
-               data->sample_time = MSEC_PER_SEC / 8;
-               break;
-       case tcn75:
-               data->resolution = 9;
-               data->sample_time = MSEC_PER_SEC / 8;
-               break;
-       case mcp980x:
-               data->resolution_limits = 9;
-               /* fall through */
-       case tmp100:
-       case tmp101:
-               set_mask |= 3 << 5;             /* 12-bit mode */
-               data->resolution = 12;
-               data->sample_time = MSEC_PER_SEC;
-               clr_mask |= 1 << 7;             /* not one-shot mode */
-               break;
-       case tmp112:
-               set_mask |= 3 << 5;             /* 12-bit mode */
-               clr_mask |= 1 << 7;             /* not one-shot mode */
-               data->resolution = 12;
-               data->sample_time = MSEC_PER_SEC / 4;
-               break;
-       case tmp105:
-       case tmp175:
-       case tmp275:
-       case tmp75:
-               set_mask |= 3 << 5;             /* 12-bit mode */
-               clr_mask |= 1 << 7;             /* not one-shot mode */
-               data->resolution = 12;
-               data->sample_time = MSEC_PER_SEC / 2;
-               break;
-       case tmp75b:  /* not one-shot mode, Conversion rate 37Hz */
-               clr_mask |= 1 << 7 | 0x3 << 5;
-               data->resolution = 12;
-               data->sample_time = MSEC_PER_SEC / 37;
-               break;
-       case tmp75c:
-               clr_mask |= 1 << 5;             /* not one-shot mode */
-               data->resolution = 12;
-               data->sample_time = MSEC_PER_SEC / 4;
-               break;
-       }
 
-       /* configure as specified */
+       data->params = &device_params[data->kind];
+
+       /* Save default sample time and resolution*/
+       data->sample_time = data->params->default_sample_time;
+       data->resolution = data->params->default_resolution;
+
+       /* Cache original configuration */
        status = i2c_smbus_read_byte_data(client, LM75_REG_CONF);
        if (status < 0) {
                dev_dbg(dev, "Can't read config? %d\n", status);
                return status;
        }
        data->orig_conf = status;
-       new = status & ~clr_mask;
-       new |= set_mask;
-       if (status != new)
-               i2c_smbus_write_byte_data(client, LM75_REG_CONF, new);
+       data->current_conf = status;
 
-       err = devm_add_action_or_reset(dev, lm75_remove, data);
+       err = lm75_write_config(data, data->params->set_mask,
+                               data->params->clr_mask);
        if (err)
                return err;
 
-       dev_dbg(dev, "Config %02x\n", new);
+       err = devm_add_action_or_reset(dev, lm75_remove, data);
+       if (err)
+               return err;
 
        hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
                                                         data, &lm75_chip_info,
@@ -397,6 +624,7 @@ static const struct i2c_device_id lm75_ids[] = {
        { "max31725", max31725, },
        { "max31726", max31725, },
        { "mcp980x", mcp980x, },
+       { "pct2075", pct2075, },
        { "stds75", stds75, },
        { "stlm75", stlm75, },
        { "tcn75", tcn75, },
@@ -467,6 +695,10 @@ static const struct of_device_id __maybe_unused lm75_of_match[] = {
                .data = (void *)mcp980x
        },
        {
+               .compatible = "nxp,pct2075",
+               .data = (void *)pct2075
+       },
+       {
                .compatible = "st,stds75",
                .data = (void *)stds75
        },
index f9431ad..53ff505 100644 (file)
@@ -13,7 +13,7 @@
 #include <linux/i2c.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/of.h>
+#include <linux/property.h>
 
 #define LTC2990_STATUS 0x00
 #define LTC2990_CONTROL        0x01
@@ -206,7 +206,6 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
        int ret;
        struct device *hwmon_dev;
        struct ltc2990_data *data;
-       struct device_node *of_node = i2c->dev.of_node;
 
        if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
                                     I2C_FUNC_SMBUS_WORD_DATA))
@@ -218,9 +217,10 @@ static int ltc2990_i2c_probe(struct i2c_client *i2c,
 
        data->i2c = i2c;
 
-       if (of_node) {
-               ret = of_property_read_u32_array(of_node, "lltc,meas-mode",
-                                                data->mode, 2);
+       if (dev_fwnode(&i2c->dev)) {
+               ret = device_property_read_u32_array(&i2c->dev,
+                                                    "lltc,meas-mode",
+                                                    data->mode, 2);
                if (ret < 0)
                        return ret;
 
index d42bc08..7efa6bf 100644 (file)
@@ -20,6 +20,7 @@
  *
  * Chip        #vin    #fan    #pwm    #temp  chip IDs       man ID
  * nct6106d     9      3       3       6+3    0xc450 0xc1    0x5ca3
+ * nct6116d     9      5       5       3+3    0xd280 0xc1    0x5ca3
  * nct6775f     9      4       3       6+3    0xb470 0xc1    0x5ca3
  * nct6776f     9      5       3       6+3    0xc330 0xc1    0x5ca3
  * nct6779d    15      5       5       2+6    0xc560 0xc1    0x5ca3
 
 #define USE_ALTERNATE
 
-enum kinds { nct6106, nct6775, nct6776, nct6779, nct6791, nct6792, nct6793,
-            nct6795, nct6796, nct6797, nct6798 };
+enum kinds { nct6106, nct6116, nct6775, nct6776, nct6779, nct6791, nct6792,
+            nct6793, nct6795, nct6796, nct6797, nct6798 };
 
 /* used to set data->name = nct6775_device_names[data->sio_kind] */
 static const char * const nct6775_device_names[] = {
        "nct6106",
+       "nct6116",
        "nct6775",
        "nct6776",
        "nct6779",
@@ -78,6 +80,7 @@ static const char * const nct6775_device_names[] = {
 
 static const char * const nct6775_sio_names[] __initconst = {
        "NCT6106D",
+       "NCT6116D",
        "NCT6775F",
        "NCT6776D/F",
        "NCT6779D",
@@ -115,6 +118,7 @@ MODULE_PARM_DESC(fan_debounce, "Enable debouncing for fan RPM signal");
 #define SIO_REG_ADDR           0x60    /* Logical device address (2 bytes) */
 
 #define SIO_NCT6106_ID         0xc450
+#define SIO_NCT6116_ID         0xd280
 #define SIO_NCT6775_ID         0xb470
 #define SIO_NCT6776_ID         0xc330
 #define SIO_NCT6779_ID         0xc560
@@ -825,10 +829,8 @@ static const u16 NCT6106_FAN_PULSE_SHIFT[] = { 0, 2, 4 };
 
 static const u8 NCT6106_REG_PWM_MODE[] = { 0xf3, 0xf3, 0xf3 };
 static const u8 NCT6106_PWM_MODE_MASK[] = { 0x01, 0x02, 0x04 };
-static const u16 NCT6106_REG_PWM[] = { 0x119, 0x129, 0x139 };
 static const u16 NCT6106_REG_PWM_READ[] = { 0x4a, 0x4b, 0x4c };
 static const u16 NCT6106_REG_FAN_MODE[] = { 0x113, 0x123, 0x133 };
-static const u16 NCT6106_REG_TEMP_SEL[] = { 0x110, 0x120, 0x130 };
 static const u16 NCT6106_REG_TEMP_SOURCE[] = {
        0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5 };
 
@@ -896,6 +898,70 @@ static const u16 NCT6106_REG_TEMP_CRIT[32] = {
        [12] = 0x205,
 };
 
+/* NCT6112D/NCT6114D/NCT6116D specific data */
+
+static const u16 NCT6116_REG_FAN[] = { 0x20, 0x22, 0x24, 0x26, 0x28 };
+static const u16 NCT6116_REG_FAN_MIN[] = { 0xe0, 0xe2, 0xe4, 0xe6, 0xe8 };
+static const u16 NCT6116_REG_FAN_PULSES[] = { 0xf6, 0xf6, 0xf6, 0xf6, 0xf5 };
+static const u16 NCT6116_FAN_PULSE_SHIFT[] = { 0, 2, 4, 6, 6 };
+
+static const u16 NCT6116_REG_PWM[] = { 0x119, 0x129, 0x139, 0x199, 0x1a9 };
+static const u16 NCT6116_REG_FAN_MODE[] = { 0x113, 0x123, 0x133, 0x193, 0x1a3 };
+static const u16 NCT6116_REG_TEMP_SEL[] = { 0x110, 0x120, 0x130, 0x190, 0x1a0 };
+static const u16 NCT6116_REG_TEMP_SOURCE[] = {
+       0xb0, 0xb1, 0xb2 };
+
+static const u16 NCT6116_REG_CRITICAL_TEMP[] = {
+       0x11a, 0x12a, 0x13a, 0x19a, 0x1aa };
+static const u16 NCT6116_REG_CRITICAL_TEMP_TOLERANCE[] = {
+       0x11b, 0x12b, 0x13b, 0x19b, 0x1ab };
+
+static const u16 NCT6116_REG_CRITICAL_PWM_ENABLE[] = {
+       0x11c, 0x12c, 0x13c, 0x19c, 0x1ac };
+static const u16 NCT6116_REG_CRITICAL_PWM[] = {
+       0x11d, 0x12d, 0x13d, 0x19d, 0x1ad };
+
+static const u16 NCT6116_REG_FAN_STEP_UP_TIME[] = {
+       0x114, 0x124, 0x134, 0x194, 0x1a4 };
+static const u16 NCT6116_REG_FAN_STEP_DOWN_TIME[] = {
+       0x115, 0x125, 0x135, 0x195, 0x1a5 };
+static const u16 NCT6116_REG_FAN_STOP_OUTPUT[] = {
+       0x116, 0x126, 0x136, 0x196, 0x1a6 };
+static const u16 NCT6116_REG_FAN_START_OUTPUT[] = {
+       0x117, 0x127, 0x137, 0x197, 0x1a7 };
+static const u16 NCT6116_REG_FAN_STOP_TIME[] = {
+       0x118, 0x128, 0x138, 0x198, 0x1a8 };
+static const u16 NCT6116_REG_TOLERANCE_H[] = {
+       0x112, 0x122, 0x132, 0x192, 0x1a2 };
+
+static const u16 NCT6116_REG_TARGET[] = {
+       0x111, 0x121, 0x131, 0x191, 0x1a1 };
+
+static const u16 NCT6116_REG_AUTO_TEMP[] = {
+       0x160, 0x170, 0x180, 0x1d0, 0x1e0 };
+static const u16 NCT6116_REG_AUTO_PWM[] = {
+       0x164, 0x174, 0x184, 0x1d4, 0x1e4 };
+
+static const s8 NCT6116_ALARM_BITS[] = {
+       0, 1, 2, 3, 4, 5, 7, 8,         /* in0.. in7 */
+       9, -1, -1, -1, -1, -1, -1,      /* in8..in9 */
+       -1,                             /* unused */
+       32, 33, 34, 35, 36,             /* fan1..fan5 */
+       -1, -1, -1,                     /* unused */
+       16, 17, 18, -1, -1, -1,         /* temp1..temp6 */
+       48, -1                          /* intrusion0, intrusion1 */
+};
+
+static const s8 NCT6116_BEEP_BITS[] = {
+       0, 1, 2, 3, 4, 5, 7, 8,         /* in0.. in7 */
+       9, 10, 11, 12, -1, -1, -1,      /* in8..in14 */
+       32,                             /* global beep enable */
+       24, 25, 26, 27, 28,             /* fan1..fan5 */
+       -1, -1, -1,                     /* unused */
+       16, 17, 18, -1, -1, -1,         /* temp1..temp6 */
+       34, -1                          /* intrusion0, intrusion1 */
+};
+
 static enum pwm_enable reg_to_pwm_enable(int pwm, int mode)
 {
        if (mode == 0 && pwm == 255)
@@ -1294,6 +1360,11 @@ static bool is_word_sized(struct nct6775_data *data, u16 reg)
                return reg == 0x20 || reg == 0x22 || reg == 0x24 ||
                  reg == 0xe0 || reg == 0xe2 || reg == 0xe4 ||
                  reg == 0x111 || reg == 0x121 || reg == 0x131;
+       case nct6116:
+               return reg == 0x20 || reg == 0x22 || reg == 0x24 ||
+                 reg == 0x26 || reg == 0x28 || reg == 0xe0 || reg == 0xe2 ||
+                 reg == 0xe4 || reg == 0xe6 || reg == 0xe8 || reg == 0x111 ||
+                 reg == 0x121 || reg == 0x131 || reg == 0x191 || reg == 0x1a1;
        case nct6775:
                return (((reg & 0xff00) == 0x100 ||
                    (reg & 0xff00) == 0x200) &&
@@ -1673,6 +1744,7 @@ static void nct6775_update_pwm_limits(struct device *dev)
                        data->auto_pwm[i][data->auto_pwm_num] = 0xff;
                        break;
                case nct6106:
+               case nct6116:
                case nct6779:
                case nct6791:
                case nct6792:
@@ -3109,6 +3181,7 @@ store_auto_pwm(struct device *dev, struct device_attribute *attr,
                case nct6776:
                        break; /* always enabled, nothing to do */
                case nct6106:
+               case nct6116:
                case nct6779:
                case nct6791:
                case nct6792:
@@ -3535,6 +3608,23 @@ nct6775_check_fan_inputs(struct nct6775_data *data)
 
                fan3pin = !(cr24 & 0x80);
                pwm3pin = cr24 & 0x08;
+       } else if (data->kind == nct6116) {
+               int cr1a = superio_inb(sioreg, 0x1a);
+               int cr1b = superio_inb(sioreg, 0x1b);
+               int cr24 = superio_inb(sioreg, 0x24);
+               int cr2a = superio_inb(sioreg, 0x2a);
+               int cr2b = superio_inb(sioreg, 0x2b);
+               int cr2f = superio_inb(sioreg, 0x2f);
+
+               fan3pin = !(cr2b & 0x10);
+               fan4pin = (cr2b & 0x80) ||                      // pin 1(2)
+                       (!(cr2f & 0x10) && (cr1a & 0x04));      // pin 65(66)
+               fan5pin = (cr2b & 0x80) ||                      // pin 126(127)
+                       (!(cr1b & 0x03) && (cr2a & 0x02));      // pin 94(96)
+
+               pwm3pin = fan3pin && (cr24 & 0x08);
+               pwm4pin = fan4pin;
+               pwm5pin = fan5pin;
        } else {
                /*
                 * NCT6779D, NCT6791D, NCT6792D, NCT6793D, NCT6795D, NCT6796D,
@@ -3765,7 +3855,7 @@ static int nct6775_probe(struct platform_device *pdev)
                data->REG_FAN_TIME[1] = NCT6106_REG_FAN_STEP_UP_TIME;
                data->REG_FAN_TIME[2] = NCT6106_REG_FAN_STEP_DOWN_TIME;
                data->REG_TOLERANCE_H = NCT6106_REG_TOLERANCE_H;
-               data->REG_PWM[0] = NCT6106_REG_PWM;
+               data->REG_PWM[0] = NCT6116_REG_PWM;
                data->REG_PWM[1] = NCT6106_REG_FAN_START_OUTPUT;
                data->REG_PWM[2] = NCT6106_REG_FAN_STOP_OUTPUT;
                data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP;
@@ -3784,7 +3874,7 @@ static int nct6775_probe(struct platform_device *pdev)
                data->REG_CRITICAL_PWM = NCT6106_REG_CRITICAL_PWM;
                data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET;
                data->REG_TEMP_SOURCE = NCT6106_REG_TEMP_SOURCE;
-               data->REG_TEMP_SEL = NCT6106_REG_TEMP_SEL;
+               data->REG_TEMP_SEL = NCT6116_REG_TEMP_SEL;
                data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL;
                data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP;
                data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL;
@@ -3807,6 +3897,79 @@ static int nct6775_probe(struct platform_device *pdev)
                reg_temp_crit_h = NCT6106_REG_TEMP_CRIT_H;
 
                break;
+       case nct6116:
+               data->in_num = 9;
+               data->pwm_num = 3;
+               data->auto_pwm_num = 4;
+               data->temp_fixed_num = 3;
+               data->num_temp_alarms = 3;
+               data->num_temp_beeps = 3;
+
+               data->fan_from_reg = fan_from_reg13;
+               data->fan_from_reg_min = fan_from_reg13;
+
+               data->temp_label = nct6776_temp_label;
+               data->temp_mask = NCT6776_TEMP_MASK;
+               data->virt_temp_mask = NCT6776_VIRT_TEMP_MASK;
+
+               data->REG_VBAT = NCT6106_REG_VBAT;
+               data->REG_DIODE = NCT6106_REG_DIODE;
+               data->DIODE_MASK = NCT6106_DIODE_MASK;
+               data->REG_VIN = NCT6106_REG_IN;
+               data->REG_IN_MINMAX[0] = NCT6106_REG_IN_MIN;
+               data->REG_IN_MINMAX[1] = NCT6106_REG_IN_MAX;
+               data->REG_TARGET = NCT6116_REG_TARGET;
+               data->REG_FAN = NCT6116_REG_FAN;
+               data->REG_FAN_MODE = NCT6116_REG_FAN_MODE;
+               data->REG_FAN_MIN = NCT6116_REG_FAN_MIN;
+               data->REG_FAN_PULSES = NCT6116_REG_FAN_PULSES;
+               data->FAN_PULSE_SHIFT = NCT6116_FAN_PULSE_SHIFT;
+               data->REG_FAN_TIME[0] = NCT6116_REG_FAN_STOP_TIME;
+               data->REG_FAN_TIME[1] = NCT6116_REG_FAN_STEP_UP_TIME;
+               data->REG_FAN_TIME[2] = NCT6116_REG_FAN_STEP_DOWN_TIME;
+               data->REG_TOLERANCE_H = NCT6116_REG_TOLERANCE_H;
+               data->REG_PWM[0] = NCT6116_REG_PWM;
+               data->REG_PWM[1] = NCT6116_REG_FAN_START_OUTPUT;
+               data->REG_PWM[2] = NCT6116_REG_FAN_STOP_OUTPUT;
+               data->REG_PWM[5] = NCT6106_REG_WEIGHT_DUTY_STEP;
+               data->REG_PWM[6] = NCT6106_REG_WEIGHT_DUTY_BASE;
+               data->REG_PWM_READ = NCT6106_REG_PWM_READ;
+               data->REG_PWM_MODE = NCT6106_REG_PWM_MODE;
+               data->PWM_MODE_MASK = NCT6106_PWM_MODE_MASK;
+               data->REG_AUTO_TEMP = NCT6116_REG_AUTO_TEMP;
+               data->REG_AUTO_PWM = NCT6116_REG_AUTO_PWM;
+               data->REG_CRITICAL_TEMP = NCT6116_REG_CRITICAL_TEMP;
+               data->REG_CRITICAL_TEMP_TOLERANCE
+                 = NCT6116_REG_CRITICAL_TEMP_TOLERANCE;
+               data->REG_CRITICAL_PWM_ENABLE = NCT6116_REG_CRITICAL_PWM_ENABLE;
+               data->CRITICAL_PWM_ENABLE_MASK
+                 = NCT6106_CRITICAL_PWM_ENABLE_MASK;
+               data->REG_CRITICAL_PWM = NCT6116_REG_CRITICAL_PWM;
+               data->REG_TEMP_OFFSET = NCT6106_REG_TEMP_OFFSET;
+               data->REG_TEMP_SOURCE = NCT6116_REG_TEMP_SOURCE;
+               data->REG_TEMP_SEL = NCT6116_REG_TEMP_SEL;
+               data->REG_WEIGHT_TEMP_SEL = NCT6106_REG_WEIGHT_TEMP_SEL;
+               data->REG_WEIGHT_TEMP[0] = NCT6106_REG_WEIGHT_TEMP_STEP;
+               data->REG_WEIGHT_TEMP[1] = NCT6106_REG_WEIGHT_TEMP_STEP_TOL;
+               data->REG_WEIGHT_TEMP[2] = NCT6106_REG_WEIGHT_TEMP_BASE;
+               data->REG_ALARM = NCT6106_REG_ALARM;
+               data->ALARM_BITS = NCT6116_ALARM_BITS;
+               data->REG_BEEP = NCT6106_REG_BEEP;
+               data->BEEP_BITS = NCT6116_BEEP_BITS;
+
+               reg_temp = NCT6106_REG_TEMP;
+               reg_temp_mon = NCT6106_REG_TEMP_MON;
+               num_reg_temp = ARRAY_SIZE(NCT6106_REG_TEMP);
+               num_reg_temp_mon = ARRAY_SIZE(NCT6106_REG_TEMP_MON);
+               reg_temp_over = NCT6106_REG_TEMP_OVER;
+               reg_temp_hyst = NCT6106_REG_TEMP_HYST;
+               reg_temp_config = NCT6106_REG_TEMP_CONFIG;
+               reg_temp_alternate = NCT6106_REG_TEMP_ALTERNATE;
+               reg_temp_crit = NCT6106_REG_TEMP_CRIT;
+               reg_temp_crit_l = NCT6106_REG_TEMP_CRIT_L;
+               reg_temp_crit_h = NCT6106_REG_TEMP_CRIT_H;
+
+               break;
        case nct6775:
                data->in_num = 9;
                data->pwm_num = 3;
@@ -4352,6 +4515,7 @@ static int nct6775_probe(struct platform_device *pdev)
                data->have_vid = (cr2a & 0x60) == 0x40;
                break;
        case nct6106:
+       case nct6116:
        case nct6779:
        case nct6791:
        case nct6792:
@@ -4381,6 +4545,7 @@ static int nct6775_probe(struct platform_device *pdev)
                                  NCT6775_REG_CR_FAN_DEBOUNCE);
                switch (data->kind) {
                case nct6106:
+               case nct6116:
                        tmp |= 0xe0;
                        break;
                case nct6775:
@@ -4576,6 +4741,9 @@ static int __init nct6775_find(int sioaddr, struct nct6775_sio_data *sio_data)
        case SIO_NCT6106_ID:
                sio_data->kind = nct6106;
                break;
+       case SIO_NCT6116_ID:
+               sio_data->kind = nct6116;
+               break;
        case SIO_NCT6775_ID:
                sio_data->kind = nct6775;
                break;
index 710c305..95b447c 100644 (file)
 #define DTS_T_CTRL1_REG                0x27
 #define VT_ADC_MD_REG          0x2E
 
+#define VSEN1_HV_LL_REG                0x02    /* Bank 1; 2 regs (HV/LV) per sensor */
+#define VSEN1_LV_LL_REG                0x03    /* Bank 1; 2 regs (HV/LV) per sensor */
+#define VSEN1_HV_HL_REG                0x00    /* Bank 1; 2 regs (HV/LV) per sensor */
+#define VSEN1_LV_HL_REG                0x01    /* Bank 1; 2 regs (HV/LV) per sensor */
+#define SMI_STS1_REG           0xC1    /* Bank 0; SMI Status Register */
+#define SMI_STS3_REG           0xC3    /* Bank 0; SMI Status Register */
+#define SMI_STS5_REG           0xC5    /* Bank 0; SMI Status Register */
+#define SMI_STS7_REG           0xC7    /* Bank 0; SMI Status Register */
+#define SMI_STS8_REG           0xC8    /* Bank 0; SMI Status Register */
+
 #define VSEN1_HV_REG           0x40    /* Bank 0; 2 regs (HV/LV) per sensor */
 #define TEMP_CH1_HV_REG                0x42    /* Bank 0; same as VSEN2_HV */
 #define LTD_HV_REG             0x62    /* Bank 0; 2 regs in VSEN range */
+#define LTD_HV_HL_REG          0x44    /* Bank 1; 1 reg for LTD */
+#define LTD_LV_HL_REG          0x45    /* Bank 1; 1 reg for LTD */
+#define LTD_HV_LL_REG          0x46    /* Bank 1; 1 reg for LTD */
+#define LTD_LV_LL_REG          0x47    /* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_CH_REG                0x05    /* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_W_REG         0x06    /* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_WH_REG                0x07    /* Bank 1; 1 reg for LTD */
+#define TEMP_CH1_C_REG         0x04    /* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_C_REG       0x90    /* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_CH_REG      0x91    /* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_W_REG       0x92    /* Bank 1; 1 reg per sensor */
+#define DTS_T_CPU1_WH_REG      0x93    /* Bank 1; 1 reg per sensor */
 #define FANIN1_HV_REG          0x80    /* Bank 0; 2 regs (HV/LV) per sensor */
+#define FANIN1_HV_HL_REG       0x60    /* Bank 1; 2 regs (HV/LV) per sensor */
+#define FANIN1_LV_HL_REG       0x61    /* Bank 1; 2 regs (HV/LV) per sensor */
 #define T_CPU1_HV_REG          0xA0    /* Bank 0; 2 regs (HV/LV) per sensor */
 
 #define PRTS_REG               0x03    /* Bank 2 */
@@ -58,6 +82,8 @@
 #define FANCTL1_FMR_REG                0x00    /* Bank 3; 1 reg per channel */
 #define FANCTL1_OUT_REG                0x10    /* Bank 3; 1 reg per channel */
 
+#define ENABLE_TSI     BIT(1)
+
 static const unsigned short normal_i2c[] = {
        0x2d, 0x2e, I2C_CLIENT_END
 };
@@ -72,6 +98,7 @@ struct nct7904_data {
        u8 fan_mode[FANCTL_MAX];
        u8 enable_dts;
        u8 has_dts;
+       u8 temp_mode; /* 0: TR mode, 1: TD mode */
 };
 
 /* Access functions */
@@ -170,6 +197,25 @@ static int nct7904_read_fan(struct device *dev, u32 attr, int channel,
                        rpm = 1350000 / cnt;
                *val = rpm;
                return 0;
+       case hwmon_fan_min:
+               ret = nct7904_read_reg16(data, BANK_1,
+                                        FANIN1_HV_HL_REG + channel * 2);
+               if (ret < 0)
+                       return ret;
+               cnt = ((ret & 0xff00) >> 3) | (ret & 0x1f);
+               if (cnt == 0x1fff)
+                       rpm = 0;
+               else
+                       rpm = 1350000 / cnt;
+               *val = rpm;
+               return 0;
+       case hwmon_fan_alarm:
+               ret = nct7904_read_reg(data, BANK_0,
+                                      SMI_STS5_REG + (channel >> 3));
+               if (ret < 0)
+                       return ret;
+               *val = (ret >> (channel & 0x07)) & 1;
+               return 0;
        default:
                return -EOPNOTSUPP;
        }
@@ -179,8 +225,20 @@ static umode_t nct7904_fan_is_visible(const void *_data, u32 attr, int channel)
 {
        const struct nct7904_data *data = _data;
 
-       if (attr == hwmon_fan_input && data->fanin_mask & (1 << channel))
-               return 0444;
+       switch (attr) {
+       case hwmon_fan_input:
+       case hwmon_fan_alarm:
+               if (data->fanin_mask & (1 << channel))
+                       return 0444;
+               break;
+       case hwmon_fan_min:
+               if (data->fanin_mask & (1 << channel))
+                       return 0644;
+               break;
+       default:
+               break;
+       }
+
        return 0;
 }
 
@@ -211,6 +269,37 @@ static int nct7904_read_in(struct device *dev, u32 attr, int channel,
                        volt *= 6; /* 0.006V scale */
                *val = volt;
                return 0;
+       case hwmon_in_min:
+               ret = nct7904_read_reg16(data, BANK_1,
+                                        VSEN1_HV_LL_REG + index * 4);
+               if (ret < 0)
+                       return ret;
+               volt = ((ret & 0xff00) >> 5) | (ret & 0x7);
+               if (index < 14)
+                       volt *= 2; /* 0.002V scale */
+               else
+                       volt *= 6; /* 0.006V scale */
+               *val = volt;
+               return 0;
+       case hwmon_in_max:
+               ret = nct7904_read_reg16(data, BANK_1,
+                                        VSEN1_HV_HL_REG + index * 4);
+               if (ret < 0)
+                       return ret;
+               volt = ((ret & 0xff00) >> 5) | (ret & 0x7);
+               if (index < 14)
+                       volt *= 2; /* 0.002V scale */
+               else
+                       volt *= 6; /* 0.006V scale */
+               *val = volt;
+               return 0;
+       case hwmon_in_alarm:
+               ret = nct7904_read_reg(data, BANK_0,
+                                      SMI_STS1_REG + (index >> 3));
+               if (ret < 0)
+                       return ret;
+               *val = (ret >> (index & 0x07)) & 1;
+               return 0;
        default:
                return -EOPNOTSUPP;
        }
@@ -221,9 +310,20 @@ static umode_t nct7904_in_is_visible(const void *_data, u32 attr, int channel)
        const struct nct7904_data *data = _data;
        int index = nct7904_chan_to_index[channel];
 
-       if (channel > 0 && attr == hwmon_in_input &&
-           (data->vsen_mask & BIT(index)))
-               return 0444;
+       switch (attr) {
+       case hwmon_in_input:
+       case hwmon_in_alarm:
+               if (channel > 0 && (data->vsen_mask & BIT(index)))
+                       return 0444;
+               break;
+       case hwmon_in_min:
+       case hwmon_in_max:
+               if (channel > 0 && (data->vsen_mask & BIT(index)))
+                       return 0644;
+               break;
+       default:
+               break;
+       }
 
        return 0;
 }
@@ -233,6 +333,7 @@ static int nct7904_read_temp(struct device *dev, u32 attr, int channel,
 {
        struct nct7904_data *data = dev_get_drvdata(dev);
        int ret, temp;
+       unsigned int reg1, reg2, reg3;
 
        switch (attr) {
        case hwmon_temp_input:
@@ -250,16 +351,106 @@ static int nct7904_read_temp(struct device *dev, u32 attr, int channel,
                temp = ((ret & 0xff00) >> 5) | (ret & 0x7);
                *val = sign_extend32(temp, 10) * 125;
                return 0;
+       case hwmon_temp_alarm:
+               if (channel == 4) {
+                       ret = nct7904_read_reg(data, BANK_0,
+                                              SMI_STS3_REG);
+                       if (ret < 0)
+                               return ret;
+                       *val = (ret >> 1) & 1;
+               } else if (channel < 4) {
+                       ret = nct7904_read_reg(data, BANK_0,
+                                              SMI_STS1_REG);
+                       if (ret < 0)
+                               return ret;
+                       *val = (ret >> (((channel * 2) + 1) & 0x07)) & 1;
+               } else {
+                       if ((channel - 5) < 4) {
+                               ret = nct7904_read_reg(data, BANK_0,
+                                                      SMI_STS7_REG +
+                                                      ((channel - 5) >> 3));
+                               if (ret < 0)
+                                       return ret;
+                               *val = (ret >> ((channel - 5) & 0x07)) & 1;
+                       } else {
+                               ret = nct7904_read_reg(data, BANK_0,
+                                                      SMI_STS8_REG +
+                                                      ((channel - 5) >> 3));
+                               if (ret < 0)
+                                       return ret;
+                               *val = (ret >> (((channel - 5) & 0x07) - 4))
+                                                       & 1;
+                       }
+               }
+               return 0;
+       case hwmon_temp_type:
+               if (channel < 5) {
+                       if ((data->tcpu_mask >> channel) & 0x01) {
+                               if ((data->temp_mode >> channel) & 0x01)
+                                       *val = 3; /* TD */
+                               else
+                                       *val = 4; /* TR */
+                       } else {
+                               *val = 0;
+                       }
+               } else {
+                       if ((data->has_dts >> (channel - 5)) & 0x01) {
+                               if (data->enable_dts & ENABLE_TSI)
+                                       *val = 5; /* TSI */
+                               else
+                                       *val = 6; /* PECI */
+                       } else {
+                               *val = 0;
+                       }
+               }
+               return 0;
+       case hwmon_temp_max:
+               reg1 = LTD_HV_LL_REG;
+               reg2 = TEMP_CH1_W_REG;
+               reg3 = DTS_T_CPU1_W_REG;
+               break;
+       case hwmon_temp_max_hyst:
+               reg1 = LTD_LV_LL_REG;
+               reg2 = TEMP_CH1_WH_REG;
+               reg3 = DTS_T_CPU1_WH_REG;
+               break;
+       case hwmon_temp_crit:
+               reg1 = LTD_HV_HL_REG;
+               reg2 = TEMP_CH1_C_REG;
+               reg3 = DTS_T_CPU1_C_REG;
+               break;
+       case hwmon_temp_crit_hyst:
+               reg1 = LTD_LV_HL_REG;
+               reg2 = TEMP_CH1_CH_REG;
+               reg3 = DTS_T_CPU1_CH_REG;
+               break;
        default:
                return -EOPNOTSUPP;
        }
+
+       if (channel == 4)
+               ret = nct7904_read_reg(data, BANK_1, reg1);
+       else if (channel < 5)
+               ret = nct7904_read_reg(data, BANK_1,
+                                      reg2 + channel * 8);
+       else
+               ret = nct7904_read_reg(data, BANK_1,
+                                      reg3 + (channel - 5) * 4);
+
+       if (ret < 0)
+               return ret;
+       *val = ret * 1000;
+       return 0;
 }
 
 static umode_t nct7904_temp_is_visible(const void *_data, u32 attr, int channel)
 {
        const struct nct7904_data *data = _data;
 
-       if (attr == hwmon_temp_input) {
+       switch (attr) {
+       case hwmon_temp_input:
+       case hwmon_temp_alarm:
+       case hwmon_temp_type:
                if (channel < 5) {
                        if (data->tcpu_mask & BIT(channel))
                                return 0444;
@@ -267,6 +458,21 @@ static umode_t nct7904_temp_is_visible(const void *_data, u32 attr, int channel)
                        if (data->has_dts & BIT(channel - 5))
                                return 0444;
                }
+               break;
+       case hwmon_temp_max:
+       case hwmon_temp_max_hyst:
+       case hwmon_temp_crit:
+       case hwmon_temp_crit_hyst:
+               if (channel < 5) {
+                       if (data->tcpu_mask & BIT(channel))
+                               return 0644;
+               } else {
+                       if (data->has_dts & BIT(channel - 5))
+                               return 0644;
+               }
+               break;
+       default:
+               break;
        }
 
        return 0;
@@ -297,6 +503,137 @@ static int nct7904_read_pwm(struct device *dev, u32 attr, int channel,
        }
 }
 
+static int nct7904_write_temp(struct device *dev, u32 attr, int channel,
+                             long val)
+{
+       struct nct7904_data *data = dev_get_drvdata(dev);
+       int ret;
+       unsigned int reg1, reg2, reg3;
+
+       val = clamp_val(val / 1000, -128, 127);
+
+       switch (attr) {
+       case hwmon_temp_max:
+               reg1 = LTD_HV_LL_REG;
+               reg2 = TEMP_CH1_W_REG;
+               reg3 = DTS_T_CPU1_W_REG;
+               break;
+       case hwmon_temp_max_hyst:
+               reg1 = LTD_LV_LL_REG;
+               reg2 = TEMP_CH1_WH_REG;
+               reg3 = DTS_T_CPU1_WH_REG;
+               break;
+       case hwmon_temp_crit:
+               reg1 = LTD_HV_HL_REG;
+               reg2 = TEMP_CH1_C_REG;
+               reg3 = DTS_T_CPU1_C_REG;
+               break;
+       case hwmon_temp_crit_hyst:
+               reg1 = LTD_LV_HL_REG;
+               reg2 = TEMP_CH1_CH_REG;
+               reg3 = DTS_T_CPU1_CH_REG;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+       if (channel == 4)
+               ret = nct7904_write_reg(data, BANK_1, reg1, val);
+       else if (channel < 5)
+               ret = nct7904_write_reg(data, BANK_1,
+                                       reg2 + channel * 8, val);
+       else
+               ret = nct7904_write_reg(data, BANK_1,
+                                       reg3 + (channel - 5) * 4, val);
+
+       return ret;
+}
+
+static int nct7904_write_fan(struct device *dev, u32 attr, int channel,
+                            long val)
+{
+       struct nct7904_data *data = dev_get_drvdata(dev);
+       int ret;
+       u8 tmp;
+
+       switch (attr) {
+       case hwmon_fan_min:
+               if (val <= 0)
+                       return -EINVAL;
+
+               val = clamp_val(DIV_ROUND_CLOSEST(1350000, val), 1, 0x1fff);
+               tmp = (val >> 5) & 0xff;
+               ret = nct7904_write_reg(data, BANK_1,
+                                       FANIN1_HV_HL_REG + channel * 2, tmp);
+               if (ret < 0)
+                       return ret;
+               tmp = val & 0x1f;
+               ret = nct7904_write_reg(data, BANK_1,
+                                       FANIN1_LV_HL_REG + channel * 2, tmp);
+               return ret;
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static int nct7904_write_in(struct device *dev, u32 attr, int channel,
+                           long val)
+{
+       struct nct7904_data *data = dev_get_drvdata(dev);
+       int ret, index, tmp;
+
+       index = nct7904_chan_to_index[channel];
+
+       if (index < 14)
+               val = val / 2; /* 0.002V scale */
+       else
+               val = val / 6; /* 0.006V scale */
+
+       val = clamp_val(val, 0, 0x7ff);
+
+       switch (attr) {
+       case hwmon_in_min:
+               tmp = nct7904_read_reg(data, BANK_1,
+                                      VSEN1_LV_LL_REG + index * 4);
+               if (tmp < 0)
+                       return tmp;
+               tmp &= ~0x7;
+               tmp |= val & 0x7;
+               ret = nct7904_write_reg(data, BANK_1,
+                                       VSEN1_LV_LL_REG + index * 4, tmp);
+               if (ret < 0)
+                       return ret;
+               tmp = nct7904_read_reg(data, BANK_1,
+                                      VSEN1_HV_LL_REG + index * 4);
+               if (tmp < 0)
+                       return tmp;
+               tmp = (val >> 3) & 0xff;
+               ret = nct7904_write_reg(data, BANK_1,
+                                       VSEN1_HV_LL_REG + index * 4, tmp);
+               return ret;
+       case hwmon_in_max:
+               tmp = nct7904_read_reg(data, BANK_1,
+                                      VSEN1_LV_HL_REG + index * 4);
+               if (tmp < 0)
+                       return tmp;
+               tmp &= ~0x7;
+               tmp |= val & 0x7;
+               ret = nct7904_write_reg(data, BANK_1,
+                                       VSEN1_LV_HL_REG + index * 4, tmp);
+               if (ret < 0)
+                       return ret;
+               tmp = nct7904_read_reg(data, BANK_1,
+                                      VSEN1_HV_HL_REG + index * 4);
+               if (tmp < 0)
+                       return tmp;
+               tmp = (val >> 3) & 0xff;
+               ret = nct7904_write_reg(data, BANK_1,
+                                       VSEN1_HV_HL_REG + index * 4, tmp);
+               return ret;
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
 static int nct7904_write_pwm(struct device *dev, u32 attr, int channel,
                             long val)
 {
@@ -354,8 +691,14 @@ static int nct7904_write(struct device *dev, enum hwmon_sensor_types type,
                         u32 attr, int channel, long val)
 {
        switch (type) {
+       case hwmon_in:
+               return nct7904_write_in(dev, attr, channel, val);
+       case hwmon_fan:
+               return nct7904_write_fan(dev, attr, channel, val);
        case hwmon_pwm:
                return nct7904_write_pwm(dev, attr, channel, val);
+       case hwmon_temp:
+               return nct7904_write_temp(dev, attr, channel, val);
        default:
                return -EOPNOTSUPP;
        }
@@ -404,51 +747,91 @@ static int nct7904_detect(struct i2c_client *client,
 
 static const struct hwmon_channel_info *nct7904_info[] = {
        HWMON_CHANNEL_INFO(in,
-                          HWMON_I_INPUT, /* dummy, skipped in is_visible */
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT,
-                          HWMON_I_INPUT),
+                          /* dummy, skipped in is_visible */
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM,
+                          HWMON_I_INPUT | HWMON_I_MIN | HWMON_I_MAX |
+                          HWMON_I_ALARM),
        HWMON_CHANNEL_INFO(fan,
-                          HWMON_F_INPUT,
-                          HWMON_F_INPUT,
-                          HWMON_F_INPUT,
-                          HWMON_F_INPUT,
-                          HWMON_F_INPUT,
-                          HWMON_F_INPUT,
-                          HWMON_F_INPUT,
-                          HWMON_F_INPUT),
+                          HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
+                          HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
+                          HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
+                          HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
+                          HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
+                          HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
+                          HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM,
+                          HWMON_F_INPUT | HWMON_F_MIN | HWMON_F_ALARM),
        HWMON_CHANNEL_INFO(pwm,
                           HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
                           HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
                           HWMON_PWM_INPUT | HWMON_PWM_ENABLE,
                           HWMON_PWM_INPUT | HWMON_PWM_ENABLE),
        HWMON_CHANNEL_INFO(temp,
-                          HWMON_T_INPUT,
-                          HWMON_T_INPUT,
-                          HWMON_T_INPUT,
-                          HWMON_T_INPUT,
-                          HWMON_T_INPUT,
-                          HWMON_T_INPUT,
-                          HWMON_T_INPUT,
-                          HWMON_T_INPUT,
-                          HWMON_T_INPUT),
+                          HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
+                          HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
+                          HWMON_T_CRIT_HYST,
+                          HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
+                          HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
+                          HWMON_T_CRIT_HYST,
+                          HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
+                          HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
+                          HWMON_T_CRIT_HYST,
+                          HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
+                          HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
+                          HWMON_T_CRIT_HYST,
+                          HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
+                          HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
+                          HWMON_T_CRIT_HYST,
+                          HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
+                          HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
+                          HWMON_T_CRIT_HYST,
+                          HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
+                          HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
+                          HWMON_T_CRIT_HYST,
+                          HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
+                          HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
+                          HWMON_T_CRIT_HYST,
+                          HWMON_T_INPUT | HWMON_T_ALARM | HWMON_T_MAX |
+                          HWMON_T_MAX_HYST | HWMON_T_TYPE | HWMON_T_CRIT |
+                          HWMON_T_CRIT_HYST),
        NULL
 };
 
@@ -530,11 +913,14 @@ static int nct7904_probe(struct i2c_client *client,
        if (ret < 0)
                return ret;
 
+       data->temp_mode = 0;
        for (i = 0; i < 4; i++) {
                val = (ret & (0x03 << i)) >> (i * 2);
                bit = (1 << i);
                if (val == 0)
                        data->tcpu_mask &= ~bit;
+               else if (val == 0x1 || val == 0x2)
+                       data->temp_mode |= bit;
        }
 
        /* PECI */
@@ -557,7 +943,7 @@ static int nct7904_probe(struct i2c_client *client,
                if (ret < 0)
                        return ret;
                data->has_dts = ret & 0xF;
-               if (data->enable_dts & 0x2) {
+               if (data->enable_dts & ENABLE_TSI) {
                        ret = nct7904_read_reg(data, BANK_0, DTS_T_CTRL1_REG);
                        if (ret < 0)
                                return ret;
index 09aaefa..11a2860 100644 (file)
@@ -967,10 +967,8 @@ static int npcm7xx_pwm_fan_probe(struct platform_device *pdev)
                spin_lock_init(&data->fan_lock[i]);
 
                data->fan_irq[i] = platform_get_irq(pdev, i);
-               if (data->fan_irq[i] < 0) {
-                       dev_err(dev, "get IRQ fan%d failed\n", i);
+               if (data->fan_irq[i] < 0)
                        return data->fan_irq[i];
-               }
 
                sprintf(name, "NPCM7XX-FAN-MD%d", i);
                ret = devm_request_irq(dev, data->fan_irq[i], npcm7xx_fan_isr,
index b658848..d62d69b 100644 (file)
@@ -46,6 +46,15 @@ config SENSORS_IBM_CFFPS
          This driver can also be built as a module. If so, the module will
          be called ibm-cffps.
 
+config SENSORS_INSPUR_IPSPS
+       tristate "INSPUR Power System Power Supply"
+       help
+         If you say yes here you get hardware monitoring support for the INSPUR
+         Power System power supply.
+
+         This driver can also be built as a module. If so, the module will
+         be called inspur-ipsps.
+
 config SENSORS_IR35221
        tristate "Infineon IR35221"
        help
index c950ea9..03bacfc 100644 (file)
@@ -7,6 +7,7 @@ obj-$(CONFIG_PMBUS)             += pmbus_core.o
 obj-$(CONFIG_SENSORS_PMBUS)    += pmbus.o
 obj-$(CONFIG_SENSORS_ADM1275)  += adm1275.o
 obj-$(CONFIG_SENSORS_IBM_CFFPS)        += ibm-cffps.o
+obj-$(CONFIG_SENSORS_INSPUR_IPSPS) += inspur-ipsps.o
 obj-$(CONFIG_SENSORS_IR35221)  += ir35221.o
 obj-$(CONFIG_SENSORS_IR38064)  += ir38064.o
 obj-$(CONFIG_SENSORS_IRPS5401) += irps5401.o
index ee2ee9e..d44745e 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/leds.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
+#include <linux/of_device.h>
 #include <linux/pmbus.h>
 
 #include "pmbus.h"
@@ -20,8 +21,9 @@
 #define CFFPS_PN_CMD                           0x9B
 #define CFFPS_SN_CMD                           0x9E
 #define CFFPS_CCIN_CMD                         0xBD
-#define CFFPS_FW_CMD_START                     0xFA
-#define CFFPS_FW_NUM_BYTES                     4
+#define CFFPS_FW_CMD                           0xFA
+#define CFFPS1_FW_NUM_BYTES                    4
+#define CFFPS2_FW_NUM_WORDS                    3
 #define CFFPS_SYS_CONFIG_CMD                   0xDA
 
 #define CFFPS_INPUT_HISTORY_CMD                        0xD6
@@ -52,6 +54,8 @@ enum {
        CFFPS_DEBUGFS_NUM_ENTRIES
 };
 
+enum versions { cffps1, cffps2 };
+
 struct ibm_cffps_input_history {
        struct mutex update_lock;
        unsigned long last_update;
@@ -61,6 +65,7 @@ struct ibm_cffps_input_history {
 };
 
 struct ibm_cffps {
+       enum versions version;
        struct i2c_client *client;
 
        struct ibm_cffps_input_history input_history;
@@ -132,6 +137,8 @@ static ssize_t ibm_cffps_debugfs_op(struct file *file, char __user *buf,
        struct ibm_cffps *psu = to_psu(idxp, idx);
        char data[I2C_SMBUS_BLOCK_MAX] = { 0 };
 
+       pmbus_set_page(psu->client, 0);
+
        switch (idx) {
        case CFFPS_DEBUGFS_INPUT_HISTORY:
                return ibm_cffps_read_input_history(psu, buf, count, ppos);
@@ -152,16 +159,36 @@ static ssize_t ibm_cffps_debugfs_op(struct file *file, char __user *buf,
                rc = snprintf(data, 5, "%04X", rc);
                goto done;
        case CFFPS_DEBUGFS_FW:
-               for (i = 0; i < CFFPS_FW_NUM_BYTES; ++i) {
-                       rc = i2c_smbus_read_byte_data(psu->client,
-                                                     CFFPS_FW_CMD_START + i);
-                       if (rc < 0)
-                               return rc;
+               switch (psu->version) {
+               case cffps1:
+                       for (i = 0; i < CFFPS1_FW_NUM_BYTES; ++i) {
+                               rc = i2c_smbus_read_byte_data(psu->client,
+                                                             CFFPS_FW_CMD +
+                                                               i);
+                               if (rc < 0)
+                                       return rc;
+
+                               snprintf(&data[i * 2], 3, "%02X", rc);
+                       }
 
-                       snprintf(&data[i * 2], 3, "%02X", rc);
-               }
+                       rc = i * 2;
+                       break;
+               case cffps2:
+                       for (i = 0; i < CFFPS2_FW_NUM_WORDS; ++i) {
+                               rc = i2c_smbus_read_word_data(psu->client,
+                                                             CFFPS_FW_CMD +
+                                                               i);
+                               if (rc < 0)
+                                       return rc;
+
+                               snprintf(&data[i * 4], 5, "%04X", rc);
+                       }
 
-               rc = i * 2;
+                       rc = i * 4;
+                       break;
+               default:
+                       return -EOPNOTSUPP;
+               }
                goto done;
        default:
                return -EINVAL;
@@ -279,6 +306,8 @@ static void ibm_cffps_led_brightness_set(struct led_classdev *led_cdev,
                        psu->led_state = CFFPS_LED_ON;
        }
 
+       pmbus_set_page(psu->client, 0);
+
        rc = i2c_smbus_write_byte_data(psu->client, CFFPS_SYS_CONFIG_CMD,
                                       psu->led_state);
        if (rc < 0)
@@ -299,6 +328,8 @@ static int ibm_cffps_led_blink_set(struct led_classdev *led_cdev,
        if (led_cdev->brightness == LED_OFF)
                return 0;
 
+       pmbus_set_page(psu->client, 0);
+
        rc = i2c_smbus_write_byte_data(psu->client, CFFPS_SYS_CONFIG_CMD,
                                       CFFPS_LED_BLINK);
        if (rc < 0)
@@ -328,15 +359,32 @@ static void ibm_cffps_create_led_class(struct ibm_cffps *psu)
                dev_warn(dev, "failed to register led class: %d\n", rc);
 }
 
-static struct pmbus_driver_info ibm_cffps_info = {
-       .pages = 1,
-       .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT |
-               PMBUS_HAVE_PIN | PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP |
-               PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_VOUT |
-               PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT |
-               PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_FAN12,
-       .read_byte_data = ibm_cffps_read_byte_data,
-       .read_word_data = ibm_cffps_read_word_data,
+static struct pmbus_driver_info ibm_cffps_info[] = {
+       [cffps1] = {
+               .pages = 1,
+               .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT |
+                       PMBUS_HAVE_PIN | PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP |
+                       PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 |
+                       PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT |
+                       PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP |
+                       PMBUS_HAVE_STATUS_FAN12,
+               .read_byte_data = ibm_cffps_read_byte_data,
+               .read_word_data = ibm_cffps_read_word_data,
+       },
+       [cffps2] = {
+               .pages = 2,
+               .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT |
+                       PMBUS_HAVE_PIN | PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP |
+                       PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 |
+                       PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT |
+                       PMBUS_HAVE_STATUS_INPUT | PMBUS_HAVE_STATUS_TEMP |
+                       PMBUS_HAVE_STATUS_FAN12,
+               .func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT |
+                       PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | PMBUS_HAVE_TEMP3 |
+                       PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT,
+               .read_byte_data = ibm_cffps_read_byte_data,
+               .read_word_data = ibm_cffps_read_word_data,
+       },
 };
 
 static struct pmbus_platform_data ibm_cffps_pdata = {
@@ -347,12 +395,21 @@ static int ibm_cffps_probe(struct i2c_client *client,
                           const struct i2c_device_id *id)
 {
        int i, rc;
+       enum versions vs;
        struct dentry *debugfs;
        struct dentry *ibm_cffps_dir;
        struct ibm_cffps *psu;
+       const void *md = of_device_get_match_data(&client->dev);
+
+       if (md)
+               vs = (enum versions)md;
+       else if (id)
+               vs = (enum versions)id->driver_data;
+       else
+               vs = cffps1;
 
        client->dev.platform_data = &ibm_cffps_pdata;
-       rc = pmbus_do_probe(client, id, &ibm_cffps_info);
+       rc = pmbus_do_probe(client, id, &ibm_cffps_info[vs]);
        if (rc)
                return rc;
 
@@ -364,6 +421,7 @@ static int ibm_cffps_probe(struct i2c_client *client,
        if (!psu)
                return 0;
 
+       psu->version = vs;
        psu->client = client;
        mutex_init(&psu->input_history.update_lock);
        psu->input_history.last_update = jiffies - HZ;
@@ -405,13 +463,21 @@ static int ibm_cffps_probe(struct i2c_client *client,
 }
 
 static const struct i2c_device_id ibm_cffps_id[] = {
-       { "ibm_cffps1", 1 },
+       { "ibm_cffps1", cffps1 },
+       { "ibm_cffps2", cffps2 },
        {}
 };
 MODULE_DEVICE_TABLE(i2c, ibm_cffps_id);
 
 static const struct of_device_id ibm_cffps_of_match[] = {
-       { .compatible = "ibm,cffps1" },
+       {
+               .compatible = "ibm,cffps1",
+               .data = (void *)cffps1
+       },
+       {
+               .compatible = "ibm,cffps2",
+               .data = (void *)cffps2
+       },
        {}
 };
 MODULE_DEVICE_TABLE(of, ibm_cffps_of_match);
diff --git a/drivers/hwmon/pmbus/inspur-ipsps.c b/drivers/hwmon/pmbus/inspur-ipsps.c
new file mode 100644 (file)
index 0000000..42e0154
--- /dev/null
@@ -0,0 +1,228 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2019 Inspur Corp.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/i2c.h>
+#include <linux/module.h>
+#include <linux/pmbus.h>
+#include <linux/hwmon-sysfs.h>
+
+#include "pmbus.h"
+
+#define IPSPS_REG_VENDOR_ID    0x99
+#define IPSPS_REG_MODEL                0x9A
+#define IPSPS_REG_FW_VERSION   0x9B
+#define IPSPS_REG_PN           0x9C
+#define IPSPS_REG_SN           0x9E
+#define IPSPS_REG_HW_VERSION   0xB0
+#define IPSPS_REG_MODE         0xFC
+
+#define MODE_ACTIVE            0x55
+#define MODE_STANDBY           0x0E
+#define MODE_REDUNDANCY                0x00
+
+#define MODE_ACTIVE_STRING             "active"
+#define MODE_STANDBY_STRING            "standby"
+#define MODE_REDUNDANCY_STRING         "redundancy"
+
+enum ipsps_index {
+       vendor,
+       model,
+       fw_version,
+       part_number,
+       serial_number,
+       hw_version,
+       mode,
+       num_regs,
+};
+
+static const u8 ipsps_regs[num_regs] = {
+       [vendor] = IPSPS_REG_VENDOR_ID,
+       [model] = IPSPS_REG_MODEL,
+       [fw_version] = IPSPS_REG_FW_VERSION,
+       [part_number] = IPSPS_REG_PN,
+       [serial_number] = IPSPS_REG_SN,
+       [hw_version] = IPSPS_REG_HW_VERSION,
+       [mode] = IPSPS_REG_MODE,
+};
+
+static ssize_t ipsps_string_show(struct device *dev,
+                                struct device_attribute *devattr,
+                                char *buf)
+{
+       u8 reg;
+       int rc;
+       char *p;
+       char data[I2C_SMBUS_BLOCK_MAX + 1];
+       struct i2c_client *client = to_i2c_client(dev->parent);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+
+       reg = ipsps_regs[attr->index];
+       rc = i2c_smbus_read_block_data(client, reg, data);
+       if (rc < 0)
+               return rc;
+
+       /* filled with printable characters, ending with # */
+       p = memscan(data, '#', rc);
+       *p = '\0';
+
+       return snprintf(buf, PAGE_SIZE, "%s\n", data);
+}
+
+static ssize_t ipsps_fw_version_show(struct device *dev,
+                                    struct device_attribute *devattr,
+                                    char *buf)
+{
+       u8 reg;
+       int rc;
+       u8 data[I2C_SMBUS_BLOCK_MAX] = { 0 };
+       struct i2c_client *client = to_i2c_client(dev->parent);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+
+       reg = ipsps_regs[attr->index];
+       rc = i2c_smbus_read_block_data(client, reg, data);
+       if (rc < 0)
+               return rc;
+
+       if (rc != 6)
+               return -EPROTO;
+
+       return snprintf(buf, PAGE_SIZE, "%u.%02u%u-%u.%02u\n",
+                       data[1], data[2]/* < 100 */, data[3]/*< 10*/,
+                       data[4], data[5]/* < 100 */);
+}
+
+static ssize_t ipsps_mode_show(struct device *dev,
+                              struct device_attribute *devattr, char *buf)
+{
+       u8 reg;
+       int rc;
+       struct i2c_client *client = to_i2c_client(dev->parent);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+
+       reg = ipsps_regs[attr->index];
+       rc = i2c_smbus_read_byte_data(client, reg);
+       if (rc < 0)
+               return rc;
+
+       switch (rc) {
+       case MODE_ACTIVE:
+               return snprintf(buf, PAGE_SIZE, "[%s] %s %s\n",
+                               MODE_ACTIVE_STRING,
+                               MODE_STANDBY_STRING, MODE_REDUNDANCY_STRING);
+       case MODE_STANDBY:
+               return snprintf(buf, PAGE_SIZE, "%s [%s] %s\n",
+                               MODE_ACTIVE_STRING,
+                               MODE_STANDBY_STRING, MODE_REDUNDANCY_STRING);
+       case MODE_REDUNDANCY:
+               return snprintf(buf, PAGE_SIZE, "%s %s [%s]\n",
+                               MODE_ACTIVE_STRING,
+                               MODE_STANDBY_STRING, MODE_REDUNDANCY_STRING);
+       default:
+               return snprintf(buf, PAGE_SIZE, "unspecified\n");
+       }
+}
+
+static ssize_t ipsps_mode_store(struct device *dev,
+                               struct device_attribute *devattr,
+                               const char *buf, size_t count)
+{
+       u8 reg;
+       int rc;
+       struct i2c_client *client = to_i2c_client(dev->parent);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+
+       reg = ipsps_regs[attr->index];
+       if (sysfs_streq(MODE_STANDBY_STRING, buf)) {
+               rc = i2c_smbus_write_byte_data(client, reg,
+                                              MODE_STANDBY);
+               if (rc < 0)
+                       return rc;
+               return count;
+       } else if (sysfs_streq(MODE_ACTIVE_STRING, buf)) {
+               rc = i2c_smbus_write_byte_data(client, reg,
+                                              MODE_ACTIVE);
+               if (rc < 0)
+                       return rc;
+               return count;
+       }
+
+       return -EINVAL;
+}
+
+static SENSOR_DEVICE_ATTR_RO(vendor, ipsps_string, vendor);
+static SENSOR_DEVICE_ATTR_RO(model, ipsps_string, model);
+static SENSOR_DEVICE_ATTR_RO(part_number, ipsps_string, part_number);
+static SENSOR_DEVICE_ATTR_RO(serial_number, ipsps_string, serial_number);
+static SENSOR_DEVICE_ATTR_RO(hw_version, ipsps_string, hw_version);
+static SENSOR_DEVICE_ATTR_RO(fw_version, ipsps_fw_version, fw_version);
+static SENSOR_DEVICE_ATTR_RW(mode, ipsps_mode, mode);
+
+static struct attribute *ipsps_attrs[] = {
+       &sensor_dev_attr_vendor.dev_attr.attr,
+       &sensor_dev_attr_model.dev_attr.attr,
+       &sensor_dev_attr_part_number.dev_attr.attr,
+       &sensor_dev_attr_serial_number.dev_attr.attr,
+       &sensor_dev_attr_hw_version.dev_attr.attr,
+       &sensor_dev_attr_fw_version.dev_attr.attr,
+       &sensor_dev_attr_mode.dev_attr.attr,
+       NULL,
+};
+
+ATTRIBUTE_GROUPS(ipsps);
+
+static struct pmbus_driver_info ipsps_info = {
+       .pages = 1,
+       .func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT |
+               PMBUS_HAVE_IIN | PMBUS_HAVE_POUT | PMBUS_HAVE_PIN |
+               PMBUS_HAVE_FAN12 | PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 |
+               PMBUS_HAVE_TEMP3 | PMBUS_HAVE_STATUS_VOUT |
+               PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_STATUS_INPUT |
+               PMBUS_HAVE_STATUS_TEMP | PMBUS_HAVE_STATUS_FAN12,
+       .groups = ipsps_groups,
+};
+
+static struct pmbus_platform_data ipsps_pdata = {
+       .flags = PMBUS_SKIP_STATUS_CHECK,
+};
+
+static int ipsps_probe(struct i2c_client *client,
+                      const struct i2c_device_id *id)
+{
+       client->dev.platform_data = &ipsps_pdata;
+       return pmbus_do_probe(client, id, &ipsps_info);
+}
+
+static const struct i2c_device_id ipsps_id[] = {
+       { "ipsps1", 0 },
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, ipsps_id);
+
+#ifdef CONFIG_OF
+static const struct of_device_id ipsps_of_match[] = {
+       { .compatible = "inspur,ipsps1" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, ipsps_of_match);
+#endif
+
+static struct i2c_driver ipsps_driver = {
+       .driver = {
+               .name = "inspur-ipsps",
+               .of_match_table = of_match_ptr(ipsps_of_match),
+       },
+       .probe = ipsps_probe,
+       .remove = pmbus_do_remove,
+       .id_table = ipsps_id,
+};
+
+module_i2c_driver(ipsps_driver);
+
+MODULE_AUTHOR("John Wang");
+MODULE_DESCRIPTION("PMBus driver for Inspur Power System power supplies");
+MODULE_LICENSE("GPL");
index 69d9029..254b0f9 100644 (file)
@@ -244,8 +244,6 @@ static int max31785_write_word_data(struct i2c_client *client, int page,
 #define MAX31785_VOUT_FUNCS \
        (PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT)
 
-#define MAX37185_NUM_FAN_PAGES 6
-
 static const struct pmbus_driver_info max31785_info = {
        .pages = MAX31785_NR_PAGES,
 
index c846759..a9229c6 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/slab.h>
 #include <linux/i2c.h>
 #include <linux/pmbus.h>
-#include <linux/gpio.h>
 #include <linux/gpio/driver.h>
 #include "pmbus.h"
 
index efe4bb1..d3a64a3 100644 (file)
@@ -146,7 +146,7 @@ static struct platform_driver rpi_hwmon_driver = {
 };
 module_platform_driver(rpi_hwmon_driver);
 
-MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>");
+MODULE_AUTHOR("Stefan Wahren <wahrenst@gmx.net>");
 MODULE_DESCRIPTION("Raspberry Pi voltage sensor driver");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("platform:raspberrypi-hwmon");
index 0c93fc5..8a7732c 100644 (file)
@@ -72,7 +72,7 @@ static int scmi_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
        const struct scmi_handle *h = scmi_sensors->handle;
 
        sensor = *(scmi_sensors->info[type] + channel);
-       ret = h->sensor_ops->reading_get(h, sensor->id, false, &value);
+       ret = h->sensor_ops->reading_get(h, sensor->id, &value);
        if (ret)
                return ret;
 
index 83fe081..a0078cc 100644 (file)
@@ -24,19 +24,33 @@ static const unsigned char shtc1_cmd_measure_blocking_lpm[]    = { 0x64, 0x58 };
 static const unsigned char shtc1_cmd_measure_nonblocking_lpm[] = { 0x60, 0x9c };
 
 /* command for reading the ID register */
-static const unsigned char shtc1_cmd_read_id_reg[]            = { 0xef, 0xc8 };
+static const unsigned char shtc1_cmd_read_id_reg[]             = { 0xef, 0xc8 };
 
-/* constants for reading the ID register */
-#define SHTC1_ID         0x07
-#define SHTC1_ID_REG_MASK 0x1f
+/*
+ * constants for reading the ID register
+ * SHTC1: 0x0007 with mask 0x003f
+ * SHTW1: 0x0007 with mask 0x003f
+ * SHTC3: 0x0807 with mask 0x083f
+ */
+#define SHTC3_ID      0x0807
+#define SHTC3_ID_MASK 0x083f
+#define SHTC1_ID      0x0007
+#define SHTC1_ID_MASK 0x003f
 
 /* delays for non-blocking i2c commands, both in us */
 #define SHTC1_NONBLOCKING_WAIT_TIME_HPM  14400
 #define SHTC1_NONBLOCKING_WAIT_TIME_LPM   1000
+#define SHTC3_NONBLOCKING_WAIT_TIME_HPM  12100
+#define SHTC3_NONBLOCKING_WAIT_TIME_LPM    800
 
 #define SHTC1_CMD_LENGTH      2
 #define SHTC1_RESPONSE_LENGTH 6
 
+enum shtcx_chips {
+       shtc1,
+       shtc3,
+};
+
 struct shtc1_data {
        struct i2c_client *client;
        struct mutex update_lock;
@@ -47,6 +61,7 @@ struct shtc1_data {
        unsigned int nonblocking_wait_time; /* in us */
 
        struct shtc1_platform_data setup;
+       enum shtcx_chips chip;
 
        int temperature; /* 1000 * temperature in dgr C */
        int humidity; /* 1000 * relative humidity in %RH */
@@ -157,13 +172,16 @@ static void shtc1_select_command(struct shtc1_data *data)
                data->command = data->setup.blocking_io ?
                                shtc1_cmd_measure_blocking_hpm :
                                shtc1_cmd_measure_nonblocking_hpm;
-               data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_HPM;
-
+               data->nonblocking_wait_time = (data->chip == shtc1) ?
+                               SHTC1_NONBLOCKING_WAIT_TIME_HPM :
+                               SHTC3_NONBLOCKING_WAIT_TIME_HPM;
        } else {
                data->command = data->setup.blocking_io ?
                                shtc1_cmd_measure_blocking_lpm :
                                shtc1_cmd_measure_nonblocking_lpm;
-               data->nonblocking_wait_time = SHTC1_NONBLOCKING_WAIT_TIME_LPM;
+               data->nonblocking_wait_time = (data->chip == shtc1) ?
+                               SHTC1_NONBLOCKING_WAIT_TIME_LPM :
+                               SHTC3_NONBLOCKING_WAIT_TIME_LPM;
        }
 }
 
@@ -171,9 +189,11 @@ static int shtc1_probe(struct i2c_client *client,
                       const struct i2c_device_id *id)
 {
        int ret;
-       char id_reg[2];
+       u16 id_reg;
+       char id_reg_buf[2];
        struct shtc1_data *data;
        struct device *hwmon_dev;
+       enum shtcx_chips chip = id->driver_data;
        struct i2c_adapter *adap = client->adapter;
        struct device *dev = &client->dev;
 
@@ -187,13 +207,20 @@ static int shtc1_probe(struct i2c_client *client,
                dev_err(dev, "could not send read_id_reg command: %d\n", ret);
                return ret < 0 ? ret : -ENODEV;
        }
-       ret = i2c_master_recv(client, id_reg, sizeof(id_reg));
-       if (ret != sizeof(id_reg)) {
+       ret = i2c_master_recv(client, id_reg_buf, sizeof(id_reg_buf));
+       if (ret != sizeof(id_reg_buf)) {
                dev_err(dev, "could not read ID register: %d\n", ret);
                return -ENODEV;
        }
-       if ((id_reg[1] & SHTC1_ID_REG_MASK) != SHTC1_ID) {
-               dev_err(dev, "ID register doesn't match\n");
+
+       id_reg = be16_to_cpup((__be16 *)id_reg_buf);
+       if (chip == shtc3) {
+               if ((id_reg & SHTC3_ID_MASK) != SHTC3_ID) {
+                       dev_err(dev, "SHTC3 ID register does not match\n");
+                       return -ENODEV;
+               }
+       } else if ((id_reg & SHTC1_ID_MASK) != SHTC1_ID) {
+               dev_err(dev, "SHTC1 ID register does not match\n");
                return -ENODEV;
        }
 
@@ -204,6 +231,7 @@ static int shtc1_probe(struct i2c_client *client,
        data->setup.blocking_io = false;
        data->setup.high_precision = true;
        data->client = client;
+       data->chip = chip;
 
        if (client->dev.platform_data)
                data->setup = *(struct shtc1_platform_data *)dev->platform_data;
@@ -222,8 +250,9 @@ static int shtc1_probe(struct i2c_client *client,
 
 /* device ID table */
 static const struct i2c_device_id shtc1_id[] = {
-       { "shtc1", 0 },
-       { "shtw1", 0 },
+       { "shtc1", shtc1 },
+       { "shtw1", shtc1 },
+       { "shtc3", shtc3 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, shtc1_id);
index d8c91c2..6eff14f 100644 (file)
@@ -586,10 +586,10 @@ static int smm665_probe(struct i2c_client *client,
 
        data->client = client;
        data->type = id->driver_data;
-       data->cmdreg = i2c_new_dummy(adapter, (client->addr & ~SMM665_REGMASK)
+       data->cmdreg = i2c_new_dummy_device(adapter, (client->addr & ~SMM665_REGMASK)
                                     | SMM665_CMDREG_BASE);
-       if (!data->cmdreg)
-               return -ENOMEM;
+       if (IS_ERR(data->cmdreg))
+               return PTR_ERR(data->cmdreg);
 
        switch (data->type) {
        case smm465:
index d2c04b6..015f1ea 100644 (file)
@@ -894,12 +894,12 @@ w83781d_detect_subclients(struct i2c_client *new_client)
        }
 
        for (i = 0; i < num_sc; i++) {
-               data->lm75[i] = i2c_new_dummy(adapter, sc_addr[i]);
-               if (!data->lm75[i]) {
+               data->lm75[i] = i2c_new_dummy_device(adapter, sc_addr[i]);
+               if (IS_ERR(data->lm75[i])) {
                        dev_err(&new_client->dev,
                                "Subclient %d registration at address 0x%x failed.\n",
                                i, sc_addr[i]);
-                       err = -ENOMEM;
+                       err = PTR_ERR(data->lm75[i]);
                        if (i == 1)
                                goto ERROR_SC_3;
                        goto ERROR_SC_2;
index 050ad42..aad8d4d 100644 (file)
@@ -1260,7 +1260,7 @@ static int w83791d_detect_subclients(struct i2c_client *client)
        struct i2c_adapter *adapter = client->adapter;
        struct w83791d_data *data = i2c_get_clientdata(client);
        int address = client->addr;
-       int i, id, err;
+       int i, id;
        u8 val;
 
        id = i2c_adapter_id(adapter);
@@ -1272,8 +1272,7 @@ static int w83791d_detect_subclients(struct i2c_client *client)
                                        "invalid subclient "
                                        "address %d; must be 0x48-0x4f\n",
                                        force_subclients[i]);
-                               err = -ENODEV;
-                               goto error_sc_0;
+                               return -ENODEV;
                        }
                }
                w83791d_write(client, W83791D_REG_I2C_SUBADDR,
@@ -1283,29 +1282,22 @@ static int w83791d_detect_subclients(struct i2c_client *client)
 
        val = w83791d_read(client, W83791D_REG_I2C_SUBADDR);
        if (!(val & 0x08))
-               data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (val & 0x7));
+               data->lm75[0] = devm_i2c_new_dummy_device(&client->dev, adapter,
+                                                         0x48 + (val & 0x7));
        if (!(val & 0x80)) {
-               if ((data->lm75[0] != NULL) &&
+               if (!IS_ERR(data->lm75[0]) &&
                                ((val & 0x7) == ((val >> 4) & 0x7))) {
                        dev_err(&client->dev,
                                "duplicate addresses 0x%x, "
                                "use force_subclient\n",
                                data->lm75[0]->addr);
-                       err = -ENODEV;
-                       goto error_sc_1;
+                       return -ENODEV;
                }
-               data->lm75[1] = i2c_new_dummy(adapter,
-                                             0x48 + ((val >> 4) & 0x7));
+               data->lm75[1] = devm_i2c_new_dummy_device(&client->dev, adapter,
+                                                         0x48 + ((val >> 4) & 0x7));
        }
 
        return 0;
-
-/* Undo inits in case of errors */
-
-error_sc_1:
-       i2c_unregister_device(data->lm75[0]);
-error_sc_0:
-       return err;
 }
 
 
@@ -1394,7 +1386,7 @@ static int w83791d_probe(struct i2c_client *client,
        /* Register sysfs hooks */
        err = sysfs_create_group(&client->dev.kobj, &w83791d_group);
        if (err)
-               goto error3;
+               return err;
 
        /* Check if pins of fan/pwm 4-5 are in use as GPIO */
        has_fanpwm45 = w83791d_read(client, W83791D_REG_GPIO) & 0x10;
@@ -1419,9 +1411,6 @@ error5:
                sysfs_remove_group(&client->dev.kobj, &w83791d_group_fanpwm45);
 error4:
        sysfs_remove_group(&client->dev.kobj, &w83791d_group);
-error3:
-       i2c_unregister_device(data->lm75[0]);
-       i2c_unregister_device(data->lm75[1]);
        return err;
 }
 
@@ -1432,9 +1421,6 @@ static int w83791d_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &w83791d_group);
 
-       i2c_unregister_device(data->lm75[0]);
-       i2c_unregister_device(data->lm75[1]);
-
        return 0;
 }
 
index da8a6d6..7fc8a11 100644 (file)
@@ -924,7 +924,7 @@ store_sf2_level(struct device *dev, struct device_attribute *attr,
 static int
 w83792d_detect_subclients(struct i2c_client *new_client)
 {
-       int i, id, err;
+       int i, id;
        int address = new_client->addr;
        u8 val;
        struct i2c_adapter *adapter = new_client->adapter;
@@ -938,8 +938,7 @@ w83792d_detect_subclients(struct i2c_client *new_client)
                                dev_err(&new_client->dev,
                                        "invalid subclient address %d; must be 0x48-0x4f\n",
                                        force_subclients[i]);
-                               err = -ENODEV;
-                               goto ERROR_SC_0;
+                               return -ENODEV;
                        }
                }
                w83792d_write_value(new_client, W83792D_REG_I2C_SUBADDR,
@@ -949,28 +948,21 @@ w83792d_detect_subclients(struct i2c_client *new_client)
 
        val = w83792d_read_value(new_client, W83792D_REG_I2C_SUBADDR);
        if (!(val & 0x08))
-               data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (val & 0x7));
+               data->lm75[0] = devm_i2c_new_dummy_device(&new_client->dev, adapter,
+                                                         0x48 + (val & 0x7));
        if (!(val & 0x80)) {
-               if ((data->lm75[0] != NULL) &&
+               if (!IS_ERR(data->lm75[0]) &&
                        ((val & 0x7) == ((val >> 4) & 0x7))) {
                        dev_err(&new_client->dev,
                                "duplicate addresses 0x%x, use force_subclient\n",
                                data->lm75[0]->addr);
-                       err = -ENODEV;
-                       goto ERROR_SC_1;
+                       return -ENODEV;
                }
-               data->lm75[1] = i2c_new_dummy(adapter,
-                                             0x48 + ((val >> 4) & 0x7));
+               data->lm75[1] = devm_i2c_new_dummy_device(&new_client->dev, adapter,
+                                                         0x48 + ((val >> 4) & 0x7));
        }
 
        return 0;
-
-/* Undo inits in case of errors */
-
-ERROR_SC_1:
-       i2c_unregister_device(data->lm75[0]);
-ERROR_SC_0:
-       return err;
 }
 
 static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, show_in, NULL, 0);
@@ -1396,7 +1388,7 @@ w83792d_probe(struct i2c_client *client, const struct i2c_device_id *id)
        /* Register sysfs hooks */
        err = sysfs_create_group(&dev->kobj, &w83792d_group);
        if (err)
-               goto exit_i2c_unregister;
+               return err;
 
        /*
         * Read GPIO enable register to check if pins for fan 4,5 are used as
@@ -1441,9 +1433,6 @@ exit_remove_files:
        sysfs_remove_group(&dev->kobj, &w83792d_group);
        for (i = 0; i < ARRAY_SIZE(w83792d_group_fan); i++)
                sysfs_remove_group(&dev->kobj, &w83792d_group_fan[i]);
-exit_i2c_unregister:
-       i2c_unregister_device(data->lm75[0]);
-       i2c_unregister_device(data->lm75[1]);
        return err;
 }
 
@@ -1459,9 +1448,6 @@ w83792d_remove(struct i2c_client *client)
                sysfs_remove_group(&client->dev.kobj,
                                   &w83792d_group_fan[i]);
 
-       i2c_unregister_device(data->lm75[0]);
-       i2c_unregister_device(data->lm75[1]);
-
        return 0;
 }
 
index 46f5dfe..9df48b7 100644 (file)
@@ -1551,9 +1551,6 @@ static int w83793_remove(struct i2c_client *client)
        for (i = 0; i < ARRAY_SIZE(w83793_temp); i++)
                device_remove_file(dev, &w83793_temp[i].dev_attr);
 
-       i2c_unregister_device(data->lm75[0]);
-       i2c_unregister_device(data->lm75[1]);
-
        /* Decrease data reference counter */
        mutex_lock(&watchdog_data_mutex);
        kref_put(&data->kref, w83793_release_resources);
@@ -1565,7 +1562,7 @@ static int w83793_remove(struct i2c_client *client)
 static int
 w83793_detect_subclients(struct i2c_client *client)
 {
-       int i, id, err;
+       int i, id;
        int address = client->addr;
        u8 tmp;
        struct i2c_adapter *adapter = client->adapter;
@@ -1580,8 +1577,7 @@ w83793_detect_subclients(struct i2c_client *client)
                                        "invalid subclient "
                                        "address %d; must be 0x48-0x4f\n",
                                        force_subclients[i]);
-                               err = -EINVAL;
-                               goto ERROR_SC_0;
+                               return -EINVAL;
                        }
                }
                w83793_write_value(client, W83793_REG_I2C_SUBADDR,
@@ -1591,28 +1587,21 @@ w83793_detect_subclients(struct i2c_client *client)
 
        tmp = w83793_read_value(client, W83793_REG_I2C_SUBADDR);
        if (!(tmp & 0x08))
-               data->lm75[0] = i2c_new_dummy(adapter, 0x48 + (tmp & 0x7));
+               data->lm75[0] = devm_i2c_new_dummy_device(&client->dev, adapter,
+                                                         0x48 + (tmp & 0x7));
        if (!(tmp & 0x80)) {
-               if ((data->lm75[0] != NULL)
+               if (!IS_ERR(data->lm75[0])
                    && ((tmp & 0x7) == ((tmp >> 4) & 0x7))) {
                        dev_err(&client->dev,
                                "duplicate addresses 0x%x, "
                                "use force_subclients\n", data->lm75[0]->addr);
-                       err = -ENODEV;
-                       goto ERROR_SC_1;
+                       return -ENODEV;
                }
-               data->lm75[1] = i2c_new_dummy(adapter,
-                                             0x48 + ((tmp >> 4) & 0x7));
+               data->lm75[1] = devm_i2c_new_dummy_device(&client->dev, adapter,
+                                                         0x48 + ((tmp >> 4) & 0x7));
        }
 
        return 0;
-
-       /* Undo inits in case of errors */
-
-ERROR_SC_1:
-       i2c_unregister_device(data->lm75[0]);
-ERROR_SC_0:
-       return err;
 }
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
@@ -1945,9 +1934,6 @@ exit_remove:
 
        for (i = 0; i < ARRAY_SIZE(w83793_temp); i++)
                device_remove_file(dev, &w83793_temp[i].dev_attr);
-
-       i2c_unregister_device(data->lm75[0]);
-       i2c_unregister_device(data->lm75[1]);
 free_mem:
        kfree(data);
 exit:
index c0378c3..91dfeba 100644 (file)
@@ -165,6 +165,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
                .driver_data = (kernel_ulong_t)0,
        },
        {
+               /* Lewisburg PCH */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa226),
+               .driver_data = (kernel_ulong_t)0,
+       },
+       {
                /* Gemini Lake */
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x318e),
                .driver_data = (kernel_ulong_t)&intel_th_2x,
@@ -199,6 +204,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x45c5),
                .driver_data = (kernel_ulong_t)&intel_th_2x,
        },
+       {
+               /* Tiger Lake PCH */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa0a6),
+               .driver_data = (kernel_ulong_t)&intel_th_2x,
+       },
        { 0 },
 };
 
index e55b902..181e7ff 100644 (file)
@@ -1276,7 +1276,6 @@ int stm_source_register_device(struct device *parent,
 
 err:
        put_device(&src->dev);
-       kfree(src);
 
        return err;
 }
index 09367fc..f8c77ed 100644 (file)
@@ -684,7 +684,7 @@ config 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
+       depends on ARCH_IOP32X || ARCH_IXP4XX
        help
          Say Y here if you want to use the IIC bus controller on
          the Intel IOPx3xx I/O Processors or IXP4xx Network Processors.
index d7fd76b..19ef2b0 100644 (file)
@@ -790,7 +790,10 @@ static int bcm_iproc_i2c_xfer(struct i2c_adapter *adapter,
 
 static uint32_t bcm_iproc_i2c_functionality(struct i2c_adapter *adap)
 {
-       u32 val = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+       u32 val;
+
+       /* We do not support the SMBUS Quick command */
+       val = I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
 
        if (adap->algo->reg_slave)
                val |= I2C_FUNC_SLAVE;
index e7f9305..f5f0017 100644 (file)
@@ -94,6 +94,7 @@ static int i2c_dw_unreg_slave(struct i2c_client *slave)
 
        dev->disable_int(dev);
        dev->disable(dev);
+       synchronize_irq(dev->irq);
        dev->slave = NULL;
        pm_runtime_put(dev->dev);
 
index f295693..2e08b47 100644 (file)
@@ -1194,19 +1194,28 @@ static acpi_status check_acpi_smo88xx_device(acpi_handle obj_handle,
        int i;
 
        status = acpi_get_object_info(obj_handle, &info);
-       if (!ACPI_SUCCESS(status) || !(info->valid & ACPI_VALID_HID))
+       if (ACPI_FAILURE(status))
                return AE_OK;
 
+       if (!(info->valid & ACPI_VALID_HID))
+               goto smo88xx_not_found;
+
        hid = info->hardware_id.string;
        if (!hid)
-               return AE_OK;
+               goto smo88xx_not_found;
 
        i = match_string(acpi_smo8800_ids, ARRAY_SIZE(acpi_smo8800_ids), hid);
        if (i < 0)
-               return AE_OK;
+               goto smo88xx_not_found;
+
+       kfree(info);
 
        *((bool *)return_value) = true;
        return AE_CTRL_TERMINATE;
+
+smo88xx_not_found:
+       kfree(info);
+       return AE_OK;
 }
 
 static bool is_dell_system_with_lis3lv02d(void)
index 252edb4..29eae1b 100644 (file)
@@ -234,6 +234,10 @@ static const struct i2c_adapter_quirks mt7622_i2c_quirks = {
        .max_num_msgs = 255,
 };
 
+static const struct i2c_adapter_quirks mt8183_i2c_quirks = {
+       .flags = I2C_AQ_NO_ZERO_LEN,
+};
+
 static const struct mtk_i2c_compatible mt2712_compat = {
        .regs = mt_i2c_regs_v1,
        .pmic_i2c = 0,
@@ -298,6 +302,7 @@ static const struct mtk_i2c_compatible mt8173_compat = {
 };
 
 static const struct mtk_i2c_compatible mt8183_compat = {
+       .quirks = &mt8183_i2c_quirks,
        .regs = mt_i2c_regs_v2,
        .pmic_i2c = 0,
        .dcm = 0,
@@ -870,7 +875,11 @@ static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id)
 
 static u32 mtk_i2c_functionality(struct i2c_adapter *adap)
 {
-       return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+       if (adap->quirks->flags & I2C_AQ_NO_ZERO_LEN)
+               return I2C_FUNC_I2C |
+                       (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
+       else
+               return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 }
 
 static const struct i2c_algorithm mtk_i2c_algorithm = {
index c46c4bd..cba325e 100644 (file)
@@ -91,7 +91,7 @@
 #define SB800_PIIX4_PORT_IDX_MASK      0x06
 #define SB800_PIIX4_PORT_IDX_SHIFT     1
 
-/* On kerncz, SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */
+/* On kerncz and Hudson2, SmBus0Sel is at bit 20:19 of PMx00 DecodeEn */
 #define SB800_PIIX4_PORT_IDX_KERNCZ            0x02
 #define SB800_PIIX4_PORT_IDX_MASK_KERNCZ       0x18
 #define SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ      3
@@ -358,18 +358,16 @@ static int piix4_setup_sb800(struct pci_dev *PIIX4_dev,
        /* Find which register is used for port selection */
        if (PIIX4_dev->vendor == PCI_VENDOR_ID_AMD ||
            PIIX4_dev->vendor == PCI_VENDOR_ID_HYGON) {
-               switch (PIIX4_dev->device) {
-               case PCI_DEVICE_ID_AMD_KERNCZ_SMBUS:
+               if (PIIX4_dev->device == PCI_DEVICE_ID_AMD_KERNCZ_SMBUS ||
+                   (PIIX4_dev->device == PCI_DEVICE_ID_AMD_HUDSON2_SMBUS &&
+                    PIIX4_dev->revision >= 0x1F)) {
                        piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_KERNCZ;
                        piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK_KERNCZ;
                        piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT_KERNCZ;
-                       break;
-               case PCI_DEVICE_ID_AMD_HUDSON2_SMBUS:
-               default:
+               } else {
                        piix4_port_sel_sb800 = SB800_PIIX4_PORT_IDX_ALT;
                        piix4_port_mask_sb800 = SB800_PIIX4_PORT_IDX_MASK;
                        piix4_port_shift_sb800 = SB800_PIIX4_PORT_IDX_SHIFT;
-                       break;
                }
        } else {
                if (!request_muxed_region(SB800_PIIX4_SMB_IDX, 2,
index f26ed49..9c440fa 100644 (file)
@@ -832,7 +832,7 @@ EXPORT_SYMBOL_GPL(i2c_new_device);
  */
 void i2c_unregister_device(struct i2c_client *client)
 {
-       if (!client)
+       if (IS_ERR_OR_NULL(client))
                return;
 
        if (client->dev.of_node) {
index 69cc040..9e2e140 100644 (file)
@@ -201,6 +201,59 @@ struct i3c_device *dev_to_i3cdev(struct device *dev)
 EXPORT_SYMBOL_GPL(dev_to_i3cdev);
 
 /**
+ * i3c_device_match_id() - Returns the i3c_device_id entry matching @i3cdev
+ * @i3cdev: I3C device
+ * @id_table: I3C device match table
+ *
+ * Return: a pointer to an i3c_device_id object or NULL if there's no match.
+ */
+const struct i3c_device_id *
+i3c_device_match_id(struct i3c_device *i3cdev,
+                   const struct i3c_device_id *id_table)
+{
+       struct i3c_device_info devinfo;
+       const struct i3c_device_id *id;
+
+       i3c_device_get_info(i3cdev, &devinfo);
+
+       /*
+        * The lower 32bits of the provisional ID is just filled with a random
+        * value, try to match using DCR info.
+        */
+       if (!I3C_PID_RND_LOWER_32BITS(devinfo.pid)) {
+               u16 manuf = I3C_PID_MANUF_ID(devinfo.pid);
+               u16 part = I3C_PID_PART_ID(devinfo.pid);
+               u16 ext_info = I3C_PID_EXTRA_INFO(devinfo.pid);
+
+               /* First try to match by manufacturer/part ID. */
+               for (id = id_table; id->match_flags != 0; id++) {
+                       if ((id->match_flags & I3C_MATCH_MANUF_AND_PART) !=
+                           I3C_MATCH_MANUF_AND_PART)
+                               continue;
+
+                       if (manuf != id->manuf_id || part != id->part_id)
+                               continue;
+
+                       if ((id->match_flags & I3C_MATCH_EXTRA_INFO) &&
+                           ext_info != id->extra_info)
+                               continue;
+
+                       return id;
+               }
+       }
+
+       /* Fallback to DCR match. */
+       for (id = id_table; id->match_flags != 0; id++) {
+               if ((id->match_flags & I3C_MATCH_DCR) &&
+                   id->dcr == devinfo.dcr)
+                       return id;
+       }
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(i3c_device_match_id);
+
+/**
  * i3c_driver_register_with_owner() - register an I3C device driver
  *
  * @drv: driver to register
index d6f8b03..5c051db 100644 (file)
@@ -123,7 +123,7 @@ static struct i3c_dev_desc *dev_to_i3cdesc(struct device *dev)
        if (dev->type == &i3c_device_type)
                return dev_to_i3cdev(dev)->desc;
 
-       master = container_of(dev, struct i3c_master_controller, dev);
+       master = dev_to_i3cmaster(dev);
 
        return master->this;
 }
@@ -276,51 +276,6 @@ static const struct device_type i3c_device_type = {
        .uevent = i3c_device_uevent,
 };
 
-static const struct i3c_device_id *
-i3c_device_match_id(struct i3c_device *i3cdev,
-                   const struct i3c_device_id *id_table)
-{
-       struct i3c_device_info devinfo;
-       const struct i3c_device_id *id;
-
-       i3c_device_get_info(i3cdev, &devinfo);
-
-       /*
-        * The lower 32bits of the provisional ID is just filled with a random
-        * value, try to match using DCR info.
-        */
-       if (!I3C_PID_RND_LOWER_32BITS(devinfo.pid)) {
-               u16 manuf = I3C_PID_MANUF_ID(devinfo.pid);
-               u16 part = I3C_PID_PART_ID(devinfo.pid);
-               u16 ext_info = I3C_PID_EXTRA_INFO(devinfo.pid);
-
-               /* First try to match by manufacturer/part ID. */
-               for (id = id_table; id->match_flags != 0; id++) {
-                       if ((id->match_flags & I3C_MATCH_MANUF_AND_PART) !=
-                           I3C_MATCH_MANUF_AND_PART)
-                               continue;
-
-                       if (manuf != id->manuf_id || part != id->part_id)
-                               continue;
-
-                       if ((id->match_flags & I3C_MATCH_EXTRA_INFO) &&
-                           ext_info != id->extra_info)
-                               continue;
-
-                       return id;
-               }
-       }
-
-       /* Fallback to DCR match. */
-       for (id = id_table; id->match_flags != 0; id++) {
-               if ((id->match_flags & I3C_MATCH_DCR) &&
-                   id->dcr == devinfo.dcr)
-                       return id;
-       }
-
-       return NULL;
-}
-
 static int i3c_device_match(struct device *dev, struct device_driver *drv)
 {
        struct i3c_device *i3cdev;
@@ -645,6 +600,8 @@ i3c_master_alloc_i2c_dev(struct i3c_master_controller *master,
 
        dev->common.master = master;
        dev->boardinfo = boardinfo;
+       dev->addr = boardinfo->base.addr;
+       dev->lvr = boardinfo->lvr;
 
        return dev;
 }
@@ -963,8 +920,8 @@ int i3c_master_defslvs_locked(struct i3c_master_controller *master)
 
        desc = defslvs->slaves;
        i3c_bus_for_each_i2cdev(bus, i2cdev) {
-               desc->lvr = i2cdev->boardinfo->lvr;
-               desc->static_addr = i2cdev->boardinfo->base.addr << 1;
+               desc->lvr = i2cdev->lvr;
+               desc->static_addr = i2cdev->addr << 1;
                desc++;
        }
 
@@ -1084,8 +1041,10 @@ static int i3c_master_getmwl_locked(struct i3c_master_controller *master,
        if (ret)
                goto out;
 
-       if (dest.payload.len != sizeof(*mwl))
-               return -EIO;
+       if (dest.payload.len != sizeof(*mwl)) {
+               ret = -EIO;
+               goto out;
+       }
 
        info->max_write_len = be16_to_cpu(mwl->len);
 
@@ -1631,8 +1590,8 @@ static void i3c_master_detach_free_devs(struct i3c_master_controller *master)
                                 common.node) {
                i3c_master_detach_i2c_dev(i2cdev);
                i3c_bus_set_addr_slot_status(&master->bus,
-                                       i2cdev->boardinfo->base.addr,
-                                       I3C_ADDR_SLOT_FREE);
+                                            i2cdev->addr,
+                                            I3C_ADDR_SLOT_FREE);
                i3c_master_free_i2c_dev(i2cdev);
        }
 }
@@ -2093,8 +2052,10 @@ static int of_populate_i3c_bus(struct i3c_master_controller *master)
 
        for_each_available_child_of_node(i3cbus_np, node) {
                ret = of_i3c_master_add_dev(master, node);
-               if (ret)
+               if (ret) {
+                       of_node_put(node);
                        return ret;
+               }
        }
 
        /*
index 09912d7..b0ff0e1 100644 (file)
@@ -1033,12 +1033,12 @@ static int dw_i3c_master_attach_i2c_dev(struct i2c_dev_desc *dev)
                return -ENOMEM;
 
        data->index = pos;
-       master->addrs[pos] = dev->boardinfo->base.addr;
+       master->addrs[pos] = dev->addr;
        master->free_pos &= ~BIT(pos);
        i2c_dev_set_master_data(dev, data);
 
        writel(DEV_ADDR_TABLE_LEGACY_I2C_DEV |
-              DEV_ADDR_TABLE_STATIC_ADDR(dev->boardinfo->base.addr),
+              DEV_ADDR_TABLE_STATIC_ADDR(dev->addr),
               master->regs +
               DEV_ADDR_TABLE_LOC(master->datstartaddr, data->index));
 
index 237f24a..10db0bf 100644 (file)
@@ -903,7 +903,8 @@ static void cdns_i3c_master_upd_i3c_addr(struct i3c_dev_desc *dev)
 static int cdns_i3c_master_get_rr_slot(struct cdns_i3c_master *master,
                                       u8 dyn_addr)
 {
-       u32 activedevs, rr;
+       unsigned long activedevs;
+       u32 rr;
        int i;
 
        if (!dyn_addr) {
@@ -913,13 +914,10 @@ static int cdns_i3c_master_get_rr_slot(struct cdns_i3c_master *master,
                return ffs(master->free_rr_slots) - 1;
        }
 
-       activedevs = readl(master->regs + DEVS_CTRL) &
-                    DEVS_CTRL_DEVS_ACTIVE_MASK;
-
-       for (i = 1; i <= master->maxdevs; i++) {
-               if (!(BIT(i) & activedevs))
-                       continue;
+       activedevs = readl(master->regs + DEVS_CTRL) & DEVS_CTRL_DEVS_ACTIVE_MASK;
+       activedevs &= ~BIT(0);
 
+       for_each_set_bit(i, &activedevs, master->maxdevs + 1) {
                rr = readl(master->regs + DEV_ID_RR0(i));
                if (!(rr & DEV_ID_RR0_IS_I3C) ||
                    DEV_ID_RR0_GET_DEV_ADDR(rr) != dyn_addr)
@@ -1005,9 +1003,9 @@ static int cdns_i3c_master_attach_i2c_dev(struct i2c_dev_desc *dev)
        master->free_rr_slots &= ~BIT(slot);
        i2c_dev_set_master_data(dev, data);
 
-       writel(prepare_rr0_dev_address(dev->boardinfo->base.addr),
+       writel(prepare_rr0_dev_address(dev->addr),
               master->regs + DEV_ID_RR0(data->id));
-       writel(dev->boardinfo->lvr, master->regs + DEV_ID_RR2(data->id));
+       writel(dev->lvr, master->regs + DEV_ID_RR2(data->id));
        writel(readl(master->regs + DEVS_CTRL) |
               DEVS_CTRL_DEV_ACTIVE(data->id),
               master->regs + DEVS_CTRL);
@@ -1126,18 +1124,16 @@ static void cdns_i3c_master_upd_i3c_scl_lim(struct cdns_i3c_master *master)
 static int cdns_i3c_master_do_daa(struct i3c_master_controller *m)
 {
        struct cdns_i3c_master *master = to_cdns_i3c_master(m);
-       u32 olddevs, newdevs;
+       unsigned long olddevs, newdevs;
        int ret, slot;
        u8 addrs[MAX_DEVS] = { };
        u8 last_addr = 0;
 
        olddevs = readl(master->regs + DEVS_CTRL) & DEVS_CTRL_DEVS_ACTIVE_MASK;
+       olddevs |= BIT(0);
 
        /* Prepare RR slots before launching DAA. */
-       for (slot = 1; slot <= master->maxdevs; slot++) {
-               if (olddevs & BIT(slot))
-                       continue;
-
+       for_each_clear_bit(slot, &olddevs, master->maxdevs + 1) {
                ret = i3c_master_get_free_addr(m, last_addr + 1);
                if (ret < 0)
                        return -ENOSPC;
@@ -1161,10 +1157,8 @@ static int cdns_i3c_master_do_daa(struct i3c_master_controller *m)
         * Clear all retaining registers filled during DAA. We already
         * have the addressed assigned to them in the addrs array.
         */
-       for (slot = 1; slot <= master->maxdevs; slot++) {
-               if (newdevs & BIT(slot))
-                       i3c_master_add_i3c_dev_locked(m, addrs[slot]);
-       }
+       for_each_set_bit(slot, &newdevs, master->maxdevs + 1)
+               i3c_master_add_i3c_dev_locked(m, addrs[slot]);
 
        /*
         * Clear slots that ended up not being used. Can be caused by I3C
index 9eada39..1c227ea 100644 (file)
@@ -567,15 +567,6 @@ config BLK_DEV_SVWKS
          This driver adds PIO/(U)DMA support for the ServerWorks OSB4/CSB5
          chipsets.
 
-config BLK_DEV_SGIIOC4
-       tristate "Silicon Graphics IOC4 chipset ATA/ATAPI support"
-       depends on (IA64_SGI_SN2 || IA64_GENERIC) && SGI_IOC4
-       select BLK_DEV_IDEDMA_PCI
-       help
-         This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4
-         chipset, which has one channel and can support two devices.
-         Please say Y here if you have an Altix System from SGI.
-
 config BLK_DEV_SIIMAGE
        tristate "Silicon Image chipset support"
        select BLK_DEV_IDEDMA_PCI
index 9f617a7..cac02db 100644 (file)
@@ -59,7 +59,6 @@ obj-$(CONFIG_BLK_DEV_PDC202XX_NEW)    += pdc202xx_new.o
 obj-$(CONFIG_BLK_DEV_PIIX)             += piix.o
 obj-$(CONFIG_BLK_DEV_RZ1000)           += rz1000.o
 obj-$(CONFIG_BLK_DEV_SVWKS)            += serverworks.o
-obj-$(CONFIG_BLK_DEV_SGIIOC4)          += sgiioc4.o
 obj-$(CONFIG_BLK_DEV_SIIMAGE)          += siimage.o
 obj-$(CONFIG_BLK_DEV_SIS5513)          += sis5513.o
 obj-$(CONFIG_BLK_DEV_SL82C105)         += sl82c105.o
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c
deleted file mode 100644 (file)
index 2d35e9f..0000000
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * Copyright (c) 2003-2006 Silicon Graphics, Inc.  All Rights Reserved.
- * Copyright (C) 2008-2009 MontaVista Software, Inc.
- *
- * 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 would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/blkdev.h>
-#include <linux/scatterlist.h>
-#include <linux/ioc4.h>
-#include <linux/io.h>
-#include <linux/ide.h>
-
-#define DRV_NAME "SGIIOC4"
-
-/* IOC4 Specific Definitions */
-#define IOC4_CMD_OFFSET                0x100
-#define IOC4_CTRL_OFFSET       0x120
-#define IOC4_DMA_OFFSET                0x140
-#define IOC4_INTR_OFFSET       0x0
-
-#define IOC4_TIMING            0x00
-#define IOC4_DMA_PTR_L         0x01
-#define IOC4_DMA_PTR_H         0x02
-#define IOC4_DMA_ADDR_L                0x03
-#define IOC4_DMA_ADDR_H                0x04
-#define IOC4_BC_DEV            0x05
-#define IOC4_BC_MEM            0x06
-#define        IOC4_DMA_CTRL           0x07
-#define        IOC4_DMA_END_ADDR       0x08
-
-/* Bits in the IOC4 Control/Status Register */
-#define        IOC4_S_DMA_START        0x01
-#define        IOC4_S_DMA_STOP         0x02
-#define        IOC4_S_DMA_DIR          0x04
-#define        IOC4_S_DMA_ACTIVE       0x08
-#define        IOC4_S_DMA_ERROR        0x10
-#define        IOC4_ATA_MEMERR         0x02
-
-/* Read/Write Directions */
-#define        IOC4_DMA_WRITE          0x04
-#define        IOC4_DMA_READ           0x00
-
-/* Interrupt Register Offsets */
-#define IOC4_INTR_REG          0x03
-#define        IOC4_INTR_SET           0x05
-#define        IOC4_INTR_CLEAR         0x07
-
-#define IOC4_IDE_CACHELINE_SIZE        128
-#define IOC4_CMD_CTL_BLK_SIZE  0x20
-#define IOC4_SUPPORTED_FIRMWARE_REV 46
-
-struct ioc4_dma_regs {
-       u32 timing_reg0;
-       u32 timing_reg1;
-       u32 low_mem_ptr;
-       u32 high_mem_ptr;
-       u32 low_mem_addr;
-       u32 high_mem_addr;
-       u32 dev_byte_count;
-       u32 mem_byte_count;
-       u32 status;
-};
-
-/* Each Physical Region Descriptor Entry size is 16 bytes (2 * 64 bits) */
-/* IOC4 has only 1 IDE channel */
-#define IOC4_PRD_BYTES         16
-#define IOC4_PRD_ENTRIES       (PAGE_SIZE / (4 * IOC4_PRD_BYTES))
-
-
-static void sgiioc4_init_hwif_ports(struct ide_hw *hw,
-                                   unsigned long data_port,
-                                   unsigned long ctrl_port,
-                                   unsigned long irq_port)
-{
-       unsigned long reg = data_port;
-       int i;
-
-       /* Registers are word (32 bit) aligned */
-       for (i = 0; i <= 7; i++)
-               hw->io_ports_array[i] = reg + i * 4;
-
-       hw->io_ports.ctl_addr = ctrl_port;
-       hw->io_ports.irq_addr = irq_port;
-}
-
-static int sgiioc4_checkirq(ide_hwif_t *hwif)
-{
-       unsigned long intr_addr = hwif->io_ports.irq_addr + IOC4_INTR_REG * 4;
-
-       if (readl((void __iomem *)intr_addr) & 0x03)
-               return 1;
-
-       return 0;
-}
-
-static u8 sgiioc4_read_status(ide_hwif_t *);
-
-static int sgiioc4_clearirq(ide_drive_t *drive)
-{
-       u32 intr_reg;
-       ide_hwif_t *hwif = drive->hwif;
-       struct ide_io_ports *io_ports = &hwif->io_ports;
-       unsigned long other_ir = io_ports->irq_addr + (IOC4_INTR_REG << 2);
-
-       /* Code to check for PCI error conditions */
-       intr_reg = readl((void __iomem *)other_ir);
-       if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */
-               /*
-                * Using sgiioc4_read_status to read the Status register has a
-                * side effect of clearing the interrupt.  The first read should
-                * clear it if it is set.  The second read should return
-                * a "clear" status if it got cleared.  If not, then spin
-                * for a bit trying to clear it.
-                */
-               u8 stat = sgiioc4_read_status(hwif);
-               int count = 0;
-
-               stat = sgiioc4_read_status(hwif);
-               while ((stat & ATA_BUSY) && (count++ < 100)) {
-                       udelay(1);
-                       stat = sgiioc4_read_status(hwif);
-               }
-
-               if (intr_reg & 0x02) {
-                       struct pci_dev *dev = to_pci_dev(hwif->dev);
-                       /* Error when transferring DMA data on PCI bus */
-                       u32 pci_err_addr_low, pci_err_addr_high,
-                           pci_stat_cmd_reg;
-
-                       pci_err_addr_low =
-                               readl((void __iomem *)io_ports->irq_addr);
-                       pci_err_addr_high =
-                               readl((void __iomem *)(io_ports->irq_addr + 4));
-                       pci_read_config_dword(dev, PCI_COMMAND,
-                                             &pci_stat_cmd_reg);
-                       printk(KERN_ERR "%s(%s): PCI Bus Error when doing DMA: "
-                              "status-cmd reg is 0x%x\n",
-                              __func__, drive->name, pci_stat_cmd_reg);
-                       printk(KERN_ERR "%s(%s): PCI Error Address is 0x%x%x\n",
-                              __func__, drive->name,
-                              pci_err_addr_high, pci_err_addr_low);
-                       /* Clear the PCI Error indicator */
-                       pci_write_config_dword(dev, PCI_COMMAND, 0x00000146);
-               }
-
-               /* Clear the Interrupt, Error bits on the IOC4 */
-               writel(0x03, (void __iomem *)other_ir);
-
-               intr_reg = readl((void __iomem *)other_ir);
-       }
-
-       return intr_reg & 3;
-}
-
-static void sgiioc4_dma_start(ide_drive_t *drive)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       unsigned long ioc4_dma_addr = hwif->dma_base + IOC4_DMA_CTRL * 4;
-       unsigned int reg = readl((void __iomem *)ioc4_dma_addr);
-       unsigned int temp_reg = reg | IOC4_S_DMA_START;
-
-       writel(temp_reg, (void __iomem *)ioc4_dma_addr);
-}
-
-static u32 sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
-{
-       unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
-       u32     ioc4_dma;
-       int     count;
-
-       count = 0;
-       ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
-       while ((ioc4_dma & IOC4_S_DMA_STOP) && (count++ < 200)) {
-               udelay(1);
-               ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
-       }
-       return ioc4_dma;
-}
-
-/* Stops the IOC4 DMA Engine */
-static int sgiioc4_dma_end(ide_drive_t *drive)
-{
-       u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0;
-       ide_hwif_t *hwif = drive->hwif;
-       unsigned long dma_base = hwif->dma_base;
-       int dma_stat = 0;
-       unsigned long *ending_dma = ide_get_hwifdata(hwif);
-
-       writel(IOC4_S_DMA_STOP, (void __iomem *)(dma_base + IOC4_DMA_CTRL * 4));
-
-       ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
-
-       if (ioc4_dma & IOC4_S_DMA_STOP) {
-               printk(KERN_ERR
-                      "%s(%s): IOC4 DMA STOP bit is still 1 :"
-                      "ioc4_dma_reg 0x%x\n",
-                      __func__, drive->name, ioc4_dma);
-               dma_stat = 1;
-       }
-
-       /*
-        * The IOC4 will DMA 1's to the ending DMA area to indicate that
-        * previous data DMA is complete.  This is necessary because of relaxed
-        * ordering between register reads and DMA writes on the Altix.
-        */
-       while ((cnt++ < 200) && (!valid)) {
-               for (num = 0; num < 16; num++) {
-                       if (ending_dma[num]) {
-                               valid = 1;
-                               break;
-                       }
-               }
-               udelay(1);
-       }
-       if (!valid) {
-               printk(KERN_ERR "%s(%s) : DMA incomplete\n", __func__,
-                      drive->name);
-               dma_stat = 1;
-       }
-
-       bc_dev = readl((void __iomem *)(dma_base + IOC4_BC_DEV * 4));
-       bc_mem = readl((void __iomem *)(dma_base + IOC4_BC_MEM * 4));
-
-       if ((bc_dev & 0x01FF) || (bc_mem & 0x1FF)) {
-               if (bc_dev > bc_mem + 8) {
-                       printk(KERN_ERR
-                              "%s(%s): WARNING!! byte_count_dev %d "
-                              "!= byte_count_mem %d\n",
-                              __func__, drive->name, bc_dev, bc_mem);
-               }
-       }
-
-       return dma_stat;
-}
-
-static void sgiioc4_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
-{
-}
-
-/* Returns 1 if DMA IRQ issued, 0 otherwise */
-static int sgiioc4_dma_test_irq(ide_drive_t *drive)
-{
-       return sgiioc4_checkirq(drive->hwif);
-}
-
-static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
-{
-       if (!on)
-               sgiioc4_clearirq(drive);
-}
-
-static void sgiioc4_resetproc(ide_drive_t *drive)
-{
-       struct ide_cmd *cmd = &drive->hwif->cmd;
-
-       sgiioc4_dma_end(drive);
-       ide_dma_unmap_sg(drive, cmd);
-       sgiioc4_clearirq(drive);
-}
-
-static void sgiioc4_dma_lost_irq(ide_drive_t *drive)
-{
-       sgiioc4_resetproc(drive);
-
-       ide_dma_lost_irq(drive);
-}
-
-static u8 sgiioc4_read_status(ide_hwif_t *hwif)
-{
-       unsigned long port = hwif->io_ports.status_addr;
-       u8 reg = (u8) readb((void __iomem *) port);
-
-       if (!(reg & ATA_BUSY)) {        /* Not busy... check for interrupt */
-               unsigned long other_ir = port - 0x110;
-               unsigned int intr_reg = (u32) readl((void __iomem *) other_ir);
-
-               /* Clear the Interrupt, Error bits on the IOC4 */
-               if (intr_reg & 0x03) {
-                       writel(0x03, (void __iomem *) other_ir);
-                       intr_reg = (u32) readl((void __iomem *) other_ir);
-               }
-       }
-
-       return reg;
-}
-
-/* Creates a DMA map for the scatter-gather list entries */
-static int ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d)
-{
-       struct pci_dev *dev = to_pci_dev(hwif->dev);
-       unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET;
-       int num_ports = sizeof(struct ioc4_dma_regs);
-       void *pad;
-
-       printk(KERN_INFO "    %s: MMIO-DMA\n", hwif->name);
-
-       if (request_mem_region(dma_base, num_ports, hwif->name) == NULL) {
-               printk(KERN_ERR "%s(%s) -- ERROR: addresses 0x%08lx to 0x%08lx "
-                      "already in use\n", __func__, hwif->name,
-                      dma_base, dma_base + num_ports - 1);
-               return -1;
-       }
-
-       hwif->dma_base = (unsigned long)hwif->io_ports.irq_addr +
-                        IOC4_DMA_OFFSET;
-
-       hwif->sg_max_nents = IOC4_PRD_ENTRIES;
-
-       hwif->prd_max_nents = IOC4_PRD_ENTRIES;
-       hwif->prd_ent_size = IOC4_PRD_BYTES;
-
-       if (ide_allocate_dma_engine(hwif))
-               goto dma_pci_alloc_failure;
-
-       pad = dma_alloc_coherent(&dev->dev, IOC4_IDE_CACHELINE_SIZE,
-                                  (dma_addr_t *)&hwif->extra_base, GFP_KERNEL);
-       if (pad) {
-               ide_set_hwifdata(hwif, pad);
-               return 0;
-       }
-
-       ide_release_dma_engine(hwif);
-
-       printk(KERN_ERR "%s(%s) -- ERROR: Unable to allocate DMA maps\n",
-              __func__, hwif->name);
-       printk(KERN_INFO "%s: changing from DMA to PIO mode", hwif->name);
-
-dma_pci_alloc_failure:
-       release_mem_region(dma_base, num_ports);
-
-       return -1;
-}
-
-/* Initializes the IOC4 DMA Engine */
-static void sgiioc4_configure_for_dma(int dma_direction, ide_drive_t *drive)
-{
-       u32 ioc4_dma;
-       ide_hwif_t *hwif = drive->hwif;
-       unsigned long dma_base = hwif->dma_base;
-       unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
-       u32 dma_addr, ending_dma_addr;
-
-       ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
-
-       if (ioc4_dma & IOC4_S_DMA_ACTIVE) {
-               printk(KERN_WARNING "%s(%s): Warning!! DMA from previous "
-                      "transfer was still active\n", __func__, drive->name);
-               writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
-               ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
-
-               if (ioc4_dma & IOC4_S_DMA_STOP)
-                       printk(KERN_ERR "%s(%s): IOC4 DMA STOP bit is "
-                              "still 1\n", __func__, drive->name);
-       }
-
-       ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
-       if (ioc4_dma & IOC4_S_DMA_ERROR) {
-               printk(KERN_WARNING "%s(%s): Warning!! DMA Error during "
-                      "previous transfer, status 0x%x\n",
-                      __func__, drive->name, ioc4_dma);
-               writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
-               ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
-
-               if (ioc4_dma & IOC4_S_DMA_STOP)
-                       printk(KERN_ERR "%s(%s): IOC4 DMA STOP bit is "
-                              "still 1\n", __func__, drive->name);
-       }
-
-       /* Address of the Scatter Gather List */
-       dma_addr = cpu_to_le32(hwif->dmatable_dma);
-       writel(dma_addr, (void __iomem *)(dma_base + IOC4_DMA_PTR_L * 4));
-
-       /* Address of the Ending DMA */
-       memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
-       ending_dma_addr = cpu_to_le32(hwif->extra_base);
-       writel(ending_dma_addr, (void __iomem *)(dma_base +
-                                                IOC4_DMA_END_ADDR * 4));
-
-       writel(dma_direction, (void __iomem *)ioc4_dma_addr);
-}
-
-/* IOC4 Scatter Gather list Format                                      */
-/* 128 Bit entries to support 64 bit addresses in the future            */
-/* The Scatter Gather list Entry should be in the BIG-ENDIAN Format     */
-/* --------------------------------------------------------------------- */
-/* | Upper 32 bits - Zero          |           Lower 32 bits- address | */
-/* --------------------------------------------------------------------- */
-/* | Upper 32 bits - Zero          |EOL| 15 unused     | 16 Bit Length| */
-/* --------------------------------------------------------------------- */
-/* Creates the scatter gather list, DMA Table                           */
-
-static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-       ide_hwif_t *hwif = drive->hwif;
-       unsigned int *table = hwif->dmatable_cpu;
-       unsigned int count = 0, i = cmd->sg_nents;
-       struct scatterlist *sg = hwif->sg_table;
-
-       while (i && sg_dma_len(sg)) {
-               dma_addr_t cur_addr;
-               int cur_len;
-               cur_addr = sg_dma_address(sg);
-               cur_len = sg_dma_len(sg);
-
-               while (cur_len) {
-                       if (count++ >= IOC4_PRD_ENTRIES) {
-                               printk(KERN_WARNING
-                                      "%s: DMA table too small\n",
-                                      drive->name);
-                               return 0;
-                       } else {
-                               u32 bcount =
-                                   0x10000 - (cur_addr & 0xffff);
-
-                               if (bcount > cur_len)
-                                       bcount = cur_len;
-
-                               /*
-                                * Put the address, length in
-                                * the IOC4 dma-table format
-                                */
-                               *table = 0x0;
-                               table++;
-                               *table = cpu_to_be32(cur_addr);
-                               table++;
-                               *table = 0x0;
-                               table++;
-
-                               *table = cpu_to_be32(bcount);
-                               table++;
-
-                               cur_addr += bcount;
-                               cur_len -= bcount;
-                       }
-               }
-
-               sg = sg_next(sg);
-               i--;
-       }
-
-       if (count) {
-               table--;
-               *table |= cpu_to_be32(0x80000000);
-               return count;
-       }
-
-       return 0;               /* revert to PIO for this request */
-}
-
-static int sgiioc4_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
-{
-       int ddir;
-       u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
-
-       if (sgiioc4_build_dmatable(drive, cmd) == 0)
-               /* try PIO instead of DMA */
-               return 1;
-
-       if (write)
-               /* Writes TO the IOC4 FROM Main Memory */
-               ddir = IOC4_DMA_READ;
-       else
-               /* Writes FROM the IOC4 TO Main Memory */
-               ddir = IOC4_DMA_WRITE;
-
-       sgiioc4_configure_for_dma(ddir, drive);
-
-       return 0;
-}
-
-static const struct ide_tp_ops sgiioc4_tp_ops = {
-       .exec_command           = ide_exec_command,
-       .read_status            = sgiioc4_read_status,
-       .read_altstatus         = ide_read_altstatus,
-       .write_devctl           = ide_write_devctl,
-
-       .dev_select             = ide_dev_select,
-       .tf_load                = ide_tf_load,
-       .tf_read                = ide_tf_read,
-
-       .input_data             = ide_input_data,
-       .output_data            = ide_output_data,
-};
-
-static const struct ide_port_ops sgiioc4_port_ops = {
-       .set_dma_mode           = sgiioc4_set_dma_mode,
-       /* reset DMA engine, clear IRQs */
-       .resetproc              = sgiioc4_resetproc,
-};
-
-static const struct ide_dma_ops sgiioc4_dma_ops = {
-       .dma_host_set           = sgiioc4_dma_host_set,
-       .dma_setup              = sgiioc4_dma_setup,
-       .dma_start              = sgiioc4_dma_start,
-       .dma_end                = sgiioc4_dma_end,
-       .dma_test_irq           = sgiioc4_dma_test_irq,
-       .dma_lost_irq           = sgiioc4_dma_lost_irq,
-};
-
-static const struct ide_port_info sgiioc4_port_info = {
-       .name                   = DRV_NAME,
-       .chipset                = ide_pci,
-       .init_dma               = ide_dma_sgiioc4,
-       .tp_ops                 = &sgiioc4_tp_ops,
-       .port_ops               = &sgiioc4_port_ops,
-       .dma_ops                = &sgiioc4_dma_ops,
-       .host_flags             = IDE_HFLAG_MMIO,
-       .irq_flags              = IRQF_SHARED,
-       .mwdma_mask             = ATA_MWDMA2_ONLY,
-};
-
-static int sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
-{
-       unsigned long cmd_base, irqport;
-       unsigned long bar0, cmd_phys_base, ctl;
-       void __iomem *virt_base;
-       struct ide_hw hw, *hws[] = { &hw };
-       int rc;
-
-       /* Get the CmdBlk and CtrlBlk base registers */
-       bar0 = pci_resource_start(dev, 0);
-       virt_base = pci_ioremap_bar(dev, 0);
-       if (virt_base == NULL) {
-               printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n",
-                               DRV_NAME, bar0);
-               return -ENOMEM;
-       }
-       cmd_base = (unsigned long)virt_base + IOC4_CMD_OFFSET;
-       ctl = (unsigned long)virt_base + IOC4_CTRL_OFFSET;
-       irqport = (unsigned long)virt_base + IOC4_INTR_OFFSET;
-
-       cmd_phys_base = bar0 + IOC4_CMD_OFFSET;
-       if (request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
-                              DRV_NAME) == NULL) {
-               printk(KERN_ERR "%s %s -- ERROR: addresses 0x%08lx to 0x%08lx "
-                      "already in use\n", DRV_NAME, pci_name(dev),
-                      cmd_phys_base, cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE);
-               rc = -EBUSY;
-               goto req_mem_rgn_err;
-       }
-
-       /* Initialize the IO registers */
-       memset(&hw, 0, sizeof(hw));
-       sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
-       hw.irq = dev->irq;
-       hw.dev = &dev->dev;
-
-       /* Initialize chipset IRQ registers */
-       writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
-
-       rc = ide_host_add(&sgiioc4_port_info, hws, 1, NULL);
-       if (!rc)
-               return 0;
-
-       release_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE);
-req_mem_rgn_err:
-       iounmap(virt_base);
-       return rc;
-}
-
-static unsigned int pci_init_sgiioc4(struct pci_dev *dev)
-{
-       int ret;
-
-       printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d\n",
-                        DRV_NAME, pci_name(dev), dev->revision);
-
-       if (dev->revision < IOC4_SUPPORTED_FIRMWARE_REV) {
-               printk(KERN_ERR "Skipping %s IDE controller in slot %s: "
-                               "firmware is obsolete - please upgrade to "
-                               "revision46 or higher\n",
-                               DRV_NAME, pci_name(dev));
-               ret = -EAGAIN;
-               goto out;
-       }
-       ret = sgiioc4_ide_setup_pci_device(dev);
-out:
-       return ret;
-}
-
-static int ioc4_ide_attach_one(struct ioc4_driver_data *idd)
-{
-       /*
-        * PCI-RT does not bring out IDE connection.
-        * Do not attach to this particular IOC4.
-        */
-       if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
-               return 0;
-
-       return pci_init_sgiioc4(idd->idd_pdev);
-}
-
-static struct ioc4_submodule ioc4_ide_submodule = {
-       .is_name = "IOC4_ide",
-       .is_owner = THIS_MODULE,
-       .is_probe = ioc4_ide_attach_one,
-};
-
-static int __init ioc4_ide_init(void)
-{
-       return ioc4_register_submodule(&ioc4_ide_submodule);
-}
-
-late_initcall(ioc4_ide_init); /* Call only after IDE init is done */
-
-MODULE_AUTHOR("Aniket Malatpure/Jeremy Higdon");
-MODULE_DESCRIPTION("IDE PCI driver module for SGI IOC4 Base-IO Card");
-MODULE_LICENSE("GPL");
index 7e32862..f0af3a4 100644 (file)
@@ -958,7 +958,7 @@ config TI_ADC161S626
 
 config TI_ADS1015
        tristate "Texas Instruments ADS1015 ADC"
-       depends on I2C && !SENSORS_ADS1015
+       depends on I2C
        select REGMAP_I2C
        select IIO_BUFFER
        select IIO_TRIGGERED_BUFFER
index 1db5ad3..8c1931a 100644 (file)
@@ -1962,6 +1962,10 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
                struct sockaddr_in s_laddr, *s_raddr;
                const struct in_ifaddr *ifa;
 
+               if (!in_dev) {
+                       rv = -ENODEV;
+                       goto out;
+               }
                memcpy(&s_laddr, &id->local_addr, sizeof(s_laddr));
                s_raddr = (struct sockaddr_in *)&id->remote_addr;
 
@@ -1991,22 +1995,27 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
                struct sockaddr_in6 *s_laddr = &to_sockaddr_in6(id->local_addr),
                        *s_raddr = &to_sockaddr_in6(id->remote_addr);
 
+               if (!in6_dev) {
+                       rv = -ENODEV;
+                       goto out;
+               }
                siw_dbg(id->device,
                        "laddr %pI6:%d, raddr %pI6:%d\n",
                        &s_laddr->sin6_addr, ntohs(s_laddr->sin6_port),
                        &s_raddr->sin6_addr, ntohs(s_raddr->sin6_port));
 
-               read_lock_bh(&in6_dev->lock);
+               rtnl_lock();
                list_for_each_entry(ifp, &in6_dev->addr_list, if_list) {
-                       struct sockaddr_in6 bind_addr;
-
+                       if (ifp->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
+                               continue;
                        if (ipv6_addr_any(&s_laddr->sin6_addr) ||
                            ipv6_addr_equal(&s_laddr->sin6_addr, &ifp->addr)) {
-                               bind_addr.sin6_family = AF_INET6;
-                               bind_addr.sin6_port = s_laddr->sin6_port;
-                               bind_addr.sin6_flowinfo = 0;
-                               bind_addr.sin6_addr = ifp->addr;
-                               bind_addr.sin6_scope_id = dev->ifindex;
+                               struct sockaddr_in6 bind_addr  = {
+                                       .sin6_family = AF_INET6,
+                                       .sin6_port = s_laddr->sin6_port,
+                                       .sin6_flowinfo = 0,
+                                       .sin6_addr = ifp->addr,
+                                       .sin6_scope_id = dev->ifindex };
 
                                rv = siw_listen_address(id, backlog,
                                                (struct sockaddr *)&bind_addr,
@@ -2015,12 +2024,12 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
                                        listeners++;
                        }
                }
-               read_unlock_bh(&in6_dev->lock);
-
+               rtnl_unlock();
                in6_dev_put(in6_dev);
        } else {
-               return -EAFNOSUPPORT;
+               rv = -EAFNOSUPPORT;
        }
+out:
        if (listeners)
                rv = 0;
        else if (!rv)
index e15cdcd..e3842ea 100644 (file)
@@ -177,11 +177,12 @@ config DMAR_TABLE
 
 config INTEL_IOMMU
        bool "Support for Intel IOMMU using DMA Remapping Devices"
-       depends on PCI_MSI && ACPI && (X86 || IA64_GENERIC)
+       depends on PCI_MSI && ACPI && (X86 || IA64)
        select IOMMU_API
        select IOMMU_IOVA
        select NEED_DMA_MAP_STATE
        select DMAR_TABLE
+       select SWIOTLB
        help
          DMA remapping (DMAR) devices support enables independent address
          translations for Direct Memory Access (DMA) from devices.
index f13f36a..4f405f9 100644 (file)
@@ -10,13 +10,14 @@ obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o
 obj-$(CONFIG_IOMMU_IOVA) += iova.o
 obj-$(CONFIG_OF_IOMMU) += of_iommu.o
 obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
-obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
+obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o amd_iommu_quirks.o
 obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
-obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
+obj-$(CONFIG_ARM_SMMU) += arm-smmu.o arm-smmu-impl.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
 obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o intel-pasid.o
+obj-$(CONFIG_INTEL_IOMMU) += intel-trace.o
 obj-$(CONFIG_INTEL_IOMMU_DEBUGFS) += intel-iommu-debugfs.o
 obj-$(CONFIG_INTEL_IOMMU_SVM) += intel-svm.o
 obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
index b607a92..1ed3b98 100644 (file)
@@ -436,7 +436,7 @@ static int iommu_init_device(struct device *dev)
         * invalid address), we ignore the capability for the device so
         * it'll be forced to go into translation mode.
         */
-       if ((iommu_pass_through || !amd_iommu_force_isolation) &&
+       if ((iommu_default_passthrough() || !amd_iommu_force_isolation) &&
            dev_is_pci(dev) && pci_iommuv2_capable(to_pci_dev(dev))) {
                struct amd_iommu *iommu;
 
@@ -1143,6 +1143,17 @@ static void amd_iommu_flush_tlb_all(struct amd_iommu *iommu)
        iommu_completion_wait(iommu);
 }
 
+static void amd_iommu_flush_tlb_domid(struct amd_iommu *iommu, u32 dom_id)
+{
+       struct iommu_cmd cmd;
+
+       build_inv_iommu_pages(&cmd, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
+                             dom_id, 1);
+       iommu_queue_command(iommu, &cmd);
+
+       iommu_completion_wait(iommu);
+}
+
 static void amd_iommu_flush_all(struct amd_iommu *iommu)
 {
        struct iommu_cmd cmd;
@@ -1424,18 +1435,21 @@ static void free_pagetable(struct protection_domain *domain)
  * another level increases the size of the address space by 9 bits to a size up
  * to 64 bits.
  */
-static bool increase_address_space(struct protection_domain *domain,
+static void increase_address_space(struct protection_domain *domain,
                                   gfp_t gfp)
 {
+       unsigned long flags;
        u64 *pte;
 
-       if (domain->mode == PAGE_MODE_6_LEVEL)
+       spin_lock_irqsave(&domain->lock, flags);
+
+       if (WARN_ON_ONCE(domain->mode == PAGE_MODE_6_LEVEL))
                /* address space already 64 bit large */
-               return false;
+               goto out;
 
        pte = (void *)get_zeroed_page(gfp);
        if (!pte)
-               return false;
+               goto out;
 
        *pte             = PM_LEVEL_PDE(domain->mode,
                                        iommu_virt_to_phys(domain->pt_root));
@@ -1443,7 +1457,10 @@ static bool increase_address_space(struct protection_domain *domain,
        domain->mode    += 1;
        domain->updated  = true;
 
-       return true;
+out:
+       spin_unlock_irqrestore(&domain->lock, flags);
+
+       return;
 }
 
 static u64 *alloc_pte(struct protection_domain *domain,
@@ -1873,6 +1890,7 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain,
 {
        u64 pte_root = 0;
        u64 flags = 0;
+       u32 old_domid;
 
        if (domain->mode != PAGE_MODE_NONE)
                pte_root = iommu_virt_to_phys(domain->pt_root);
@@ -1922,8 +1940,20 @@ static void set_dte_entry(u16 devid, struct protection_domain *domain,
        flags &= ~DEV_DOMID_MASK;
        flags |= domain->id;
 
+       old_domid = amd_iommu_dev_table[devid].data[1] & DEV_DOMID_MASK;
        amd_iommu_dev_table[devid].data[1]  = flags;
        amd_iommu_dev_table[devid].data[0]  = pte_root;
+
+       /*
+        * A kdump kernel might be replacing a domain ID that was copied from
+        * the previous kernel--if so, it needs to flush the translation cache
+        * entries for the old domain ID that is being overwritten
+        */
+       if (old_domid) {
+               struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
+
+               amd_iommu_flush_tlb_domid(iommu, old_domid);
+       }
 }
 
 static void clear_dte_entry(u16 devid)
@@ -2226,7 +2256,7 @@ static int amd_iommu_add_device(struct device *dev)
 
        BUG_ON(!dev_data);
 
-       if (iommu_pass_through || dev_data->iommu_v2)
+       if (dev_data->iommu_v2)
                iommu_request_dm_for_dev(dev);
 
        /* Domains are initialized for this device - have a look what we ended up with */
@@ -2547,7 +2577,9 @@ static int map_sg(struct device *dev, struct scatterlist *sglist,
 
                        bus_addr  = address + s->dma_address + (j << PAGE_SHIFT);
                        phys_addr = (sg_phys(s) & PAGE_MASK) + (j << PAGE_SHIFT);
-                       ret = iommu_map_page(domain, bus_addr, phys_addr, PAGE_SIZE, prot, GFP_ATOMIC);
+                       ret = iommu_map_page(domain, bus_addr, phys_addr,
+                                            PAGE_SIZE, prot,
+                                            GFP_ATOMIC | __GFP_NOWARN);
                        if (ret)
                                goto out_unmap;
 
@@ -2805,7 +2837,7 @@ int __init amd_iommu_init_api(void)
 
 int __init amd_iommu_init_dma_ops(void)
 {
-       swiotlb        = (iommu_pass_through || sme_me_mask) ? 1 : 0;
+       swiotlb        = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0;
        iommu_detected = 1;
 
        if (amd_iommu_unmap_flush)
@@ -3055,7 +3087,8 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova,
 }
 
 static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova,
-                          size_t page_size)
+                             size_t page_size,
+                             struct iommu_iotlb_gather *gather)
 {
        struct protection_domain *domain = to_pdomain(dom);
        size_t unmap_size;
@@ -3196,9 +3229,10 @@ static void amd_iommu_flush_iotlb_all(struct iommu_domain *domain)
        domain_flush_complete(dom);
 }
 
-static void amd_iommu_iotlb_range_add(struct iommu_domain *domain,
-                                     unsigned long iova, size_t size)
+static void amd_iommu_iotlb_sync(struct iommu_domain *domain,
+                                struct iommu_iotlb_gather *gather)
 {
+       amd_iommu_flush_iotlb_all(domain);
 }
 
 const struct iommu_ops amd_iommu_ops = {
@@ -3219,8 +3253,7 @@ const struct iommu_ops amd_iommu_ops = {
        .is_attach_deferred = amd_iommu_is_attach_deferred,
        .pgsize_bitmap  = AMD_IOMMU_PGSIZES,
        .flush_iotlb_all = amd_iommu_flush_iotlb_all,
-       .iotlb_range_add = amd_iommu_iotlb_range_add,
-       .iotlb_sync = amd_iommu_flush_iotlb_all,
+       .iotlb_sync = amd_iommu_iotlb_sync,
 };
 
 /*****************************************************************************
@@ -4313,13 +4346,62 @@ static const struct irq_domain_ops amd_ir_domain_ops = {
        .deactivate = irq_remapping_deactivate,
 };
 
+int amd_iommu_activate_guest_mode(void *data)
+{
+       struct amd_ir_data *ir_data = (struct amd_ir_data *)data;
+       struct irte_ga *entry = (struct irte_ga *) ir_data->entry;
+
+       if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) ||
+           !entry || entry->lo.fields_vapic.guest_mode)
+               return 0;
+
+       entry->lo.val = 0;
+       entry->hi.val = 0;
+
+       entry->lo.fields_vapic.guest_mode  = 1;
+       entry->lo.fields_vapic.ga_log_intr = 1;
+       entry->hi.fields.ga_root_ptr       = ir_data->ga_root_ptr;
+       entry->hi.fields.vector            = ir_data->ga_vector;
+       entry->lo.fields_vapic.ga_tag      = ir_data->ga_tag;
+
+       return modify_irte_ga(ir_data->irq_2_irte.devid,
+                             ir_data->irq_2_irte.index, entry, NULL);
+}
+EXPORT_SYMBOL(amd_iommu_activate_guest_mode);
+
+int amd_iommu_deactivate_guest_mode(void *data)
+{
+       struct amd_ir_data *ir_data = (struct amd_ir_data *)data;
+       struct irte_ga *entry = (struct irte_ga *) ir_data->entry;
+       struct irq_cfg *cfg = ir_data->cfg;
+
+       if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir) ||
+           !entry || !entry->lo.fields_vapic.guest_mode)
+               return 0;
+
+       entry->lo.val = 0;
+       entry->hi.val = 0;
+
+       entry->lo.fields_remap.dm          = apic->irq_dest_mode;
+       entry->lo.fields_remap.int_type    = apic->irq_delivery_mode;
+       entry->hi.fields.vector            = cfg->vector;
+       entry->lo.fields_remap.destination =
+                               APICID_TO_IRTE_DEST_LO(cfg->dest_apicid);
+       entry->hi.fields.destination =
+                               APICID_TO_IRTE_DEST_HI(cfg->dest_apicid);
+
+       return modify_irte_ga(ir_data->irq_2_irte.devid,
+                             ir_data->irq_2_irte.index, entry, NULL);
+}
+EXPORT_SYMBOL(amd_iommu_deactivate_guest_mode);
+
 static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
 {
+       int ret;
        struct amd_iommu *iommu;
        struct amd_iommu_pi_data *pi_data = vcpu_info;
        struct vcpu_data *vcpu_pi_info = pi_data->vcpu_data;
        struct amd_ir_data *ir_data = data->chip_data;
-       struct irte_ga *irte = (struct irte_ga *) ir_data->entry;
        struct irq_2_irte *irte_info = &ir_data->irq_2_irte;
        struct iommu_dev_data *dev_data = search_dev_data(irte_info->devid);
 
@@ -4330,6 +4412,7 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
        if (!dev_data || !dev_data->use_vapic)
                return 0;
 
+       ir_data->cfg = irqd_cfg(data);
        pi_data->ir_data = ir_data;
 
        /* Note:
@@ -4348,37 +4431,24 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info)
 
        pi_data->prev_ga_tag = ir_data->cached_ga_tag;
        if (pi_data->is_guest_mode) {
-               /* Setting */
-               irte->hi.fields.ga_root_ptr = (pi_data->base >> 12);
-               irte->hi.fields.vector = vcpu_pi_info->vector;
-               irte->lo.fields_vapic.ga_log_intr = 1;
-               irte->lo.fields_vapic.guest_mode = 1;
-               irte->lo.fields_vapic.ga_tag = pi_data->ga_tag;
-
-               ir_data->cached_ga_tag = pi_data->ga_tag;
+               ir_data->ga_root_ptr = (pi_data->base >> 12);
+               ir_data->ga_vector = vcpu_pi_info->vector;
+               ir_data->ga_tag = pi_data->ga_tag;
+               ret = amd_iommu_activate_guest_mode(ir_data);
+               if (!ret)
+                       ir_data->cached_ga_tag = pi_data->ga_tag;
        } else {
-               /* Un-Setting */
-               struct irq_cfg *cfg = irqd_cfg(data);
-
-               irte->hi.val = 0;
-               irte->lo.val = 0;
-               irte->hi.fields.vector = cfg->vector;
-               irte->lo.fields_remap.guest_mode = 0;
-               irte->lo.fields_remap.destination =
-                               APICID_TO_IRTE_DEST_LO(cfg->dest_apicid);
-               irte->hi.fields.destination =
-                               APICID_TO_IRTE_DEST_HI(cfg->dest_apicid);
-               irte->lo.fields_remap.int_type = apic->irq_delivery_mode;
-               irte->lo.fields_remap.dm = apic->irq_dest_mode;
+               ret = amd_iommu_deactivate_guest_mode(ir_data);
 
                /*
                 * This communicates the ga_tag back to the caller
                 * so that it can do all the necessary clean up.
                 */
-               ir_data->cached_ga_tag = 0;
+               if (!ret)
+                       ir_data->cached_ga_tag = 0;
        }
 
-       return modify_irte_ga(irte_info->devid, irte_info->index, irte, ir_data);
+       return ret;
 }
 
 
diff --git a/drivers/iommu/amd_iommu.h b/drivers/iommu/amd_iommu.h
new file mode 100644 (file)
index 0000000..12d540d
--- /dev/null
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef AMD_IOMMU_H
+#define AMD_IOMMU_H
+
+int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line);
+
+#ifdef CONFIG_DMI
+void amd_iommu_apply_ivrs_quirks(void);
+#else
+static void amd_iommu_apply_ivrs_quirks(void) { }
+#endif
+
+#endif
index 4413aa6..568c523 100644 (file)
@@ -32,6 +32,7 @@
 #include <asm/irq_remapping.h>
 
 #include <linux/crash_dump.h>
+#include "amd_iommu.h"
 #include "amd_iommu_proto.h"
 #include "amd_iommu_types.h"
 #include "irq_remapping.h"
@@ -1002,7 +1003,7 @@ static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu,
        set_iommu_for_device(iommu, devid);
 }
 
-static int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line)
+int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line)
 {
        struct devid_map *entry;
        struct list_head *list;
@@ -1153,6 +1154,8 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
        if (ret)
                return ret;
 
+       amd_iommu_apply_ivrs_quirks();
+
        /*
         * First save the recommended feature enable bits from ACPI
         */
diff --git a/drivers/iommu/amd_iommu_quirks.c b/drivers/iommu/amd_iommu_quirks.c
new file mode 100644 (file)
index 0000000..c235f79
--- /dev/null
@@ -0,0 +1,92 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+/*
+ * Quirks for AMD IOMMU
+ *
+ * Copyright (C) 2019 Kai-Heng Feng <kai.heng.feng@canonical.com>
+ */
+
+#ifdef CONFIG_DMI
+#include <linux/dmi.h>
+
+#include "amd_iommu.h"
+
+#define IVHD_SPECIAL_IOAPIC            1
+
+struct ivrs_quirk_entry {
+       u8 id;
+       u16 devid;
+};
+
+enum {
+       DELL_INSPIRON_7375 = 0,
+       DELL_LATITUDE_5495,
+       LENOVO_IDEAPAD_330S_15ARR,
+};
+
+static const struct ivrs_quirk_entry ivrs_ioapic_quirks[][3] __initconst = {
+       /* ivrs_ioapic[4]=00:14.0 ivrs_ioapic[5]=00:00.2 */
+       [DELL_INSPIRON_7375] = {
+               { .id = 4, .devid = 0xa0 },
+               { .id = 5, .devid = 0x2 },
+               {}
+       },
+       /* ivrs_ioapic[4]=00:14.0 */
+       [DELL_LATITUDE_5495] = {
+               { .id = 4, .devid = 0xa0 },
+               {}
+       },
+       /* ivrs_ioapic[32]=00:14.0 */
+       [LENOVO_IDEAPAD_330S_15ARR] = {
+               { .id = 32, .devid = 0xa0 },
+               {}
+       },
+       {}
+};
+
+static int __init ivrs_ioapic_quirk_cb(const struct dmi_system_id *d)
+{
+       const struct ivrs_quirk_entry *i;
+
+       for (i = d->driver_data; i->id != 0 && i->devid != 0; i++)
+               add_special_device(IVHD_SPECIAL_IOAPIC, i->id, (u16 *)&i->devid, 0);
+
+       return 0;
+}
+
+static const struct dmi_system_id ivrs_quirks[] __initconst = {
+       {
+               .callback = ivrs_ioapic_quirk_cb,
+               .ident = "Dell Inspiron 7375",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7375"),
+               },
+               .driver_data = (void *)&ivrs_ioapic_quirks[DELL_INSPIRON_7375],
+       },
+       {
+               .callback = ivrs_ioapic_quirk_cb,
+               .ident = "Dell Latitude 5495",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 5495"),
+               },
+               .driver_data = (void *)&ivrs_ioapic_quirks[DELL_LATITUDE_5495],
+       },
+       {
+               .callback = ivrs_ioapic_quirk_cb,
+               .ident = "Lenovo ideapad 330S-15ARR",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "81FB"),
+               },
+               .driver_data = (void *)&ivrs_ioapic_quirks[LENOVO_IDEAPAD_330S_15ARR],
+       },
+       {}
+};
+
+void __init amd_iommu_apply_ivrs_quirks(void)
+{
+       dmi_check_system(ivrs_quirks);
+}
+#endif
index 64edd5a..9ac229e 100644 (file)
@@ -873,6 +873,15 @@ struct amd_ir_data {
        struct msi_msg msi_entry;
        void *entry;    /* Pointer to union irte or struct irte_ga */
        void *ref;      /* Pointer to the actual irte */
+
+       /**
+        * Store information for activate/de-activate
+        * Guest virtual APIC mode during runtime.
+        */
+       struct irq_cfg *cfg;
+       int ga_vector;
+       int ga_root_ptr;
+       int ga_tag;
 };
 
 struct amd_irte_ops {
diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
new file mode 100644 (file)
index 0000000..5c87a38
--- /dev/null
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Miscellaneous Arm SMMU implementation and integration quirks
+// Copyright (C) 2019 Arm Limited
+
+#define pr_fmt(fmt) "arm-smmu: " fmt
+
+#include <linux/bitfield.h>
+#include <linux/of.h>
+
+#include "arm-smmu.h"
+
+
+static int arm_smmu_gr0_ns(int offset)
+{
+       switch(offset) {
+       case ARM_SMMU_GR0_sCR0:
+       case ARM_SMMU_GR0_sACR:
+       case ARM_SMMU_GR0_sGFSR:
+       case ARM_SMMU_GR0_sGFSYNR0:
+       case ARM_SMMU_GR0_sGFSYNR1:
+       case ARM_SMMU_GR0_sGFSYNR2:
+               return offset + 0x400;
+       default:
+               return offset;
+       }
+}
+
+static u32 arm_smmu_read_ns(struct arm_smmu_device *smmu, int page,
+                           int offset)
+{
+       if (page == ARM_SMMU_GR0)
+               offset = arm_smmu_gr0_ns(offset);
+       return readl_relaxed(arm_smmu_page(smmu, page) + offset);
+}
+
+static void arm_smmu_write_ns(struct arm_smmu_device *smmu, int page,
+                             int offset, u32 val)
+{
+       if (page == ARM_SMMU_GR0)
+               offset = arm_smmu_gr0_ns(offset);
+       writel_relaxed(val, arm_smmu_page(smmu, page) + offset);
+}
+
+/* Since we don't care for sGFAR, we can do without 64-bit accessors */
+static const struct arm_smmu_impl calxeda_impl = {
+       .read_reg = arm_smmu_read_ns,
+       .write_reg = arm_smmu_write_ns,
+};
+
+
+struct cavium_smmu {
+       struct arm_smmu_device smmu;
+       u32 id_base;
+};
+
+static int cavium_cfg_probe(struct arm_smmu_device *smmu)
+{
+       static atomic_t context_count = ATOMIC_INIT(0);
+       struct cavium_smmu *cs = container_of(smmu, struct cavium_smmu, smmu);
+       /*
+        * Cavium CN88xx erratum #27704.
+        * Ensure ASID and VMID allocation is unique across all SMMUs in
+        * the system.
+        */
+       cs->id_base = atomic_fetch_add(smmu->num_context_banks, &context_count);
+       dev_notice(smmu->dev, "\tenabling workaround for Cavium erratum 27704\n");
+
+       return 0;
+}
+
+static int cavium_init_context(struct arm_smmu_domain *smmu_domain)
+{
+       struct cavium_smmu *cs = container_of(smmu_domain->smmu,
+                                             struct cavium_smmu, smmu);
+
+       if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2)
+               smmu_domain->cfg.vmid += cs->id_base;
+       else
+               smmu_domain->cfg.asid += cs->id_base;
+
+       return 0;
+}
+
+static const struct arm_smmu_impl cavium_impl = {
+       .cfg_probe = cavium_cfg_probe,
+       .init_context = cavium_init_context,
+};
+
+static struct arm_smmu_device *cavium_smmu_impl_init(struct arm_smmu_device *smmu)
+{
+       struct cavium_smmu *cs;
+
+       cs = devm_kzalloc(smmu->dev, sizeof(*cs), GFP_KERNEL);
+       if (!cs)
+               return ERR_PTR(-ENOMEM);
+
+       cs->smmu = *smmu;
+       cs->smmu.impl = &cavium_impl;
+
+       devm_kfree(smmu->dev, smmu);
+
+       return &cs->smmu;
+}
+
+
+#define ARM_MMU500_ACTLR_CPRE          (1 << 1)
+
+#define ARM_MMU500_ACR_CACHE_LOCK      (1 << 26)
+#define ARM_MMU500_ACR_S2CRB_TLBEN     (1 << 10)
+#define ARM_MMU500_ACR_SMTNMB_TLBEN    (1 << 8)
+
+static int arm_mmu500_reset(struct arm_smmu_device *smmu)
+{
+       u32 reg, major;
+       int i;
+       /*
+        * On MMU-500 r2p0 onwards we need to clear ACR.CACHE_LOCK before
+        * writes to the context bank ACTLRs will stick. And we just hope that
+        * Secure has also cleared SACR.CACHE_LOCK for this to take effect...
+        */
+       reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_ID7);
+       major = FIELD_GET(ID7_MAJOR, reg);
+       reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sACR);
+       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 | ARM_MMU500_ACR_S2CRB_TLBEN;
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sACR, reg);
+
+       /*
+        * Disable MMU-500's not-particularly-beneficial next-page
+        * prefetcher for the sake of errata #841119 and #826419.
+        */
+       for (i = 0; i < smmu->num_context_banks; ++i) {
+               reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR);
+               reg &= ~ARM_MMU500_ACTLR_CPRE;
+               arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_ACTLR, reg);
+       }
+
+       return 0;
+}
+
+static const struct arm_smmu_impl arm_mmu500_impl = {
+       .reset = arm_mmu500_reset,
+};
+
+
+struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
+{
+       /*
+        * We will inevitably have to combine model-specific implementation
+        * quirks with platform-specific integration quirks, but everything
+        * we currently support happens to work out as straightforward
+        * mutually-exclusive assignments.
+        */
+       switch (smmu->model) {
+       case ARM_MMU500:
+               smmu->impl = &arm_mmu500_impl;
+               break;
+       case CAVIUM_SMMUV2:
+               return cavium_smmu_impl_init(smmu);
+       default:
+               break;
+       }
+
+       if (of_property_read_bool(smmu->dev->of_node,
+                                 "calxeda,smmu-secure-config-access"))
+               smmu->impl = &calxeda_impl;
+
+       return smmu;
+}
diff --git a/drivers/iommu/arm-smmu-regs.h b/drivers/iommu/arm-smmu-regs.h
deleted file mode 100644 (file)
index 1c278f7..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * IOMMU API for ARM architected SMMU implementations.
- *
- * Copyright (C) 2013 ARM Limited
- *
- * Author: Will Deacon <will.deacon@arm.com>
- */
-
-#ifndef _ARM_SMMU_REGS_H
-#define _ARM_SMMU_REGS_H
-
-/* Configuration registers */
-#define ARM_SMMU_GR0_sCR0              0x0
-#define sCR0_CLIENTPD                  (1 << 0)
-#define sCR0_GFRE                      (1 << 1)
-#define sCR0_GFIE                      (1 << 2)
-#define sCR0_EXIDENABLE                        (1 << 3)
-#define sCR0_GCFGFRE                   (1 << 4)
-#define sCR0_GCFGFIE                   (1 << 5)
-#define sCR0_USFCFG                    (1 << 10)
-#define sCR0_VMIDPNE                   (1 << 11)
-#define sCR0_PTM                       (1 << 12)
-#define sCR0_FB                                (1 << 13)
-#define sCR0_VMID16EN                  (1 << 31)
-#define sCR0_BSU_SHIFT                 14
-#define sCR0_BSU_MASK                  0x3
-
-/* Auxiliary Configuration register */
-#define ARM_SMMU_GR0_sACR              0x10
-
-/* Identification registers */
-#define ARM_SMMU_GR0_ID0               0x20
-#define ARM_SMMU_GR0_ID1               0x24
-#define ARM_SMMU_GR0_ID2               0x28
-#define ARM_SMMU_GR0_ID3               0x2c
-#define ARM_SMMU_GR0_ID4               0x30
-#define ARM_SMMU_GR0_ID5               0x34
-#define ARM_SMMU_GR0_ID6               0x38
-#define ARM_SMMU_GR0_ID7               0x3c
-#define ARM_SMMU_GR0_sGFSR             0x48
-#define ARM_SMMU_GR0_sGFSYNR0          0x50
-#define ARM_SMMU_GR0_sGFSYNR1          0x54
-#define ARM_SMMU_GR0_sGFSYNR2          0x58
-
-#define ID0_S1TS                       (1 << 30)
-#define ID0_S2TS                       (1 << 29)
-#define ID0_NTS                                (1 << 28)
-#define ID0_SMS                                (1 << 27)
-#define ID0_ATOSNS                     (1 << 26)
-#define ID0_PTFS_NO_AARCH32            (1 << 25)
-#define ID0_PTFS_NO_AARCH32S           (1 << 24)
-#define ID0_CTTW                       (1 << 14)
-#define ID0_NUMIRPT_SHIFT              16
-#define ID0_NUMIRPT_MASK               0xff
-#define ID0_NUMSIDB_SHIFT              9
-#define ID0_NUMSIDB_MASK               0xf
-#define ID0_EXIDS                      (1 << 8)
-#define ID0_NUMSMRG_SHIFT              0
-#define ID0_NUMSMRG_MASK               0xff
-
-#define ID1_PAGESIZE                   (1 << 31)
-#define ID1_NUMPAGENDXB_SHIFT          28
-#define ID1_NUMPAGENDXB_MASK           7
-#define ID1_NUMS2CB_SHIFT              16
-#define ID1_NUMS2CB_MASK               0xff
-#define ID1_NUMCB_SHIFT                        0
-#define ID1_NUMCB_MASK                 0xff
-
-#define ID2_OAS_SHIFT                  4
-#define ID2_OAS_MASK                   0xf
-#define ID2_IAS_SHIFT                  0
-#define ID2_IAS_MASK                   0xf
-#define ID2_UBS_SHIFT                  8
-#define ID2_UBS_MASK                   0xf
-#define ID2_PTFS_4K                    (1 << 12)
-#define ID2_PTFS_16K                   (1 << 13)
-#define ID2_PTFS_64K                   (1 << 14)
-#define ID2_VMID16                     (1 << 15)
-
-#define ID7_MAJOR_SHIFT                        4
-#define ID7_MAJOR_MASK                 0xf
-
-/* Global TLB invalidation */
-#define ARM_SMMU_GR0_TLBIVMID          0x64
-#define ARM_SMMU_GR0_TLBIALLNSNH       0x68
-#define ARM_SMMU_GR0_TLBIALLH          0x6c
-#define ARM_SMMU_GR0_sTLBGSYNC         0x70
-#define ARM_SMMU_GR0_sTLBGSTATUS       0x74
-#define sTLBGSTATUS_GSACTIVE           (1 << 0)
-
-/* Stream mapping registers */
-#define ARM_SMMU_GR0_SMR(n)            (0x800 + ((n) << 2))
-#define SMR_VALID                      (1 << 31)
-#define SMR_MASK_SHIFT                 16
-#define SMR_ID_SHIFT                   0
-
-#define ARM_SMMU_GR0_S2CR(n)           (0xc00 + ((n) << 2))
-#define S2CR_CBNDX_SHIFT               0
-#define S2CR_CBNDX_MASK                        0xff
-#define S2CR_EXIDVALID                 (1 << 10)
-#define S2CR_TYPE_SHIFT                        16
-#define S2CR_TYPE_MASK                 0x3
-enum arm_smmu_s2cr_type {
-       S2CR_TYPE_TRANS,
-       S2CR_TYPE_BYPASS,
-       S2CR_TYPE_FAULT,
-};
-
-#define S2CR_PRIVCFG_SHIFT             24
-#define S2CR_PRIVCFG_MASK              0x3
-enum arm_smmu_s2cr_privcfg {
-       S2CR_PRIVCFG_DEFAULT,
-       S2CR_PRIVCFG_DIPAN,
-       S2CR_PRIVCFG_UNPRIV,
-       S2CR_PRIVCFG_PRIV,
-};
-
-/* Context bank attribute registers */
-#define ARM_SMMU_GR1_CBAR(n)           (0x0 + ((n) << 2))
-#define CBAR_VMID_SHIFT                        0
-#define CBAR_VMID_MASK                 0xff
-#define CBAR_S1_BPSHCFG_SHIFT          8
-#define CBAR_S1_BPSHCFG_MASK           3
-#define CBAR_S1_BPSHCFG_NSH            3
-#define CBAR_S1_MEMATTR_SHIFT          12
-#define CBAR_S1_MEMATTR_MASK           0xf
-#define CBAR_S1_MEMATTR_WB             0xf
-#define CBAR_TYPE_SHIFT                        16
-#define CBAR_TYPE_MASK                 0x3
-#define CBAR_TYPE_S2_TRANS             (0 << CBAR_TYPE_SHIFT)
-#define CBAR_TYPE_S1_TRANS_S2_BYPASS   (1 << CBAR_TYPE_SHIFT)
-#define CBAR_TYPE_S1_TRANS_S2_FAULT    (2 << CBAR_TYPE_SHIFT)
-#define CBAR_TYPE_S1_TRANS_S2_TRANS    (3 << CBAR_TYPE_SHIFT)
-#define CBAR_IRPTNDX_SHIFT             24
-#define CBAR_IRPTNDX_MASK              0xff
-
-#define ARM_SMMU_GR1_CBFRSYNRA(n)      (0x400 + ((n) << 2))
-
-#define ARM_SMMU_GR1_CBA2R(n)          (0x800 + ((n) << 2))
-#define CBA2R_RW64_32BIT               (0 << 0)
-#define CBA2R_RW64_64BIT               (1 << 0)
-#define CBA2R_VMID_SHIFT               16
-#define CBA2R_VMID_MASK                        0xffff
-
-#define ARM_SMMU_CB_SCTLR              0x0
-#define ARM_SMMU_CB_ACTLR              0x4
-#define ARM_SMMU_CB_RESUME             0x8
-#define ARM_SMMU_CB_TTBCR2             0x10
-#define ARM_SMMU_CB_TTBR0              0x20
-#define ARM_SMMU_CB_TTBR1              0x28
-#define ARM_SMMU_CB_TTBCR              0x30
-#define ARM_SMMU_CB_CONTEXTIDR         0x34
-#define ARM_SMMU_CB_S1_MAIR0           0x38
-#define ARM_SMMU_CB_S1_MAIR1           0x3c
-#define ARM_SMMU_CB_PAR                        0x50
-#define ARM_SMMU_CB_FSR                        0x58
-#define ARM_SMMU_CB_FAR                        0x60
-#define ARM_SMMU_CB_FSYNR0             0x68
-#define ARM_SMMU_CB_S1_TLBIVA          0x600
-#define ARM_SMMU_CB_S1_TLBIASID                0x610
-#define ARM_SMMU_CB_S1_TLBIVAL         0x620
-#define ARM_SMMU_CB_S2_TLBIIPAS2       0x630
-#define ARM_SMMU_CB_S2_TLBIIPAS2L      0x638
-#define ARM_SMMU_CB_TLBSYNC            0x7f0
-#define ARM_SMMU_CB_TLBSTATUS          0x7f4
-#define ARM_SMMU_CB_ATS1PR             0x800
-#define ARM_SMMU_CB_ATSR               0x8f0
-
-#define SCTLR_S1_ASIDPNE               (1 << 12)
-#define SCTLR_CFCFG                    (1 << 7)
-#define SCTLR_CFIE                     (1 << 6)
-#define SCTLR_CFRE                     (1 << 5)
-#define SCTLR_E                                (1 << 4)
-#define SCTLR_AFE                      (1 << 2)
-#define SCTLR_TRE                      (1 << 1)
-#define SCTLR_M                                (1 << 0)
-
-#define CB_PAR_F                       (1 << 0)
-
-#define ATSR_ACTIVE                    (1 << 0)
-
-#define RESUME_RETRY                   (0 << 0)
-#define RESUME_TERMINATE               (1 << 0)
-
-#define TTBCR2_SEP_SHIFT               15
-#define TTBCR2_SEP_UPSTREAM            (0x7 << TTBCR2_SEP_SHIFT)
-#define TTBCR2_AS                      (1 << 4)
-
-#define TTBRn_ASID_SHIFT               48
-
-#define FSR_MULTI                      (1 << 31)
-#define FSR_SS                         (1 << 30)
-#define FSR_UUT                                (1 << 8)
-#define FSR_ASF                                (1 << 7)
-#define FSR_TLBLKF                     (1 << 6)
-#define FSR_TLBMCF                     (1 << 5)
-#define FSR_EF                         (1 << 4)
-#define FSR_PF                         (1 << 3)
-#define FSR_AFF                                (1 << 2)
-#define FSR_TF                         (1 << 1)
-
-#define FSR_IGN                                (FSR_AFF | FSR_ASF | \
-                                        FSR_TLBMCF | FSR_TLBLKF)
-#define FSR_FAULT                      (FSR_MULTI | FSR_SS | FSR_UUT | \
-                                        FSR_EF | FSR_PF | FSR_TF | FSR_IGN)
-
-#define FSYNR0_WNR                     (1 << 4)
-
-#endif /* _ARM_SMMU_REGS_H */
index c5c93e4..4aa4148 100644 (file)
 #define ARM_SMMU_MEMATTR_DEVICE_nGnRE  0x1
 #define ARM_SMMU_MEMATTR_OIWB          0xf
 
-#define Q_IDX(q, p)                    ((p) & ((1 << (q)->max_n_shift) - 1))
-#define Q_WRP(q, p)                    ((p) & (1 << (q)->max_n_shift))
-#define Q_OVERFLOW_FLAG                        (1 << 31)
-#define Q_OVF(q, p)                    ((p) & Q_OVERFLOW_FLAG)
+#define Q_IDX(llq, p)                  ((p) & ((1 << (llq)->max_n_shift) - 1))
+#define Q_WRP(llq, p)                  ((p) & (1 << (llq)->max_n_shift))
+#define Q_OVERFLOW_FLAG                        (1U << 31)
+#define Q_OVF(p)                       ((p) & Q_OVERFLOW_FLAG)
 #define Q_ENT(q, p)                    ((q)->base +                    \
-                                        Q_IDX(q, p) * (q)->ent_dwords)
+                                        Q_IDX(&((q)->llq), p) *        \
+                                        (q)->ent_dwords)
 
 #define Q_BASE_RWA                     (1UL << 62)
 #define Q_BASE_ADDR_MASK               GENMASK_ULL(51, 5)
 #define CMDQ_ERR_CERROR_ABT_IDX                2
 #define CMDQ_ERR_CERROR_ATC_INV_IDX    3
 
+#define CMDQ_PROD_OWNED_FLAG           Q_OVERFLOW_FLAG
+
+/*
+ * This is used to size the command queue and therefore must be at least
+ * BITS_PER_LONG so that the valid_map works correctly (it relies on the
+ * total number of queue entries being a multiple of BITS_PER_LONG).
+ */
+#define CMDQ_BATCH_ENTRIES             BITS_PER_LONG
+
 #define CMDQ_0_OP                      GENMASK_ULL(7, 0)
 #define CMDQ_0_SSV                     (1UL << 11)
 
 #define PRIQ_1_ADDR_MASK               GENMASK_ULL(63, 12)
 
 /* High-level queue structures */
-#define ARM_SMMU_POLL_TIMEOUT_US       100
-#define ARM_SMMU_CMDQ_SYNC_TIMEOUT_US  1000000 /* 1s! */
-#define ARM_SMMU_CMDQ_SYNC_SPIN_COUNT  10
+#define ARM_SMMU_POLL_TIMEOUT_US       1000000 /* 1s! */
+#define ARM_SMMU_POLL_SPIN_COUNT       10
 
 #define MSI_IOVA_BASE                  0x8000000
 #define MSI_IOVA_LENGTH                        0x100000
@@ -472,13 +481,29 @@ struct arm_smmu_cmdq_ent {
 
                #define CMDQ_OP_CMD_SYNC        0x46
                struct {
-                       u32                     msidata;
                        u64                     msiaddr;
                } sync;
        };
 };
 
+struct arm_smmu_ll_queue {
+       union {
+               u64                     val;
+               struct {
+                       u32             prod;
+                       u32             cons;
+               };
+               struct {
+                       atomic_t        prod;
+                       atomic_t        cons;
+               } atomic;
+               u8                      __pad[SMP_CACHE_BYTES];
+       } ____cacheline_aligned_in_smp;
+       u32                             max_n_shift;
+};
+
 struct arm_smmu_queue {
+       struct arm_smmu_ll_queue        llq;
        int                             irq; /* Wired interrupt */
 
        __le64                          *base;
@@ -486,17 +511,23 @@ struct arm_smmu_queue {
        u64                             q_base;
 
        size_t                          ent_dwords;
-       u32                             max_n_shift;
-       u32                             prod;
-       u32                             cons;
 
        u32 __iomem                     *prod_reg;
        u32 __iomem                     *cons_reg;
 };
 
+struct arm_smmu_queue_poll {
+       ktime_t                         timeout;
+       unsigned int                    delay;
+       unsigned int                    spin_cnt;
+       bool                            wfe;
+};
+
 struct arm_smmu_cmdq {
        struct arm_smmu_queue           q;
-       spinlock_t                      lock;
+       atomic_long_t                   *valid_map;
+       atomic_t                        owner_prod;
+       atomic_t                        lock;
 };
 
 struct arm_smmu_evtq {
@@ -576,8 +607,6 @@ struct arm_smmu_device {
 
        int                             gerr_irq;
        int                             combined_irq;
-       u32                             sync_nr;
-       u8                              prev_cmd_opcode;
 
        unsigned long                   ias; /* IPA */
        unsigned long                   oas; /* PA */
@@ -596,12 +625,6 @@ struct arm_smmu_device {
 
        struct arm_smmu_strtab_cfg      strtab_cfg;
 
-       /* Hi16xx adds an extra 32 bits of goodness to its MSI payload */
-       union {
-               u32                     sync_count;
-               u64                     padding;
-       };
-
        /* IOMMU core code handle */
        struct iommu_device             iommu;
 };
@@ -614,7 +637,7 @@ struct arm_smmu_master {
        struct list_head                domain_head;
        u32                             *sids;
        unsigned int                    num_sids;
-       bool                            ats_enabled             :1;
+       bool                            ats_enabled;
 };
 
 /* SMMU private data for an IOMMU domain */
@@ -631,6 +654,7 @@ struct arm_smmu_domain {
 
        struct io_pgtable_ops           *pgtbl_ops;
        bool                            non_strict;
+       atomic_t                        nr_ats_masters;
 
        enum arm_smmu_domain_stage      stage;
        union {
@@ -685,85 +709,97 @@ static void parse_driver_options(struct arm_smmu_device *smmu)
 }
 
 /* Low-level queue manipulation functions */
-static bool queue_full(struct arm_smmu_queue *q)
+static bool queue_has_space(struct arm_smmu_ll_queue *q, u32 n)
+{
+       u32 space, prod, cons;
+
+       prod = Q_IDX(q, q->prod);
+       cons = Q_IDX(q, q->cons);
+
+       if (Q_WRP(q, q->prod) == Q_WRP(q, q->cons))
+               space = (1 << q->max_n_shift) - (prod - cons);
+       else
+               space = cons - prod;
+
+       return space >= n;
+}
+
+static bool queue_full(struct arm_smmu_ll_queue *q)
 {
        return Q_IDX(q, q->prod) == Q_IDX(q, q->cons) &&
               Q_WRP(q, q->prod) != Q_WRP(q, q->cons);
 }
 
-static bool queue_empty(struct arm_smmu_queue *q)
+static bool queue_empty(struct arm_smmu_ll_queue *q)
 {
        return Q_IDX(q, q->prod) == Q_IDX(q, q->cons) &&
               Q_WRP(q, q->prod) == Q_WRP(q, q->cons);
 }
 
-static void queue_sync_cons(struct arm_smmu_queue *q)
+static bool queue_consumed(struct arm_smmu_ll_queue *q, u32 prod)
 {
-       q->cons = readl_relaxed(q->cons_reg);
+       return ((Q_WRP(q, q->cons) == Q_WRP(q, prod)) &&
+               (Q_IDX(q, q->cons) > Q_IDX(q, prod))) ||
+              ((Q_WRP(q, q->cons) != Q_WRP(q, prod)) &&
+               (Q_IDX(q, q->cons) <= Q_IDX(q, prod)));
 }
 
-static void queue_inc_cons(struct arm_smmu_queue *q)
+static void queue_sync_cons_out(struct arm_smmu_queue *q)
 {
-       u32 cons = (Q_WRP(q, q->cons) | Q_IDX(q, q->cons)) + 1;
-
-       q->cons = Q_OVF(q, q->cons) | Q_WRP(q, cons) | Q_IDX(q, cons);
-
        /*
         * Ensure that all CPU accesses (reads and writes) to the queue
         * are complete before we update the cons pointer.
         */
        mb();
-       writel_relaxed(q->cons, q->cons_reg);
+       writel_relaxed(q->llq.cons, q->cons_reg);
+}
+
+static void queue_inc_cons(struct arm_smmu_ll_queue *q)
+{
+       u32 cons = (Q_WRP(q, q->cons) | Q_IDX(q, q->cons)) + 1;
+       q->cons = Q_OVF(q->cons) | Q_WRP(q, cons) | Q_IDX(q, cons);
 }
 
-static int queue_sync_prod(struct arm_smmu_queue *q)
+static int queue_sync_prod_in(struct arm_smmu_queue *q)
 {
        int ret = 0;
        u32 prod = readl_relaxed(q->prod_reg);
 
-       if (Q_OVF(q, prod) != Q_OVF(q, q->prod))
+       if (Q_OVF(prod) != Q_OVF(q->llq.prod))
                ret = -EOVERFLOW;
 
-       q->prod = prod;
+       q->llq.prod = prod;
        return ret;
 }
 
-static void queue_inc_prod(struct arm_smmu_queue *q)
+static u32 queue_inc_prod_n(struct arm_smmu_ll_queue *q, int n)
 {
-       u32 prod = (Q_WRP(q, q->prod) | Q_IDX(q, q->prod)) + 1;
-
-       q->prod = Q_OVF(q, q->prod) | Q_WRP(q, prod) | Q_IDX(q, prod);
-       writel(q->prod, q->prod_reg);
+       u32 prod = (Q_WRP(q, q->prod) | Q_IDX(q, q->prod)) + n;
+       return Q_OVF(q->prod) | Q_WRP(q, prod) | Q_IDX(q, prod);
 }
 
-/*
- * Wait for the SMMU to consume items. If sync is true, wait until the queue
- * is empty. Otherwise, wait until there is at least one free slot.
- */
-static int queue_poll_cons(struct arm_smmu_queue *q, bool sync, bool wfe)
+static void queue_poll_init(struct arm_smmu_device *smmu,
+                           struct arm_smmu_queue_poll *qp)
 {
-       ktime_t timeout;
-       unsigned int delay = 1, spin_cnt = 0;
-
-       /* Wait longer if it's a CMD_SYNC */
-       timeout = ktime_add_us(ktime_get(), sync ?
-                                           ARM_SMMU_CMDQ_SYNC_TIMEOUT_US :
-                                           ARM_SMMU_POLL_TIMEOUT_US);
+       qp->delay = 1;
+       qp->spin_cnt = 0;
+       qp->wfe = !!(smmu->features & ARM_SMMU_FEAT_SEV);
+       qp->timeout = ktime_add_us(ktime_get(), ARM_SMMU_POLL_TIMEOUT_US);
+}
 
-       while (queue_sync_cons(q), (sync ? !queue_empty(q) : queue_full(q))) {
-               if (ktime_compare(ktime_get(), timeout) > 0)
-                       return -ETIMEDOUT;
+static int queue_poll(struct arm_smmu_queue_poll *qp)
+{
+       if (ktime_compare(ktime_get(), qp->timeout) > 0)
+               return -ETIMEDOUT;
 
-               if (wfe) {
-                       wfe();
-               } else if (++spin_cnt < ARM_SMMU_CMDQ_SYNC_SPIN_COUNT) {
-                       cpu_relax();
-                       continue;
-               } else {
-                       udelay(delay);
-                       delay *= 2;
-                       spin_cnt = 0;
-               }
+       if (qp->wfe) {
+               wfe();
+       } else if (++qp->spin_cnt < ARM_SMMU_POLL_SPIN_COUNT) {
+               cpu_relax();
+       } else {
+               udelay(qp->delay);
+               qp->delay *= 2;
+               qp->spin_cnt = 0;
        }
 
        return 0;
@@ -777,16 +813,6 @@ static void queue_write(__le64 *dst, u64 *src, size_t n_dwords)
                *dst++ = cpu_to_le64(*src++);
 }
 
-static int queue_insert_raw(struct arm_smmu_queue *q, u64 *ent)
-{
-       if (queue_full(q))
-               return -ENOSPC;
-
-       queue_write(Q_ENT(q, q->prod), ent, q->ent_dwords);
-       queue_inc_prod(q);
-       return 0;
-}
-
 static void queue_read(__le64 *dst, u64 *src, size_t n_dwords)
 {
        int i;
@@ -797,11 +823,12 @@ static void queue_read(__le64 *dst, u64 *src, size_t n_dwords)
 
 static int queue_remove_raw(struct arm_smmu_queue *q, u64 *ent)
 {
-       if (queue_empty(q))
+       if (queue_empty(&q->llq))
                return -EAGAIN;
 
-       queue_read(ent, Q_ENT(q, q->cons), q->ent_dwords);
-       queue_inc_cons(q);
+       queue_read(ent, Q_ENT(q, q->llq.cons), q->ent_dwords);
+       queue_inc_cons(&q->llq);
+       queue_sync_cons_out(q);
        return 0;
 }
 
@@ -868,20 +895,14 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
                cmd[1] |= FIELD_PREP(CMDQ_PRI_1_RESP, ent->pri.resp);
                break;
        case CMDQ_OP_CMD_SYNC:
-               if (ent->sync.msiaddr)
+               if (ent->sync.msiaddr) {
                        cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_CS, CMDQ_SYNC_0_CS_IRQ);
-               else
+                       cmd[1] |= ent->sync.msiaddr & CMDQ_SYNC_1_MSIADDR_MASK;
+               } else {
                        cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_CS, CMDQ_SYNC_0_CS_SEV);
+               }
                cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_MSH, ARM_SMMU_SH_ISH);
                cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_MSIATTR, ARM_SMMU_MEMATTR_OIWB);
-               /*
-                * Commands are written little-endian, but we want the SMMU to
-                * receive MSIData, and thus write it back to memory, in CPU
-                * byte order, so big-endian needs an extra byteswap here.
-                */
-               cmd[0] |= FIELD_PREP(CMDQ_SYNC_0_MSIDATA,
-                                    cpu_to_le32(ent->sync.msidata));
-               cmd[1] |= ent->sync.msiaddr & CMDQ_SYNC_1_MSIADDR_MASK;
                break;
        default:
                return -ENOENT;
@@ -890,6 +911,27 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
        return 0;
 }
 
+static void arm_smmu_cmdq_build_sync_cmd(u64 *cmd, struct arm_smmu_device *smmu,
+                                        u32 prod)
+{
+       struct arm_smmu_queue *q = &smmu->cmdq.q;
+       struct arm_smmu_cmdq_ent ent = {
+               .opcode = CMDQ_OP_CMD_SYNC,
+       };
+
+       /*
+        * Beware that Hi16xx adds an extra 32 bits of goodness to its MSI
+        * payload, so the write will zero the entire command on that platform.
+        */
+       if (smmu->features & ARM_SMMU_FEAT_MSI &&
+           smmu->features & ARM_SMMU_FEAT_COHERENCY) {
+               ent.sync.msiaddr = q->base_dma + Q_IDX(&q->llq, prod) *
+                                  q->ent_dwords * 8;
+       }
+
+       arm_smmu_cmdq_build_cmd(cmd, &ent);
+}
+
 static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
 {
        static const char *cerror_str[] = {
@@ -948,109 +990,456 @@ static void arm_smmu_cmdq_skip_err(struct arm_smmu_device *smmu)
        queue_write(Q_ENT(q, cons), cmd, q->ent_dwords);
 }
 
-static void arm_smmu_cmdq_insert_cmd(struct arm_smmu_device *smmu, u64 *cmd)
+/*
+ * Command queue locking.
+ * This is a form of bastardised rwlock with the following major changes:
+ *
+ * - The only LOCK routines are exclusive_trylock() and shared_lock().
+ *   Neither have barrier semantics, and instead provide only a control
+ *   dependency.
+ *
+ * - The UNLOCK routines are supplemented with shared_tryunlock(), which
+ *   fails if the caller appears to be the last lock holder (yes, this is
+ *   racy). All successful UNLOCK routines have RELEASE semantics.
+ */
+static void arm_smmu_cmdq_shared_lock(struct arm_smmu_cmdq *cmdq)
 {
-       struct arm_smmu_queue *q = &smmu->cmdq.q;
-       bool wfe = !!(smmu->features & ARM_SMMU_FEAT_SEV);
+       int val;
+
+       /*
+        * We can try to avoid the cmpxchg() loop by simply incrementing the
+        * lock counter. When held in exclusive state, the lock counter is set
+        * to INT_MIN so these increments won't hurt as the value will remain
+        * negative.
+        */
+       if (atomic_fetch_inc_relaxed(&cmdq->lock) >= 0)
+               return;
+
+       do {
+               val = atomic_cond_read_relaxed(&cmdq->lock, VAL >= 0);
+       } while (atomic_cmpxchg_relaxed(&cmdq->lock, val, val + 1) != val);
+}
+
+static void arm_smmu_cmdq_shared_unlock(struct arm_smmu_cmdq *cmdq)
+{
+       (void)atomic_dec_return_release(&cmdq->lock);
+}
+
+static bool arm_smmu_cmdq_shared_tryunlock(struct arm_smmu_cmdq *cmdq)
+{
+       if (atomic_read(&cmdq->lock) == 1)
+               return false;
+
+       arm_smmu_cmdq_shared_unlock(cmdq);
+       return true;
+}
+
+#define arm_smmu_cmdq_exclusive_trylock_irqsave(cmdq, flags)           \
+({                                                                     \
+       bool __ret;                                                     \
+       local_irq_save(flags);                                          \
+       __ret = !atomic_cmpxchg_relaxed(&cmdq->lock, 0, INT_MIN);       \
+       if (!__ret)                                                     \
+               local_irq_restore(flags);                               \
+       __ret;                                                          \
+})
+
+#define arm_smmu_cmdq_exclusive_unlock_irqrestore(cmdq, flags)         \
+({                                                                     \
+       atomic_set_release(&cmdq->lock, 0);                             \
+       local_irq_restore(flags);                                       \
+})
+
+
+/*
+ * Command queue insertion.
+ * This is made fiddly by our attempts to achieve some sort of scalability
+ * since there is one queue shared amongst all of the CPUs in the system.  If
+ * you like mixed-size concurrency, dependency ordering and relaxed atomics,
+ * then you'll *love* this monstrosity.
+ *
+ * The basic idea is to split the queue up into ranges of commands that are
+ * owned by a given CPU; the owner may not have written all of the commands
+ * itself, but is responsible for advancing the hardware prod pointer when
+ * the time comes. The algorithm is roughly:
+ *
+ *     1. Allocate some space in the queue. At this point we also discover
+ *        whether the head of the queue is currently owned by another CPU,
+ *        or whether we are the owner.
+ *
+ *     2. Write our commands into our allocated slots in the queue.
+ *
+ *     3. Mark our slots as valid in arm_smmu_cmdq.valid_map.
+ *
+ *     4. If we are an owner:
+ *             a. Wait for the previous owner to finish.
+ *             b. Mark the queue head as unowned, which tells us the range
+ *                that we are responsible for publishing.
+ *             c. Wait for all commands in our owned range to become valid.
+ *             d. Advance the hardware prod pointer.
+ *             e. Tell the next owner we've finished.
+ *
+ *     5. If we are inserting a CMD_SYNC (we may or may not have been an
+ *        owner), then we need to stick around until it has completed:
+ *             a. If we have MSIs, the SMMU can write back into the CMD_SYNC
+ *                to clear the first 4 bytes.
+ *             b. Otherwise, we spin waiting for the hardware cons pointer to
+ *                advance past our command.
+ *
+ * The devil is in the details, particularly the use of locking for handling
+ * SYNC completion and freeing up space in the queue before we think that it is
+ * full.
+ */
+static void __arm_smmu_cmdq_poll_set_valid_map(struct arm_smmu_cmdq *cmdq,
+                                              u32 sprod, u32 eprod, bool set)
+{
+       u32 swidx, sbidx, ewidx, ebidx;
+       struct arm_smmu_ll_queue llq = {
+               .max_n_shift    = cmdq->q.llq.max_n_shift,
+               .prod           = sprod,
+       };
+
+       ewidx = BIT_WORD(Q_IDX(&llq, eprod));
+       ebidx = Q_IDX(&llq, eprod) % BITS_PER_LONG;
+
+       while (llq.prod != eprod) {
+               unsigned long mask;
+               atomic_long_t *ptr;
+               u32 limit = BITS_PER_LONG;
+
+               swidx = BIT_WORD(Q_IDX(&llq, llq.prod));
+               sbidx = Q_IDX(&llq, llq.prod) % BITS_PER_LONG;
 
-       smmu->prev_cmd_opcode = FIELD_GET(CMDQ_0_OP, cmd[0]);
+               ptr = &cmdq->valid_map[swidx];
 
-       while (queue_insert_raw(q, cmd) == -ENOSPC) {
-               if (queue_poll_cons(q, false, wfe))
-                       dev_err_ratelimited(smmu->dev, "CMDQ timeout\n");
+               if ((swidx == ewidx) && (sbidx < ebidx))
+                       limit = ebidx;
+
+               mask = GENMASK(limit - 1, sbidx);
+
+               /*
+                * The valid bit is the inverse of the wrap bit. This means
+                * that a zero-initialised queue is invalid and, after marking
+                * all entries as valid, they become invalid again when we
+                * wrap.
+                */
+               if (set) {
+                       atomic_long_xor(mask, ptr);
+               } else { /* Poll */
+                       unsigned long valid;
+
+                       valid = (ULONG_MAX + !!Q_WRP(&llq, llq.prod)) & mask;
+                       atomic_long_cond_read_relaxed(ptr, (VAL & mask) == valid);
+               }
+
+               llq.prod = queue_inc_prod_n(&llq, limit - sbidx);
        }
 }
 
-static void arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
-                                   struct arm_smmu_cmdq_ent *ent)
+/* Mark all entries in the range [sprod, eprod) as valid */
+static void arm_smmu_cmdq_set_valid_map(struct arm_smmu_cmdq *cmdq,
+                                       u32 sprod, u32 eprod)
+{
+       __arm_smmu_cmdq_poll_set_valid_map(cmdq, sprod, eprod, true);
+}
+
+/* Wait for all entries in the range [sprod, eprod) to become valid */
+static void arm_smmu_cmdq_poll_valid_map(struct arm_smmu_cmdq *cmdq,
+                                        u32 sprod, u32 eprod)
+{
+       __arm_smmu_cmdq_poll_set_valid_map(cmdq, sprod, eprod, false);
+}
+
+/* Wait for the command queue to become non-full */
+static int arm_smmu_cmdq_poll_until_not_full(struct arm_smmu_device *smmu,
+                                            struct arm_smmu_ll_queue *llq)
 {
-       u64 cmd[CMDQ_ENT_DWORDS];
        unsigned long flags;
+       struct arm_smmu_queue_poll qp;
+       struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+       int ret = 0;
 
-       if (arm_smmu_cmdq_build_cmd(cmd, ent)) {
-               dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n",
-                        ent->opcode);
-               return;
+       /*
+        * Try to update our copy of cons by grabbing exclusive cmdq access. If
+        * that fails, spin until somebody else updates it for us.
+        */
+       if (arm_smmu_cmdq_exclusive_trylock_irqsave(cmdq, flags)) {
+               WRITE_ONCE(cmdq->q.llq.cons, readl_relaxed(cmdq->q.cons_reg));
+               arm_smmu_cmdq_exclusive_unlock_irqrestore(cmdq, flags);
+               llq->val = READ_ONCE(cmdq->q.llq.val);
+               return 0;
        }
 
-       spin_lock_irqsave(&smmu->cmdq.lock, flags);
-       arm_smmu_cmdq_insert_cmd(smmu, cmd);
-       spin_unlock_irqrestore(&smmu->cmdq.lock, flags);
+       queue_poll_init(smmu, &qp);
+       do {
+               llq->val = READ_ONCE(smmu->cmdq.q.llq.val);
+               if (!queue_full(llq))
+                       break;
+
+               ret = queue_poll(&qp);
+       } while (!ret);
+
+       return ret;
 }
 
 /*
- * The difference between val and sync_idx is bounded by the maximum size of
- * a queue at 2^20 entries, so 32 bits is plenty for wrap-safe arithmetic.
+ * Wait until the SMMU signals a CMD_SYNC completion MSI.
+ * Must be called with the cmdq lock held in some capacity.
  */
-static int __arm_smmu_sync_poll_msi(struct arm_smmu_device *smmu, u32 sync_idx)
+static int __arm_smmu_cmdq_poll_until_msi(struct arm_smmu_device *smmu,
+                                         struct arm_smmu_ll_queue *llq)
 {
-       ktime_t timeout;
-       u32 val;
+       int ret = 0;
+       struct arm_smmu_queue_poll qp;
+       struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+       u32 *cmd = (u32 *)(Q_ENT(&cmdq->q, llq->prod));
 
-       timeout = ktime_add_us(ktime_get(), ARM_SMMU_CMDQ_SYNC_TIMEOUT_US);
-       val = smp_cond_load_acquire(&smmu->sync_count,
-                                   (int)(VAL - sync_idx) >= 0 ||
-                                   !ktime_before(ktime_get(), timeout));
+       queue_poll_init(smmu, &qp);
 
-       return (int)(val - sync_idx) < 0 ? -ETIMEDOUT : 0;
+       /*
+        * The MSI won't generate an event, since it's being written back
+        * into the command queue.
+        */
+       qp.wfe = false;
+       smp_cond_load_relaxed(cmd, !VAL || (ret = queue_poll(&qp)));
+       llq->cons = ret ? llq->prod : queue_inc_prod_n(llq, 1);
+       return ret;
 }
 
-static int __arm_smmu_cmdq_issue_sync_msi(struct arm_smmu_device *smmu)
+/*
+ * Wait until the SMMU cons index passes llq->prod.
+ * Must be called with the cmdq lock held in some capacity.
+ */
+static int __arm_smmu_cmdq_poll_until_consumed(struct arm_smmu_device *smmu,
+                                              struct arm_smmu_ll_queue *llq)
 {
-       u64 cmd[CMDQ_ENT_DWORDS];
-       unsigned long flags;
-       struct arm_smmu_cmdq_ent ent = {
-               .opcode = CMDQ_OP_CMD_SYNC,
-               .sync   = {
-                       .msiaddr = virt_to_phys(&smmu->sync_count),
-               },
-       };
+       struct arm_smmu_queue_poll qp;
+       struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+       u32 prod = llq->prod;
+       int ret = 0;
 
-       spin_lock_irqsave(&smmu->cmdq.lock, flags);
+       queue_poll_init(smmu, &qp);
+       llq->val = READ_ONCE(smmu->cmdq.q.llq.val);
+       do {
+               if (queue_consumed(llq, prod))
+                       break;
 
-       /* Piggy-back on the previous command if it's a SYNC */
-       if (smmu->prev_cmd_opcode == CMDQ_OP_CMD_SYNC) {
-               ent.sync.msidata = smmu->sync_nr;
-       } else {
-               ent.sync.msidata = ++smmu->sync_nr;
-               arm_smmu_cmdq_build_cmd(cmd, &ent);
-               arm_smmu_cmdq_insert_cmd(smmu, cmd);
-       }
+               ret = queue_poll(&qp);
 
-       spin_unlock_irqrestore(&smmu->cmdq.lock, flags);
+               /*
+                * This needs to be a readl() so that our subsequent call
+                * to arm_smmu_cmdq_shared_tryunlock() can fail accurately.
+                *
+                * Specifically, we need to ensure that we observe all
+                * shared_lock()s by other CMD_SYNCs that share our owner,
+                * so that a failing call to tryunlock() means that we're
+                * the last one out and therefore we can safely advance
+                * cmdq->q.llq.cons. Roughly speaking:
+                *
+                * CPU 0                CPU1                    CPU2 (us)
+                *
+                * if (sync)
+                *      shared_lock();
+                *
+                * dma_wmb();
+                * set_valid_map();
+                *
+                *                      if (owner) {
+                *                              poll_valid_map();
+                *                              <control dependency>
+                *                              writel(prod_reg);
+                *
+                *                                              readl(cons_reg);
+                *                                              tryunlock();
+                *
+                * Requires us to see CPU 0's shared_lock() acquisition.
+                */
+               llq->cons = readl(cmdq->q.cons_reg);
+       } while (!ret);
 
-       return __arm_smmu_sync_poll_msi(smmu, ent.sync.msidata);
+       return ret;
 }
 
-static int __arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
+static int arm_smmu_cmdq_poll_until_sync(struct arm_smmu_device *smmu,
+                                        struct arm_smmu_ll_queue *llq)
 {
-       u64 cmd[CMDQ_ENT_DWORDS];
+       if (smmu->features & ARM_SMMU_FEAT_MSI &&
+           smmu->features & ARM_SMMU_FEAT_COHERENCY)
+               return __arm_smmu_cmdq_poll_until_msi(smmu, llq);
+
+       return __arm_smmu_cmdq_poll_until_consumed(smmu, llq);
+}
+
+static void arm_smmu_cmdq_write_entries(struct arm_smmu_cmdq *cmdq, u64 *cmds,
+                                       u32 prod, int n)
+{
+       int i;
+       struct arm_smmu_ll_queue llq = {
+               .max_n_shift    = cmdq->q.llq.max_n_shift,
+               .prod           = prod,
+       };
+
+       for (i = 0; i < n; ++i) {
+               u64 *cmd = &cmds[i * CMDQ_ENT_DWORDS];
+
+               prod = queue_inc_prod_n(&llq, i);
+               queue_write(Q_ENT(&cmdq->q, prod), cmd, CMDQ_ENT_DWORDS);
+       }
+}
+
+/*
+ * This is the actual insertion function, and provides the following
+ * ordering guarantees to callers:
+ *
+ * - There is a dma_wmb() before publishing any commands to the queue.
+ *   This can be relied upon to order prior writes to data structures
+ *   in memory (such as a CD or an STE) before the command.
+ *
+ * - On completion of a CMD_SYNC, there is a control dependency.
+ *   This can be relied upon to order subsequent writes to memory (e.g.
+ *   freeing an IOVA) after completion of the CMD_SYNC.
+ *
+ * - Command insertion is totally ordered, so if two CPUs each race to
+ *   insert their own list of commands then all of the commands from one
+ *   CPU will appear before any of the commands from the other CPU.
+ */
+static int arm_smmu_cmdq_issue_cmdlist(struct arm_smmu_device *smmu,
+                                      u64 *cmds, int n, bool sync)
+{
+       u64 cmd_sync[CMDQ_ENT_DWORDS];
+       u32 prod;
        unsigned long flags;
-       bool wfe = !!(smmu->features & ARM_SMMU_FEAT_SEV);
-       struct arm_smmu_cmdq_ent ent = { .opcode = CMDQ_OP_CMD_SYNC };
-       int ret;
+       bool owner;
+       struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+       struct arm_smmu_ll_queue llq = {
+               .max_n_shift = cmdq->q.llq.max_n_shift,
+       }, head = llq;
+       int ret = 0;
 
-       arm_smmu_cmdq_build_cmd(cmd, &ent);
+       /* 1. Allocate some space in the queue */
+       local_irq_save(flags);
+       llq.val = READ_ONCE(cmdq->q.llq.val);
+       do {
+               u64 old;
+
+               while (!queue_has_space(&llq, n + sync)) {
+                       local_irq_restore(flags);
+                       if (arm_smmu_cmdq_poll_until_not_full(smmu, &llq))
+                               dev_err_ratelimited(smmu->dev, "CMDQ timeout\n");
+                       local_irq_save(flags);
+               }
 
-       spin_lock_irqsave(&smmu->cmdq.lock, flags);
-       arm_smmu_cmdq_insert_cmd(smmu, cmd);
-       ret = queue_poll_cons(&smmu->cmdq.q, true, wfe);
-       spin_unlock_irqrestore(&smmu->cmdq.lock, flags);
+               head.cons = llq.cons;
+               head.prod = queue_inc_prod_n(&llq, n + sync) |
+                                            CMDQ_PROD_OWNED_FLAG;
 
+               old = cmpxchg_relaxed(&cmdq->q.llq.val, llq.val, head.val);
+               if (old == llq.val)
+                       break;
+
+               llq.val = old;
+       } while (1);
+       owner = !(llq.prod & CMDQ_PROD_OWNED_FLAG);
+       head.prod &= ~CMDQ_PROD_OWNED_FLAG;
+       llq.prod &= ~CMDQ_PROD_OWNED_FLAG;
+
+       /*
+        * 2. Write our commands into the queue
+        * Dependency ordering from the cmpxchg() loop above.
+        */
+       arm_smmu_cmdq_write_entries(cmdq, cmds, llq.prod, n);
+       if (sync) {
+               prod = queue_inc_prod_n(&llq, n);
+               arm_smmu_cmdq_build_sync_cmd(cmd_sync, smmu, prod);
+               queue_write(Q_ENT(&cmdq->q, prod), cmd_sync, CMDQ_ENT_DWORDS);
+
+               /*
+                * In order to determine completion of our CMD_SYNC, we must
+                * ensure that the queue can't wrap twice without us noticing.
+                * We achieve that by taking the cmdq lock as shared before
+                * marking our slot as valid.
+                */
+               arm_smmu_cmdq_shared_lock(cmdq);
+       }
+
+       /* 3. Mark our slots as valid, ensuring commands are visible first */
+       dma_wmb();
+       arm_smmu_cmdq_set_valid_map(cmdq, llq.prod, head.prod);
+
+       /* 4. If we are the owner, take control of the SMMU hardware */
+       if (owner) {
+               /* a. Wait for previous owner to finish */
+               atomic_cond_read_relaxed(&cmdq->owner_prod, VAL == llq.prod);
+
+               /* b. Stop gathering work by clearing the owned flag */
+               prod = atomic_fetch_andnot_relaxed(CMDQ_PROD_OWNED_FLAG,
+                                                  &cmdq->q.llq.atomic.prod);
+               prod &= ~CMDQ_PROD_OWNED_FLAG;
+
+               /*
+                * c. Wait for any gathered work to be written to the queue.
+                * Note that we read our own entries so that we have the control
+                * dependency required by (d).
+                */
+               arm_smmu_cmdq_poll_valid_map(cmdq, llq.prod, prod);
+
+               /*
+                * d. Advance the hardware prod pointer
+                * Control dependency ordering from the entries becoming valid.
+                */
+               writel_relaxed(prod, cmdq->q.prod_reg);
+
+               /*
+                * e. Tell the next owner we're done
+                * Make sure we've updated the hardware first, so that we don't
+                * race to update prod and potentially move it backwards.
+                */
+               atomic_set_release(&cmdq->owner_prod, prod);
+       }
+
+       /* 5. If we are inserting a CMD_SYNC, we must wait for it to complete */
+       if (sync) {
+               llq.prod = queue_inc_prod_n(&llq, n);
+               ret = arm_smmu_cmdq_poll_until_sync(smmu, &llq);
+               if (ret) {
+                       dev_err_ratelimited(smmu->dev,
+                                           "CMD_SYNC timeout at 0x%08x [hwprod 0x%08x, hwcons 0x%08x]\n",
+                                           llq.prod,
+                                           readl_relaxed(cmdq->q.prod_reg),
+                                           readl_relaxed(cmdq->q.cons_reg));
+               }
+
+               /*
+                * Try to unlock the cmq lock. This will fail if we're the last
+                * reader, in which case we can safely update cmdq->q.llq.cons
+                */
+               if (!arm_smmu_cmdq_shared_tryunlock(cmdq)) {
+                       WRITE_ONCE(cmdq->q.llq.cons, llq.cons);
+                       arm_smmu_cmdq_shared_unlock(cmdq);
+               }
+       }
+
+       local_irq_restore(flags);
        return ret;
 }
 
-static int arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
+static int arm_smmu_cmdq_issue_cmd(struct arm_smmu_device *smmu,
+                                  struct arm_smmu_cmdq_ent *ent)
 {
-       int ret;
-       bool msi = (smmu->features & ARM_SMMU_FEAT_MSI) &&
-                  (smmu->features & ARM_SMMU_FEAT_COHERENCY);
+       u64 cmd[CMDQ_ENT_DWORDS];
 
-       ret = msi ? __arm_smmu_cmdq_issue_sync_msi(smmu)
-                 : __arm_smmu_cmdq_issue_sync(smmu);
-       if (ret)
-               dev_err_ratelimited(smmu->dev, "CMD_SYNC timeout\n");
-       return ret;
+       if (arm_smmu_cmdq_build_cmd(cmd, ent)) {
+               dev_warn(smmu->dev, "ignoring unknown CMDQ opcode 0x%x\n",
+                        ent->opcode);
+               return -EINVAL;
+       }
+
+       return arm_smmu_cmdq_issue_cmdlist(smmu, cmd, 1, false);
+}
+
+static int arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
+{
+       return arm_smmu_cmdq_issue_cmdlist(smmu, NULL, 0, true);
 }
 
 /* Context descriptor manipulation functions */
@@ -1305,6 +1694,7 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev)
        int i;
        struct arm_smmu_device *smmu = dev;
        struct arm_smmu_queue *q = &smmu->evtq.q;
+       struct arm_smmu_ll_queue *llq = &q->llq;
        u64 evt[EVTQ_ENT_DWORDS];
 
        do {
@@ -1322,12 +1712,13 @@ static irqreturn_t arm_smmu_evtq_thread(int irq, void *dev)
                 * Not much we can do on overflow, so scream and pretend we're
                 * trying harder.
                 */
-               if (queue_sync_prod(q) == -EOVERFLOW)
+               if (queue_sync_prod_in(q) == -EOVERFLOW)
                        dev_err(smmu->dev, "EVTQ overflow detected -- events lost\n");
-       } while (!queue_empty(q));
+       } while (!queue_empty(llq));
 
        /* Sync our overflow flag, as we believe we're up to speed */
-       q->cons = Q_OVF(q, q->prod) | Q_WRP(q, q->cons) | Q_IDX(q, q->cons);
+       llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
+                   Q_IDX(llq, llq->cons);
        return IRQ_HANDLED;
 }
 
@@ -1373,19 +1764,21 @@ static irqreturn_t arm_smmu_priq_thread(int irq, void *dev)
 {
        struct arm_smmu_device *smmu = dev;
        struct arm_smmu_queue *q = &smmu->priq.q;
+       struct arm_smmu_ll_queue *llq = &q->llq;
        u64 evt[PRIQ_ENT_DWORDS];
 
        do {
                while (!queue_remove_raw(q, evt))
                        arm_smmu_handle_ppr(smmu, evt);
 
-               if (queue_sync_prod(q) == -EOVERFLOW)
+               if (queue_sync_prod_in(q) == -EOVERFLOW)
                        dev_err(smmu->dev, "PRIQ overflow detected -- requests lost\n");
-       } while (!queue_empty(q));
+       } while (!queue_empty(llq));
 
        /* Sync our overflow flag, as we believe we're up to speed */
-       q->cons = Q_OVF(q, q->prod) | Q_WRP(q, q->cons) | Q_IDX(q, q->cons);
-       writel(q->cons, q->cons_reg);
+       llq->cons = Q_OVF(llq->prod) | Q_WRP(llq, llq->cons) |
+                     Q_IDX(llq, llq->cons);
+       queue_sync_cons_out(q);
        return IRQ_HANDLED;
 }
 
@@ -1534,6 +1927,23 @@ static int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain,
        if (!(smmu_domain->smmu->features & ARM_SMMU_FEAT_ATS))
                return 0;
 
+       /*
+        * Ensure that we've completed prior invalidation of the main TLBs
+        * before we read 'nr_ats_masters' in case of a concurrent call to
+        * arm_smmu_enable_ats():
+        *
+        *      // unmap()                      // arm_smmu_enable_ats()
+        *      TLBI+SYNC                       atomic_inc(&nr_ats_masters);
+        *      smp_mb();                       [...]
+        *      atomic_read(&nr_ats_masters);   pci_enable_ats() // writel()
+        *
+        * Ensures that we always see the incremented 'nr_ats_masters' count if
+        * ATS was enabled at the PCI device before completion of the TLBI.
+        */
+       smp_mb();
+       if (!atomic_read(&smmu_domain->nr_ats_masters))
+               return 0;
+
        arm_smmu_atc_inv_to_cmd(ssid, iova, size, &cmd);
 
        spin_lock_irqsave(&smmu_domain->devices_lock, flags);
@@ -1545,13 +1955,6 @@ static int arm_smmu_atc_inv_domain(struct arm_smmu_domain *smmu_domain,
 }
 
 /* IO_PGTABLE API */
-static void arm_smmu_tlb_sync(void *cookie)
-{
-       struct arm_smmu_domain *smmu_domain = cookie;
-
-       arm_smmu_cmdq_issue_sync(smmu_domain->smmu);
-}
-
 static void arm_smmu_tlb_inv_context(void *cookie)
 {
        struct arm_smmu_domain *smmu_domain = cookie;
@@ -1570,25 +1973,32 @@ static void arm_smmu_tlb_inv_context(void *cookie)
        /*
         * NOTE: when io-pgtable is in non-strict mode, we may get here with
         * PTEs previously cleared by unmaps on the current CPU not yet visible
-        * to the SMMU. We are relying on the DSB implicit in queue_inc_prod()
-        * to guarantee those are observed before the TLBI. Do be careful, 007.
+        * to the SMMU. We are relying on the dma_wmb() implicit during cmd
+        * insertion to guarantee those are observed before the TLBI. Do be
+        * careful, 007.
         */
        arm_smmu_cmdq_issue_cmd(smmu, &cmd);
        arm_smmu_cmdq_issue_sync(smmu);
+       arm_smmu_atc_inv_domain(smmu_domain, 0, 0, 0);
 }
 
-static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
-                                         size_t granule, bool leaf, void *cookie)
+static void arm_smmu_tlb_inv_range(unsigned long iova, size_t size,
+                                  size_t granule, bool leaf,
+                                  struct arm_smmu_domain *smmu_domain)
 {
-       struct arm_smmu_domain *smmu_domain = cookie;
+       u64 cmds[CMDQ_BATCH_ENTRIES * CMDQ_ENT_DWORDS];
        struct arm_smmu_device *smmu = smmu_domain->smmu;
+       unsigned long start = iova, end = iova + size;
+       int i = 0;
        struct arm_smmu_cmdq_ent cmd = {
                .tlbi = {
                        .leaf   = leaf,
-                       .addr   = iova,
                },
        };
 
+       if (!size)
+               return;
+
        if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
                cmd.opcode      = CMDQ_OP_TLBI_NH_VA;
                cmd.tlbi.asid   = smmu_domain->s1_cfg.cd.asid;
@@ -1597,16 +2007,54 @@ static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
                cmd.tlbi.vmid   = smmu_domain->s2_cfg.vmid;
        }
 
-       do {
-               arm_smmu_cmdq_issue_cmd(smmu, &cmd);
-               cmd.tlbi.addr += granule;
-       } while (size -= granule);
+       while (iova < end) {
+               if (i == CMDQ_BATCH_ENTRIES) {
+                       arm_smmu_cmdq_issue_cmdlist(smmu, cmds, i, false);
+                       i = 0;
+               }
+
+               cmd.tlbi.addr = iova;
+               arm_smmu_cmdq_build_cmd(&cmds[i * CMDQ_ENT_DWORDS], &cmd);
+               iova += granule;
+               i++;
+       }
+
+       arm_smmu_cmdq_issue_cmdlist(smmu, cmds, i, true);
+
+       /*
+        * Unfortunately, this can't be leaf-only since we may have
+        * zapped an entire table.
+        */
+       arm_smmu_atc_inv_domain(smmu_domain, 0, start, size);
+}
+
+static void arm_smmu_tlb_inv_page_nosync(struct iommu_iotlb_gather *gather,
+                                        unsigned long iova, size_t granule,
+                                        void *cookie)
+{
+       struct arm_smmu_domain *smmu_domain = cookie;
+       struct iommu_domain *domain = &smmu_domain->domain;
+
+       iommu_iotlb_gather_add_page(domain, gather, iova, granule);
 }
 
-static const struct iommu_gather_ops arm_smmu_gather_ops = {
+static void arm_smmu_tlb_inv_walk(unsigned long iova, size_t size,
+                                 size_t granule, void *cookie)
+{
+       arm_smmu_tlb_inv_range(iova, size, granule, false, cookie);
+}
+
+static void arm_smmu_tlb_inv_leaf(unsigned long iova, size_t size,
+                                 size_t granule, void *cookie)
+{
+       arm_smmu_tlb_inv_range(iova, size, granule, true, cookie);
+}
+
+static const struct iommu_flush_ops arm_smmu_flush_ops = {
        .tlb_flush_all  = arm_smmu_tlb_inv_context,
-       .tlb_add_flush  = arm_smmu_tlb_inv_range_nosync,
-       .tlb_sync       = arm_smmu_tlb_sync,
+       .tlb_flush_walk = arm_smmu_tlb_inv_walk,
+       .tlb_flush_leaf = arm_smmu_tlb_inv_leaf,
+       .tlb_add_page   = arm_smmu_tlb_inv_page_nosync,
 };
 
 /* IOMMU API */
@@ -1796,7 +2244,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
                .ias            = ias,
                .oas            = oas,
                .coherent_walk  = smmu->features & ARM_SMMU_FEAT_COHERENCY,
-               .tlb            = &arm_smmu_gather_ops,
+               .tlb            = &arm_smmu_flush_ops,
                .iommu_dev      = smmu->dev,
        };
 
@@ -1863,44 +2311,65 @@ static void arm_smmu_install_ste_for_dev(struct arm_smmu_master *master)
        }
 }
 
-static int arm_smmu_enable_ats(struct arm_smmu_master *master)
+#ifdef CONFIG_PCI_ATS
+static bool arm_smmu_ats_supported(struct arm_smmu_master *master)
 {
-       int ret;
-       size_t stu;
        struct pci_dev *pdev;
        struct arm_smmu_device *smmu = master->smmu;
        struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(master->dev);
 
        if (!(smmu->features & ARM_SMMU_FEAT_ATS) || !dev_is_pci(master->dev) ||
            !(fwspec->flags & IOMMU_FWSPEC_PCI_RC_ATS) || pci_ats_disabled())
-               return -ENXIO;
+               return false;
 
        pdev = to_pci_dev(master->dev);
-       if (pdev->untrusted)
-               return -EPERM;
+       return !pdev->untrusted && pdev->ats_cap;
+}
+#else
+static bool arm_smmu_ats_supported(struct arm_smmu_master *master)
+{
+       return false;
+}
+#endif
+
+static void arm_smmu_enable_ats(struct arm_smmu_master *master)
+{
+       size_t stu;
+       struct pci_dev *pdev;
+       struct arm_smmu_device *smmu = master->smmu;
+       struct arm_smmu_domain *smmu_domain = master->domain;
+
+       /* Don't enable ATS at the endpoint if it's not enabled in the STE */
+       if (!master->ats_enabled)
+               return;
 
        /* Smallest Translation Unit: log2 of the smallest supported granule */
        stu = __ffs(smmu->pgsize_bitmap);
+       pdev = to_pci_dev(master->dev);
 
-       ret = pci_enable_ats(pdev, stu);
-       if (ret)
-               return ret;
-
-       master->ats_enabled = true;
-       return 0;
+       atomic_inc(&smmu_domain->nr_ats_masters);
+       arm_smmu_atc_inv_domain(smmu_domain, 0, 0, 0);
+       if (pci_enable_ats(pdev, stu))
+               dev_err(master->dev, "Failed to enable ATS (STU %zu)\n", stu);
 }
 
 static void arm_smmu_disable_ats(struct arm_smmu_master *master)
 {
        struct arm_smmu_cmdq_ent cmd;
+       struct arm_smmu_domain *smmu_domain = master->domain;
 
-       if (!master->ats_enabled || !dev_is_pci(master->dev))
+       if (!master->ats_enabled)
                return;
 
+       pci_disable_ats(to_pci_dev(master->dev));
+       /*
+        * Ensure ATS is disabled at the endpoint before we issue the
+        * ATC invalidation via the SMMU.
+        */
+       wmb();
        arm_smmu_atc_inv_to_cmd(0, 0, 0, &cmd);
        arm_smmu_atc_inv_master(master, &cmd);
-       pci_disable_ats(to_pci_dev(master->dev));
-       master->ats_enabled = false;
+       atomic_dec(&smmu_domain->nr_ats_masters);
 }
 
 static void arm_smmu_detach_dev(struct arm_smmu_master *master)
@@ -1911,14 +2380,15 @@ static void arm_smmu_detach_dev(struct arm_smmu_master *master)
        if (!smmu_domain)
                return;
 
+       arm_smmu_disable_ats(master);
+
        spin_lock_irqsave(&smmu_domain->devices_lock, flags);
        list_del(&master->domain_head);
        spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
 
        master->domain = NULL;
+       master->ats_enabled = false;
        arm_smmu_install_ste_for_dev(master);
-
-       arm_smmu_disable_ats(master);
 }
 
 static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
@@ -1958,17 +2428,20 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 
        master->domain = smmu_domain;
 
-       spin_lock_irqsave(&smmu_domain->devices_lock, flags);
-       list_add(&master->domain_head, &smmu_domain->devices);
-       spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
-
        if (smmu_domain->stage != ARM_SMMU_DOMAIN_BYPASS)
-               arm_smmu_enable_ats(master);
+               master->ats_enabled = arm_smmu_ats_supported(master);
 
        if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1)
                arm_smmu_write_ctx_desc(smmu, &smmu_domain->s1_cfg);
 
        arm_smmu_install_ste_for_dev(master);
+
+       spin_lock_irqsave(&smmu_domain->devices_lock, flags);
+       list_add(&master->domain_head, &smmu_domain->devices);
+       spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
+
+       arm_smmu_enable_ats(master);
+
 out_unlock:
        mutex_unlock(&smmu_domain->init_mutex);
        return ret;
@@ -1985,21 +2458,16 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
        return ops->map(ops, iova, paddr, size, prot);
 }
 
-static size_t
-arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
+static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
+                            size_t size, struct iommu_iotlb_gather *gather)
 {
-       int ret;
        struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
        struct io_pgtable_ops *ops = smmu_domain->pgtbl_ops;
 
        if (!ops)
                return 0;
 
-       ret = ops->unmap(ops, iova, size);
-       if (ret && arm_smmu_atc_inv_domain(smmu_domain, 0, iova, size))
-               return 0;
-
-       return ret;
+       return ops->unmap(ops, iova, size, gather);
 }
 
 static void arm_smmu_flush_iotlb_all(struct iommu_domain *domain)
@@ -2010,12 +2478,13 @@ static void arm_smmu_flush_iotlb_all(struct iommu_domain *domain)
                arm_smmu_tlb_inv_context(smmu_domain);
 }
 
-static void arm_smmu_iotlb_sync(struct iommu_domain *domain)
+static void arm_smmu_iotlb_sync(struct iommu_domain *domain,
+                               struct iommu_iotlb_gather *gather)
 {
-       struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
+       struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
 
-       if (smmu)
-               arm_smmu_cmdq_issue_sync(smmu);
+       arm_smmu_tlb_inv_range(gather->start, gather->end - gather->start,
+                              gather->pgsize, true, smmu_domain);
 }
 
 static phys_addr_t
@@ -2286,13 +2755,13 @@ static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
        size_t qsz;
 
        do {
-               qsz = ((1 << q->max_n_shift) * dwords) << 3;
+               qsz = ((1 << q->llq.max_n_shift) * dwords) << 3;
                q->base = dmam_alloc_coherent(smmu->dev, qsz, &q->base_dma,
                                              GFP_KERNEL);
                if (q->base || qsz < PAGE_SIZE)
                        break;
 
-               q->max_n_shift--;
+               q->llq.max_n_shift--;
        } while (1);
 
        if (!q->base) {
@@ -2304,7 +2773,7 @@ static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
 
        if (!WARN_ON(q->base_dma & (qsz - 1))) {
                dev_info(smmu->dev, "allocated %u entries for %s\n",
-                        1 << q->max_n_shift, name);
+                        1 << q->llq.max_n_shift, name);
        }
 
        q->prod_reg     = arm_smmu_page1_fixup(prod_off, smmu);
@@ -2313,24 +2782,55 @@ static int arm_smmu_init_one_queue(struct arm_smmu_device *smmu,
 
        q->q_base  = Q_BASE_RWA;
        q->q_base |= q->base_dma & Q_BASE_ADDR_MASK;
-       q->q_base |= FIELD_PREP(Q_BASE_LOG2SIZE, q->max_n_shift);
+       q->q_base |= FIELD_PREP(Q_BASE_LOG2SIZE, q->llq.max_n_shift);
 
-       q->prod = q->cons = 0;
+       q->llq.prod = q->llq.cons = 0;
        return 0;
 }
 
+static void arm_smmu_cmdq_free_bitmap(void *data)
+{
+       unsigned long *bitmap = data;
+       bitmap_free(bitmap);
+}
+
+static int arm_smmu_cmdq_init(struct arm_smmu_device *smmu)
+{
+       int ret = 0;
+       struct arm_smmu_cmdq *cmdq = &smmu->cmdq;
+       unsigned int nents = 1 << cmdq->q.llq.max_n_shift;
+       atomic_long_t *bitmap;
+
+       atomic_set(&cmdq->owner_prod, 0);
+       atomic_set(&cmdq->lock, 0);
+
+       bitmap = (atomic_long_t *)bitmap_zalloc(nents, GFP_KERNEL);
+       if (!bitmap) {
+               dev_err(smmu->dev, "failed to allocate cmdq bitmap\n");
+               ret = -ENOMEM;
+       } else {
+               cmdq->valid_map = bitmap;
+               devm_add_action(smmu->dev, arm_smmu_cmdq_free_bitmap, bitmap);
+       }
+
+       return ret;
+}
+
 static int arm_smmu_init_queues(struct arm_smmu_device *smmu)
 {
        int ret;
 
        /* cmdq */
-       spin_lock_init(&smmu->cmdq.lock);
        ret = arm_smmu_init_one_queue(smmu, &smmu->cmdq.q, ARM_SMMU_CMDQ_PROD,
                                      ARM_SMMU_CMDQ_CONS, CMDQ_ENT_DWORDS,
                                      "cmdq");
        if (ret)
                return ret;
 
+       ret = arm_smmu_cmdq_init(smmu);
+       if (ret)
+               return ret;
+
        /* evtq */
        ret = arm_smmu_init_one_queue(smmu, &smmu->evtq.q, ARM_SMMU_EVTQ_PROD,
                                      ARM_SMMU_EVTQ_CONS, EVTQ_ENT_DWORDS,
@@ -2708,8 +3208,8 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 
        /* Command queue */
        writeq_relaxed(smmu->cmdq.q.q_base, smmu->base + ARM_SMMU_CMDQ_BASE);
-       writel_relaxed(smmu->cmdq.q.prod, smmu->base + ARM_SMMU_CMDQ_PROD);
-       writel_relaxed(smmu->cmdq.q.cons, smmu->base + ARM_SMMU_CMDQ_CONS);
+       writel_relaxed(smmu->cmdq.q.llq.prod, smmu->base + ARM_SMMU_CMDQ_PROD);
+       writel_relaxed(smmu->cmdq.q.llq.cons, smmu->base + ARM_SMMU_CMDQ_CONS);
 
        enables = CR0_CMDQEN;
        ret = arm_smmu_write_reg_sync(smmu, enables, ARM_SMMU_CR0,
@@ -2736,9 +3236,9 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
 
        /* Event queue */
        writeq_relaxed(smmu->evtq.q.q_base, smmu->base + ARM_SMMU_EVTQ_BASE);
-       writel_relaxed(smmu->evtq.q.prod,
+       writel_relaxed(smmu->evtq.q.llq.prod,
                       arm_smmu_page1_fixup(ARM_SMMU_EVTQ_PROD, smmu));
-       writel_relaxed(smmu->evtq.q.cons,
+       writel_relaxed(smmu->evtq.q.llq.cons,
                       arm_smmu_page1_fixup(ARM_SMMU_EVTQ_CONS, smmu));
 
        enables |= CR0_EVTQEN;
@@ -2753,9 +3253,9 @@ static int arm_smmu_device_reset(struct arm_smmu_device *smmu, bool bypass)
        if (smmu->features & ARM_SMMU_FEAT_PRI) {
                writeq_relaxed(smmu->priq.q.q_base,
                               smmu->base + ARM_SMMU_PRIQ_BASE);
-               writel_relaxed(smmu->priq.q.prod,
+               writel_relaxed(smmu->priq.q.llq.prod,
                               arm_smmu_page1_fixup(ARM_SMMU_PRIQ_PROD, smmu));
-               writel_relaxed(smmu->priq.q.cons,
+               writel_relaxed(smmu->priq.q.llq.cons,
                               arm_smmu_page1_fixup(ARM_SMMU_PRIQ_CONS, smmu));
 
                enables |= CR0_PRIQEN;
@@ -2909,18 +3409,24 @@ static int arm_smmu_device_hw_probe(struct arm_smmu_device *smmu)
        }
 
        /* Queue sizes, capped to ensure natural alignment */
-       smmu->cmdq.q.max_n_shift = min_t(u32, CMDQ_MAX_SZ_SHIFT,
-                                        FIELD_GET(IDR1_CMDQS, reg));
-       if (!smmu->cmdq.q.max_n_shift) {
-               /* Odd alignment restrictions on the base, so ignore for now */
-               dev_err(smmu->dev, "unit-length command queue not supported\n");
+       smmu->cmdq.q.llq.max_n_shift = min_t(u32, CMDQ_MAX_SZ_SHIFT,
+                                            FIELD_GET(IDR1_CMDQS, reg));
+       if (smmu->cmdq.q.llq.max_n_shift <= ilog2(CMDQ_BATCH_ENTRIES)) {
+               /*
+                * We don't support splitting up batches, so one batch of
+                * commands plus an extra sync needs to fit inside the command
+                * queue. There's also no way we can handle the weird alignment
+                * restrictions on the base pointer for a unit-length queue.
+                */
+               dev_err(smmu->dev, "command queue size <= %d entries not supported\n",
+                       CMDQ_BATCH_ENTRIES);
                return -ENXIO;
        }
 
-       smmu->evtq.q.max_n_shift = min_t(u32, EVTQ_MAX_SZ_SHIFT,
-                                        FIELD_GET(IDR1_EVTQS, reg));
-       smmu->priq.q.max_n_shift = min_t(u32, PRIQ_MAX_SZ_SHIFT,
-                                        FIELD_GET(IDR1_PRIQS, reg));
+       smmu->evtq.q.llq.max_n_shift = min_t(u32, EVTQ_MAX_SZ_SHIFT,
+                                            FIELD_GET(IDR1_EVTQS, reg));
+       smmu->priq.q.llq.max_n_shift = min_t(u32, PRIQ_MAX_SZ_SHIFT,
+                                            FIELD_GET(IDR1_PRIQS, reg));
 
        /* SID/SSID sizes */
        smmu->ssid_bits = FIELD_GET(IDR1_SSIDSIZE, reg);
index 64977c1..5b93c79 100644 (file)
 
 #include <linux/acpi.h>
 #include <linux/acpi_iort.h>
-#include <linux/atomic.h>
+#include <linux/bitfield.h>
 #include <linux/delay.h>
 #include <linux/dma-iommu.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
-#include <linux/io-64-nonatomic-hi-lo.h>
-#include <linux/io-pgtable.h>
-#include <linux/iommu.h>
 #include <linux/iopoll.h>
 #include <linux/init.h>
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
-#include <linux/spinlock.h>
 
 #include <linux/amba/bus.h>
 #include <linux/fsl/mc.h>
 
-#include "arm-smmu-regs.h"
+#include "arm-smmu.h"
 
 /*
  * Apparently, some Qualcomm arm64 platforms which appear to expose their SMMU
  */
 #define QCOM_DUMMY_VAL -1
 
-#define ARM_MMU500_ACTLR_CPRE          (1 << 1)
-
-#define ARM_MMU500_ACR_CACHE_LOCK      (1 << 26)
-#define ARM_MMU500_ACR_S2CRB_TLBEN     (1 << 10)
-#define ARM_MMU500_ACR_SMTNMB_TLBEN    (1 << 8)
-
 #define TLB_LOOP_TIMEOUT               1000000 /* 1s! */
 #define TLB_SPIN_COUNT                 10
 
-/* Maximum number of context banks per SMMU */
-#define ARM_SMMU_MAX_CBS               128
-
-/* SMMU global address space */
-#define ARM_SMMU_GR0(smmu)             ((smmu)->base)
-#define ARM_SMMU_GR1(smmu)             ((smmu)->base + (1 << (smmu)->pgshift))
-
-/*
- * SMMU global address space with conditional offset to access secure
- * aliases of non-secure registers (e.g. nsCR0: 0x400, nsGFSR: 0x448,
- * nsGFSYNR0: 0x450)
- */
-#define ARM_SMMU_GR0_NS(smmu)                                          \
-       ((smmu)->base +                                                 \
-               ((smmu->options & ARM_SMMU_OPT_SECURE_CFG_ACCESS)       \
-                       ? 0x400 : 0))
-
-/*
- * Some 64-bit registers only make sense to write atomically, but in such
- * cases all the data relevant to AArch32 formats lies within the lower word,
- * therefore this actually makes more sense than it might first appear.
- */
-#ifdef CONFIG_64BIT
-#define smmu_write_atomic_lq           writeq_relaxed
-#else
-#define smmu_write_atomic_lq           writel_relaxed
-#endif
-
-/* Translation context bank */
-#define ARM_SMMU_CB(smmu, n)   ((smmu)->cb_base + ((n) << (smmu)->pgshift))
-
 #define MSI_IOVA_BASE                  0x8000000
 #define MSI_IOVA_LENGTH                        0x100000
 
@@ -113,19 +72,6 @@ module_param(disable_bypass, bool, S_IRUGO);
 MODULE_PARM_DESC(disable_bypass,
        "Disable bypass streams such that incoming transactions from devices that are not attached to an iommu domain will report an abort back to the device and will not be allowed to pass through the SMMU.");
 
-enum arm_smmu_arch_version {
-       ARM_SMMU_V1,
-       ARM_SMMU_V1_64K,
-       ARM_SMMU_V2,
-};
-
-enum arm_smmu_implementation {
-       GENERIC_SMMU,
-       ARM_MMU500,
-       CAVIUM_SMMUV2,
-       QCOM_SMMUV2,
-};
-
 struct arm_smmu_s2cr {
        struct iommu_group              *group;
        int                             count;
@@ -163,117 +109,8 @@ struct arm_smmu_master_cfg {
 #define for_each_cfg_sme(fw, i, idx) \
        for (i = 0; idx = fwspec_smendx(fw, i), i < fw->num_ids; ++i)
 
-struct arm_smmu_device {
-       struct device                   *dev;
-
-       void __iomem                    *base;
-       void __iomem                    *cb_base;
-       unsigned long                   pgshift;
-
-#define ARM_SMMU_FEAT_COHERENT_WALK    (1 << 0)
-#define ARM_SMMU_FEAT_STREAM_MATCH     (1 << 1)
-#define ARM_SMMU_FEAT_TRANS_S1         (1 << 2)
-#define ARM_SMMU_FEAT_TRANS_S2         (1 << 3)
-#define ARM_SMMU_FEAT_TRANS_NESTED     (1 << 4)
-#define ARM_SMMU_FEAT_TRANS_OPS                (1 << 5)
-#define ARM_SMMU_FEAT_VMID16           (1 << 6)
-#define ARM_SMMU_FEAT_FMT_AARCH64_4K   (1 << 7)
-#define ARM_SMMU_FEAT_FMT_AARCH64_16K  (1 << 8)
-#define ARM_SMMU_FEAT_FMT_AARCH64_64K  (1 << 9)
-#define ARM_SMMU_FEAT_FMT_AARCH32_L    (1 << 10)
-#define ARM_SMMU_FEAT_FMT_AARCH32_S    (1 << 11)
-#define ARM_SMMU_FEAT_EXIDS            (1 << 12)
-       u32                             features;
-
-#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0)
-       u32                             options;
-       enum arm_smmu_arch_version      version;
-       enum arm_smmu_implementation    model;
-
-       u32                             num_context_banks;
-       u32                             num_s2_context_banks;
-       DECLARE_BITMAP(context_map, ARM_SMMU_MAX_CBS);
-       struct arm_smmu_cb              *cbs;
-       atomic_t                        irptndx;
-
-       u32                             num_mapping_groups;
-       u16                             streamid_mask;
-       u16                             smr_mask_mask;
-       struct arm_smmu_smr             *smrs;
-       struct arm_smmu_s2cr            *s2crs;
-       struct mutex                    stream_map_mutex;
-
-       unsigned long                   va_size;
-       unsigned long                   ipa_size;
-       unsigned long                   pa_size;
-       unsigned long                   pgsize_bitmap;
-
-       u32                             num_global_irqs;
-       u32                             num_context_irqs;
-       unsigned int                    *irqs;
-       struct clk_bulk_data            *clks;
-       int                             num_clks;
-
-       u32                             cavium_id_base; /* Specific to Cavium */
-
-       spinlock_t                      global_sync_lock;
-
-       /* IOMMU core code handle */
-       struct iommu_device             iommu;
-};
-
-enum arm_smmu_context_fmt {
-       ARM_SMMU_CTX_FMT_NONE,
-       ARM_SMMU_CTX_FMT_AARCH64,
-       ARM_SMMU_CTX_FMT_AARCH32_L,
-       ARM_SMMU_CTX_FMT_AARCH32_S,
-};
-
-struct arm_smmu_cfg {
-       u8                              cbndx;
-       u8                              irptndx;
-       union {
-               u16                     asid;
-               u16                     vmid;
-       };
-       u32                             cbar;
-       enum arm_smmu_context_fmt       fmt;
-};
-#define INVALID_IRPTNDX                        0xff
-
-enum arm_smmu_domain_stage {
-       ARM_SMMU_DOMAIN_S1 = 0,
-       ARM_SMMU_DOMAIN_S2,
-       ARM_SMMU_DOMAIN_NESTED,
-       ARM_SMMU_DOMAIN_BYPASS,
-};
-
-struct arm_smmu_domain {
-       struct arm_smmu_device          *smmu;
-       struct io_pgtable_ops           *pgtbl_ops;
-       const struct iommu_gather_ops   *tlb_ops;
-       struct arm_smmu_cfg             cfg;
-       enum arm_smmu_domain_stage      stage;
-       bool                            non_strict;
-       struct mutex                    init_mutex; /* Protects smmu pointer */
-       spinlock_t                      cb_lock; /* Serialises ATS1* ops and TLB syncs */
-       struct iommu_domain             domain;
-};
-
-struct arm_smmu_option_prop {
-       u32 opt;
-       const char *prop;
-};
-
-static atomic_t cavium_smmu_context_count = ATOMIC_INIT(0);
-
 static bool using_legacy_binding, using_generic_binding;
 
-static struct arm_smmu_option_prop arm_smmu_options[] = {
-       { ARM_SMMU_OPT_SECURE_CFG_ACCESS, "calxeda,smmu-secure-config-access" },
-       { 0, NULL},
-};
-
 static inline int arm_smmu_rpm_get(struct arm_smmu_device *smmu)
 {
        if (pm_runtime_enabled(smmu->dev))
@@ -293,20 +130,6 @@ static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
        return container_of(dom, struct arm_smmu_domain, domain);
 }
 
-static void parse_driver_options(struct arm_smmu_device *smmu)
-{
-       int i = 0;
-
-       do {
-               if (of_property_read_bool(smmu->dev->of_node,
-                                               arm_smmu_options[i].prop)) {
-                       smmu->options |= arm_smmu_options[i].opt;
-                       dev_notice(smmu->dev, "option %s\n",
-                               arm_smmu_options[i].prop);
-               }
-       } while (arm_smmu_options[++i].opt);
-}
-
 static struct device_node *dev_get_dev_node(struct device *dev)
 {
        if (dev_is_pci(dev)) {
@@ -415,15 +238,17 @@ static void __arm_smmu_free_bitmap(unsigned long *map, int idx)
 }
 
 /* Wait for any pending TLB invalidations to complete */
-static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu,
-                               void __iomem *sync, void __iomem *status)
+static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, int page,
+                               int sync, int status)
 {
        unsigned int spin_cnt, delay;
+       u32 reg;
 
-       writel_relaxed(QCOM_DUMMY_VAL, sync);
+       arm_smmu_writel(smmu, page, sync, QCOM_DUMMY_VAL);
        for (delay = 1; delay < TLB_LOOP_TIMEOUT; delay *= 2) {
                for (spin_cnt = TLB_SPIN_COUNT; spin_cnt > 0; spin_cnt--) {
-                       if (!(readl_relaxed(status) & sTLBGSTATUS_GSACTIVE))
+                       reg = arm_smmu_readl(smmu, page, status);
+                       if (!(reg & sTLBGSTATUS_GSACTIVE))
                                return;
                        cpu_relax();
                }
@@ -435,12 +260,11 @@ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu,
 
 static void arm_smmu_tlb_sync_global(struct arm_smmu_device *smmu)
 {
-       void __iomem *base = ARM_SMMU_GR0(smmu);
        unsigned long flags;
 
        spin_lock_irqsave(&smmu->global_sync_lock, flags);
-       __arm_smmu_tlb_sync(smmu, base + ARM_SMMU_GR0_sTLBGSYNC,
-                           base + ARM_SMMU_GR0_sTLBGSTATUS);
+       __arm_smmu_tlb_sync(smmu, ARM_SMMU_GR0, ARM_SMMU_GR0_sTLBGSYNC,
+                           ARM_SMMU_GR0_sTLBGSTATUS);
        spin_unlock_irqrestore(&smmu->global_sync_lock, flags);
 }
 
@@ -448,12 +272,11 @@ static void arm_smmu_tlb_sync_context(void *cookie)
 {
        struct arm_smmu_domain *smmu_domain = cookie;
        struct arm_smmu_device *smmu = smmu_domain->smmu;
-       void __iomem *base = ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx);
        unsigned long flags;
 
        spin_lock_irqsave(&smmu_domain->cb_lock, flags);
-       __arm_smmu_tlb_sync(smmu, base + ARM_SMMU_CB_TLBSYNC,
-                           base + ARM_SMMU_CB_TLBSTATUS);
+       __arm_smmu_tlb_sync(smmu, ARM_SMMU_CB(smmu, smmu_domain->cfg.cbndx),
+                           ARM_SMMU_CB_TLBSYNC, ARM_SMMU_CB_TLBSTATUS);
        spin_unlock_irqrestore(&smmu_domain->cb_lock, flags);
 }
 
@@ -467,14 +290,13 @@ static void arm_smmu_tlb_sync_vmid(void *cookie)
 static void arm_smmu_tlb_inv_context_s1(void *cookie)
 {
        struct arm_smmu_domain *smmu_domain = cookie;
-       struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
-       void __iomem *base = ARM_SMMU_CB(smmu_domain->smmu, cfg->cbndx);
-
        /*
-        * NOTE: this is not a relaxed write; it needs to guarantee that PTEs
-        * cleared by the current CPU are visible to the SMMU before the TLBI.
+        * The TLBI write may be relaxed, so ensure that PTEs cleared by the
+        * current CPU are visible beforehand.
         */
-       writel(cfg->asid, base + ARM_SMMU_CB_S1_TLBIASID);
+       wmb();
+       arm_smmu_cb_write(smmu_domain->smmu, smmu_domain->cfg.cbndx,
+                         ARM_SMMU_CB_S1_TLBIASID, smmu_domain->cfg.asid);
        arm_smmu_tlb_sync_context(cookie);
 }
 
@@ -482,87 +304,143 @@ static void arm_smmu_tlb_inv_context_s2(void *cookie)
 {
        struct arm_smmu_domain *smmu_domain = cookie;
        struct arm_smmu_device *smmu = smmu_domain->smmu;
-       void __iomem *base = ARM_SMMU_GR0(smmu);
 
-       /* NOTE: see above */
-       writel(smmu_domain->cfg.vmid, base + ARM_SMMU_GR0_TLBIVMID);
+       /* See above */
+       wmb();
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_TLBIVMID, smmu_domain->cfg.vmid);
        arm_smmu_tlb_sync_global(smmu);
 }
 
-static void arm_smmu_tlb_inv_range_nosync(unsigned long iova, size_t size,
-                                         size_t granule, bool leaf, void *cookie)
+static void arm_smmu_tlb_inv_range_s1(unsigned long iova, size_t size,
+                                     size_t granule, bool leaf, void *cookie)
 {
        struct arm_smmu_domain *smmu_domain = cookie;
+       struct arm_smmu_device *smmu = smmu_domain->smmu;
        struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
-       bool stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
-       void __iomem *reg = ARM_SMMU_CB(smmu_domain->smmu, cfg->cbndx);
+       int reg, idx = cfg->cbndx;
 
-       if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
+       if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
                wmb();
 
-       if (stage1) {
-               reg += leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA;
-
-               if (cfg->fmt != ARM_SMMU_CTX_FMT_AARCH64) {
-                       iova &= ~12UL;
-                       iova |= cfg->asid;
-                       do {
-                               writel_relaxed(iova, reg);
-                               iova += granule;
-                       } while (size -= granule);
-               } else {
-                       iova >>= 12;
-                       iova |= (u64)cfg->asid << 48;
-                       do {
-                               writeq_relaxed(iova, reg);
-                               iova += granule >> 12;
-                       } while (size -= granule);
-               }
+       reg = leaf ? ARM_SMMU_CB_S1_TLBIVAL : ARM_SMMU_CB_S1_TLBIVA;
+
+       if (cfg->fmt != ARM_SMMU_CTX_FMT_AARCH64) {
+               iova = (iova >> 12) << 12;
+               iova |= cfg->asid;
+               do {
+                       arm_smmu_cb_write(smmu, idx, reg, iova);
+                       iova += granule;
+               } while (size -= granule);
        } else {
-               reg += leaf ? ARM_SMMU_CB_S2_TLBIIPAS2L :
-                             ARM_SMMU_CB_S2_TLBIIPAS2;
                iova >>= 12;
+               iova |= (u64)cfg->asid << 48;
                do {
-                       smmu_write_atomic_lq(iova, reg);
+                       arm_smmu_cb_writeq(smmu, idx, reg, iova);
                        iova += granule >> 12;
                } while (size -= granule);
        }
 }
 
+static void arm_smmu_tlb_inv_range_s2(unsigned long iova, size_t size,
+                                     size_t granule, bool leaf, void *cookie)
+{
+       struct arm_smmu_domain *smmu_domain = cookie;
+       struct arm_smmu_device *smmu = smmu_domain->smmu;
+       int reg, idx = smmu_domain->cfg.cbndx;
+
+       if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
+               wmb();
+
+       reg = leaf ? ARM_SMMU_CB_S2_TLBIIPAS2L : ARM_SMMU_CB_S2_TLBIIPAS2;
+       iova >>= 12;
+       do {
+               if (smmu_domain->cfg.fmt == ARM_SMMU_CTX_FMT_AARCH64)
+                       arm_smmu_cb_writeq(smmu, idx, reg, iova);
+               else
+                       arm_smmu_cb_write(smmu, idx, reg, iova);
+               iova += granule >> 12;
+       } while (size -= granule);
+}
+
 /*
  * On MMU-401 at least, the cost of firing off multiple TLBIVMIDs appears
  * almost negligible, but the benefit of getting the first one in as far ahead
  * of the sync as possible is significant, hence we don't just make this a
- * no-op and set .tlb_sync to arm_smmu_inv_context_s2() as you might think.
+ * no-op and set .tlb_sync to arm_smmu_tlb_inv_context_s2() as you might think.
  */
 static void arm_smmu_tlb_inv_vmid_nosync(unsigned long iova, size_t size,
                                         size_t granule, bool leaf, void *cookie)
 {
        struct arm_smmu_domain *smmu_domain = cookie;
-       void __iomem *base = ARM_SMMU_GR0(smmu_domain->smmu);
+       struct arm_smmu_device *smmu = smmu_domain->smmu;
 
-       if (smmu_domain->smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
+       if (smmu->features & ARM_SMMU_FEAT_COHERENT_WALK)
                wmb();
 
-       writel_relaxed(smmu_domain->cfg.vmid, base + ARM_SMMU_GR0_TLBIVMID);
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_TLBIVMID, smmu_domain->cfg.vmid);
+}
+
+static void arm_smmu_tlb_inv_walk(unsigned long iova, size_t size,
+                                 size_t granule, void *cookie)
+{
+       struct arm_smmu_domain *smmu_domain = cookie;
+       const struct arm_smmu_flush_ops *ops = smmu_domain->flush_ops;
+
+       ops->tlb_inv_range(iova, size, granule, false, cookie);
+       ops->tlb_sync(cookie);
+}
+
+static void arm_smmu_tlb_inv_leaf(unsigned long iova, size_t size,
+                                 size_t granule, void *cookie)
+{
+       struct arm_smmu_domain *smmu_domain = cookie;
+       const struct arm_smmu_flush_ops *ops = smmu_domain->flush_ops;
+
+       ops->tlb_inv_range(iova, size, granule, true, cookie);
+       ops->tlb_sync(cookie);
+}
+
+static void arm_smmu_tlb_add_page(struct iommu_iotlb_gather *gather,
+                                 unsigned long iova, size_t granule,
+                                 void *cookie)
+{
+       struct arm_smmu_domain *smmu_domain = cookie;
+       const struct arm_smmu_flush_ops *ops = smmu_domain->flush_ops;
+
+       ops->tlb_inv_range(iova, granule, granule, true, cookie);
 }
 
-static const struct iommu_gather_ops arm_smmu_s1_tlb_ops = {
-       .tlb_flush_all  = arm_smmu_tlb_inv_context_s1,
-       .tlb_add_flush  = arm_smmu_tlb_inv_range_nosync,
-       .tlb_sync       = arm_smmu_tlb_sync_context,
+static const struct arm_smmu_flush_ops arm_smmu_s1_tlb_ops = {
+       .tlb = {
+               .tlb_flush_all  = arm_smmu_tlb_inv_context_s1,
+               .tlb_flush_walk = arm_smmu_tlb_inv_walk,
+               .tlb_flush_leaf = arm_smmu_tlb_inv_leaf,
+               .tlb_add_page   = arm_smmu_tlb_add_page,
+       },
+       .tlb_inv_range          = arm_smmu_tlb_inv_range_s1,
+       .tlb_sync               = arm_smmu_tlb_sync_context,
 };
 
-static const struct iommu_gather_ops arm_smmu_s2_tlb_ops_v2 = {
-       .tlb_flush_all  = arm_smmu_tlb_inv_context_s2,
-       .tlb_add_flush  = arm_smmu_tlb_inv_range_nosync,
-       .tlb_sync       = arm_smmu_tlb_sync_context,
+static const struct arm_smmu_flush_ops arm_smmu_s2_tlb_ops_v2 = {
+       .tlb = {
+               .tlb_flush_all  = arm_smmu_tlb_inv_context_s2,
+               .tlb_flush_walk = arm_smmu_tlb_inv_walk,
+               .tlb_flush_leaf = arm_smmu_tlb_inv_leaf,
+               .tlb_add_page   = arm_smmu_tlb_add_page,
+       },
+       .tlb_inv_range          = arm_smmu_tlb_inv_range_s2,
+       .tlb_sync               = arm_smmu_tlb_sync_context,
 };
 
-static const struct iommu_gather_ops arm_smmu_s2_tlb_ops_v1 = {
-       .tlb_flush_all  = arm_smmu_tlb_inv_context_s2,
-       .tlb_add_flush  = arm_smmu_tlb_inv_vmid_nosync,
-       .tlb_sync       = arm_smmu_tlb_sync_vmid,
+static const struct arm_smmu_flush_ops arm_smmu_s2_tlb_ops_v1 = {
+       .tlb = {
+               .tlb_flush_all  = arm_smmu_tlb_inv_context_s2,
+               .tlb_flush_walk = arm_smmu_tlb_inv_walk,
+               .tlb_flush_leaf = arm_smmu_tlb_inv_leaf,
+               .tlb_add_page   = arm_smmu_tlb_add_page,
+       },
+       .tlb_inv_range          = arm_smmu_tlb_inv_vmid_nosync,
+       .tlb_sync               = arm_smmu_tlb_sync_vmid,
 };
 
 static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
@@ -571,26 +449,22 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
        unsigned long iova;
        struct iommu_domain *domain = dev;
        struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
-       struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
        struct arm_smmu_device *smmu = smmu_domain->smmu;
-       void __iomem *gr1_base = ARM_SMMU_GR1(smmu);
-       void __iomem *cb_base;
-
-       cb_base = ARM_SMMU_CB(smmu, cfg->cbndx);
-       fsr = readl_relaxed(cb_base + ARM_SMMU_CB_FSR);
+       int idx = smmu_domain->cfg.cbndx;
 
+       fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
        if (!(fsr & FSR_FAULT))
                return IRQ_NONE;
 
-       fsynr = readl_relaxed(cb_base + ARM_SMMU_CB_FSYNR0);
-       iova = readq_relaxed(cb_base + ARM_SMMU_CB_FAR);
-       cbfrsynra = readl_relaxed(gr1_base + ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx));
+       fsynr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSYNR0);
+       iova = arm_smmu_cb_readq(smmu, idx, ARM_SMMU_CB_FAR);
+       cbfrsynra = arm_smmu_gr1_read(smmu, ARM_SMMU_GR1_CBFRSYNRA(idx));
 
        dev_err_ratelimited(smmu->dev,
        "Unhandled context fault: fsr=0x%x, iova=0x%08lx, fsynr=0x%x, cbfrsynra=0x%x, cb=%d\n",
-                           fsr, iova, fsynr, cbfrsynra, cfg->cbndx);
+                           fsr, iova, fsynr, cbfrsynra, idx);
 
-       writel(fsr, cb_base + ARM_SMMU_CB_FSR);
+       arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_FSR, fsr);
        return IRQ_HANDLED;
 }
 
@@ -598,12 +472,11 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
 {
        u32 gfsr, gfsynr0, gfsynr1, gfsynr2;
        struct arm_smmu_device *smmu = dev;
-       void __iomem *gr0_base = ARM_SMMU_GR0_NS(smmu);
 
-       gfsr = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSR);
-       gfsynr0 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR0);
-       gfsynr1 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR1);
-       gfsynr2 = readl_relaxed(gr0_base + ARM_SMMU_GR0_sGFSYNR2);
+       gfsr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSR);
+       gfsynr0 = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSYNR0);
+       gfsynr1 = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSYNR1);
+       gfsynr2 = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSYNR2);
 
        if (!gfsr)
                return IRQ_NONE;
@@ -614,7 +487,7 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
                "\tGFSR 0x%08x, GFSYNR0 0x%08x, GFSYNR1 0x%08x, GFSYNR2 0x%08x\n",
                gfsr, gfsynr0, gfsynr1, gfsynr2);
 
-       writel(gfsr, gr0_base + ARM_SMMU_GR0_sGFSR);
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sGFSR, gfsr);
        return IRQ_HANDLED;
 }
 
@@ -627,16 +500,16 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
 
        cb->cfg = cfg;
 
-       /* TTBCR */
+       /* TCR */
        if (stage1) {
                if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
                        cb->tcr[0] = pgtbl_cfg->arm_v7s_cfg.tcr;
                } else {
                        cb->tcr[0] = pgtbl_cfg->arm_lpae_s1_cfg.tcr;
                        cb->tcr[1] = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32;
-                       cb->tcr[1] |= TTBCR2_SEP_UPSTREAM;
+                       cb->tcr[1] |= FIELD_PREP(TCR2_SEP, TCR2_SEP_UPSTREAM);
                        if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
-                               cb->tcr[1] |= TTBCR2_AS;
+                               cb->tcr[1] |= TCR2_AS;
                }
        } else {
                cb->tcr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
@@ -649,9 +522,9 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
                        cb->ttbr[1] = pgtbl_cfg->arm_v7s_cfg.ttbr[1];
                } else {
                        cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
-                       cb->ttbr[0] |= (u64)cfg->asid << TTBRn_ASID_SHIFT;
+                       cb->ttbr[0] |= FIELD_PREP(TTBRn_ASID, cfg->asid);
                        cb->ttbr[1] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
-                       cb->ttbr[1] |= (u64)cfg->asid << TTBRn_ASID_SHIFT;
+                       cb->ttbr[1] |= FIELD_PREP(TTBRn_ASID, cfg->asid);
                }
        } else {
                cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
@@ -675,74 +548,71 @@ static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx)
        bool stage1;
        struct arm_smmu_cb *cb = &smmu->cbs[idx];
        struct arm_smmu_cfg *cfg = cb->cfg;
-       void __iomem *cb_base, *gr1_base;
-
-       cb_base = ARM_SMMU_CB(smmu, idx);
 
        /* Unassigned context banks only need disabling */
        if (!cfg) {
-               writel_relaxed(0, cb_base + ARM_SMMU_CB_SCTLR);
+               arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, 0);
                return;
        }
 
-       gr1_base = ARM_SMMU_GR1(smmu);
        stage1 = cfg->cbar != CBAR_TYPE_S2_TRANS;
 
        /* CBA2R */
        if (smmu->version > ARM_SMMU_V1) {
                if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
-                       reg = CBA2R_RW64_64BIT;
+                       reg = CBA2R_VA64;
                else
-                       reg = CBA2R_RW64_32BIT;
+                       reg = 0;
                /* 16-bit VMIDs live in CBA2R */
                if (smmu->features & ARM_SMMU_FEAT_VMID16)
-                       reg |= cfg->vmid << CBA2R_VMID_SHIFT;
+                       reg |= FIELD_PREP(CBA2R_VMID16, cfg->vmid);
 
-               writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBA2R(idx));
+               arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBA2R(idx), reg);
        }
 
        /* CBAR */
-       reg = cfg->cbar;
+       reg = FIELD_PREP(CBAR_TYPE, cfg->cbar);
        if (smmu->version < ARM_SMMU_V2)
-               reg |= cfg->irptndx << CBAR_IRPTNDX_SHIFT;
+               reg |= FIELD_PREP(CBAR_IRPTNDX, cfg->irptndx);
 
        /*
         * Use the weakest shareability/memory types, so they are
         * overridden by the ttbcr/pte.
         */
        if (stage1) {
-               reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) |
-                       (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
+               reg |= FIELD_PREP(CBAR_S1_BPSHCFG, CBAR_S1_BPSHCFG_NSH) |
+                       FIELD_PREP(CBAR_S1_MEMATTR, CBAR_S1_MEMATTR_WB);
        } else if (!(smmu->features & ARM_SMMU_FEAT_VMID16)) {
                /* 8-bit VMIDs live in CBAR */
-               reg |= cfg->vmid << CBAR_VMID_SHIFT;
+               reg |= FIELD_PREP(CBAR_VMID, cfg->vmid);
        }
-       writel_relaxed(reg, gr1_base + ARM_SMMU_GR1_CBAR(idx));
+       arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(idx), reg);
 
        /*
-        * TTBCR
+        * TCR
         * We must write this before the TTBRs, since it determines the
         * access behaviour of some fields (in particular, ASID[15:8]).
         */
        if (stage1 && smmu->version > ARM_SMMU_V1)
-               writel_relaxed(cb->tcr[1], cb_base + ARM_SMMU_CB_TTBCR2);
-       writel_relaxed(cb->tcr[0], cb_base + ARM_SMMU_CB_TTBCR);
+               arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_TCR2, cb->tcr[1]);
+       arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_TCR, cb->tcr[0]);
 
        /* TTBRs */
        if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
-               writel_relaxed(cfg->asid, cb_base + ARM_SMMU_CB_CONTEXTIDR);
-               writel_relaxed(cb->ttbr[0], cb_base + ARM_SMMU_CB_TTBR0);
-               writel_relaxed(cb->ttbr[1], cb_base + ARM_SMMU_CB_TTBR1);
+               arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_CONTEXTIDR, cfg->asid);
+               arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_TTBR0, cb->ttbr[0]);
+               arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_TTBR1, cb->ttbr[1]);
        } else {
-               writeq_relaxed(cb->ttbr[0], cb_base + ARM_SMMU_CB_TTBR0);
+               arm_smmu_cb_writeq(smmu, idx, ARM_SMMU_CB_TTBR0, cb->ttbr[0]);
                if (stage1)
-                       writeq_relaxed(cb->ttbr[1], cb_base + ARM_SMMU_CB_TTBR1);
+                       arm_smmu_cb_writeq(smmu, idx, ARM_SMMU_CB_TTBR1,
+                                          cb->ttbr[1]);
        }
 
        /* MAIRs (stage-1 only) */
        if (stage1) {
-               writel_relaxed(cb->mair[0], cb_base + ARM_SMMU_CB_S1_MAIR0);
-               writel_relaxed(cb->mair[1], cb_base + ARM_SMMU_CB_S1_MAIR1);
+               arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_S1_MAIR0, cb->mair[0]);
+               arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_S1_MAIR1, cb->mair[1]);
        }
 
        /* SCTLR */
@@ -752,7 +622,7 @@ static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx)
        if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
                reg |= SCTLR_E;
 
-       writel_relaxed(reg, cb_base + ARM_SMMU_CB_SCTLR);
+       arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, reg);
 }
 
 static int arm_smmu_init_domain_context(struct iommu_domain *domain,
@@ -842,7 +712,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
                        ias = min(ias, 32UL);
                        oas = min(oas, 32UL);
                }
-               smmu_domain->tlb_ops = &arm_smmu_s1_tlb_ops;
+               smmu_domain->flush_ops = &arm_smmu_s1_tlb_ops;
                break;
        case ARM_SMMU_DOMAIN_NESTED:
                /*
@@ -862,9 +732,9 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
                        oas = min(oas, 40UL);
                }
                if (smmu->version == ARM_SMMU_V2)
-                       smmu_domain->tlb_ops = &arm_smmu_s2_tlb_ops_v2;
+                       smmu_domain->flush_ops = &arm_smmu_s2_tlb_ops_v2;
                else
-                       smmu_domain->tlb_ops = &arm_smmu_s2_tlb_ops_v1;
+                       smmu_domain->flush_ops = &arm_smmu_s2_tlb_ops_v1;
                break;
        default:
                ret = -EINVAL;
@@ -884,23 +754,29 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
        }
 
        if (smmu_domain->stage == ARM_SMMU_DOMAIN_S2)
-               cfg->vmid = cfg->cbndx + 1 + smmu->cavium_id_base;
+               cfg->vmid = cfg->cbndx + 1;
        else
-               cfg->asid = cfg->cbndx + smmu->cavium_id_base;
+               cfg->asid = cfg->cbndx;
+
+       smmu_domain->smmu = smmu;
+       if (smmu->impl && smmu->impl->init_context) {
+               ret = smmu->impl->init_context(smmu_domain);
+               if (ret)
+                       goto out_unlock;
+       }
 
        pgtbl_cfg = (struct io_pgtable_cfg) {
                .pgsize_bitmap  = smmu->pgsize_bitmap,
                .ias            = ias,
                .oas            = oas,
                .coherent_walk  = smmu->features & ARM_SMMU_FEAT_COHERENT_WALK,
-               .tlb            = smmu_domain->tlb_ops,
+               .tlb            = &smmu_domain->flush_ops->tlb,
                .iommu_dev      = smmu->dev,
        };
 
        if (smmu_domain->non_strict)
                pgtbl_cfg.quirks |= IO_PGTABLE_QUIRK_NON_STRICT;
 
-       smmu_domain->smmu = smmu;
        pgtbl_ops = alloc_io_pgtable_ops(fmt, &pgtbl_cfg, smmu_domain);
        if (!pgtbl_ops) {
                ret = -ENOMEM;
@@ -1019,24 +895,24 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
 static void arm_smmu_write_smr(struct arm_smmu_device *smmu, int idx)
 {
        struct arm_smmu_smr *smr = smmu->smrs + idx;
-       u32 reg = smr->id << SMR_ID_SHIFT | smr->mask << SMR_MASK_SHIFT;
+       u32 reg = FIELD_PREP(SMR_ID, smr->id) | FIELD_PREP(SMR_MASK, smr->mask);
 
        if (!(smmu->features & ARM_SMMU_FEAT_EXIDS) && smr->valid)
                reg |= SMR_VALID;
-       writel_relaxed(reg, ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_SMR(idx));
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_SMR(idx), reg);
 }
 
 static void arm_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
 {
        struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
-       u32 reg = (s2cr->type & S2CR_TYPE_MASK) << S2CR_TYPE_SHIFT |
-                 (s2cr->cbndx & S2CR_CBNDX_MASK) << S2CR_CBNDX_SHIFT |
-                 (s2cr->privcfg & S2CR_PRIVCFG_MASK) << S2CR_PRIVCFG_SHIFT;
+       u32 reg = FIELD_PREP(S2CR_TYPE, s2cr->type) |
+                 FIELD_PREP(S2CR_CBNDX, s2cr->cbndx) |
+                 FIELD_PREP(S2CR_PRIVCFG, s2cr->privcfg);
 
        if (smmu->features & ARM_SMMU_FEAT_EXIDS && smmu->smrs &&
            smmu->smrs[idx].valid)
                reg |= S2CR_EXIDVALID;
-       writel_relaxed(reg, ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_S2CR(idx));
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_S2CR(idx), reg);
 }
 
 static void arm_smmu_write_sme(struct arm_smmu_device *smmu, int idx)
@@ -1052,7 +928,6 @@ static void arm_smmu_write_sme(struct arm_smmu_device *smmu, int idx)
  */
 static void arm_smmu_test_smr_masks(struct arm_smmu_device *smmu)
 {
-       void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
        u32 smr;
 
        if (!smmu->smrs)
@@ -1063,15 +938,15 @@ static void arm_smmu_test_smr_masks(struct arm_smmu_device *smmu)
         * bits are set, so check each one separately. We can reject
         * masters later if they try to claim IDs outside these masks.
         */
-       smr = smmu->streamid_mask << SMR_ID_SHIFT;
-       writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
-       smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
-       smmu->streamid_mask = smr >> SMR_ID_SHIFT;
+       smr = FIELD_PREP(SMR_ID, smmu->streamid_mask);
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_SMR(0), smr);
+       smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(0));
+       smmu->streamid_mask = FIELD_GET(SMR_ID, smr);
 
-       smr = smmu->streamid_mask << SMR_MASK_SHIFT;
-       writel_relaxed(smr, gr0_base + ARM_SMMU_GR0_SMR(0));
-       smr = readl_relaxed(gr0_base + ARM_SMMU_GR0_SMR(0));
-       smmu->smr_mask_mask = smr >> SMR_MASK_SHIFT;
+       smr = FIELD_PREP(SMR_MASK, smmu->streamid_mask);
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_SMR(0), smr);
+       smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(0));
+       smmu->smr_mask_mask = FIELD_GET(SMR_MASK, smr);
 }
 
 static int arm_smmu_find_sme(struct arm_smmu_device *smmu, u16 id, u16 mask)
@@ -1140,8 +1015,8 @@ static int arm_smmu_master_alloc_smes(struct device *dev)
        mutex_lock(&smmu->stream_map_mutex);
        /* Figure out a viable stream map entry allocation */
        for_each_cfg_sme(fwspec, i, idx) {
-               u16 sid = fwspec->ids[i];
-               u16 mask = fwspec->ids[i] >> SMR_MASK_SHIFT;
+               u16 sid = FIELD_GET(SMR_ID, fwspec->ids[i]);
+               u16 mask = FIELD_GET(SMR_MASK, fwspec->ids[i]);
 
                if (idx != INVALID_SMENDX) {
                        ret = -EEXIST;
@@ -1301,7 +1176,7 @@ static int arm_smmu_map(struct iommu_domain *domain, unsigned long iova,
 }
 
 static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
-                            size_t size)
+                            size_t size, struct iommu_iotlb_gather *gather)
 {
        struct io_pgtable_ops *ops = to_smmu_domain(domain)->pgtbl_ops;
        struct arm_smmu_device *smmu = to_smmu_domain(domain)->smmu;
@@ -1311,7 +1186,7 @@ static size_t arm_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
                return 0;
 
        arm_smmu_rpm_get(smmu);
-       ret = ops->unmap(ops, iova, size);
+       ret = ops->unmap(ops, iova, size, gather);
        arm_smmu_rpm_put(smmu);
 
        return ret;
@@ -1322,21 +1197,22 @@ static void arm_smmu_flush_iotlb_all(struct iommu_domain *domain)
        struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
        struct arm_smmu_device *smmu = smmu_domain->smmu;
 
-       if (smmu_domain->tlb_ops) {
+       if (smmu_domain->flush_ops) {
                arm_smmu_rpm_get(smmu);
-               smmu_domain->tlb_ops->tlb_flush_all(smmu_domain);
+               smmu_domain->flush_ops->tlb.tlb_flush_all(smmu_domain);
                arm_smmu_rpm_put(smmu);
        }
 }
 
-static void arm_smmu_iotlb_sync(struct iommu_domain *domain)
+static void arm_smmu_iotlb_sync(struct iommu_domain *domain,
+                               struct iommu_iotlb_gather *gather)
 {
        struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
        struct arm_smmu_device *smmu = smmu_domain->smmu;
 
-       if (smmu_domain->tlb_ops) {
+       if (smmu_domain->flush_ops) {
                arm_smmu_rpm_get(smmu);
-               smmu_domain->tlb_ops->tlb_sync(smmu_domain);
+               smmu_domain->flush_ops->tlb_sync(smmu_domain);
                arm_smmu_rpm_put(smmu);
        }
 }
@@ -1349,28 +1225,25 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
        struct arm_smmu_cfg *cfg = &smmu_domain->cfg;
        struct io_pgtable_ops *ops= smmu_domain->pgtbl_ops;
        struct device *dev = smmu->dev;
-       void __iomem *cb_base;
+       void __iomem *reg;
        u32 tmp;
        u64 phys;
        unsigned long va, flags;
-       int ret;
+       int ret, idx = cfg->cbndx;
 
        ret = arm_smmu_rpm_get(smmu);
        if (ret < 0)
                return 0;
 
-       cb_base = ARM_SMMU_CB(smmu, cfg->cbndx);
-
        spin_lock_irqsave(&smmu_domain->cb_lock, flags);
-       /* ATS1 registers can only be written atomically */
        va = iova & ~0xfffUL;
-       if (smmu->version == ARM_SMMU_V2)
-               smmu_write_atomic_lq(va, cb_base + ARM_SMMU_CB_ATS1PR);
-       else /* Register is only 32-bit in v1 */
-               writel_relaxed(va, cb_base + ARM_SMMU_CB_ATS1PR);
+       if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
+               arm_smmu_cb_writeq(smmu, idx, ARM_SMMU_CB_ATS1PR, va);
+       else
+               arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_ATS1PR, va);
 
-       if (readl_poll_timeout_atomic(cb_base + ARM_SMMU_CB_ATSR, tmp,
-                                     !(tmp & ATSR_ACTIVE), 5, 50)) {
+       reg = arm_smmu_page(smmu, ARM_SMMU_CB(smmu, idx)) + ARM_SMMU_CB_ATSR;
+       if (readl_poll_timeout_atomic(reg, tmp, !(tmp & ATSR_ACTIVE), 5, 50)) {
                spin_unlock_irqrestore(&smmu_domain->cb_lock, flags);
                dev_err(dev,
                        "iova to phys timed out on %pad. Falling back to software table walk.\n",
@@ -1378,7 +1251,7 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
                return ops->iova_to_phys(ops, iova);
        }
 
-       phys = readq_relaxed(cb_base + ARM_SMMU_CB_PAR);
+       phys = arm_smmu_cb_readq(smmu, idx, ARM_SMMU_CB_PAR);
        spin_unlock_irqrestore(&smmu_domain->cb_lock, flags);
        if (phys & CB_PAR_F) {
                dev_err(dev, "translation fault!\n");
@@ -1466,8 +1339,8 @@ static int arm_smmu_add_device(struct device *dev)
 
        ret = -EINVAL;
        for (i = 0; i < fwspec->num_ids; i++) {
-               u16 sid = fwspec->ids[i];
-               u16 mask = fwspec->ids[i] >> SMR_MASK_SHIFT;
+               u16 sid = FIELD_GET(SMR_ID, fwspec->ids[i]);
+               u16 mask = FIELD_GET(SMR_MASK, fwspec->ids[i]);
 
                if (sid & ~smmu->streamid_mask) {
                        dev_err(dev, "stream ID 0x%x out of range for SMMU (0x%x)\n",
@@ -1648,12 +1521,12 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
        u32 mask, fwid = 0;
 
        if (args->args_count > 0)
-               fwid |= (u16)args->args[0];
+               fwid |= FIELD_PREP(SMR_ID, args->args[0]);
 
        if (args->args_count > 1)
-               fwid |= (u16)args->args[1] << SMR_MASK_SHIFT;
+               fwid |= FIELD_PREP(SMR_MASK, args->args[1]);
        else if (!of_property_read_u32(args->np, "stream-match-mask", &mask))
-               fwid |= (u16)mask << SMR_MASK_SHIFT;
+               fwid |= FIELD_PREP(SMR_MASK, mask);
 
        return iommu_fwspec_add_ids(dev, &fwid, 1);
 }
@@ -1706,13 +1579,12 @@ static struct iommu_ops arm_smmu_ops = {
 
 static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
 {
-       void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
        int i;
-       u32 reg, major;
+       u32 reg;
 
        /* clear global FSR */
-       reg = readl_relaxed(ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR);
-       writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sGFSR);
+       reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sGFSR);
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sGFSR, reg);
 
        /*
         * Reset stream mapping groups: Initial values mark all SMRn as
@@ -1721,47 +1593,17 @@ 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);
 
-       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);
-               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 | ARM_MMU500_ACR_S2CRB_TLBEN;
-               writel_relaxed(reg, gr0_base + ARM_SMMU_GR0_sACR);
-       }
-
        /* Make sure all context banks are disabled and clear CB_FSR  */
        for (i = 0; i < smmu->num_context_banks; ++i) {
-               void __iomem *cb_base = ARM_SMMU_CB(smmu, i);
-
                arm_smmu_write_context_bank(smmu, i);
-               writel_relaxed(FSR_FAULT, cb_base + ARM_SMMU_CB_FSR);
-               /*
-                * Disable MMU-500's not-particularly-beneficial next-page
-                * prefetcher for the sake of errata #841119 and #826419.
-                */
-               if (smmu->model == ARM_MMU500) {
-                       reg = readl_relaxed(cb_base + ARM_SMMU_CB_ACTLR);
-                       reg &= ~ARM_MMU500_ACTLR_CPRE;
-                       writel_relaxed(reg, cb_base + ARM_SMMU_CB_ACTLR);
-               }
+               arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_FSR, FSR_FAULT);
        }
 
        /* Invalidate the TLB, just in case */
-       writel_relaxed(QCOM_DUMMY_VAL, gr0_base + ARM_SMMU_GR0_TLBIALLH);
-       writel_relaxed(QCOM_DUMMY_VAL, gr0_base + ARM_SMMU_GR0_TLBIALLNSNH);
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_TLBIALLH, QCOM_DUMMY_VAL);
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_TLBIALLNSNH, QCOM_DUMMY_VAL);
 
-       reg = readl_relaxed(ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
+       reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sCR0);
 
        /* Enable fault reporting */
        reg |= (sCR0_GFRE | sCR0_GFIE | sCR0_GCFGFRE | sCR0_GCFGFIE);
@@ -1780,7 +1622,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
        reg &= ~sCR0_FB;
 
        /* Don't upgrade barriers */
-       reg &= ~(sCR0_BSU_MASK << sCR0_BSU_SHIFT);
+       reg &= ~(sCR0_BSU);
 
        if (smmu->features & ARM_SMMU_FEAT_VMID16)
                reg |= sCR0_VMID16EN;
@@ -1788,9 +1630,12 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
        if (smmu->features & ARM_SMMU_FEAT_EXIDS)
                reg |= sCR0_EXIDENABLE;
 
+       if (smmu->impl && smmu->impl->reset)
+               smmu->impl->reset(smmu);
+
        /* Push the button */
        arm_smmu_tlb_sync_global(smmu);
-       writel(reg, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sCR0, reg);
 }
 
 static int arm_smmu_id_size_to_bits(int size)
@@ -1814,8 +1659,7 @@ static int arm_smmu_id_size_to_bits(int size)
 
 static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 {
-       unsigned long size;
-       void __iomem *gr0_base = ARM_SMMU_GR0(smmu);
+       unsigned int size;
        u32 id;
        bool cttw_reg, cttw_fw = smmu->features & ARM_SMMU_FEAT_COHERENT_WALK;
        int i;
@@ -1825,7 +1669,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
                        smmu->version == ARM_SMMU_V2 ? 2 : 1);
 
        /* ID0 */
-       id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID0);
+       id = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_ID0);
 
        /* Restrict available stages based on module parameter */
        if (force_stage == 1)
@@ -1879,12 +1723,12 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
                smmu->features |= ARM_SMMU_FEAT_EXIDS;
                size = 1 << 16;
        } else {
-               size = 1 << ((id >> ID0_NUMSIDB_SHIFT) & ID0_NUMSIDB_MASK);
+               size = 1 << FIELD_GET(ID0_NUMSIDB, id);
        }
        smmu->streamid_mask = size - 1;
        if (id & ID0_SMS) {
                smmu->features |= ARM_SMMU_FEAT_STREAM_MATCH;
-               size = (id >> ID0_NUMSMRG_SHIFT) & ID0_NUMSMRG_MASK;
+               size = FIELD_GET(ID0_NUMSMRG, id);
                if (size == 0) {
                        dev_err(smmu->dev,
                                "stream-matching supported, but no SMRs present!\n");
@@ -1898,7 +1742,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
                        return -ENOMEM;
 
                dev_notice(smmu->dev,
-                          "\tstream matching with %lu register groups", size);
+                          "\tstream matching with %u register groups", size);
        }
        /* s2cr->type == 0 means translation, so initialise explicitly */
        smmu->s2crs = devm_kmalloc_array(smmu->dev, size, sizeof(*smmu->s2crs),
@@ -1919,49 +1763,38 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
        }
 
        /* ID1 */
-       id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID1);
+       id = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_ID1);
        smmu->pgshift = (id & ID1_PAGESIZE) ? 16 : 12;
 
        /* Check for size mismatch of SMMU address space from mapped region */
-       size = 1 << (((id >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1);
-       size <<= smmu->pgshift;
-       if (smmu->cb_base != gr0_base + size)
+       size = 1 << (FIELD_GET(ID1_NUMPAGENDXB, id) + 1);
+       if (smmu->numpage != 2 * size << smmu->pgshift)
                dev_warn(smmu->dev,
-                       "SMMU address space size (0x%lx) differs from mapped region size (0x%tx)!\n",
-                       size * 2, (smmu->cb_base - gr0_base) * 2);
+                       "SMMU address space size (0x%x) differs from mapped region size (0x%x)!\n",
+                       2 * size << smmu->pgshift, smmu->numpage);
+       /* Now properly encode NUMPAGE to subsequently derive SMMU_CB_BASE */
+       smmu->numpage = size;
 
-       smmu->num_s2_context_banks = (id >> ID1_NUMS2CB_SHIFT) & ID1_NUMS2CB_MASK;
-       smmu->num_context_banks = (id >> ID1_NUMCB_SHIFT) & ID1_NUMCB_MASK;
+       smmu->num_s2_context_banks = FIELD_GET(ID1_NUMS2CB, id);
+       smmu->num_context_banks = FIELD_GET(ID1_NUMCB, id);
        if (smmu->num_s2_context_banks > smmu->num_context_banks) {
                dev_err(smmu->dev, "impossible number of S2 context banks!\n");
                return -ENODEV;
        }
        dev_notice(smmu->dev, "\t%u context banks (%u stage-2 only)\n",
                   smmu->num_context_banks, smmu->num_s2_context_banks);
-       /*
-        * Cavium CN88xx erratum #27704.
-        * Ensure ASID and VMID allocation is unique across all SMMUs in
-        * the system.
-        */
-       if (smmu->model == CAVIUM_SMMUV2) {
-               smmu->cavium_id_base =
-                       atomic_add_return(smmu->num_context_banks,
-                                         &cavium_smmu_context_count);
-               smmu->cavium_id_base -= smmu->num_context_banks;
-               dev_notice(smmu->dev, "\tenabling workaround for Cavium erratum 27704\n");
-       }
        smmu->cbs = devm_kcalloc(smmu->dev, smmu->num_context_banks,
                                 sizeof(*smmu->cbs), GFP_KERNEL);
        if (!smmu->cbs)
                return -ENOMEM;
 
        /* ID2 */
-       id = readl_relaxed(gr0_base + ARM_SMMU_GR0_ID2);
-       size = arm_smmu_id_size_to_bits((id >> ID2_IAS_SHIFT) & ID2_IAS_MASK);
+       id = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_ID2);
+       size = arm_smmu_id_size_to_bits(FIELD_GET(ID2_IAS, id));
        smmu->ipa_size = size;
 
        /* The output mask is also applied for bypass */
-       size = arm_smmu_id_size_to_bits((id >> ID2_OAS_SHIFT) & ID2_OAS_MASK);
+       size = arm_smmu_id_size_to_bits(FIELD_GET(ID2_OAS, id));
        smmu->pa_size = size;
 
        if (id & ID2_VMID16)
@@ -1981,7 +1814,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
                if (smmu->version == ARM_SMMU_V1_64K)
                        smmu->features |= ARM_SMMU_FEAT_FMT_AARCH64_64K;
        } else {
-               size = (id >> ID2_UBS_SHIFT) & ID2_UBS_MASK;
+               size = FIELD_GET(ID2_UBS, id);
                smmu->va_size = arm_smmu_id_size_to_bits(size);
                if (id & ID2_PTFS_4K)
                        smmu->features |= ARM_SMMU_FEAT_FMT_AARCH64_4K;
@@ -2018,6 +1851,9 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
                dev_notice(smmu->dev, "\tStage-2: %lu-bit IPA -> %lu-bit PA\n",
                           smmu->ipa_size, smmu->pa_size);
 
+       if (smmu->impl && smmu->impl->cfg_probe)
+               return smmu->impl->cfg_probe(smmu);
+
        return 0;
 }
 
@@ -2130,8 +1966,6 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
        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)
@@ -2194,12 +2028,20 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
        if (err)
                return err;
 
+       smmu = arm_smmu_impl_init(smmu);
+       if (IS_ERR(smmu))
+               return PTR_ERR(smmu);
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        ioaddr = res->start;
        smmu->base = devm_ioremap_resource(dev, res);
        if (IS_ERR(smmu->base))
                return PTR_ERR(smmu->base);
-       smmu->cb_base = smmu->base + resource_size(res) / 2;
+       /*
+        * The resource size should effectively match the value of SMMU_TOP;
+        * stash that temporarily until we know PAGESIZE to validate it with.
+        */
+       smmu->numpage = resource_size(res);
 
        num_irqs = 0;
        while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, num_irqs))) {
@@ -2339,7 +2181,7 @@ static void arm_smmu_device_shutdown(struct platform_device *pdev)
 
        arm_smmu_rpm_get(smmu);
        /* Turn the thing off */
-       writel(sCR0_CLIENTPD, ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0);
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sCR0, sCR0_CLIENTPD);
        arm_smmu_rpm_put(smmu);
 
        if (pm_runtime_enabled(smmu->dev))
diff --git a/drivers/iommu/arm-smmu.h b/drivers/iommu/arm-smmu.h
new file mode 100644 (file)
index 0000000..b19b6ca
--- /dev/null
@@ -0,0 +1,402 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * IOMMU API for ARM architected SMMU implementations.
+ *
+ * Copyright (C) 2013 ARM Limited
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#ifndef _ARM_SMMU_H
+#define _ARM_SMMU_H
+
+#include <linux/atomic.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/io-64-nonatomic-hi-lo.h>
+#include <linux/io-pgtable.h>
+#include <linux/iommu.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+/* Configuration registers */
+#define ARM_SMMU_GR0_sCR0              0x0
+#define sCR0_VMID16EN                  BIT(31)
+#define sCR0_BSU                       GENMASK(15, 14)
+#define sCR0_FB                                BIT(13)
+#define sCR0_PTM                       BIT(12)
+#define sCR0_VMIDPNE                   BIT(11)
+#define sCR0_USFCFG                    BIT(10)
+#define sCR0_GCFGFIE                   BIT(5)
+#define sCR0_GCFGFRE                   BIT(4)
+#define sCR0_EXIDENABLE                        BIT(3)
+#define sCR0_GFIE                      BIT(2)
+#define sCR0_GFRE                      BIT(1)
+#define sCR0_CLIENTPD                  BIT(0)
+
+/* Auxiliary Configuration register */
+#define ARM_SMMU_GR0_sACR              0x10
+
+/* Identification registers */
+#define ARM_SMMU_GR0_ID0               0x20
+#define ID0_S1TS                       BIT(30)
+#define ID0_S2TS                       BIT(29)
+#define ID0_NTS                                BIT(28)
+#define ID0_SMS                                BIT(27)
+#define ID0_ATOSNS                     BIT(26)
+#define ID0_PTFS_NO_AARCH32            BIT(25)
+#define ID0_PTFS_NO_AARCH32S           BIT(24)
+#define ID0_NUMIRPT                    GENMASK(23, 16)
+#define ID0_CTTW                       BIT(14)
+#define ID0_NUMSIDB                    GENMASK(12, 9)
+#define ID0_EXIDS                      BIT(8)
+#define ID0_NUMSMRG                    GENMASK(7, 0)
+
+#define ARM_SMMU_GR0_ID1               0x24
+#define ID1_PAGESIZE                   BIT(31)
+#define ID1_NUMPAGENDXB                        GENMASK(30, 28)
+#define ID1_NUMS2CB                    GENMASK(23, 16)
+#define ID1_NUMCB                      GENMASK(7, 0)
+
+#define ARM_SMMU_GR0_ID2               0x28
+#define ID2_VMID16                     BIT(15)
+#define ID2_PTFS_64K                   BIT(14)
+#define ID2_PTFS_16K                   BIT(13)
+#define ID2_PTFS_4K                    BIT(12)
+#define ID2_UBS                                GENMASK(11, 8)
+#define ID2_OAS                                GENMASK(7, 4)
+#define ID2_IAS                                GENMASK(3, 0)
+
+#define ARM_SMMU_GR0_ID3               0x2c
+#define ARM_SMMU_GR0_ID4               0x30
+#define ARM_SMMU_GR0_ID5               0x34
+#define ARM_SMMU_GR0_ID6               0x38
+
+#define ARM_SMMU_GR0_ID7               0x3c
+#define ID7_MAJOR                      GENMASK(7, 4)
+#define ID7_MINOR                      GENMASK(3, 0)
+
+#define ARM_SMMU_GR0_sGFSR             0x48
+#define ARM_SMMU_GR0_sGFSYNR0          0x50
+#define ARM_SMMU_GR0_sGFSYNR1          0x54
+#define ARM_SMMU_GR0_sGFSYNR2          0x58
+
+/* Global TLB invalidation */
+#define ARM_SMMU_GR0_TLBIVMID          0x64
+#define ARM_SMMU_GR0_TLBIALLNSNH       0x68
+#define ARM_SMMU_GR0_TLBIALLH          0x6c
+#define ARM_SMMU_GR0_sTLBGSYNC         0x70
+
+#define ARM_SMMU_GR0_sTLBGSTATUS       0x74
+#define sTLBGSTATUS_GSACTIVE           BIT(0)
+
+/* Stream mapping registers */
+#define ARM_SMMU_GR0_SMR(n)            (0x800 + ((n) << 2))
+#define SMR_VALID                      BIT(31)
+#define SMR_MASK                       GENMASK(31, 16)
+#define SMR_ID                         GENMASK(15, 0)
+
+#define ARM_SMMU_GR0_S2CR(n)           (0xc00 + ((n) << 2))
+#define S2CR_PRIVCFG                   GENMASK(25, 24)
+enum arm_smmu_s2cr_privcfg {
+       S2CR_PRIVCFG_DEFAULT,
+       S2CR_PRIVCFG_DIPAN,
+       S2CR_PRIVCFG_UNPRIV,
+       S2CR_PRIVCFG_PRIV,
+};
+#define S2CR_TYPE                      GENMASK(17, 16)
+enum arm_smmu_s2cr_type {
+       S2CR_TYPE_TRANS,
+       S2CR_TYPE_BYPASS,
+       S2CR_TYPE_FAULT,
+};
+#define S2CR_EXIDVALID                 BIT(10)
+#define S2CR_CBNDX                     GENMASK(7, 0)
+
+/* Context bank attribute registers */
+#define ARM_SMMU_GR1_CBAR(n)           (0x0 + ((n) << 2))
+#define CBAR_IRPTNDX                   GENMASK(31, 24)
+#define CBAR_TYPE                      GENMASK(17, 16)
+enum arm_smmu_cbar_type {
+       CBAR_TYPE_S2_TRANS,
+       CBAR_TYPE_S1_TRANS_S2_BYPASS,
+       CBAR_TYPE_S1_TRANS_S2_FAULT,
+       CBAR_TYPE_S1_TRANS_S2_TRANS,
+};
+#define CBAR_S1_MEMATTR                        GENMASK(15, 12)
+#define CBAR_S1_MEMATTR_WB             0xf
+#define CBAR_S1_BPSHCFG                        GENMASK(9, 8)
+#define CBAR_S1_BPSHCFG_NSH            3
+#define CBAR_VMID                      GENMASK(7, 0)
+
+#define ARM_SMMU_GR1_CBFRSYNRA(n)      (0x400 + ((n) << 2))
+
+#define ARM_SMMU_GR1_CBA2R(n)          (0x800 + ((n) << 2))
+#define CBA2R_VMID16                   GENMASK(31, 16)
+#define CBA2R_VA64                     BIT(0)
+
+#define ARM_SMMU_CB_SCTLR              0x0
+#define SCTLR_S1_ASIDPNE               BIT(12)
+#define SCTLR_CFCFG                    BIT(7)
+#define SCTLR_CFIE                     BIT(6)
+#define SCTLR_CFRE                     BIT(5)
+#define SCTLR_E                                BIT(4)
+#define SCTLR_AFE                      BIT(2)
+#define SCTLR_TRE                      BIT(1)
+#define SCTLR_M                                BIT(0)
+
+#define ARM_SMMU_CB_ACTLR              0x4
+
+#define ARM_SMMU_CB_RESUME             0x8
+#define RESUME_TERMINATE               BIT(0)
+
+#define ARM_SMMU_CB_TCR2               0x10
+#define TCR2_SEP                       GENMASK(17, 15)
+#define TCR2_SEP_UPSTREAM              0x7
+#define TCR2_AS                                BIT(4)
+
+#define ARM_SMMU_CB_TTBR0              0x20
+#define ARM_SMMU_CB_TTBR1              0x28
+#define TTBRn_ASID                     GENMASK_ULL(63, 48)
+
+#define ARM_SMMU_CB_TCR                        0x30
+#define ARM_SMMU_CB_CONTEXTIDR         0x34
+#define ARM_SMMU_CB_S1_MAIR0           0x38
+#define ARM_SMMU_CB_S1_MAIR1           0x3c
+
+#define ARM_SMMU_CB_PAR                        0x50
+#define CB_PAR_F                       BIT(0)
+
+#define ARM_SMMU_CB_FSR                        0x58
+#define FSR_MULTI                      BIT(31)
+#define FSR_SS                         BIT(30)
+#define FSR_UUT                                BIT(8)
+#define FSR_ASF                                BIT(7)
+#define FSR_TLBLKF                     BIT(6)
+#define FSR_TLBMCF                     BIT(5)
+#define FSR_EF                         BIT(4)
+#define FSR_PF                         BIT(3)
+#define FSR_AFF                                BIT(2)
+#define FSR_TF                         BIT(1)
+
+#define FSR_IGN                                (FSR_AFF | FSR_ASF | \
+                                        FSR_TLBMCF | FSR_TLBLKF)
+#define FSR_FAULT                      (FSR_MULTI | FSR_SS | FSR_UUT | \
+                                        FSR_EF | FSR_PF | FSR_TF | FSR_IGN)
+
+#define ARM_SMMU_CB_FAR                        0x60
+
+#define ARM_SMMU_CB_FSYNR0             0x68
+#define FSYNR0_WNR                     BIT(4)
+
+#define ARM_SMMU_CB_S1_TLBIVA          0x600
+#define ARM_SMMU_CB_S1_TLBIASID                0x610
+#define ARM_SMMU_CB_S1_TLBIVAL         0x620
+#define ARM_SMMU_CB_S2_TLBIIPAS2       0x630
+#define ARM_SMMU_CB_S2_TLBIIPAS2L      0x638
+#define ARM_SMMU_CB_TLBSYNC            0x7f0
+#define ARM_SMMU_CB_TLBSTATUS          0x7f4
+#define ARM_SMMU_CB_ATS1PR             0x800
+
+#define ARM_SMMU_CB_ATSR               0x8f0
+#define ATSR_ACTIVE                    BIT(0)
+
+
+/* Maximum number of context banks per SMMU */
+#define ARM_SMMU_MAX_CBS               128
+
+
+/* Shared driver definitions */
+enum arm_smmu_arch_version {
+       ARM_SMMU_V1,
+       ARM_SMMU_V1_64K,
+       ARM_SMMU_V2,
+};
+
+enum arm_smmu_implementation {
+       GENERIC_SMMU,
+       ARM_MMU500,
+       CAVIUM_SMMUV2,
+       QCOM_SMMUV2,
+};
+
+struct arm_smmu_device {
+       struct device                   *dev;
+
+       void __iomem                    *base;
+       unsigned int                    numpage;
+       unsigned int                    pgshift;
+
+#define ARM_SMMU_FEAT_COHERENT_WALK    (1 << 0)
+#define ARM_SMMU_FEAT_STREAM_MATCH     (1 << 1)
+#define ARM_SMMU_FEAT_TRANS_S1         (1 << 2)
+#define ARM_SMMU_FEAT_TRANS_S2         (1 << 3)
+#define ARM_SMMU_FEAT_TRANS_NESTED     (1 << 4)
+#define ARM_SMMU_FEAT_TRANS_OPS                (1 << 5)
+#define ARM_SMMU_FEAT_VMID16           (1 << 6)
+#define ARM_SMMU_FEAT_FMT_AARCH64_4K   (1 << 7)
+#define ARM_SMMU_FEAT_FMT_AARCH64_16K  (1 << 8)
+#define ARM_SMMU_FEAT_FMT_AARCH64_64K  (1 << 9)
+#define ARM_SMMU_FEAT_FMT_AARCH32_L    (1 << 10)
+#define ARM_SMMU_FEAT_FMT_AARCH32_S    (1 << 11)
+#define ARM_SMMU_FEAT_EXIDS            (1 << 12)
+       u32                             features;
+
+       enum arm_smmu_arch_version      version;
+       enum arm_smmu_implementation    model;
+       const struct arm_smmu_impl      *impl;
+
+       u32                             num_context_banks;
+       u32                             num_s2_context_banks;
+       DECLARE_BITMAP(context_map, ARM_SMMU_MAX_CBS);
+       struct arm_smmu_cb              *cbs;
+       atomic_t                        irptndx;
+
+       u32                             num_mapping_groups;
+       u16                             streamid_mask;
+       u16                             smr_mask_mask;
+       struct arm_smmu_smr             *smrs;
+       struct arm_smmu_s2cr            *s2crs;
+       struct mutex                    stream_map_mutex;
+
+       unsigned long                   va_size;
+       unsigned long                   ipa_size;
+       unsigned long                   pa_size;
+       unsigned long                   pgsize_bitmap;
+
+       u32                             num_global_irqs;
+       u32                             num_context_irqs;
+       unsigned int                    *irqs;
+       struct clk_bulk_data            *clks;
+       int                             num_clks;
+
+       spinlock_t                      global_sync_lock;
+
+       /* IOMMU core code handle */
+       struct iommu_device             iommu;
+};
+
+enum arm_smmu_context_fmt {
+       ARM_SMMU_CTX_FMT_NONE,
+       ARM_SMMU_CTX_FMT_AARCH64,
+       ARM_SMMU_CTX_FMT_AARCH32_L,
+       ARM_SMMU_CTX_FMT_AARCH32_S,
+};
+
+struct arm_smmu_cfg {
+       u8                              cbndx;
+       u8                              irptndx;
+       union {
+               u16                     asid;
+               u16                     vmid;
+       };
+       enum arm_smmu_cbar_type         cbar;
+       enum arm_smmu_context_fmt       fmt;
+};
+#define INVALID_IRPTNDX                        0xff
+
+enum arm_smmu_domain_stage {
+       ARM_SMMU_DOMAIN_S1 = 0,
+       ARM_SMMU_DOMAIN_S2,
+       ARM_SMMU_DOMAIN_NESTED,
+       ARM_SMMU_DOMAIN_BYPASS,
+};
+
+struct arm_smmu_flush_ops {
+       struct iommu_flush_ops          tlb;
+       void (*tlb_inv_range)(unsigned long iova, size_t size, size_t granule,
+                             bool leaf, void *cookie);
+       void (*tlb_sync)(void *cookie);
+};
+
+struct arm_smmu_domain {
+       struct arm_smmu_device          *smmu;
+       struct io_pgtable_ops           *pgtbl_ops;
+       const struct arm_smmu_flush_ops *flush_ops;
+       struct arm_smmu_cfg             cfg;
+       enum arm_smmu_domain_stage      stage;
+       bool                            non_strict;
+       struct mutex                    init_mutex; /* Protects smmu pointer */
+       spinlock_t                      cb_lock; /* Serialises ATS1* ops and TLB syncs */
+       struct iommu_domain             domain;
+};
+
+
+/* Implementation details, yay! */
+struct arm_smmu_impl {
+       u32 (*read_reg)(struct arm_smmu_device *smmu, int page, int offset);
+       void (*write_reg)(struct arm_smmu_device *smmu, int page, int offset,
+                         u32 val);
+       u64 (*read_reg64)(struct arm_smmu_device *smmu, int page, int offset);
+       void (*write_reg64)(struct arm_smmu_device *smmu, int page, int offset,
+                           u64 val);
+       int (*cfg_probe)(struct arm_smmu_device *smmu);
+       int (*reset)(struct arm_smmu_device *smmu);
+       int (*init_context)(struct arm_smmu_domain *smmu_domain);
+};
+
+static inline void __iomem *arm_smmu_page(struct arm_smmu_device *smmu, int n)
+{
+       return smmu->base + (n << smmu->pgshift);
+}
+
+static inline u32 arm_smmu_readl(struct arm_smmu_device *smmu, int page, int offset)
+{
+       if (smmu->impl && unlikely(smmu->impl->read_reg))
+               return smmu->impl->read_reg(smmu, page, offset);
+       return readl_relaxed(arm_smmu_page(smmu, page) + offset);
+}
+
+static inline void arm_smmu_writel(struct arm_smmu_device *smmu, int page,
+                                  int offset, u32 val)
+{
+       if (smmu->impl && unlikely(smmu->impl->write_reg))
+               smmu->impl->write_reg(smmu, page, offset, val);
+       else
+               writel_relaxed(val, arm_smmu_page(smmu, page) + offset);
+}
+
+static inline u64 arm_smmu_readq(struct arm_smmu_device *smmu, int page, int offset)
+{
+       if (smmu->impl && unlikely(smmu->impl->read_reg64))
+               return smmu->impl->read_reg64(smmu, page, offset);
+       return readq_relaxed(arm_smmu_page(smmu, page) + offset);
+}
+
+static inline void arm_smmu_writeq(struct arm_smmu_device *smmu, int page,
+                                  int offset, u64 val)
+{
+       if (smmu->impl && unlikely(smmu->impl->write_reg64))
+               smmu->impl->write_reg64(smmu, page, offset, val);
+       else
+               writeq_relaxed(val, arm_smmu_page(smmu, page) + offset);
+}
+
+#define ARM_SMMU_GR0           0
+#define ARM_SMMU_GR1           1
+#define ARM_SMMU_CB(s, n)      ((s)->numpage + (n))
+
+#define arm_smmu_gr0_read(s, o)                \
+       arm_smmu_readl((s), ARM_SMMU_GR0, (o))
+#define arm_smmu_gr0_write(s, o, v)    \
+       arm_smmu_writel((s), ARM_SMMU_GR0, (o), (v))
+
+#define arm_smmu_gr1_read(s, o)                \
+       arm_smmu_readl((s), ARM_SMMU_GR1, (o))
+#define arm_smmu_gr1_write(s, o, v)    \
+       arm_smmu_writel((s), ARM_SMMU_GR1, (o), (v))
+
+#define arm_smmu_cb_read(s, n, o)      \
+       arm_smmu_readl((s), ARM_SMMU_CB((s), (n)), (o))
+#define arm_smmu_cb_write(s, n, o, v)  \
+       arm_smmu_writel((s), ARM_SMMU_CB((s), (n)), (o), (v))
+#define arm_smmu_cb_readq(s, n, o)     \
+       arm_smmu_readq((s), ARM_SMMU_CB((s), (n)), (o))
+#define arm_smmu_cb_writeq(s, n, o, v) \
+       arm_smmu_writeq((s), ARM_SMMU_CB((s), (n)), (o), (v))
+
+struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu);
+
+#endif /* _ARM_SMMU_H */
index f68a62c..8f412af 100644 (file)
@@ -303,13 +303,15 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base,
                u64 size, struct device *dev)
 {
        struct iommu_dma_cookie *cookie = domain->iova_cookie;
-       struct iova_domain *iovad = &cookie->iovad;
        unsigned long order, base_pfn;
+       struct iova_domain *iovad;
        int attr;
 
        if (!cookie || cookie->type != IOMMU_DMA_IOVA_COOKIE)
                return -EINVAL;
 
+       iovad = &cookie->iovad;
+
        /* Use the smallest supported page size for IOVA granularity */
        order = __ffs(domain->pgsize_bitmap);
        base_pfn = max_t(unsigned long, 1, base >> order);
@@ -444,13 +446,18 @@ static void __iommu_dma_unmap(struct device *dev, dma_addr_t dma_addr,
        struct iommu_dma_cookie *cookie = domain->iova_cookie;
        struct iova_domain *iovad = &cookie->iovad;
        size_t iova_off = iova_offset(iovad, dma_addr);
+       struct iommu_iotlb_gather iotlb_gather;
+       size_t unmapped;
 
        dma_addr -= iova_off;
        size = iova_align(iovad, size + iova_off);
+       iommu_iotlb_gather_init(&iotlb_gather);
+
+       unmapped = iommu_unmap_fast(domain, dma_addr, size, &iotlb_gather);
+       WARN_ON(unmapped != size);
 
-       WARN_ON(iommu_unmap_fast(domain, dma_addr, size) != size);
        if (!cookie->fq_domain)
-               iommu_tlb_sync(domain);
+               iommu_tlb_sync(domain, &iotlb_gather);
        iommu_dma_free_iova(cookie, dma_addr, size);
 }
 
index 5d0754e..eecd6a4 100644 (file)
@@ -1519,6 +1519,64 @@ static const char *dma_remap_fault_reasons[] =
        "PCE for translation request specifies blocking",
 };
 
+static const char * const dma_remap_sm_fault_reasons[] = {
+       "SM: Invalid Root Table Address",
+       "SM: TTM 0 for request with PASID",
+       "SM: TTM 0 for page group request",
+       "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", /* 0x33-0x37 */
+       "SM: Error attempting to access Root Entry",
+       "SM: Present bit in Root Entry is clear",
+       "SM: Non-zero reserved field set in Root Entry",
+       "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", /* 0x3B-0x3F */
+       "SM: Error attempting to access Context Entry",
+       "SM: Present bit in Context Entry is clear",
+       "SM: Non-zero reserved field set in the Context Entry",
+       "SM: Invalid Context Entry",
+       "SM: DTE field in Context Entry is clear",
+       "SM: PASID Enable field in Context Entry is clear",
+       "SM: PASID is larger than the max in Context Entry",
+       "SM: PRE field in Context-Entry is clear",
+       "SM: RID_PASID field error in Context-Entry",
+       "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", /* 0x49-0x4F */
+       "SM: Error attempting to access the PASID Directory Entry",
+       "SM: Present bit in Directory Entry is clear",
+       "SM: Non-zero reserved field set in PASID Directory Entry",
+       "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", /* 0x53-0x57 */
+       "SM: Error attempting to access PASID Table Entry",
+       "SM: Present bit in PASID Table Entry is clear",
+       "SM: Non-zero reserved field set in PASID Table Entry",
+       "SM: Invalid Scalable-Mode PASID Table Entry",
+       "SM: ERE field is clear in PASID Table Entry",
+       "SM: SRE field is clear in PASID Table Entry",
+       "Unknown", "Unknown",/* 0x5E-0x5F */
+       "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", /* 0x60-0x67 */
+       "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", /* 0x68-0x6F */
+       "SM: Error attempting to access first-level paging entry",
+       "SM: Present bit in first-level paging entry is clear",
+       "SM: Non-zero reserved field set in first-level paging entry",
+       "SM: Error attempting to access FL-PML4 entry",
+       "SM: First-level entry address beyond MGAW in Nested translation",
+       "SM: Read permission error in FL-PML4 entry in Nested translation",
+       "SM: Read permission error in first-level paging entry in Nested translation",
+       "SM: Write permission error in first-level paging entry in Nested translation",
+       "SM: Error attempting to access second-level paging entry",
+       "SM: Read/Write permission error in second-level paging entry",
+       "SM: Non-zero reserved field set in second-level paging entry",
+       "SM: Invalid second-level page table pointer",
+       "SM: A/D bit update needed in second-level entry when set up in no snoop",
+       "Unknown", "Unknown", "Unknown", /* 0x7D-0x7F */
+       "SM: Address in first-level translation is not canonical",
+       "SM: U/S set 0 for first-level translation with user privilege",
+       "SM: No execute permission for request with PASID and ER=1",
+       "SM: Address beyond the DMA hardware max",
+       "SM: Second-level entry address beyond the max",
+       "SM: No write permission for Write/AtomicOp request",
+       "SM: No read permission for Read/AtomicOp request",
+       "SM: Invalid address-interrupt address",
+       "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", /* 0x88-0x8F */
+       "SM: A/D bit update needed in first-level entry when set up in no snoop",
+};
+
 static const char *irq_remap_fault_reasons[] =
 {
        "Detected reserved fields in the decoded interrupt-remapped request",
@@ -1536,6 +1594,10 @@ static const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
                                        ARRAY_SIZE(irq_remap_fault_reasons))) {
                *fault_type = INTR_REMAP;
                return irq_remap_fault_reasons[fault_reason - 0x20];
+       } else if (fault_reason >= 0x30 && (fault_reason - 0x30 <
+                       ARRAY_SIZE(dma_remap_sm_fault_reasons))) {
+               *fault_type = DMA_REMAP;
+               return dma_remap_sm_fault_reasons[fault_reason - 0x30];
        } else if (fault_reason < ARRAY_SIZE(dma_remap_fault_reasons)) {
                *fault_type = DMA_REMAP;
                return dma_remap_fault_reasons[fault_reason];
@@ -1611,7 +1673,8 @@ void dmar_msi_read(int irq, struct msi_msg *msg)
 }
 
 static int dmar_fault_do_one(struct intel_iommu *iommu, int type,
-               u8 fault_reason, u16 source_id, unsigned long long addr)
+               u8 fault_reason, int pasid, u16 source_id,
+               unsigned long long addr)
 {
        const char *reason;
        int fault_type;
@@ -1624,10 +1687,11 @@ static int dmar_fault_do_one(struct intel_iommu *iommu, int type,
                        PCI_FUNC(source_id & 0xFF), addr >> 48,
                        fault_reason, reason);
        else
-               pr_err("[%s] Request device [%02x:%02x.%d] fault addr %llx [fault reason %02d] %s\n",
+               pr_err("[%s] Request device [%02x:%02x.%d] PASID %x fault addr %llx [fault reason %02d] %s\n",
                       type ? "DMA Read" : "DMA Write",
                       source_id >> 8, PCI_SLOT(source_id & 0xFF),
-                      PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
+                      PCI_FUNC(source_id & 0xFF), pasid, addr,
+                      fault_reason, reason);
        return 0;
 }
 
@@ -1659,8 +1723,9 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
                u8 fault_reason;
                u16 source_id;
                u64 guest_addr;
-               int type;
+               int type, pasid;
                u32 data;
+               bool pasid_present;
 
                /* highest 32 bits */
                data = readl(iommu->reg + reg +
@@ -1672,10 +1737,12 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
                        fault_reason = dma_frcd_fault_reason(data);
                        type = dma_frcd_type(data);
 
+                       pasid = dma_frcd_pasid_value(data);
                        data = readl(iommu->reg + reg +
                                     fault_index * PRIMARY_FAULT_REG_LEN + 8);
                        source_id = dma_frcd_source_id(data);
 
+                       pasid_present = dma_frcd_pasid_present(data);
                        guest_addr = dmar_readq(iommu->reg + reg +
                                        fault_index * PRIMARY_FAULT_REG_LEN);
                        guest_addr = dma_frcd_page_addr(guest_addr);
@@ -1688,7 +1755,9 @@ irqreturn_t dmar_fault(int irq, void *dev_id)
                raw_spin_unlock_irqrestore(&iommu->register_lock, flag);
 
                if (!ratelimited)
+                       /* Using pasid -1 if pasid is not present */
                        dmar_fault_do_one(iommu, type, fault_reason,
+                                         pasid_present ? pasid : -1,
                                          source_id, guest_addr);
 
                fault_index++;
index b0c1e5f..9c94e16 100644 (file)
@@ -566,7 +566,7 @@ static void sysmmu_tlb_invalidate_entry(struct sysmmu_drvdata *data,
 
 static const struct iommu_ops exynos_iommu_ops;
 
-static int __init exynos_sysmmu_probe(struct platform_device *pdev)
+static int exynos_sysmmu_probe(struct platform_device *pdev)
 {
        int irq, ret;
        struct device *dev = &pdev->dev;
@@ -583,10 +583,8 @@ static int __init exynos_sysmmu_probe(struct platform_device *pdev)
                return PTR_ERR(data->sfrbase);
 
        irq = platform_get_irq(pdev, 0);
-       if (irq <= 0) {
-               dev_err(dev, "Unable to find IRQ resource\n");
+       if (irq <= 0)
                return irq;
-       }
 
        ret = devm_request_irq(dev, irq, exynos_sysmmu_irq, 0,
                                dev_name(dev), data);
@@ -1130,7 +1128,8 @@ static void exynos_iommu_tlb_invalidate_entry(struct exynos_iommu_domain *domain
 }
 
 static size_t exynos_iommu_unmap(struct iommu_domain *iommu_domain,
-                                unsigned long l_iova, size_t size)
+                                unsigned long l_iova, size_t size,
+                                struct iommu_iotlb_gather *gather)
 {
        struct exynos_iommu_domain *domain = to_exynos_domain(iommu_domain);
        sysmmu_iova_t iova = (sysmmu_iova_t)l_iova;
index 12d094d..87de0b9 100644 (file)
 #include <linux/dma-direct.h>
 #include <linux/crash_dump.h>
 #include <linux/numa.h>
+#include <linux/swiotlb.h>
 #include <asm/irq_remapping.h>
 #include <asm/cacheflush.h>
 #include <asm/iommu.h>
+#include <trace/events/intel_iommu.h>
 
 #include "irq_remapping.h"
 #include "intel-pasid.h"
@@ -339,11 +341,15 @@ static void domain_exit(struct dmar_domain *domain);
 static void domain_remove_dev_info(struct dmar_domain *domain);
 static void dmar_remove_one_dev_info(struct device *dev);
 static void __dmar_remove_one_dev_info(struct device_domain_info *info);
+static void domain_context_clear(struct intel_iommu *iommu,
+                                struct device *dev);
 static int domain_detach_iommu(struct dmar_domain *domain,
                               struct intel_iommu *iommu);
 static bool device_is_rmrr_locked(struct device *dev);
 static int intel_iommu_attach_device(struct iommu_domain *domain,
                                     struct device *dev);
+static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
+                                           dma_addr_t iova);
 
 #ifdef CONFIG_INTEL_IOMMU_DEFAULT_ON
 int dmar_disabled = 0;
@@ -360,6 +366,7 @@ static int dmar_forcedac;
 static int intel_iommu_strict;
 static int intel_iommu_superpage = 1;
 static int iommu_identity_mapping;
+static int intel_no_bounce;
 
 #define IDENTMAP_ALL           1
 #define IDENTMAP_GFX           2
@@ -373,6 +380,9 @@ EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
 static DEFINE_SPINLOCK(device_domain_lock);
 static LIST_HEAD(device_domain_list);
 
+#define device_needs_bounce(d) (!intel_no_bounce && dev_is_pci(d) &&   \
+                               to_pci_dev(d)->untrusted)
+
 /*
  * Iterate over elements in device_domain_list and call the specified
  * callback @fn against each element.
@@ -455,6 +465,9 @@ static int __init intel_iommu_setup(char *str)
                        printk(KERN_INFO
                                "Intel-IOMMU: not forcing on after tboot. This could expose security risk for tboot\n");
                        intel_iommu_tboot_noforce = 1;
+               } else if (!strncmp(str, "nobounce", 8)) {
+                       pr_info("Intel-IOMMU: No bounce buffer. This could expose security risks of DMA attacks\n");
+                       intel_no_bounce = 1;
                }
 
                str += strcspn(str, ",");
@@ -2105,9 +2118,26 @@ out_unlock:
        return ret;
 }
 
+struct domain_context_mapping_data {
+       struct dmar_domain *domain;
+       struct intel_iommu *iommu;
+       struct pasid_table *table;
+};
+
+static int domain_context_mapping_cb(struct pci_dev *pdev,
+                                    u16 alias, void *opaque)
+{
+       struct domain_context_mapping_data *data = opaque;
+
+       return domain_context_mapping_one(data->domain, data->iommu,
+                                         data->table, PCI_BUS_NUM(alias),
+                                         alias & 0xff);
+}
+
 static int
 domain_context_mapping(struct dmar_domain *domain, struct device *dev)
 {
+       struct domain_context_mapping_data data;
        struct pasid_table *table;
        struct intel_iommu *iommu;
        u8 bus, devfn;
@@ -2117,7 +2147,17 @@ domain_context_mapping(struct dmar_domain *domain, struct device *dev)
                return -ENODEV;
 
        table = intel_pasid_get_table(dev);
-       return domain_context_mapping_one(domain, iommu, table, bus, devfn);
+
+       if (!dev_is_pci(dev))
+               return domain_context_mapping_one(domain, iommu, table,
+                                                 bus, devfn);
+
+       data.domain = domain;
+       data.iommu = iommu;
+       data.table = table;
+
+       return pci_for_each_dma_alias(to_pci_dev(dev),
+                                     &domain_context_mapping_cb, &data);
 }
 
 static int domain_context_mapped_cb(struct pci_dev *pdev,
@@ -3267,7 +3307,7 @@ static int __init init_dmars(void)
                iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
        }
 
-       if (iommu_pass_through)
+       if (iommu_default_passthrough())
                iommu_identity_mapping |= IDENTMAP_ALL;
 
 #ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
@@ -3505,6 +3545,9 @@ static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
 
        start_paddr = (phys_addr_t)iova_pfn << PAGE_SHIFT;
        start_paddr += paddr & ~PAGE_MASK;
+
+       trace_map_single(dev, start_paddr, paddr, size << VTD_PAGE_SHIFT);
+
        return start_paddr;
 
 error:
@@ -3560,10 +3603,7 @@ static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
        if (dev_is_pci(dev))
                pdev = to_pci_dev(dev);
 
-       dev_dbg(dev, "Device unmapping: pfn %lx-%lx\n", start_pfn, last_pfn);
-
        freelist = domain_unmap(domain, start_pfn, last_pfn);
-
        if (intel_iommu_strict || (pdev && pdev->untrusted) ||
                        !has_iova_flush_queue(&domain->iovad)) {
                iommu_flush_iotlb_psi(iommu, domain, start_pfn,
@@ -3579,6 +3619,8 @@ static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
                 * cpu used up by the iotlb flush operation...
                 */
        }
+
+       trace_unmap_single(dev, dev_addr, size);
 }
 
 static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
@@ -3669,6 +3711,8 @@ static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,
        }
 
        intel_unmap(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
+
+       trace_unmap_sg(dev, startaddr, nrpages << VTD_PAGE_SHIFT);
 }
 
 static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
@@ -3725,6 +3769,9 @@ static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nele
                return 0;
        }
 
+       trace_map_sg(dev, iova_pfn << PAGE_SHIFT,
+                    sg_phys(sglist), size << VTD_PAGE_SHIFT);
+
        return nelems;
 }
 
@@ -3740,6 +3787,252 @@ static const struct dma_map_ops intel_dma_ops = {
        .dma_supported = dma_direct_supported,
 };
 
+static void
+bounce_sync_single(struct device *dev, dma_addr_t addr, size_t size,
+                  enum dma_data_direction dir, enum dma_sync_target target)
+{
+       struct dmar_domain *domain;
+       phys_addr_t tlb_addr;
+
+       domain = find_domain(dev);
+       if (WARN_ON(!domain))
+               return;
+
+       tlb_addr = intel_iommu_iova_to_phys(&domain->domain, addr);
+       if (is_swiotlb_buffer(tlb_addr))
+               swiotlb_tbl_sync_single(dev, tlb_addr, size, dir, target);
+}
+
+static dma_addr_t
+bounce_map_single(struct device *dev, phys_addr_t paddr, size_t size,
+                 enum dma_data_direction dir, unsigned long attrs,
+                 u64 dma_mask)
+{
+       size_t aligned_size = ALIGN(size, VTD_PAGE_SIZE);
+       struct dmar_domain *domain;
+       struct intel_iommu *iommu;
+       unsigned long iova_pfn;
+       unsigned long nrpages;
+       phys_addr_t tlb_addr;
+       int prot = 0;
+       int ret;
+
+       domain = find_domain(dev);
+       if (WARN_ON(dir == DMA_NONE || !domain))
+               return DMA_MAPPING_ERROR;
+
+       iommu = domain_get_iommu(domain);
+       if (WARN_ON(!iommu))
+               return DMA_MAPPING_ERROR;
+
+       nrpages = aligned_nrpages(0, size);
+       iova_pfn = intel_alloc_iova(dev, domain,
+                                   dma_to_mm_pfn(nrpages), dma_mask);
+       if (!iova_pfn)
+               return DMA_MAPPING_ERROR;
+
+       /*
+        * Check if DMAR supports zero-length reads on write only
+        * mappings..
+        */
+       if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL ||
+                       !cap_zlr(iommu->cap))
+               prot |= DMA_PTE_READ;
+       if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL)
+               prot |= DMA_PTE_WRITE;
+
+       /*
+        * If both the physical buffer start address and size are
+        * page aligned, we don't need to use a bounce page.
+        */
+       if (!IS_ALIGNED(paddr | size, VTD_PAGE_SIZE)) {
+               tlb_addr = swiotlb_tbl_map_single(dev,
+                               __phys_to_dma(dev, io_tlb_start),
+                               paddr, size, aligned_size, dir, attrs);
+               if (tlb_addr == DMA_MAPPING_ERROR) {
+                       goto swiotlb_error;
+               } else {
+                       /* Cleanup the padding area. */
+                       void *padding_start = phys_to_virt(tlb_addr);
+                       size_t padding_size = aligned_size;
+
+                       if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
+                           (dir == DMA_TO_DEVICE ||
+                            dir == DMA_BIDIRECTIONAL)) {
+                               padding_start += size;
+                               padding_size -= size;
+                       }
+
+                       memset(padding_start, 0, padding_size);
+               }
+       } else {
+               tlb_addr = paddr;
+       }
+
+       ret = domain_pfn_mapping(domain, mm_to_dma_pfn(iova_pfn),
+                                tlb_addr >> VTD_PAGE_SHIFT, nrpages, prot);
+       if (ret)
+               goto mapping_error;
+
+       trace_bounce_map_single(dev, iova_pfn << PAGE_SHIFT, paddr, size);
+
+       return (phys_addr_t)iova_pfn << PAGE_SHIFT;
+
+mapping_error:
+       if (is_swiotlb_buffer(tlb_addr))
+               swiotlb_tbl_unmap_single(dev, tlb_addr, size,
+                                        aligned_size, dir, attrs);
+swiotlb_error:
+       free_iova_fast(&domain->iovad, iova_pfn, dma_to_mm_pfn(nrpages));
+       dev_err(dev, "Device bounce map: %zx@%llx dir %d --- failed\n",
+               size, (unsigned long long)paddr, dir);
+
+       return DMA_MAPPING_ERROR;
+}
+
+static void
+bounce_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
+                   enum dma_data_direction dir, unsigned long attrs)
+{
+       size_t aligned_size = ALIGN(size, VTD_PAGE_SIZE);
+       struct dmar_domain *domain;
+       phys_addr_t tlb_addr;
+
+       domain = find_domain(dev);
+       if (WARN_ON(!domain))
+               return;
+
+       tlb_addr = intel_iommu_iova_to_phys(&domain->domain, dev_addr);
+       if (WARN_ON(!tlb_addr))
+               return;
+
+       intel_unmap(dev, dev_addr, size);
+       if (is_swiotlb_buffer(tlb_addr))
+               swiotlb_tbl_unmap_single(dev, tlb_addr, size,
+                                        aligned_size, dir, attrs);
+
+       trace_bounce_unmap_single(dev, dev_addr, size);
+}
+
+static dma_addr_t
+bounce_map_page(struct device *dev, struct page *page, unsigned long offset,
+               size_t size, enum dma_data_direction dir, unsigned long attrs)
+{
+       return bounce_map_single(dev, page_to_phys(page) + offset,
+                                size, dir, attrs, *dev->dma_mask);
+}
+
+static dma_addr_t
+bounce_map_resource(struct device *dev, phys_addr_t phys_addr, size_t size,
+                   enum dma_data_direction dir, unsigned long attrs)
+{
+       return bounce_map_single(dev, phys_addr, size,
+                                dir, attrs, *dev->dma_mask);
+}
+
+static void
+bounce_unmap_page(struct device *dev, dma_addr_t dev_addr, size_t size,
+                 enum dma_data_direction dir, unsigned long attrs)
+{
+       bounce_unmap_single(dev, dev_addr, size, dir, attrs);
+}
+
+static void
+bounce_unmap_resource(struct device *dev, dma_addr_t dev_addr, size_t size,
+                     enum dma_data_direction dir, unsigned long attrs)
+{
+       bounce_unmap_single(dev, dev_addr, size, dir, attrs);
+}
+
+static void
+bounce_unmap_sg(struct device *dev, struct scatterlist *sglist, int nelems,
+               enum dma_data_direction dir, unsigned long attrs)
+{
+       struct scatterlist *sg;
+       int i;
+
+       for_each_sg(sglist, sg, nelems, i)
+               bounce_unmap_page(dev, sg->dma_address,
+                                 sg_dma_len(sg), dir, attrs);
+}
+
+static int
+bounce_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
+             enum dma_data_direction dir, unsigned long attrs)
+{
+       int i;
+       struct scatterlist *sg;
+
+       for_each_sg(sglist, sg, nelems, i) {
+               sg->dma_address = bounce_map_page(dev, sg_page(sg),
+                                                 sg->offset, sg->length,
+                                                 dir, attrs);
+               if (sg->dma_address == DMA_MAPPING_ERROR)
+                       goto out_unmap;
+               sg_dma_len(sg) = sg->length;
+       }
+
+       return nelems;
+
+out_unmap:
+       bounce_unmap_sg(dev, sglist, i, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC);
+       return 0;
+}
+
+static void
+bounce_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
+                          size_t size, enum dma_data_direction dir)
+{
+       bounce_sync_single(dev, addr, size, dir, SYNC_FOR_CPU);
+}
+
+static void
+bounce_sync_single_for_device(struct device *dev, dma_addr_t addr,
+                             size_t size, enum dma_data_direction dir)
+{
+       bounce_sync_single(dev, addr, size, dir, SYNC_FOR_DEVICE);
+}
+
+static void
+bounce_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist,
+                      int nelems, enum dma_data_direction dir)
+{
+       struct scatterlist *sg;
+       int i;
+
+       for_each_sg(sglist, sg, nelems, i)
+               bounce_sync_single(dev, sg_dma_address(sg),
+                                  sg_dma_len(sg), dir, SYNC_FOR_CPU);
+}
+
+static void
+bounce_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
+                         int nelems, enum dma_data_direction dir)
+{
+       struct scatterlist *sg;
+       int i;
+
+       for_each_sg(sglist, sg, nelems, i)
+               bounce_sync_single(dev, sg_dma_address(sg),
+                                  sg_dma_len(sg), dir, SYNC_FOR_DEVICE);
+}
+
+static const struct dma_map_ops bounce_dma_ops = {
+       .alloc                  = intel_alloc_coherent,
+       .free                   = intel_free_coherent,
+       .map_sg                 = bounce_map_sg,
+       .unmap_sg               = bounce_unmap_sg,
+       .map_page               = bounce_map_page,
+       .unmap_page             = bounce_unmap_page,
+       .sync_single_for_cpu    = bounce_sync_single_for_cpu,
+       .sync_single_for_device = bounce_sync_single_for_device,
+       .sync_sg_for_cpu        = bounce_sync_sg_for_cpu,
+       .sync_sg_for_device     = bounce_sync_sg_for_device,
+       .map_resource           = bounce_map_resource,
+       .unmap_resource         = bounce_unmap_resource,
+       .dma_supported          = dma_direct_supported,
+};
+
 static inline int iommu_domain_cache_init(void)
 {
        int ret = 0;
@@ -4540,22 +4833,20 @@ const struct attribute_group *intel_iommu_groups[] = {
        NULL,
 };
 
-static int __init platform_optin_force_iommu(void)
+static inline bool has_untrusted_dev(void)
 {
        struct pci_dev *pdev = NULL;
-       bool has_untrusted_dev = false;
 
-       if (!dmar_platform_optin() || no_platform_optin)
-               return 0;
+       for_each_pci_dev(pdev)
+               if (pdev->untrusted)
+                       return true;
 
-       for_each_pci_dev(pdev) {
-               if (pdev->untrusted) {
-                       has_untrusted_dev = true;
-                       break;
-               }
-       }
+       return false;
+}
 
-       if (!has_untrusted_dev)
+static int __init platform_optin_force_iommu(void)
+{
+       if (!dmar_platform_optin() || no_platform_optin || !has_untrusted_dev())
                return 0;
 
        if (no_iommu || dmar_disabled)
@@ -4569,9 +4860,6 @@ static int __init platform_optin_force_iommu(void)
                iommu_identity_mapping |= IDENTMAP_ALL;
 
        dmar_disabled = 0;
-#if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
-       swiotlb = 0;
-#endif
        no_iommu = 0;
 
        return 1;
@@ -4711,7 +4999,14 @@ int __init intel_iommu_init(void)
        up_write(&dmar_global_lock);
 
 #if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
-       swiotlb = 0;
+       /*
+        * If the system has no untrusted device or the user has decided
+        * to disable the bounce page mechanisms, we don't need swiotlb.
+        * Mark this and the pre-allocated bounce pages will be released
+        * later.
+        */
+       if (!has_untrusted_dev() || intel_no_bounce)
+               swiotlb = 0;
 #endif
        dma_ops = &intel_dma_ops;
 
@@ -4759,6 +5054,28 @@ out_free_dmar:
        return ret;
 }
 
+static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *opaque)
+{
+       struct intel_iommu *iommu = opaque;
+
+       domain_context_clear_one(iommu, PCI_BUS_NUM(alias), alias & 0xff);
+       return 0;
+}
+
+/*
+ * NB - intel-iommu lacks any sort of reference counting for the users of
+ * dependent devices.  If multiple endpoints have intersecting dependent
+ * devices, unbinding the driver from any one of them will possibly leave
+ * the others unable to operate.
+ */
+static void domain_context_clear(struct intel_iommu *iommu, struct device *dev)
+{
+       if (!iommu || !dev || !dev_is_pci(dev))
+               return;
+
+       pci_for_each_dma_alias(to_pci_dev(dev), &domain_context_clear_one_cb, iommu);
+}
+
 static void __dmar_remove_one_dev_info(struct device_domain_info *info)
 {
        struct dmar_domain *domain;
@@ -4779,7 +5096,7 @@ static void __dmar_remove_one_dev_info(struct device_domain_info *info)
                                        PASID_RID2PASID);
 
                iommu_disable_dev_iotlb(info);
-               domain_context_clear_one(iommu, info->bus, info->devfn);
+               domain_context_clear(iommu, info->dev);
                intel_pasid_free_table(info->dev);
        }
 
@@ -5153,7 +5470,8 @@ static int intel_iommu_map(struct iommu_domain *domain,
 }
 
 static size_t intel_iommu_unmap(struct iommu_domain *domain,
-                               unsigned long iova, size_t size)
+                               unsigned long iova, size_t size,
+                               struct iommu_iotlb_gather *gather)
 {
        struct dmar_domain *dmar_domain = to_dmar_domain(domain);
        struct page *freelist = NULL;
@@ -5309,6 +5627,11 @@ static int intel_iommu_add_device(struct device *dev)
                }
        }
 
+       if (device_needs_bounce(dev)) {
+               dev_info(dev, "Use Intel IOMMU bounce page dma_ops\n");
+               set_dma_ops(dev, &bounce_dma_ops);
+       }
+
        return 0;
 }
 
@@ -5326,6 +5649,9 @@ static void intel_iommu_remove_device(struct device *dev)
        iommu_group_remove_device(dev);
 
        iommu_device_unlink(&iommu->iommu, dev);
+
+       if (device_needs_bounce(dev))
+               set_dma_ops(dev, NULL);
 }
 
 static void intel_iommu_get_resv_regions(struct device *device,
@@ -5639,20 +5965,46 @@ const struct iommu_ops intel_iommu_ops = {
        .pgsize_bitmap          = INTEL_IOMMU_PGSIZES,
 };
 
-static void quirk_iommu_g4x_gfx(struct pci_dev *dev)
+static void quirk_iommu_igfx(struct pci_dev *dev)
 {
-       /* G4x/GM45 integrated gfx dmar support is totally busted. */
        pci_info(dev, "Disabling IOMMU for graphics on this chipset\n");
        dmar_map_gfx = 0;
 }
 
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_g4x_gfx);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_g4x_gfx);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_g4x_gfx);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_g4x_gfx);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_g4x_gfx);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_g4x_gfx);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_g4x_gfx);
+/* G4x/GM45 integrated gfx dmar support is totally busted. */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e00, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e10, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e20, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e30, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e40, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2e90, quirk_iommu_igfx);
+
+/* Broadwell igfx malfunctions with dmar */
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1606, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160B, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160E, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1602, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160A, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x160D, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1616, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161B, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161E, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1612, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161A, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x161D, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1626, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162B, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162E, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1622, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162A, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x162D, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1636, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163B, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163E, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1632, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163A, quirk_iommu_igfx);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x163D, quirk_iommu_igfx);
 
 static void quirk_iommu_rwbf(struct pci_dev *dev)
 {
index 780de0c..9b15913 100644 (file)
@@ -100,24 +100,19 @@ int intel_svm_finish_prq(struct intel_iommu *iommu)
 }
 
 static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_dev *sdev,
-                                      unsigned long address, unsigned long pages, int ih, int gl)
+                               unsigned long address, unsigned long pages, int ih)
 {
        struct qi_desc desc;
 
-       if (pages == -1) {
-               /* For global kernel pages we have to flush them in *all* PASIDs
-                * because that's the only option the hardware gives us. Despite
-                * the fact that they are actually only accessible through one. */
-               if (gl)
-                       desc.qw0 = QI_EIOTLB_PASID(svm->pasid) |
-                                       QI_EIOTLB_DID(sdev->did) |
-                                       QI_EIOTLB_GRAN(QI_GRAN_ALL_ALL) |
-                                       QI_EIOTLB_TYPE;
-               else
-                       desc.qw0 = QI_EIOTLB_PASID(svm->pasid) |
-                                       QI_EIOTLB_DID(sdev->did) |
-                                       QI_EIOTLB_GRAN(QI_GRAN_NONG_PASID) |
-                                       QI_EIOTLB_TYPE;
+       /*
+        * Do PASID granu IOTLB invalidation if page selective capability is
+        * not available.
+        */
+       if (pages == -1 || !cap_pgsel_inv(svm->iommu->cap)) {
+               desc.qw0 = QI_EIOTLB_PASID(svm->pasid) |
+                       QI_EIOTLB_DID(sdev->did) |
+                       QI_EIOTLB_GRAN(QI_GRAN_NONG_PASID) |
+                       QI_EIOTLB_TYPE;
                desc.qw1 = 0;
        } else {
                int mask = ilog2(__roundup_pow_of_two(pages));
@@ -127,7 +122,6 @@ static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_d
                                QI_EIOTLB_GRAN(QI_GRAN_PSI_PASID) |
                                QI_EIOTLB_TYPE;
                desc.qw1 = QI_EIOTLB_ADDR(address) |
-                               QI_EIOTLB_GL(gl) |
                                QI_EIOTLB_IH(ih) |
                                QI_EIOTLB_AM(mask);
        }
@@ -162,13 +156,13 @@ static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_d
 }
 
 static void intel_flush_svm_range(struct intel_svm *svm, unsigned long address,
-                                 unsigned long pages, int ih, int gl)
+                               unsigned long pages, int ih)
 {
        struct intel_svm_dev *sdev;
 
        rcu_read_lock();
        list_for_each_entry_rcu(sdev, &svm->devs, list)
-               intel_flush_svm_range_dev(svm, sdev, address, pages, ih, gl);
+               intel_flush_svm_range_dev(svm, sdev, address, pages, ih);
        rcu_read_unlock();
 }
 
@@ -180,7 +174,7 @@ static void intel_invalidate_range(struct mmu_notifier *mn,
        struct intel_svm *svm = container_of(mn, struct intel_svm, notifier);
 
        intel_flush_svm_range(svm, start,
-                             (end - start + PAGE_SIZE - 1) >> VTD_PAGE_SHIFT, 0, 0);
+                             (end - start + PAGE_SIZE - 1) >> VTD_PAGE_SHIFT, 0);
 }
 
 static void intel_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
@@ -203,7 +197,7 @@ static void intel_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
        rcu_read_lock();
        list_for_each_entry_rcu(sdev, &svm->devs, list) {
                intel_pasid_tear_down_entry(svm->iommu, sdev->dev, svm->pasid);
-               intel_flush_svm_range_dev(svm, sdev, 0, -1, 0, !svm->mm);
+               intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
        }
        rcu_read_unlock();
 
@@ -425,7 +419,7 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
                                 * large and has to be physically contiguous. So it's
                                 * hard to be as defensive as we might like. */
                                intel_pasid_tear_down_entry(iommu, dev, svm->pasid);
-                               intel_flush_svm_range_dev(svm, sdev, 0, -1, 0, !svm->mm);
+                               intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
                                kfree_rcu(sdev, rcu);
 
                                if (list_empty(&svm->devs)) {
diff --git a/drivers/iommu/intel-trace.c b/drivers/iommu/intel-trace.c
new file mode 100644 (file)
index 0000000..bfb6a6e
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel IOMMU trace support
+ *
+ * Copyright (C) 2019 Intel Corporation
+ *
+ * Author: Lu Baolu <baolu.lu@linux.intel.com>
+ */
+
+#include <linux/string.h>
+#include <linux/types.h>
+
+#define CREATE_TRACE_POINTS
+#include <trace/events/intel_iommu.h>
index 4786ca0..81e43c1 100644 (file)
@@ -376,13 +376,13 @@ static int set_msi_sid_cb(struct pci_dev *pdev, u16 alias, void *opaque)
 {
        struct set_msi_sid_data *data = opaque;
 
+       if (data->count == 0 || PCI_BUS_NUM(alias) == PCI_BUS_NUM(data->alias))
+               data->busmatch_count++;
+
        data->pdev = pdev;
        data->alias = alias;
        data->count++;
 
-       if (PCI_BUS_NUM(alias) == pdev->bus->number)
-               data->busmatch_count++;
-
        return 0;
 }
 
index 0fc8dfa..4cb3949 100644 (file)
 #define ARM_V7S_TEX_MASK               0x7
 #define ARM_V7S_ATTR_TEX(val)          (((val) & ARM_V7S_TEX_MASK) << ARM_V7S_TEX_SHIFT)
 
-#define ARM_V7S_ATTR_MTK_4GB           BIT(9) /* MTK extend it for 4GB mode */
+/* MediaTek extend the two bits for PA 32bit/33bit */
+#define ARM_V7S_ATTR_MTK_PA_BIT32      BIT(9)
+#define ARM_V7S_ATTR_MTK_PA_BIT33      BIT(4)
 
 /* *well, except for TEX on level 2 large pages, of course :( */
 #define ARM_V7S_CONT_PAGE_TEX_SHIFT    6
@@ -169,18 +171,62 @@ struct arm_v7s_io_pgtable {
        spinlock_t              split_lock;
 };
 
+static bool arm_v7s_pte_is_cont(arm_v7s_iopte pte, int lvl);
+
 static dma_addr_t __arm_v7s_dma_addr(void *pages)
 {
        return (dma_addr_t)virt_to_phys(pages);
 }
 
-static arm_v7s_iopte *iopte_deref(arm_v7s_iopte pte, int lvl)
+static bool arm_v7s_is_mtk_enabled(struct io_pgtable_cfg *cfg)
+{
+       return IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT) &&
+               (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT);
+}
+
+static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl,
+                                   struct io_pgtable_cfg *cfg)
+{
+       arm_v7s_iopte pte = paddr & ARM_V7S_LVL_MASK(lvl);
+
+       if (!arm_v7s_is_mtk_enabled(cfg))
+               return pte;
+
+       if (paddr & BIT_ULL(32))
+               pte |= ARM_V7S_ATTR_MTK_PA_BIT32;
+       if (paddr & BIT_ULL(33))
+               pte |= ARM_V7S_ATTR_MTK_PA_BIT33;
+       return pte;
+}
+
+static phys_addr_t iopte_to_paddr(arm_v7s_iopte pte, int lvl,
+                                 struct io_pgtable_cfg *cfg)
 {
+       arm_v7s_iopte mask;
+       phys_addr_t paddr;
+
        if (ARM_V7S_PTE_IS_TABLE(pte, lvl))
-               pte &= ARM_V7S_TABLE_MASK;
+               mask = ARM_V7S_TABLE_MASK;
+       else if (arm_v7s_pte_is_cont(pte, lvl))
+               mask = ARM_V7S_LVL_MASK(lvl) * ARM_V7S_CONT_PAGES;
        else
-               pte &= ARM_V7S_LVL_MASK(lvl);
-       return phys_to_virt(pte);
+               mask = ARM_V7S_LVL_MASK(lvl);
+
+       paddr = pte & mask;
+       if (!arm_v7s_is_mtk_enabled(cfg))
+               return paddr;
+
+       if (pte & ARM_V7S_ATTR_MTK_PA_BIT32)
+               paddr |= BIT_ULL(32);
+       if (pte & ARM_V7S_ATTR_MTK_PA_BIT33)
+               paddr |= BIT_ULL(33);
+       return paddr;
+}
+
+static arm_v7s_iopte *iopte_deref(arm_v7s_iopte pte, int lvl,
+                                 struct arm_v7s_io_pgtable *data)
+{
+       return phys_to_virt(iopte_to_paddr(pte, lvl, &data->iop.cfg));
 }
 
 static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp,
@@ -295,9 +341,6 @@ static arm_v7s_iopte arm_v7s_prot_to_pte(int prot, int lvl,
        if (lvl == 1 && (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS))
                pte |= ARM_V7S_ATTR_NS_SECTION;
 
-       if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB)
-               pte |= ARM_V7S_ATTR_MTK_4GB;
-
        return pte;
 }
 
@@ -362,7 +405,8 @@ static bool arm_v7s_pte_is_cont(arm_v7s_iopte pte, int lvl)
        return false;
 }
 
-static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *, unsigned long,
+static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *,
+                             struct iommu_iotlb_gather *, unsigned long,
                              size_t, int, arm_v7s_iopte *);
 
 static int arm_v7s_init_pte(struct arm_v7s_io_pgtable *data,
@@ -383,7 +427,7 @@ static int arm_v7s_init_pte(struct arm_v7s_io_pgtable *data,
                        size_t sz = ARM_V7S_BLOCK_SIZE(lvl);
 
                        tblp = ptep - ARM_V7S_LVL_IDX(iova, lvl);
-                       if (WARN_ON(__arm_v7s_unmap(data, iova + i * sz,
+                       if (WARN_ON(__arm_v7s_unmap(data, NULL, iova + i * sz,
                                                    sz, lvl, tblp) != sz))
                                return -EINVAL;
                } else if (ptep[i]) {
@@ -396,7 +440,7 @@ static int arm_v7s_init_pte(struct arm_v7s_io_pgtable *data,
        if (num_entries > 1)
                pte = arm_v7s_pte_to_cont(pte, lvl);
 
-       pte |= paddr & ARM_V7S_LVL_MASK(lvl);
+       pte |= paddr_to_iopte(paddr, lvl, cfg);
 
        __arm_v7s_set_pte(ptep, pte, num_entries, cfg);
        return 0;
@@ -462,7 +506,7 @@ static int __arm_v7s_map(struct arm_v7s_io_pgtable *data, unsigned long iova,
        }
 
        if (ARM_V7S_PTE_IS_TABLE(pte, lvl)) {
-               cptep = iopte_deref(pte, lvl);
+               cptep = iopte_deref(pte, lvl, data);
        } else if (pte) {
                /* We require an unmap first */
                WARN_ON(!selftest_running);
@@ -484,7 +528,8 @@ static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova,
        if (!(prot & (IOMMU_READ | IOMMU_WRITE)))
                return 0;
 
-       if (WARN_ON(upper_32_bits(iova) || upper_32_bits(paddr)))
+       if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias) ||
+                   paddr >= (1ULL << data->iop.cfg.oas)))
                return -ERANGE;
 
        ret = __arm_v7s_map(data, iova, paddr, size, prot, 1, data->pgd);
@@ -493,9 +538,8 @@ static int arm_v7s_map(struct io_pgtable_ops *ops, unsigned long iova,
         * a chance for anything to kick off a table walk for the new iova.
         */
        if (iop->cfg.quirks & IO_PGTABLE_QUIRK_TLBI_ON_MAP) {
-               io_pgtable_tlb_add_flush(iop, iova, size,
-                                        ARM_V7S_BLOCK_SIZE(2), false);
-               io_pgtable_tlb_sync(iop);
+               io_pgtable_tlb_flush_walk(iop, iova, size,
+                                         ARM_V7S_BLOCK_SIZE(2));
        } else {
                wmb();
        }
@@ -512,7 +556,8 @@ static void arm_v7s_free_pgtable(struct io_pgtable *iop)
                arm_v7s_iopte pte = data->pgd[i];
 
                if (ARM_V7S_PTE_IS_TABLE(pte, 1))
-                       __arm_v7s_free_table(iopte_deref(pte, 1), 2, data);
+                       __arm_v7s_free_table(iopte_deref(pte, 1, data),
+                                            2, data);
        }
        __arm_v7s_free_table(data->pgd, 1, data);
        kmem_cache_destroy(data->l2_tables);
@@ -541,12 +586,12 @@ static arm_v7s_iopte arm_v7s_split_cont(struct arm_v7s_io_pgtable *data,
        __arm_v7s_pte_sync(ptep, ARM_V7S_CONT_PAGES, &iop->cfg);
 
        size *= ARM_V7S_CONT_PAGES;
-       io_pgtable_tlb_add_flush(iop, iova, size, size, true);
-       io_pgtable_tlb_sync(iop);
+       io_pgtable_tlb_flush_leaf(iop, iova, size, size);
        return pte;
 }
 
 static size_t arm_v7s_split_blk_unmap(struct arm_v7s_io_pgtable *data,
+                                     struct iommu_iotlb_gather *gather,
                                      unsigned long iova, size_t size,
                                      arm_v7s_iopte blk_pte,
                                      arm_v7s_iopte *ptep)
@@ -582,16 +627,16 @@ static size_t arm_v7s_split_blk_unmap(struct arm_v7s_io_pgtable *data,
                if (!ARM_V7S_PTE_IS_TABLE(pte, 1))
                        return 0;
 
-               tablep = iopte_deref(pte, 1);
-               return __arm_v7s_unmap(data, iova, size, 2, tablep);
+               tablep = iopte_deref(pte, 1, data);
+               return __arm_v7s_unmap(data, gather, iova, size, 2, tablep);
        }
 
-       io_pgtable_tlb_add_flush(&data->iop, iova, size, size, true);
-       io_pgtable_tlb_sync(&data->iop);
+       io_pgtable_tlb_add_page(&data->iop, gather, iova, size);
        return size;
 }
 
 static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *data,
+                             struct iommu_iotlb_gather *gather,
                              unsigned long iova, size_t size, int lvl,
                              arm_v7s_iopte *ptep)
 {
@@ -638,10 +683,9 @@ static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *data,
                for (i = 0; i < num_entries; i++) {
                        if (ARM_V7S_PTE_IS_TABLE(pte[i], lvl)) {
                                /* Also flush any partial walks */
-                               io_pgtable_tlb_add_flush(iop, iova, blk_size,
-                                       ARM_V7S_BLOCK_SIZE(lvl + 1), false);
-                               io_pgtable_tlb_sync(iop);
-                               ptep = iopte_deref(pte[i], lvl);
+                               io_pgtable_tlb_flush_walk(iop, iova, blk_size,
+                                               ARM_V7S_BLOCK_SIZE(lvl + 1));
+                               ptep = iopte_deref(pte[i], lvl, data);
                                __arm_v7s_free_table(ptep, lvl + 1, data);
                        } else if (iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT) {
                                /*
@@ -651,8 +695,7 @@ static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *data,
                                 */
                                smp_wmb();
                        } else {
-                               io_pgtable_tlb_add_flush(iop, iova, blk_size,
-                                                        blk_size, true);
+                               io_pgtable_tlb_add_page(iop, gather, iova, blk_size);
                        }
                        iova += blk_size;
                }
@@ -662,23 +705,24 @@ static size_t __arm_v7s_unmap(struct arm_v7s_io_pgtable *data,
                 * Insert a table at the next level to map the old region,
                 * minus the part we want to unmap
                 */
-               return arm_v7s_split_blk_unmap(data, iova, size, pte[0], ptep);
+               return arm_v7s_split_blk_unmap(data, gather, iova, size, pte[0],
+                                              ptep);
        }
 
        /* Keep on walkin' */
-       ptep = iopte_deref(pte[0], lvl);
-       return __arm_v7s_unmap(data, iova, size, lvl + 1, ptep);
+       ptep = iopte_deref(pte[0], lvl, data);
+       return __arm_v7s_unmap(data, gather, iova, size, lvl + 1, ptep);
 }
 
 static size_t arm_v7s_unmap(struct io_pgtable_ops *ops, unsigned long iova,
-                           size_t size)
+                           size_t size, struct iommu_iotlb_gather *gather)
 {
        struct arm_v7s_io_pgtable *data = io_pgtable_ops_to_data(ops);
 
        if (WARN_ON(upper_32_bits(iova)))
                return 0;
 
-       return __arm_v7s_unmap(data, iova, size, 1, data->pgd);
+       return __arm_v7s_unmap(data, gather, iova, size, 1, data->pgd);
 }
 
 static phys_addr_t arm_v7s_iova_to_phys(struct io_pgtable_ops *ops,
@@ -692,7 +736,7 @@ static phys_addr_t arm_v7s_iova_to_phys(struct io_pgtable_ops *ops,
        do {
                ptep += ARM_V7S_LVL_IDX(iova, ++lvl);
                pte = READ_ONCE(*ptep);
-               ptep = iopte_deref(pte, lvl);
+               ptep = iopte_deref(pte, lvl, data);
        } while (ARM_V7S_PTE_IS_TABLE(pte, lvl));
 
        if (!ARM_V7S_PTE_IS_VALID(pte))
@@ -701,7 +745,7 @@ static phys_addr_t arm_v7s_iova_to_phys(struct io_pgtable_ops *ops,
        mask = ARM_V7S_LVL_MASK(lvl);
        if (arm_v7s_pte_is_cont(pte, lvl))
                mask *= ARM_V7S_CONT_PAGES;
-       return (pte & mask) | (iova & ~mask);
+       return iopte_to_paddr(pte, lvl, &data->iop.cfg) | (iova & ~mask);
 }
 
 static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
@@ -709,18 +753,21 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
 {
        struct arm_v7s_io_pgtable *data;
 
-       if (cfg->ias > ARM_V7S_ADDR_BITS || cfg->oas > ARM_V7S_ADDR_BITS)
+       if (cfg->ias > ARM_V7S_ADDR_BITS)
+               return NULL;
+
+       if (cfg->oas > (arm_v7s_is_mtk_enabled(cfg) ? 34 : ARM_V7S_ADDR_BITS))
                return NULL;
 
        if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
                            IO_PGTABLE_QUIRK_NO_PERMS |
                            IO_PGTABLE_QUIRK_TLBI_ON_MAP |
-                           IO_PGTABLE_QUIRK_ARM_MTK_4GB |
+                           IO_PGTABLE_QUIRK_ARM_MTK_EXT |
                            IO_PGTABLE_QUIRK_NON_STRICT))
                return NULL;
 
        /* If ARM_MTK_4GB is enabled, the NO_PERMS is also expected. */
-       if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_4GB &&
+       if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT &&
            !(cfg->quirks & IO_PGTABLE_QUIRK_NO_PERMS))
                        return NULL;
 
@@ -806,22 +853,24 @@ static void dummy_tlb_flush_all(void *cookie)
        WARN_ON(cookie != cfg_cookie);
 }
 
-static void dummy_tlb_add_flush(unsigned long iova, size_t size,
-                               size_t granule, bool leaf, void *cookie)
+static void dummy_tlb_flush(unsigned long iova, size_t size, size_t granule,
+                           void *cookie)
 {
        WARN_ON(cookie != cfg_cookie);
        WARN_ON(!(size & cfg_cookie->pgsize_bitmap));
 }
 
-static void dummy_tlb_sync(void *cookie)
+static void dummy_tlb_add_page(struct iommu_iotlb_gather *gather,
+                              unsigned long iova, size_t granule, void *cookie)
 {
-       WARN_ON(cookie != cfg_cookie);
+       dummy_tlb_flush(iova, granule, granule, cookie);
 }
 
-static const struct iommu_gather_ops dummy_tlb_ops = {
+static const struct iommu_flush_ops dummy_tlb_ops = {
        .tlb_flush_all  = dummy_tlb_flush_all,
-       .tlb_add_flush  = dummy_tlb_add_flush,
-       .tlb_sync       = dummy_tlb_sync,
+       .tlb_flush_walk = dummy_tlb_flush,
+       .tlb_flush_leaf = dummy_tlb_flush,
+       .tlb_add_page   = dummy_tlb_add_page,
 };
 
 #define __FAIL(ops)    ({                              \
@@ -896,7 +945,7 @@ static int __init arm_v7s_do_selftests(void)
        size = 1UL << __ffs(cfg.pgsize_bitmap);
        while (i < loopnr) {
                iova_start = i * SZ_16M;
-               if (ops->unmap(ops, iova_start + size, size) != size)
+               if (ops->unmap(ops, iova_start + size, size, NULL) != size)
                        return __FAIL(ops);
 
                /* Remap of partial unmap */
@@ -914,7 +963,7 @@ static int __init arm_v7s_do_selftests(void)
        for_each_set_bit(i, &cfg.pgsize_bitmap, BITS_PER_LONG) {
                size = 1UL << i;
 
-               if (ops->unmap(ops, iova, size) != size)
+               if (ops->unmap(ops, iova, size, NULL) != size)
                        return __FAIL(ops);
 
                if (ops->iova_to_phys(ops, iova + 42))
index 161a7d5..4c91359 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/atomic.h>
 #include <linux/bitops.h>
 #include <linux/io-pgtable.h>
-#include <linux/iommu.h>
 #include <linux/kernel.h>
 #include <linux/sizes.h>
 #include <linux/slab.h>
@@ -290,6 +289,7 @@ static void __arm_lpae_set_pte(arm_lpae_iopte *ptep, arm_lpae_iopte pte,
 }
 
 static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
+                              struct iommu_iotlb_gather *gather,
                               unsigned long iova, size_t size, int lvl,
                               arm_lpae_iopte *ptep);
 
@@ -335,8 +335,10 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
                size_t sz = ARM_LPAE_BLOCK_SIZE(lvl, data);
 
                tblp = ptep - ARM_LPAE_LVL_IDX(iova, lvl, data);
-               if (WARN_ON(__arm_lpae_unmap(data, iova, sz, lvl, tblp) != sz))
+               if (__arm_lpae_unmap(data, NULL, iova, sz, lvl, tblp) != sz) {
+                       WARN_ON(1);
                        return -EINVAL;
+               }
        }
 
        __arm_lpae_init_pte(data, paddr, prot, lvl, ptep);
@@ -537,6 +539,7 @@ static void arm_lpae_free_pgtable(struct io_pgtable *iop)
 }
 
 static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
+                                      struct iommu_iotlb_gather *gather,
                                       unsigned long iova, size_t size,
                                       arm_lpae_iopte blk_pte, int lvl,
                                       arm_lpae_iopte *ptep)
@@ -582,15 +585,15 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data,
 
                tablep = iopte_deref(pte, data);
        } else if (unmap_idx >= 0) {
-               io_pgtable_tlb_add_flush(&data->iop, iova, size, size, true);
-               io_pgtable_tlb_sync(&data->iop);
+               io_pgtable_tlb_add_page(&data->iop, gather, iova, size);
                return size;
        }
 
-       return __arm_lpae_unmap(data, iova, size, lvl, tablep);
+       return __arm_lpae_unmap(data, gather, iova, size, lvl, tablep);
 }
 
 static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
+                              struct iommu_iotlb_gather *gather,
                               unsigned long iova, size_t size, int lvl,
                               arm_lpae_iopte *ptep)
 {
@@ -612,9 +615,8 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
 
                if (!iopte_leaf(pte, lvl, iop->fmt)) {
                        /* Also flush any partial walks */
-                       io_pgtable_tlb_add_flush(iop, iova, size,
-                                               ARM_LPAE_GRANULE(data), false);
-                       io_pgtable_tlb_sync(iop);
+                       io_pgtable_tlb_flush_walk(iop, iova, size,
+                                                 ARM_LPAE_GRANULE(data));
                        ptep = iopte_deref(pte, data);
                        __arm_lpae_free_pgtable(data, lvl + 1, ptep);
                } else if (iop->cfg.quirks & IO_PGTABLE_QUIRK_NON_STRICT) {
@@ -625,7 +627,7 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
                         */
                        smp_wmb();
                } else {
-                       io_pgtable_tlb_add_flush(iop, iova, size, size, true);
+                       io_pgtable_tlb_add_page(iop, gather, iova, size);
                }
 
                return size;
@@ -634,17 +636,17 @@ static size_t __arm_lpae_unmap(struct arm_lpae_io_pgtable *data,
                 * Insert a table at the next level to map the old region,
                 * minus the part we want to unmap
                 */
-               return arm_lpae_split_blk_unmap(data, iova, size, pte,
+               return arm_lpae_split_blk_unmap(data, gather, iova, size, pte,
                                                lvl + 1, ptep);
        }
 
        /* Keep on walkin' */
        ptep = iopte_deref(pte, data);
-       return __arm_lpae_unmap(data, iova, size, lvl + 1, ptep);
+       return __arm_lpae_unmap(data, gather, iova, size, lvl + 1, ptep);
 }
 
 static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova,
-                            size_t size)
+                            size_t size, struct iommu_iotlb_gather *gather)
 {
        struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
        arm_lpae_iopte *ptep = data->pgd;
@@ -653,7 +655,7 @@ static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova,
        if (WARN_ON(iova >= (1ULL << data->iop.cfg.ias)))
                return 0;
 
-       return __arm_lpae_unmap(data, iova, size, lvl, ptep);
+       return __arm_lpae_unmap(data, gather, iova, size, lvl, ptep);
 }
 
 static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
@@ -1070,22 +1072,24 @@ static void dummy_tlb_flush_all(void *cookie)
        WARN_ON(cookie != cfg_cookie);
 }
 
-static void dummy_tlb_add_flush(unsigned long iova, size_t size,
-                               size_t granule, bool leaf, void *cookie)
+static void dummy_tlb_flush(unsigned long iova, size_t size, size_t granule,
+                           void *cookie)
 {
        WARN_ON(cookie != cfg_cookie);
        WARN_ON(!(size & cfg_cookie->pgsize_bitmap));
 }
 
-static void dummy_tlb_sync(void *cookie)
+static void dummy_tlb_add_page(struct iommu_iotlb_gather *gather,
+                              unsigned long iova, size_t granule, void *cookie)
 {
-       WARN_ON(cookie != cfg_cookie);
+       dummy_tlb_flush(iova, granule, granule, cookie);
 }
 
-static const struct iommu_gather_ops dummy_tlb_ops __initconst = {
+static const struct iommu_flush_ops dummy_tlb_ops __initconst = {
        .tlb_flush_all  = dummy_tlb_flush_all,
-       .tlb_add_flush  = dummy_tlb_add_flush,
-       .tlb_sync       = dummy_tlb_sync,
+       .tlb_flush_walk = dummy_tlb_flush,
+       .tlb_flush_leaf = dummy_tlb_flush,
+       .tlb_add_page   = dummy_tlb_add_page,
 };
 
 static void __init arm_lpae_dump_ops(struct io_pgtable_ops *ops)
@@ -1168,7 +1172,7 @@ static int __init arm_lpae_run_tests(struct io_pgtable_cfg *cfg)
 
                /* Partial unmap */
                size = 1UL << __ffs(cfg->pgsize_bitmap);
-               if (ops->unmap(ops, SZ_1G + size, size) != size)
+               if (ops->unmap(ops, SZ_1G + size, size, NULL) != size)
                        return __FAIL(ops, i);
 
                /* Remap of partial unmap */
@@ -1183,7 +1187,7 @@ static int __init arm_lpae_run_tests(struct io_pgtable_cfg *cfg)
                for_each_set_bit(j, &cfg->pgsize_bitmap, BITS_PER_LONG) {
                        size = 1UL << j;
 
-                       if (ops->unmap(ops, iova, size) != size)
+                       if (ops->unmap(ops, iova, size, NULL) != size)
                                return __FAIL(ops, i);
 
                        if (ops->iova_to_phys(ops, iova + 42))
index 0c674d8..d658c7c 100644 (file)
 
 static struct kset *iommu_group_kset;
 static DEFINE_IDA(iommu_group_ida);
-#ifdef CONFIG_IOMMU_DEFAULT_PASSTHROUGH
-static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
-#else
-static unsigned int iommu_def_domain_type = IOMMU_DOMAIN_DMA;
-#endif
+
+static unsigned int iommu_def_domain_type __read_mostly;
 static bool iommu_dma_strict __read_mostly = true;
+static u32 iommu_cmd_line __read_mostly;
 
 struct iommu_group {
        struct kobject kobj;
@@ -68,6 +66,18 @@ static const char * const iommu_group_resv_type_string[] = {
        [IOMMU_RESV_SW_MSI]                     = "msi",
 };
 
+#define IOMMU_CMD_LINE_DMA_API         BIT(0)
+
+static void iommu_set_cmd_line_dma_api(void)
+{
+       iommu_cmd_line |= IOMMU_CMD_LINE_DMA_API;
+}
+
+static bool iommu_cmd_line_dma_api(void)
+{
+       return !!(iommu_cmd_line & IOMMU_CMD_LINE_DMA_API);
+}
+
 #define IOMMU_GROUP_ATTR(_name, _mode, _show, _store)          \
 struct iommu_group_attribute iommu_group_attr_##_name =                \
        __ATTR(_name, _mode, _show, _store)
@@ -80,12 +90,55 @@ struct iommu_group_attribute iommu_group_attr_##_name =             \
 static LIST_HEAD(iommu_device_list);
 static DEFINE_SPINLOCK(iommu_device_lock);
 
+/*
+ * Use a function instead of an array here because the domain-type is a
+ * bit-field, so an array would waste memory.
+ */
+static const char *iommu_domain_type_str(unsigned int t)
+{
+       switch (t) {
+       case IOMMU_DOMAIN_BLOCKED:
+               return "Blocked";
+       case IOMMU_DOMAIN_IDENTITY:
+               return "Passthrough";
+       case IOMMU_DOMAIN_UNMANAGED:
+               return "Unmanaged";
+       case IOMMU_DOMAIN_DMA:
+               return "Translated";
+       default:
+               return "Unknown";
+       }
+}
+
+static int __init iommu_subsys_init(void)
+{
+       bool cmd_line = iommu_cmd_line_dma_api();
+
+       if (!cmd_line) {
+               if (IS_ENABLED(CONFIG_IOMMU_DEFAULT_PASSTHROUGH))
+                       iommu_set_default_passthrough(false);
+               else
+                       iommu_set_default_translated(false);
+
+               if (iommu_default_passthrough() && mem_encrypt_active()) {
+                       pr_info("Memory encryption detected - Disabling default IOMMU Passthrough\n");
+                       iommu_set_default_translated(false);
+               }
+       }
+
+       pr_info("Default domain type: %s %s\n",
+               iommu_domain_type_str(iommu_def_domain_type),
+               cmd_line ? "(set via kernel command line)" : "");
+
+       return 0;
+}
+subsys_initcall(iommu_subsys_init);
+
 int iommu_device_register(struct iommu_device *iommu)
 {
        spin_lock(&iommu_device_lock);
        list_add_tail(&iommu->list, &iommu_device_list);
        spin_unlock(&iommu_device_lock);
-
        return 0;
 }
 
@@ -165,7 +218,11 @@ static int __init iommu_set_def_domain_type(char *str)
        if (ret)
                return ret;
 
-       iommu_def_domain_type = pt ? IOMMU_DOMAIN_IDENTITY : IOMMU_DOMAIN_DMA;
+       if (pt)
+               iommu_set_default_passthrough(true);
+       else
+               iommu_set_default_translated(true);
+
        return 0;
 }
 early_param("iommu.passthrough", iommu_set_def_domain_type);
@@ -229,60 +286,58 @@ static ssize_t iommu_group_show_name(struct iommu_group *group, char *buf)
  * @new: new region to insert
  * @regions: list of regions
  *
- * The new element is sorted by address with respect to the other
- * regions of the same type. In case it overlaps with another
- * region of the same type, regions are merged. In case it
- * overlaps with another region of different type, regions are
- * not merged.
+ * Elements are sorted by start address and overlapping segments
+ * of the same type are merged.
  */
-static int iommu_insert_resv_region(struct iommu_resv_region *new,
-                                   struct list_head *regions)
+int iommu_insert_resv_region(struct iommu_resv_region *new,
+                            struct list_head *regions)
 {
-       struct iommu_resv_region *region;
-       phys_addr_t start = new->start;
-       phys_addr_t end = new->start + new->length - 1;
-       struct list_head *pos = regions->next;
-
-       while (pos != regions) {
-               struct iommu_resv_region *entry =
-                       list_entry(pos, struct iommu_resv_region, list);
-               phys_addr_t a = entry->start;
-               phys_addr_t b = entry->start + entry->length - 1;
-               int type = entry->type;
-
-               if (end < a) {
-                       goto insert;
-               } else if (start > b) {
-                       pos = pos->next;
-               } else if ((start >= a) && (end <= b)) {
-                       if (new->type == type)
-                               return 0;
-                       else
-                               pos = pos->next;
+       struct iommu_resv_region *iter, *tmp, *nr, *top;
+       LIST_HEAD(stack);
+
+       nr = iommu_alloc_resv_region(new->start, new->length,
+                                    new->prot, new->type);
+       if (!nr)
+               return -ENOMEM;
+
+       /* First add the new element based on start address sorting */
+       list_for_each_entry(iter, regions, list) {
+               if (nr->start < iter->start ||
+                   (nr->start == iter->start && nr->type <= iter->type))
+                       break;
+       }
+       list_add_tail(&nr->list, &iter->list);
+
+       /* Merge overlapping segments of type nr->type in @regions, if any */
+       list_for_each_entry_safe(iter, tmp, regions, list) {
+               phys_addr_t top_end, iter_end = iter->start + iter->length - 1;
+
+               /* no merge needed on elements of different types than @nr */
+               if (iter->type != nr->type) {
+                       list_move_tail(&iter->list, &stack);
+                       continue;
+               }
+
+               /* look for the last stack element of same type as @iter */
+               list_for_each_entry_reverse(top, &stack, list)
+                       if (top->type == iter->type)
+                               goto check_overlap;
+
+               list_move_tail(&iter->list, &stack);
+               continue;
+
+check_overlap:
+               top_end = top->start + top->length - 1;
+
+               if (iter->start > top_end + 1) {
+                       list_move_tail(&iter->list, &stack);
                } else {
-                       if (new->type == type) {
-                               phys_addr_t new_start = min(a, start);
-                               phys_addr_t new_end = max(b, end);
-                               int ret;
-
-                               list_del(&entry->list);
-                               entry->start = new_start;
-                               entry->length = new_end - new_start + 1;
-                               ret = iommu_insert_resv_region(entry, regions);
-                               kfree(entry);
-                               return ret;
-                       } else {
-                               pos = pos->next;
-                       }
+                       top->length = max(top_end, iter_end) - top->start + 1;
+                       list_del(&iter->list);
+                       kfree(iter);
                }
        }
-insert:
-       region = iommu_alloc_resv_region(new->start, new->length,
-                                        new->prot, new->type);
-       if (!region)
-               return -ENOMEM;
-
-       list_add_tail(&region->list, pos);
+       list_splice(&stack, regions);
        return 0;
 }
 
@@ -1862,7 +1917,7 @@ EXPORT_SYMBOL_GPL(iommu_map);
 
 static size_t __iommu_unmap(struct iommu_domain *domain,
                            unsigned long iova, size_t size,
-                           bool sync)
+                           struct iommu_iotlb_gather *iotlb_gather)
 {
        const struct iommu_ops *ops = domain->ops;
        size_t unmapped_page, unmapped = 0;
@@ -1899,13 +1954,10 @@ static size_t __iommu_unmap(struct iommu_domain *domain,
        while (unmapped < size) {
                size_t pgsize = iommu_pgsize(domain, iova, size - unmapped);
 
-               unmapped_page = ops->unmap(domain, iova, pgsize);
+               unmapped_page = ops->unmap(domain, iova, pgsize, iotlb_gather);
                if (!unmapped_page)
                        break;
 
-               if (sync && ops->iotlb_range_add)
-                       ops->iotlb_range_add(domain, iova, pgsize);
-
                pr_debug("unmapped: iova 0x%lx size 0x%zx\n",
                         iova, unmapped_page);
 
@@ -1913,9 +1965,6 @@ static size_t __iommu_unmap(struct iommu_domain *domain,
                unmapped += unmapped_page;
        }
 
-       if (sync && ops->iotlb_sync)
-               ops->iotlb_sync(domain);
-
        trace_unmap(orig_iova, size, unmapped);
        return unmapped;
 }
@@ -1923,14 +1972,22 @@ static size_t __iommu_unmap(struct iommu_domain *domain,
 size_t iommu_unmap(struct iommu_domain *domain,
                   unsigned long iova, size_t size)
 {
-       return __iommu_unmap(domain, iova, size, true);
+       struct iommu_iotlb_gather iotlb_gather;
+       size_t ret;
+
+       iommu_iotlb_gather_init(&iotlb_gather);
+       ret = __iommu_unmap(domain, iova, size, &iotlb_gather);
+       iommu_tlb_sync(domain, &iotlb_gather);
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(iommu_unmap);
 
 size_t iommu_unmap_fast(struct iommu_domain *domain,
-                       unsigned long iova, size_t size)
+                       unsigned long iova, size_t size,
+                       struct iommu_iotlb_gather *iotlb_gather)
 {
-       return __iommu_unmap(domain, iova, size, false);
+       return __iommu_unmap(domain, iova, size, iotlb_gather);
 }
 EXPORT_SYMBOL_GPL(iommu_unmap_fast);
 
@@ -2143,7 +2200,6 @@ request_default_domain_for_dev(struct device *dev, unsigned long type)
 
        mutex_lock(&group->mutex);
 
-       /* Check if the default domain is already direct mapped */
        ret = 0;
        if (group->default_domain && group->default_domain->type == type)
                goto out;
@@ -2153,7 +2209,6 @@ request_default_domain_for_dev(struct device *dev, unsigned long type)
        if (iommu_group_device_count(group) != 1)
                goto out;
 
-       /* Allocate a direct mapped domain */
        ret = -ENOMEM;
        domain = __iommu_domain_alloc(dev->bus, type);
        if (!domain)
@@ -2168,7 +2223,7 @@ request_default_domain_for_dev(struct device *dev, unsigned long type)
 
        iommu_group_create_direct_mappings(group, dev);
 
-       /* Make the direct mapped domain the default for this group */
+       /* Make the domain the default for this group */
        if (group->default_domain)
                iommu_domain_free(group->default_domain);
        group->default_domain = domain;
@@ -2196,6 +2251,28 @@ int iommu_request_dma_domain_for_dev(struct device *dev)
        return request_default_domain_for_dev(dev, IOMMU_DOMAIN_DMA);
 }
 
+void iommu_set_default_passthrough(bool cmd_line)
+{
+       if (cmd_line)
+               iommu_set_cmd_line_dma_api();
+
+       iommu_def_domain_type = IOMMU_DOMAIN_IDENTITY;
+}
+
+void iommu_set_default_translated(bool cmd_line)
+{
+       if (cmd_line)
+               iommu_set_cmd_line_dma_api();
+
+       iommu_def_domain_type = IOMMU_DOMAIN_DMA;
+}
+
+bool iommu_default_passthrough(void)
+{
+       return iommu_def_domain_type == IOMMU_DOMAIN_IDENTITY;
+}
+EXPORT_SYMBOL_GPL(iommu_default_passthrough);
+
 const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode)
 {
        const struct iommu_ops *ops = NULL;
index 3e1a8a6..41c605b 100644 (file)
@@ -577,7 +577,9 @@ void queue_iova(struct iova_domain *iovad,
 
        spin_unlock_irqrestore(&fq->lock, flags);
 
-       if (atomic_cmpxchg(&iovad->fq_timer_on, 0, 1) == 0)
+       /* Avoid false sharing as much as possible. */
+       if (!atomic_read(&iovad->fq_timer_on) &&
+           !atomic_cmpxchg(&iovad->fq_timer_on, 0, 1))
                mod_timer(&iovad->fq_timer,
                          jiffies + msecs_to_jiffies(IOVA_FQ_TIMEOUT));
 }
index ad0098c..9da8309 100644 (file)
@@ -49,6 +49,7 @@ struct ipmmu_features {
        bool setup_imbuscr;
        bool twobit_imttbcr_sl0;
        bool reserved_context;
+       bool cache_snoop;
 };
 
 struct ipmmu_vmsa_device {
@@ -115,45 +116,44 @@ static struct ipmmu_vmsa_device *to_ipmmu(struct device *dev)
 #define IMTTBCR                                0x0008
 #define IMTTBCR_EAE                    (1 << 31)
 #define IMTTBCR_PMB                    (1 << 30)
-#define IMTTBCR_SH1_NON_SHAREABLE      (0 << 28)
-#define IMTTBCR_SH1_OUTER_SHAREABLE    (2 << 28)
-#define IMTTBCR_SH1_INNER_SHAREABLE    (3 << 28)
-#define IMTTBCR_SH1_MASK               (3 << 28)
-#define IMTTBCR_ORGN1_NC               (0 << 26)
-#define IMTTBCR_ORGN1_WB_WA            (1 << 26)
-#define IMTTBCR_ORGN1_WT               (2 << 26)
-#define IMTTBCR_ORGN1_WB               (3 << 26)
-#define IMTTBCR_ORGN1_MASK             (3 << 26)
-#define IMTTBCR_IRGN1_NC               (0 << 24)
-#define IMTTBCR_IRGN1_WB_WA            (1 << 24)
-#define IMTTBCR_IRGN1_WT               (2 << 24)
-#define IMTTBCR_IRGN1_WB               (3 << 24)
-#define IMTTBCR_IRGN1_MASK             (3 << 24)
+#define IMTTBCR_SH1_NON_SHAREABLE      (0 << 28)       /* R-Car Gen2 only */
+#define IMTTBCR_SH1_OUTER_SHAREABLE    (2 << 28)       /* R-Car Gen2 only */
+#define IMTTBCR_SH1_INNER_SHAREABLE    (3 << 28)       /* R-Car Gen2 only */
+#define IMTTBCR_SH1_MASK               (3 << 28)       /* R-Car Gen2 only */
+#define IMTTBCR_ORGN1_NC               (0 << 26)       /* R-Car Gen2 only */
+#define IMTTBCR_ORGN1_WB_WA            (1 << 26)       /* R-Car Gen2 only */
+#define IMTTBCR_ORGN1_WT               (2 << 26)       /* R-Car Gen2 only */
+#define IMTTBCR_ORGN1_WB               (3 << 26)       /* R-Car Gen2 only */
+#define IMTTBCR_ORGN1_MASK             (3 << 26)       /* R-Car Gen2 only */
+#define IMTTBCR_IRGN1_NC               (0 << 24)       /* R-Car Gen2 only */
+#define IMTTBCR_IRGN1_WB_WA            (1 << 24)       /* R-Car Gen2 only */
+#define IMTTBCR_IRGN1_WT               (2 << 24)       /* R-Car Gen2 only */
+#define IMTTBCR_IRGN1_WB               (3 << 24)       /* R-Car Gen2 only */
+#define IMTTBCR_IRGN1_MASK             (3 << 24)       /* R-Car Gen2 only */
 #define IMTTBCR_TSZ1_MASK              (7 << 16)
 #define IMTTBCR_TSZ1_SHIFT             16
-#define IMTTBCR_SH0_NON_SHAREABLE      (0 << 12)
-#define IMTTBCR_SH0_OUTER_SHAREABLE    (2 << 12)
-#define IMTTBCR_SH0_INNER_SHAREABLE    (3 << 12)
-#define IMTTBCR_SH0_MASK               (3 << 12)
-#define IMTTBCR_ORGN0_NC               (0 << 10)
-#define IMTTBCR_ORGN0_WB_WA            (1 << 10)
-#define IMTTBCR_ORGN0_WT               (2 << 10)
-#define IMTTBCR_ORGN0_WB               (3 << 10)
-#define IMTTBCR_ORGN0_MASK             (3 << 10)
-#define IMTTBCR_IRGN0_NC               (0 << 8)
-#define IMTTBCR_IRGN0_WB_WA            (1 << 8)
-#define IMTTBCR_IRGN0_WT               (2 << 8)
-#define IMTTBCR_IRGN0_WB               (3 << 8)
-#define IMTTBCR_IRGN0_MASK             (3 << 8)
+#define IMTTBCR_SH0_NON_SHAREABLE      (0 << 12)       /* R-Car Gen2 only */
+#define IMTTBCR_SH0_OUTER_SHAREABLE    (2 << 12)       /* R-Car Gen2 only */
+#define IMTTBCR_SH0_INNER_SHAREABLE    (3 << 12)       /* R-Car Gen2 only */
+#define IMTTBCR_SH0_MASK               (3 << 12)       /* R-Car Gen2 only */
+#define IMTTBCR_ORGN0_NC               (0 << 10)       /* R-Car Gen2 only */
+#define IMTTBCR_ORGN0_WB_WA            (1 << 10)       /* R-Car Gen2 only */
+#define IMTTBCR_ORGN0_WT               (2 << 10)       /* R-Car Gen2 only */
+#define IMTTBCR_ORGN0_WB               (3 << 10)       /* R-Car Gen2 only */
+#define IMTTBCR_ORGN0_MASK             (3 << 10)       /* R-Car Gen2 only */
+#define IMTTBCR_IRGN0_NC               (0 << 8)        /* R-Car Gen2 only */
+#define IMTTBCR_IRGN0_WB_WA            (1 << 8)        /* R-Car Gen2 only */
+#define IMTTBCR_IRGN0_WT               (2 << 8)        /* R-Car Gen2 only */
+#define IMTTBCR_IRGN0_WB               (3 << 8)        /* R-Car Gen2 only */
+#define IMTTBCR_IRGN0_MASK             (3 << 8)        /* R-Car Gen2 only */
+#define IMTTBCR_SL0_TWOBIT_LVL_3       (0 << 6)        /* R-Car Gen3 only */
+#define IMTTBCR_SL0_TWOBIT_LVL_2       (1 << 6)        /* R-Car Gen3 only */
+#define IMTTBCR_SL0_TWOBIT_LVL_1       (2 << 6)        /* R-Car Gen3 only */
 #define IMTTBCR_SL0_LVL_2              (0 << 4)
 #define IMTTBCR_SL0_LVL_1              (1 << 4)
 #define IMTTBCR_TSZ0_MASK              (7 << 0)
 #define IMTTBCR_TSZ0_SHIFT             O
 
-#define IMTTBCR_SL0_TWOBIT_LVL_3       (0 << 6)
-#define IMTTBCR_SL0_TWOBIT_LVL_2       (1 << 6)
-#define IMTTBCR_SL0_TWOBIT_LVL_1       (2 << 6)
-
 #define IMBUSCR                                0x000c
 #define IMBUSCR_DVM                    (1 << 2)
 #define IMBUSCR_BUSSEL_SYS             (0 << 0)
@@ -361,16 +361,16 @@ static void ipmmu_tlb_flush_all(void *cookie)
        ipmmu_tlb_invalidate(domain);
 }
 
-static void ipmmu_tlb_add_flush(unsigned long iova, size_t size,
-                               size_t granule, bool leaf, void *cookie)
+static void ipmmu_tlb_flush(unsigned long iova, size_t size,
+                               size_t granule, void *cookie)
 {
-       /* The hardware doesn't support selective TLB flush. */
+       ipmmu_tlb_flush_all(cookie);
 }
 
-static const struct iommu_gather_ops ipmmu_gather_ops = {
+static const struct iommu_flush_ops ipmmu_flush_ops = {
        .tlb_flush_all = ipmmu_tlb_flush_all,
-       .tlb_add_flush = ipmmu_tlb_add_flush,
-       .tlb_sync = ipmmu_tlb_flush_all,
+       .tlb_flush_walk = ipmmu_tlb_flush,
+       .tlb_flush_leaf = ipmmu_tlb_flush,
 };
 
 /* -----------------------------------------------------------------------------
@@ -422,17 +422,19 @@ static void ipmmu_domain_setup_context(struct ipmmu_vmsa_domain *domain)
 
        /*
         * TTBCR
-        * We use long descriptors with inner-shareable WBWA tables and allocate
-        * the whole 32-bit VA space to TTBR0.
+        * We use long descriptors and allocate the whole 32-bit VA space to
+        * TTBR0.
         */
        if (domain->mmu->features->twobit_imttbcr_sl0)
                tmp = IMTTBCR_SL0_TWOBIT_LVL_1;
        else
                tmp = IMTTBCR_SL0_LVL_1;
 
-       ipmmu_ctx_write_root(domain, IMTTBCR, IMTTBCR_EAE |
-                            IMTTBCR_SH0_INNER_SHAREABLE | IMTTBCR_ORGN0_WB_WA |
-                            IMTTBCR_IRGN0_WB_WA | tmp);
+       if (domain->mmu->features->cache_snoop)
+               tmp |= IMTTBCR_SH0_INNER_SHAREABLE | IMTTBCR_ORGN0_WB_WA |
+                      IMTTBCR_IRGN0_WB_WA;
+
+       ipmmu_ctx_write_root(domain, IMTTBCR, IMTTBCR_EAE | tmp);
 
        /* MAIR0 */
        ipmmu_ctx_write_root(domain, IMMAIR0,
@@ -480,7 +482,7 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain)
        domain->cfg.pgsize_bitmap = SZ_1G | SZ_2M | SZ_4K;
        domain->cfg.ias = 32;
        domain->cfg.oas = 40;
-       domain->cfg.tlb = &ipmmu_gather_ops;
+       domain->cfg.tlb = &ipmmu_flush_ops;
        domain->io_domain.geometry.aperture_end = DMA_BIT_MASK(32);
        domain->io_domain.geometry.force_aperture = true;
        /*
@@ -733,14 +735,14 @@ static int ipmmu_map(struct iommu_domain *io_domain, unsigned long iova,
 }
 
 static size_t ipmmu_unmap(struct iommu_domain *io_domain, unsigned long iova,
-                         size_t size)
+                         size_t size, struct iommu_iotlb_gather *gather)
 {
        struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 
-       return domain->iop->unmap(domain->iop, iova, size);
+       return domain->iop->unmap(domain->iop, iova, size, gather);
 }
 
-static void ipmmu_iotlb_sync(struct iommu_domain *io_domain)
+static void ipmmu_flush_iotlb_all(struct iommu_domain *io_domain)
 {
        struct ipmmu_vmsa_domain *domain = to_vmsa_domain(io_domain);
 
@@ -748,6 +750,12 @@ static void ipmmu_iotlb_sync(struct iommu_domain *io_domain)
                ipmmu_tlb_flush_all(domain);
 }
 
+static void ipmmu_iotlb_sync(struct iommu_domain *io_domain,
+                            struct iommu_iotlb_gather *gather)
+{
+       ipmmu_flush_iotlb_all(io_domain);
+}
+
 static phys_addr_t ipmmu_iova_to_phys(struct iommu_domain *io_domain,
                                      dma_addr_t iova)
 {
@@ -957,7 +965,7 @@ static const struct iommu_ops ipmmu_ops = {
        .detach_dev = ipmmu_detach_device,
        .map = ipmmu_map,
        .unmap = ipmmu_unmap,
-       .flush_iotlb_all = ipmmu_iotlb_sync,
+       .flush_iotlb_all = ipmmu_flush_iotlb_all,
        .iotlb_sync = ipmmu_iotlb_sync,
        .iova_to_phys = ipmmu_iova_to_phys,
        .add_device = ipmmu_add_device,
@@ -988,6 +996,7 @@ static const struct ipmmu_features ipmmu_features_default = {
        .setup_imbuscr = true,
        .twobit_imttbcr_sl0 = false,
        .reserved_context = false,
+       .cache_snoop = true,
 };
 
 static const struct ipmmu_features ipmmu_features_rcar_gen3 = {
@@ -998,6 +1007,7 @@ static const struct ipmmu_features ipmmu_features_rcar_gen3 = {
        .setup_imbuscr = false,
        .twobit_imttbcr_sl0 = true,
        .reserved_context = true,
+       .cache_snoop = false,
 };
 
 static const struct of_device_id ipmmu_of_ids[] = {
index b25e2eb..be99d40 100644 (file)
@@ -168,20 +168,29 @@ fail:
        return;
 }
 
-static void __flush_iotlb_sync(void *cookie)
+static void __flush_iotlb_walk(unsigned long iova, size_t size,
+                              size_t granule, void *cookie)
 {
-       /*
-        * Nothing is needed here, the barrier to guarantee
-        * completion of the tlb sync operation is implicitly
-        * taken care when the iommu client does a writel before
-        * kick starting the other master.
-        */
+       __flush_iotlb_range(iova, size, granule, false, cookie);
+}
+
+static void __flush_iotlb_leaf(unsigned long iova, size_t size,
+                              size_t granule, void *cookie)
+{
+       __flush_iotlb_range(iova, size, granule, true, cookie);
 }
 
-static const struct iommu_gather_ops msm_iommu_gather_ops = {
+static void __flush_iotlb_page(struct iommu_iotlb_gather *gather,
+                              unsigned long iova, size_t granule, void *cookie)
+{
+       __flush_iotlb_range(iova, granule, granule, true, cookie);
+}
+
+static const struct iommu_flush_ops msm_iommu_flush_ops = {
        .tlb_flush_all = __flush_iotlb,
-       .tlb_add_flush = __flush_iotlb_range,
-       .tlb_sync = __flush_iotlb_sync,
+       .tlb_flush_walk = __flush_iotlb_walk,
+       .tlb_flush_leaf = __flush_iotlb_leaf,
+       .tlb_add_page = __flush_iotlb_page,
 };
 
 static int msm_iommu_alloc_ctx(unsigned long *map, int start, int end)
@@ -345,7 +354,7 @@ static int msm_iommu_domain_config(struct msm_priv *priv)
                .pgsize_bitmap = msm_iommu_ops.pgsize_bitmap,
                .ias = 32,
                .oas = 32,
-               .tlb = &msm_iommu_gather_ops,
+               .tlb = &msm_iommu_flush_ops,
                .iommu_dev = priv->dev,
        };
 
@@ -509,13 +518,13 @@ static int msm_iommu_map(struct iommu_domain *domain, unsigned long iova,
 }
 
 static size_t msm_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
-                             size_t len)
+                             size_t len, struct iommu_iotlb_gather *gather)
 {
        struct msm_priv *priv = to_msm_priv(domain);
        unsigned long flags;
 
        spin_lock_irqsave(&priv->pgtlock, flags);
-       len = priv->iop->unmap(priv->iop, iova, len);
+       len = priv->iop->unmap(priv->iop, iova, len, gather);
        spin_unlock_irqrestore(&priv->pgtlock, flags);
 
        return len;
@@ -691,6 +700,13 @@ static struct iommu_ops msm_iommu_ops = {
        .detach_dev = msm_iommu_detach_dev,
        .map = msm_iommu_map,
        .unmap = msm_iommu_unmap,
+       /*
+        * Nothing is needed here, the barrier to guarantee
+        * completion of the tlb sync operation is implicitly
+        * taken care when the iommu client does a writel before
+        * kick starting the other master.
+        */
+       .iotlb_sync = NULL,
        .iova_to_phys = msm_iommu_iova_to_phys,
        .add_device = msm_iommu_add_device,
        .remove_device = msm_iommu_remove_device,
@@ -750,7 +766,6 @@ static int msm_iommu_probe(struct platform_device *pdev)
 
        iommu->irq = platform_get_irq(pdev, 0);
        if (iommu->irq < 0) {
-               dev_err(iommu->dev, "could not get iommu irq\n");
                ret = -ENODEV;
                goto fail;
        }
index 82e4be4..67a483c 100644 (file)
@@ -28,6 +28,7 @@
 #include "mtk_iommu.h"
 
 #define REG_MMU_PT_BASE_ADDR                   0x000
+#define MMU_PT_ADDR_MASK                       GENMASK(31, 7)
 
 #define REG_MMU_INVALIDATE                     0x020
 #define F_ALL_INVLD                            0x2
 #define REG_MMU_DCM_DIS                                0x050
 
 #define REG_MMU_CTRL_REG                       0x110
+#define F_MMU_TF_PROT_TO_PROGRAM_ADDR          (2 << 4)
 #define F_MMU_PREFETCH_RT_REPLACE_MOD          BIT(4)
-#define F_MMU_TF_PROTECT_SEL_SHIFT(data) \
-       ((data)->m4u_plat == M4U_MT2712 ? 4 : 5)
-/* It's named by F_MMU_TF_PROT_SEL in mt2712. */
-#define F_MMU_TF_PROTECT_SEL(prot, data) \
-       (((prot) & 0x3) << F_MMU_TF_PROTECT_SEL_SHIFT(data))
+#define F_MMU_TF_PROT_TO_PROGRAM_ADDR_MT8173   (2 << 5)
 
 #define REG_MMU_IVRP_PADDR                     0x114
 
 #define F_INT_CLR_BIT                          BIT(12)
 
 #define REG_MMU_INT_MAIN_CONTROL               0x124
-#define F_INT_TRANSLATION_FAULT                        BIT(0)
-#define F_INT_MAIN_MULTI_HIT_FAULT             BIT(1)
-#define F_INT_INVALID_PA_FAULT                 BIT(2)
-#define F_INT_ENTRY_REPLACEMENT_FAULT          BIT(3)
-#define F_INT_TLB_MISS_FAULT                   BIT(4)
-#define F_INT_MISS_TRANSACTION_FIFO_FAULT      BIT(5)
-#define F_INT_PRETETCH_TRANSATION_FIFO_FAULT   BIT(6)
+                                               /* mmu0 | mmu1 */
+#define F_INT_TRANSLATION_FAULT                        (BIT(0) | BIT(7))
+#define F_INT_MAIN_MULTI_HIT_FAULT             (BIT(1) | BIT(8))
+#define F_INT_INVALID_PA_FAULT                 (BIT(2) | BIT(9))
+#define F_INT_ENTRY_REPLACEMENT_FAULT          (BIT(3) | BIT(10))
+#define F_INT_TLB_MISS_FAULT                   (BIT(4) | BIT(11))
+#define F_INT_MISS_TRANSACTION_FIFO_FAULT      (BIT(5) | BIT(12))
+#define F_INT_PRETETCH_TRANSATION_FIFO_FAULT   (BIT(6) | BIT(13))
 
 #define REG_MMU_CPE_DONE                       0x12C
 
 #define REG_MMU_FAULT_ST1                      0x134
+#define F_REG_MMU0_FAULT_MASK                  GENMASK(6, 0)
+#define F_REG_MMU1_FAULT_MASK                  GENMASK(13, 7)
 
-#define REG_MMU_FAULT_VA                       0x13c
+#define REG_MMU0_FAULT_VA                      0x13c
 #define F_MMU_FAULT_VA_WRITE_BIT               BIT(1)
 #define F_MMU_FAULT_VA_LAYER_BIT               BIT(0)
 
-#define REG_MMU_INVLD_PA                       0x140
-#define REG_MMU_INT_ID                         0x150
-#define F_MMU0_INT_ID_LARB_ID(a)               (((a) >> 7) & 0x7)
-#define F_MMU0_INT_ID_PORT_ID(a)               (((a) >> 2) & 0x1f)
+#define REG_MMU0_INVLD_PA                      0x140
+#define REG_MMU1_FAULT_VA                      0x144
+#define REG_MMU1_INVLD_PA                      0x148
+#define REG_MMU0_INT_ID                                0x150
+#define REG_MMU1_INT_ID                                0x154
+#define F_MMU_INT_ID_LARB_ID(a)                        (((a) >> 7) & 0x7)
+#define F_MMU_INT_ID_PORT_ID(a)                        (((a) >> 2) & 0x1f)
 
 #define MTK_PROTECT_PA_ALIGN                   128
 
@@ -107,6 +111,30 @@ struct mtk_iommu_domain {
 
 static const struct iommu_ops mtk_iommu_ops;
 
+/*
+ * In M4U 4GB mode, the physical address is remapped as below:
+ *
+ * CPU Physical address:
+ * ====================
+ *
+ * 0      1G       2G     3G       4G     5G
+ * |---A---|---B---|---C---|---D---|---E---|
+ * +--I/O--+------------Memory-------------+
+ *
+ * IOMMU output physical address:
+ *  =============================
+ *
+ *                                 4G      5G     6G      7G      8G
+ *                                 |---E---|---B---|---C---|---D---|
+ *                                 +------------Memory-------------+
+ *
+ * The Region 'A'(I/O) can NOT be mapped by M4U; For Region 'B'/'C'/'D', the
+ * bit32 of the CPU physical address always is needed to set, and for Region
+ * 'E', the CPU physical address keep as is.
+ * Additionally, The iommu consumers always use the CPU phyiscal address.
+ */
+#define MTK_IOMMU_4GB_MODE_REMAP_BASE   0x140000000UL
+
 static LIST_HEAD(m4ulist);     /* List all the M4U HWs */
 
 #define for_each_m4u(data)     list_for_each_entry(data, &m4ulist, list)
@@ -188,10 +216,32 @@ static void mtk_iommu_tlb_sync(void *cookie)
        }
 }
 
-static const struct iommu_gather_ops mtk_iommu_gather_ops = {
+static void mtk_iommu_tlb_flush_walk(unsigned long iova, size_t size,
+                                    size_t granule, void *cookie)
+{
+       mtk_iommu_tlb_add_flush_nosync(iova, size, granule, false, cookie);
+       mtk_iommu_tlb_sync(cookie);
+}
+
+static void mtk_iommu_tlb_flush_leaf(unsigned long iova, size_t size,
+                                    size_t granule, void *cookie)
+{
+       mtk_iommu_tlb_add_flush_nosync(iova, size, granule, true, cookie);
+       mtk_iommu_tlb_sync(cookie);
+}
+
+static void mtk_iommu_tlb_flush_page_nosync(struct iommu_iotlb_gather *gather,
+                                           unsigned long iova, size_t granule,
+                                           void *cookie)
+{
+       mtk_iommu_tlb_add_flush_nosync(iova, granule, granule, true, cookie);
+}
+
+static const struct iommu_flush_ops mtk_iommu_flush_ops = {
        .tlb_flush_all = mtk_iommu_tlb_flush_all,
-       .tlb_add_flush = mtk_iommu_tlb_add_flush_nosync,
-       .tlb_sync = mtk_iommu_tlb_sync,
+       .tlb_flush_walk = mtk_iommu_tlb_flush_walk,
+       .tlb_flush_leaf = mtk_iommu_tlb_flush_leaf,
+       .tlb_add_page = mtk_iommu_tlb_flush_page_nosync,
 };
 
 static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
@@ -204,13 +254,21 @@ static irqreturn_t mtk_iommu_isr(int irq, void *dev_id)
 
        /* Read error info from registers */
        int_state = readl_relaxed(data->base + REG_MMU_FAULT_ST1);
-       fault_iova = readl_relaxed(data->base + REG_MMU_FAULT_VA);
+       if (int_state & F_REG_MMU0_FAULT_MASK) {
+               regval = readl_relaxed(data->base + REG_MMU0_INT_ID);
+               fault_iova = readl_relaxed(data->base + REG_MMU0_FAULT_VA);
+               fault_pa = readl_relaxed(data->base + REG_MMU0_INVLD_PA);
+       } else {
+               regval = readl_relaxed(data->base + REG_MMU1_INT_ID);
+               fault_iova = readl_relaxed(data->base + REG_MMU1_FAULT_VA);
+               fault_pa = readl_relaxed(data->base + REG_MMU1_INVLD_PA);
+       }
        layer = fault_iova & F_MMU_FAULT_VA_LAYER_BIT;
        write = fault_iova & F_MMU_FAULT_VA_WRITE_BIT;
-       fault_pa = readl_relaxed(data->base + REG_MMU_INVLD_PA);
-       regval = readl_relaxed(data->base + REG_MMU_INT_ID);
-       fault_larb = F_MMU0_INT_ID_LARB_ID(regval);
-       fault_port = F_MMU0_INT_ID_PORT_ID(regval);
+       fault_larb = F_MMU_INT_ID_LARB_ID(regval);
+       fault_port = F_MMU_INT_ID_PORT_ID(regval);
+
+       fault_larb = data->plat_data->larbid_remap[fault_larb];
 
        if (report_iommu_fault(&dom->domain, data->dev, fault_iova,
                               write ? IOMMU_FAULT_WRITE : IOMMU_FAULT_READ)) {
@@ -242,7 +300,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
        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];
+               larb_mmu = &data->larb_imu[larbid];
 
                dev_dbg(dev, "%s iommu port: %d\n",
                        enable ? "enable" : "disable", portid);
@@ -263,17 +321,15 @@ static int mtk_iommu_domain_finalise(struct mtk_iommu_domain *dom)
        dom->cfg = (struct io_pgtable_cfg) {
                .quirks = IO_PGTABLE_QUIRK_ARM_NS |
                        IO_PGTABLE_QUIRK_NO_PERMS |
-                       IO_PGTABLE_QUIRK_TLBI_ON_MAP,
+                       IO_PGTABLE_QUIRK_TLBI_ON_MAP |
+                       IO_PGTABLE_QUIRK_ARM_MTK_EXT,
                .pgsize_bitmap = mtk_iommu_ops.pgsize_bitmap,
                .ias = 32,
-               .oas = 32,
-               .tlb = &mtk_iommu_gather_ops,
+               .oas = 34,
+               .tlb = &mtk_iommu_flush_ops,
                .iommu_dev = data->dev,
        };
 
-       if (data->enable_4GB)
-               dom->cfg.quirks |= IO_PGTABLE_QUIRK_ARM_MTK_4GB;
-
        dom->iop = alloc_io_pgtable_ops(ARM_V7S, &dom->cfg, data);
        if (!dom->iop) {
                dev_err(data->dev, "Failed to alloc io pgtable\n");
@@ -336,7 +392,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
        /* Update the pgtable base address register of the M4U HW */
        if (!data->m4u_dom) {
                data->m4u_dom = dom;
-               writel(dom->cfg.arm_v7s_cfg.ttbr[0],
+               writel(dom->cfg.arm_v7s_cfg.ttbr[0] & MMU_PT_ADDR_MASK,
                       data->base + REG_MMU_PT_BASE_ADDR);
        }
 
@@ -359,32 +415,43 @@ static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova,
                         phys_addr_t paddr, size_t size, int prot)
 {
        struct mtk_iommu_domain *dom = to_mtk_domain(domain);
+       struct mtk_iommu_data *data = mtk_iommu_get_m4u_data();
        unsigned long flags;
        int ret;
 
+       /* The "4GB mode" M4U physically can not use the lower remap of Dram. */
+       if (data->enable_4GB)
+               paddr |= BIT_ULL(32);
+
        spin_lock_irqsave(&dom->pgtlock, flags);
-       ret = dom->iop->map(dom->iop, iova, paddr & DMA_BIT_MASK(32),
-                           size, prot);
+       ret = dom->iop->map(dom->iop, iova, paddr, size, prot);
        spin_unlock_irqrestore(&dom->pgtlock, flags);
 
        return ret;
 }
 
 static size_t mtk_iommu_unmap(struct iommu_domain *domain,
-                             unsigned long iova, size_t size)
+                             unsigned long iova, size_t size,
+                             struct iommu_iotlb_gather *gather)
 {
        struct mtk_iommu_domain *dom = to_mtk_domain(domain);
        unsigned long flags;
        size_t unmapsz;
 
        spin_lock_irqsave(&dom->pgtlock, flags);
-       unmapsz = dom->iop->unmap(dom->iop, iova, size);
+       unmapsz = dom->iop->unmap(dom->iop, iova, size, gather);
        spin_unlock_irqrestore(&dom->pgtlock, flags);
 
        return unmapsz;
 }
 
-static void mtk_iommu_iotlb_sync(struct iommu_domain *domain)
+static void mtk_iommu_flush_iotlb_all(struct iommu_domain *domain)
+{
+       mtk_iommu_tlb_sync(mtk_iommu_get_m4u_data());
+}
+
+static void mtk_iommu_iotlb_sync(struct iommu_domain *domain,
+                                struct iommu_iotlb_gather *gather)
 {
        mtk_iommu_tlb_sync(mtk_iommu_get_m4u_data());
 }
@@ -401,8 +468,8 @@ static phys_addr_t mtk_iommu_iova_to_phys(struct iommu_domain *domain,
        pa = dom->iop->iova_to_phys(dom->iop, iova);
        spin_unlock_irqrestore(&dom->pgtlock, flags);
 
-       if (data->enable_4GB)
-               pa |= BIT_ULL(32);
+       if (data->enable_4GB && pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE)
+               pa &= ~BIT_ULL(32);
 
        return pa;
 }
@@ -490,7 +557,7 @@ static const struct iommu_ops mtk_iommu_ops = {
        .detach_dev     = mtk_iommu_detach_device,
        .map            = mtk_iommu_map,
        .unmap          = mtk_iommu_unmap,
-       .flush_iotlb_all = mtk_iommu_iotlb_sync,
+       .flush_iotlb_all = mtk_iommu_flush_iotlb_all,
        .iotlb_sync     = mtk_iommu_iotlb_sync,
        .iova_to_phys   = mtk_iommu_iova_to_phys,
        .add_device     = mtk_iommu_add_device,
@@ -511,9 +578,11 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
                return ret;
        }
 
-       regval = F_MMU_TF_PROTECT_SEL(2, data);
-       if (data->m4u_plat == M4U_MT8173)
-               regval |= F_MMU_PREFETCH_RT_REPLACE_MOD;
+       if (data->plat_data->m4u_plat == M4U_MT8173)
+               regval = F_MMU_PREFETCH_RT_REPLACE_MOD |
+                        F_MMU_TF_PROT_TO_PROGRAM_ADDR_MT8173;
+       else
+               regval = F_MMU_TF_PROT_TO_PROGRAM_ADDR;
        writel_relaxed(regval, data->base + REG_MMU_CTRL_REG);
 
        regval = F_L2_MULIT_HIT_EN |
@@ -533,14 +602,14 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
                F_INT_PRETETCH_TRANSATION_FIFO_FAULT;
        writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL);
 
-       if (data->m4u_plat == M4U_MT8173)
+       if (data->plat_data->m4u_plat == M4U_MT8173)
                regval = (data->protect_base >> 1) | (data->enable_4GB << 31);
        else
                regval = lower_32_bits(data->protect_base) |
                         upper_32_bits(data->protect_base);
        writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR);
 
-       if (data->enable_4GB && data->m4u_plat != M4U_MT8173) {
+       if (data->enable_4GB && data->plat_data->has_vld_pa_rng) {
                /*
                 * If 4GB mode is enabled, the validate PA range is from
                 * 0x1_0000_0000 to 0x1_ffff_ffff. here record bit[32:30].
@@ -550,8 +619,7 @@ static int mtk_iommu_hw_init(const struct mtk_iommu_data *data)
        }
        writel_relaxed(0, data->base + REG_MMU_DCM_DIS);
 
-       /* It's MISC control register whose default value is ok except mt8173.*/
-       if (data->m4u_plat == M4U_MT8173)
+       if (data->plat_data->reset_axi)
                writel_relaxed(0, data->base + REG_MMU_STANDARD_AXI_MODE);
 
        if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0,
@@ -584,7 +652,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
        if (!data)
                return -ENOMEM;
        data->dev = dev;
-       data->m4u_plat = (enum mtk_iommu_plat)of_device_get_match_data(dev);
+       data->plat_data = of_device_get_match_data(dev);
 
        /* Protect memory. HW will access here while translation fault.*/
        protect = devm_kzalloc(dev, MTK_PROTECT_PA_ALIGN * 2, GFP_KERNEL);
@@ -594,6 +662,8 @@ static int mtk_iommu_probe(struct platform_device *pdev)
 
        /* Whether the current dram is over 4GB */
        data->enable_4GB = !!(max_pfn > (BIT_ULL(32) >> PAGE_SHIFT));
+       if (!data->plat_data->has_4gb_mode)
+               data->enable_4GB = false;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        data->base = devm_ioremap_resource(dev, res);
@@ -605,15 +675,16 @@ static int mtk_iommu_probe(struct platform_device *pdev)
        if (data->irq < 0)
                return data->irq;
 
-       data->bclk = devm_clk_get(dev, "bclk");
-       if (IS_ERR(data->bclk))
-               return PTR_ERR(data->bclk);
+       if (data->plat_data->has_bclk) {
+               data->bclk = devm_clk_get(dev, "bclk");
+               if (IS_ERR(data->bclk))
+                       return PTR_ERR(data->bclk);
+       }
 
        larb_nr = of_count_phandle_with_args(dev->of_node,
                                             "mediatek,larbs", NULL);
        if (larb_nr < 0)
                return larb_nr;
-       data->smi_imu.larb_nr = larb_nr;
 
        for (i = 0; i < larb_nr; i++) {
                struct device_node *larbnode;
@@ -638,7 +709,7 @@ static int mtk_iommu_probe(struct platform_device *pdev)
                        of_node_put(larbnode);
                        return -EPROBE_DEFER;
                }
-               data->smi_imu.larb_imu[id].dev = &plarbdev->dev;
+               data->larb_imu[id].dev = &plarbdev->dev;
 
                component_match_add_release(dev, &match, release_of,
                                            compare_of, larbnode);
@@ -699,6 +770,7 @@ static int __maybe_unused mtk_iommu_suspend(struct device *dev)
        reg->int_control0 = readl_relaxed(base + REG_MMU_INT_CONTROL0);
        reg->int_main_control = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL);
        reg->ivrp_paddr = readl_relaxed(base + REG_MMU_IVRP_PADDR);
+       reg->vld_pa_rng = readl_relaxed(base + REG_MMU_VLD_PA_RNG);
        clk_disable_unprepare(data->bclk);
        return 0;
 }
@@ -707,6 +779,7 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev)
 {
        struct mtk_iommu_data *data = dev_get_drvdata(dev);
        struct mtk_iommu_suspend_reg *reg = &data->reg;
+       struct mtk_iommu_domain *m4u_dom = data->m4u_dom;
        void __iomem *base = data->base;
        int ret;
 
@@ -722,8 +795,9 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev)
        writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL0);
        writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL);
        writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR);
-       if (data->m4u_dom)
-               writel(data->m4u_dom->cfg.arm_v7s_cfg.ttbr[0],
+       writel_relaxed(reg->vld_pa_rng, base + REG_MMU_VLD_PA_RNG);
+       if (m4u_dom)
+               writel(m4u_dom->cfg.arm_v7s_cfg.ttbr[0] & MMU_PT_ADDR_MASK,
                       base + REG_MMU_PT_BASE_ADDR);
        return 0;
 }
@@ -732,9 +806,32 @@ static const struct dev_pm_ops mtk_iommu_pm_ops = {
        SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_iommu_suspend, mtk_iommu_resume)
 };
 
+static const struct mtk_iommu_plat_data mt2712_data = {
+       .m4u_plat     = M4U_MT2712,
+       .has_4gb_mode = true,
+       .has_bclk     = true,
+       .has_vld_pa_rng   = true,
+       .larbid_remap = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+};
+
+static const struct mtk_iommu_plat_data mt8173_data = {
+       .m4u_plat     = M4U_MT8173,
+       .has_4gb_mode = true,
+       .has_bclk     = true,
+       .reset_axi    = true,
+       .larbid_remap = {0, 1, 2, 3, 4, 5}, /* Linear mapping. */
+};
+
+static const struct mtk_iommu_plat_data mt8183_data = {
+       .m4u_plat     = M4U_MT8183,
+       .reset_axi    = true,
+       .larbid_remap = {0, 4, 5, 6, 7, 2, 3, 1},
+};
+
 static const struct of_device_id mtk_iommu_of_ids[] = {
-       { .compatible = "mediatek,mt2712-m4u", .data = (void *)M4U_MT2712},
-       { .compatible = "mediatek,mt8173-m4u", .data = (void *)M4U_MT8173},
+       { .compatible = "mediatek,mt2712-m4u", .data = &mt2712_data},
+       { .compatible = "mediatek,mt8173-m4u", .data = &mt8173_data},
+       { .compatible = "mediatek,mt8183-m4u", .data = &mt8183_data},
        {}
 };
 
index 5933732..fc0f16e 100644 (file)
@@ -24,12 +24,25 @@ struct mtk_iommu_suspend_reg {
        u32                             int_control0;
        u32                             int_main_control;
        u32                             ivrp_paddr;
+       u32                             vld_pa_rng;
 };
 
 enum mtk_iommu_plat {
        M4U_MT2701,
        M4U_MT2712,
        M4U_MT8173,
+       M4U_MT8183,
+};
+
+struct mtk_iommu_plat_data {
+       enum mtk_iommu_plat m4u_plat;
+       bool                has_4gb_mode;
+
+       /* HW will use the EMI clock if there isn't the "bclk". */
+       bool                has_bclk;
+       bool                has_vld_pa_rng;
+       bool                reset_axi;
+       unsigned char       larbid_remap[MTK_LARB_NR_MAX];
 };
 
 struct mtk_iommu_domain;
@@ -43,14 +56,14 @@ struct mtk_iommu_data {
        struct mtk_iommu_suspend_reg    reg;
        struct mtk_iommu_domain         *m4u_dom;
        struct iommu_group              *m4u_group;
-       struct mtk_smi_iommu            smi_imu;      /* SMI larb iommu info */
        bool                            enable_4GB;
        bool                            tlb_flush_active;
 
        struct iommu_device             iommu;
-       enum mtk_iommu_plat             m4u_plat;
+       const struct mtk_iommu_plat_data *plat_data;
 
        struct list_head                list;
+       struct mtk_smi_larb_iommu       larb_imu[MTK_LARB_NR_MAX];
 };
 
 static inline int compare_of(struct device *dev, void *data)
@@ -67,14 +80,14 @@ static inline int mtk_iommu_bind(struct device *dev)
 {
        struct mtk_iommu_data *data = dev_get_drvdata(dev);
 
-       return component_bind_all(dev, &data->smi_imu);
+       return component_bind_all(dev, &data->larb_imu);
 }
 
 static inline void mtk_iommu_unbind(struct device *dev)
 {
        struct mtk_iommu_data *data = dev_get_drvdata(dev);
 
-       component_unbind_all(dev, &data->smi_imu);
+       component_unbind_all(dev, &data->larb_imu);
 }
 
 #endif
index abeeac4..210b1c7 100644 (file)
@@ -206,7 +206,7 @@ static void mtk_iommu_config(struct mtk_iommu_data *data,
        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];
+               larb_mmu = &data->larb_imu[larbid];
 
                dev_dbg(dev, "%s iommu port: %d\n",
                        enable ? "enable" : "disable", portid);
@@ -324,7 +324,8 @@ static int mtk_iommu_map(struct iommu_domain *domain, unsigned long iova,
 }
 
 static size_t mtk_iommu_unmap(struct iommu_domain *domain,
-                             unsigned long iova, size_t size)
+                             unsigned long iova, size_t size,
+                             struct iommu_iotlb_gather *gather)
 {
        struct mtk_iommu_domain *dom = to_mtk_domain(domain);
        unsigned long flags;
@@ -610,14 +611,12 @@ static int mtk_iommu_probe(struct platform_device *pdev)
                        }
                }
 
-               data->smi_imu.larb_imu[larb_nr].dev = &plarbdev->dev;
+               data->larb_imu[larb_nr].dev = &plarbdev->dev;
                component_match_add_release(dev, &match, release_of,
                                            compare_of, larb_spec.np);
                larb_nr++;
        }
 
-       data->smi_imu.larb_nr = larb_nr;
-
        platform_set_drvdata(pdev, data);
 
        ret = mtk_iommu_hw_init(data);
index dfb961d..09c6e1c 100644 (file)
 
 static const struct iommu_ops omap_iommu_ops;
 
+struct orphan_dev {
+       struct device *dev;
+       struct list_head node;
+};
+
+static LIST_HEAD(orphan_dev_list);
+
+static DEFINE_SPINLOCK(orphan_lock);
+
 #define to_iommu(dev)  ((struct omap_iommu *)dev_get_drvdata(dev))
 
 /* bitmap of the page sizes currently supported */
@@ -53,6 +62,8 @@ static const struct iommu_ops omap_iommu_ops;
 static struct platform_driver omap_iommu_driver;
 static struct kmem_cache *iopte_cachep;
 
+static int _omap_iommu_add_device(struct device *dev);
+
 /**
  * to_omap_domain - Get struct omap_iommu_domain from generic iommu_domain
  * @dom:       generic iommu domain handle
@@ -65,6 +76,9 @@ static struct omap_iommu_domain *to_omap_domain(struct iommu_domain *dom)
 /**
  * omap_iommu_save_ctx - Save registers for pm off-mode support
  * @dev:       client device
+ *
+ * This should be treated as an deprecated API. It is preserved only
+ * to maintain existing functionality for OMAP3 ISP driver.
  **/
 void omap_iommu_save_ctx(struct device *dev)
 {
@@ -92,6 +106,9 @@ EXPORT_SYMBOL_GPL(omap_iommu_save_ctx);
 /**
  * omap_iommu_restore_ctx - Restore registers for pm off-mode support
  * @dev:       client device
+ *
+ * This should be treated as an deprecated API. It is preserved only
+ * to maintain existing functionality for OMAP3 ISP driver.
  **/
 void omap_iommu_restore_ctx(struct device *dev)
 {
@@ -186,36 +203,18 @@ static void omap2_iommu_disable(struct omap_iommu *obj)
 
 static int iommu_enable(struct omap_iommu *obj)
 {
-       int err;
-       struct platform_device *pdev = to_platform_device(obj->dev);
-       struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev);
-
-       if (pdata && pdata->deassert_reset) {
-               err = pdata->deassert_reset(pdev, pdata->reset_name);
-               if (err) {
-                       dev_err(obj->dev, "deassert_reset failed: %d\n", err);
-                       return err;
-               }
-       }
-
-       pm_runtime_get_sync(obj->dev);
+       int ret;
 
-       err = omap2_iommu_enable(obj);
+       ret = pm_runtime_get_sync(obj->dev);
+       if (ret < 0)
+               pm_runtime_put_noidle(obj->dev);
 
-       return err;
+       return ret < 0 ? ret : 0;
 }
 
 static void iommu_disable(struct omap_iommu *obj)
 {
-       struct platform_device *pdev = to_platform_device(obj->dev);
-       struct iommu_platform_data *pdata = dev_get_platdata(&pdev->dev);
-
-       omap2_iommu_disable(obj);
-
        pm_runtime_put_sync(obj->dev);
-
-       if (pdata && pdata->assert_reset)
-               pdata->assert_reset(pdev, pdata->reset_name);
 }
 
 /*
@@ -901,15 +900,219 @@ static void omap_iommu_detach(struct omap_iommu *obj)
 
        dma_unmap_single(obj->dev, obj->pd_dma, IOPGD_TABLE_SIZE,
                         DMA_TO_DEVICE);
-       iommu_disable(obj);
        obj->pd_dma = 0;
        obj->iopgd = NULL;
+       iommu_disable(obj);
 
        spin_unlock(&obj->iommu_lock);
 
        dev_dbg(obj->dev, "%s: %s\n", __func__, obj->name);
 }
 
+static void omap_iommu_save_tlb_entries(struct omap_iommu *obj)
+{
+       struct iotlb_lock lock;
+       struct cr_regs cr;
+       struct cr_regs *tmp;
+       int i;
+
+       /* check if there are any locked tlbs to save */
+       iotlb_lock_get(obj, &lock);
+       obj->num_cr_ctx = lock.base;
+       if (!obj->num_cr_ctx)
+               return;
+
+       tmp = obj->cr_ctx;
+       for_each_iotlb_cr(obj, obj->num_cr_ctx, i, cr)
+               * tmp++ = cr;
+}
+
+static void omap_iommu_restore_tlb_entries(struct omap_iommu *obj)
+{
+       struct iotlb_lock l;
+       struct cr_regs *tmp;
+       int i;
+
+       /* no locked tlbs to restore */
+       if (!obj->num_cr_ctx)
+               return;
+
+       l.base = 0;
+       tmp = obj->cr_ctx;
+       for (i = 0; i < obj->num_cr_ctx; i++, tmp++) {
+               l.vict = i;
+               iotlb_lock_set(obj, &l);
+               iotlb_load_cr(obj, tmp);
+       }
+       l.base = obj->num_cr_ctx;
+       l.vict = i;
+       iotlb_lock_set(obj, &l);
+}
+
+/**
+ * omap_iommu_domain_deactivate - deactivate attached iommu devices
+ * @domain: iommu domain attached to the target iommu device
+ *
+ * This API allows the client devices of IOMMU devices to suspend
+ * the IOMMUs they control at runtime, after they are idled and
+ * suspended all activity. System Suspend will leverage the PM
+ * driver late callbacks.
+ **/
+int omap_iommu_domain_deactivate(struct iommu_domain *domain)
+{
+       struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
+       struct omap_iommu_device *iommu;
+       struct omap_iommu *oiommu;
+       int i;
+
+       if (!omap_domain->dev)
+               return 0;
+
+       iommu = omap_domain->iommus;
+       iommu += (omap_domain->num_iommus - 1);
+       for (i = 0; i < omap_domain->num_iommus; i++, iommu--) {
+               oiommu = iommu->iommu_dev;
+               pm_runtime_put_sync(oiommu->dev);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(omap_iommu_domain_deactivate);
+
+/**
+ * omap_iommu_domain_activate - activate attached iommu devices
+ * @domain: iommu domain attached to the target iommu device
+ *
+ * This API allows the client devices of IOMMU devices to resume the
+ * IOMMUs they control at runtime, before they can resume operations.
+ * System Resume will leverage the PM driver late callbacks.
+ **/
+int omap_iommu_domain_activate(struct iommu_domain *domain)
+{
+       struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
+       struct omap_iommu_device *iommu;
+       struct omap_iommu *oiommu;
+       int i;
+
+       if (!omap_domain->dev)
+               return 0;
+
+       iommu = omap_domain->iommus;
+       for (i = 0; i < omap_domain->num_iommus; i++, iommu++) {
+               oiommu = iommu->iommu_dev;
+               pm_runtime_get_sync(oiommu->dev);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(omap_iommu_domain_activate);
+
+/**
+ * omap_iommu_runtime_suspend - disable an iommu device
+ * @dev:       iommu device
+ *
+ * This function performs all that is necessary to disable an
+ * IOMMU device, either during final detachment from a client
+ * device, or during system/runtime suspend of the device. This
+ * includes programming all the appropriate IOMMU registers, and
+ * managing the associated omap_hwmod's state and the device's
+ * reset line. This function also saves the context of any
+ * locked TLBs if suspending.
+ **/
+static __maybe_unused int omap_iommu_runtime_suspend(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct iommu_platform_data *pdata = dev_get_platdata(dev);
+       struct omap_iommu *obj = to_iommu(dev);
+       int ret;
+
+       /* save the TLBs only during suspend, and not for power down */
+       if (obj->domain && obj->iopgd)
+               omap_iommu_save_tlb_entries(obj);
+
+       omap2_iommu_disable(obj);
+
+       if (pdata && pdata->device_idle)
+               pdata->device_idle(pdev);
+
+       if (pdata && pdata->assert_reset)
+               pdata->assert_reset(pdev, pdata->reset_name);
+
+       if (pdata && pdata->set_pwrdm_constraint) {
+               ret = pdata->set_pwrdm_constraint(pdev, false, &obj->pwrst);
+               if (ret) {
+                       dev_warn(obj->dev, "pwrdm_constraint failed to be reset, status = %d\n",
+                                ret);
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * omap_iommu_runtime_resume - enable an iommu device
+ * @dev:       iommu device
+ *
+ * This function performs all that is necessary to enable an
+ * IOMMU device, either during initial attachment to a client
+ * device, or during system/runtime resume of the device. This
+ * includes programming all the appropriate IOMMU registers, and
+ * managing the associated omap_hwmod's state and the device's
+ * reset line. The function also restores any locked TLBs if
+ * resuming after a suspend.
+ **/
+static __maybe_unused int omap_iommu_runtime_resume(struct device *dev)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       struct iommu_platform_data *pdata = dev_get_platdata(dev);
+       struct omap_iommu *obj = to_iommu(dev);
+       int ret = 0;
+
+       if (pdata && pdata->set_pwrdm_constraint) {
+               ret = pdata->set_pwrdm_constraint(pdev, true, &obj->pwrst);
+               if (ret) {
+                       dev_warn(obj->dev, "pwrdm_constraint failed to be set, status = %d\n",
+                                ret);
+               }
+       }
+
+       if (pdata && pdata->deassert_reset) {
+               ret = pdata->deassert_reset(pdev, pdata->reset_name);
+               if (ret) {
+                       dev_err(dev, "deassert_reset failed: %d\n", ret);
+                       return ret;
+               }
+       }
+
+       if (pdata && pdata->device_enable)
+               pdata->device_enable(pdev);
+
+       /* restore the TLBs only during resume, and not for power up */
+       if (obj->domain)
+               omap_iommu_restore_tlb_entries(obj);
+
+       ret = omap2_iommu_enable(obj);
+
+       return ret;
+}
+
+/**
+ * omap_iommu_suspend_prepare - prepare() dev_pm_ops implementation
+ * @dev:       iommu device
+ *
+ * This function performs the necessary checks to determine if the IOMMU
+ * device needs suspending or not. The function checks if the runtime_pm
+ * status of the device is suspended, and returns 1 in that case. This
+ * results in the PM core to skip invoking any of the Sleep PM callbacks
+ * (suspend, suspend_late, resume, resume_early etc).
+ */
+static int omap_iommu_prepare(struct device *dev)
+{
+       if (pm_runtime_status_suspended(dev))
+               return 1;
+       return 0;
+}
+
 static bool omap_iommu_can_register(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
@@ -974,6 +1177,7 @@ static int omap_iommu_probe(struct platform_device *pdev)
        struct omap_iommu *obj;
        struct resource *res;
        struct device_node *of = pdev->dev.of_node;
+       struct orphan_dev *orphan_dev, *tmp;
 
        if (!of) {
                pr_err("%s: only DT-based devices are supported\n", __func__);
@@ -984,6 +1188,15 @@ static int omap_iommu_probe(struct platform_device *pdev)
        if (!obj)
                return -ENOMEM;
 
+       /*
+        * self-manage the ordering dependencies between omap_device_enable/idle
+        * and omap_device_assert/deassert_hardreset API
+        */
+       if (pdev->dev.pm_domain) {
+               dev_dbg(&pdev->dev, "device pm_domain is being reset\n");
+               pdev->dev.pm_domain = NULL;
+       }
+
        obj->name = dev_name(&pdev->dev);
        obj->nr_tlb_entries = 32;
        err = of_property_read_u32(of, "ti,#tlb-entries", &obj->nr_tlb_entries);
@@ -996,6 +1209,11 @@ static int omap_iommu_probe(struct platform_device *pdev)
 
        obj->dev = &pdev->dev;
        obj->ctx = (void *)obj + sizeof(*obj);
+       obj->cr_ctx = devm_kzalloc(&pdev->dev,
+                                  sizeof(*obj->cr_ctx) * obj->nr_tlb_entries,
+                                  GFP_KERNEL);
+       if (!obj->cr_ctx)
+               return -ENOMEM;
 
        spin_lock_init(&obj->iommu_lock);
        spin_lock_init(&obj->page_table_lock);
@@ -1036,13 +1254,20 @@ static int omap_iommu_probe(struct platform_device *pdev)
                        goto out_sysfs;
        }
 
-       pm_runtime_irq_safe(obj->dev);
        pm_runtime_enable(obj->dev);
 
        omap_iommu_debugfs_add(obj);
 
        dev_info(&pdev->dev, "%s registered\n", obj->name);
 
+       list_for_each_entry_safe(orphan_dev, tmp, &orphan_dev_list, node) {
+               err = _omap_iommu_add_device(orphan_dev->dev);
+               if (!err) {
+                       list_del(&orphan_dev->node);
+                       kfree(orphan_dev);
+               }
+       }
+
        return 0;
 
 out_sysfs:
@@ -1072,6 +1297,14 @@ static int omap_iommu_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct dev_pm_ops omap_iommu_pm_ops = {
+       .prepare = omap_iommu_prepare,
+       SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+                                    pm_runtime_force_resume)
+       SET_RUNTIME_PM_OPS(omap_iommu_runtime_suspend,
+                          omap_iommu_runtime_resume, NULL)
+};
+
 static const struct of_device_id omap_iommu_of_match[] = {
        { .compatible = "ti,omap2-iommu" },
        { .compatible = "ti,omap4-iommu" },
@@ -1085,6 +1318,7 @@ static struct platform_driver omap_iommu_driver = {
        .remove = omap_iommu_remove,
        .driver = {
                .name   = "omap-iommu",
+               .pm     = &omap_iommu_pm_ops,
                .of_match_table = of_match_ptr(omap_iommu_of_match),
        },
 };
@@ -1149,7 +1383,7 @@ static int omap_iommu_map(struct iommu_domain *domain, unsigned long da,
 }
 
 static size_t omap_iommu_unmap(struct iommu_domain *domain, unsigned long da,
-                              size_t size)
+                              size_t size, struct iommu_iotlb_gather *gather)
 {
        struct omap_iommu_domain *omap_domain = to_omap_domain(domain);
        struct device *dev = omap_domain->dev;
@@ -1423,7 +1657,7 @@ static phys_addr_t omap_iommu_iova_to_phys(struct iommu_domain *domain,
        return ret;
 }
 
-static int omap_iommu_add_device(struct device *dev)
+static int _omap_iommu_add_device(struct device *dev)
 {
        struct omap_iommu_arch_data *arch_data, *tmp;
        struct omap_iommu *oiommu;
@@ -1432,6 +1666,8 @@ static int omap_iommu_add_device(struct device *dev)
        struct platform_device *pdev;
        int num_iommus, i;
        int ret;
+       struct orphan_dev *orphan_dev;
+       unsigned long flags;
 
        /*
         * Allocate the archdata iommu structure for DT-based devices.
@@ -1463,10 +1699,26 @@ static int omap_iommu_add_device(struct device *dev)
                }
 
                pdev = of_find_device_by_node(np);
-               if (WARN_ON(!pdev)) {
+               if (!pdev) {
                        of_node_put(np);
                        kfree(arch_data);
-                       return -EINVAL;
+                       spin_lock_irqsave(&orphan_lock, flags);
+                       list_for_each_entry(orphan_dev, &orphan_dev_list,
+                                           node) {
+                               if (orphan_dev->dev == dev)
+                                       break;
+                       }
+                       spin_unlock_irqrestore(&orphan_lock, flags);
+
+                       if (orphan_dev && orphan_dev->dev == dev)
+                               return -EPROBE_DEFER;
+
+                       orphan_dev = kzalloc(sizeof(*orphan_dev), GFP_KERNEL);
+                       orphan_dev->dev = dev;
+                       spin_lock_irqsave(&orphan_lock, flags);
+                       list_add(&orphan_dev->node, &orphan_dev_list);
+                       spin_unlock_irqrestore(&orphan_lock, flags);
+                       return -EPROBE_DEFER;
                }
 
                oiommu = platform_get_drvdata(pdev);
@@ -1477,6 +1729,7 @@ static int omap_iommu_add_device(struct device *dev)
                }
 
                tmp->iommu_dev = oiommu;
+               tmp->dev = &pdev->dev;
 
                of_node_put(np);
        }
@@ -1511,6 +1764,17 @@ static int omap_iommu_add_device(struct device *dev)
        return 0;
 }
 
+static int omap_iommu_add_device(struct device *dev)
+{
+       int ret;
+
+       ret = _omap_iommu_add_device(dev);
+       if (ret == -EPROBE_DEFER)
+               return 0;
+
+       return ret;
+}
+
 static void omap_iommu_remove_device(struct device *dev)
 {
        struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
@@ -1554,7 +1818,7 @@ static const struct iommu_ops omap_iommu_ops = {
 static int __init omap_iommu_init(void)
 {
        struct kmem_cache *p;
-       const unsigned long flags = SLAB_HWCACHE_ALIGN;
+       const slab_flags_t flags = SLAB_HWCACHE_ALIGN;
        size_t align = 1 << 10; /* L2 pagetable alignement */
        struct device_node *np;
        int ret;
index 09968a0..18ee713 100644 (file)
@@ -73,16 +73,22 @@ struct omap_iommu {
 
        void *ctx; /* iommu context: registres saved area */
 
+       struct cr_regs *cr_ctx;
+       u32 num_cr_ctx;
+
        int has_bus_err_back;
        u32 id;
 
        struct iommu_device iommu;
        struct iommu_group *group;
+
+       u8 pwrst;
 };
 
 /**
  * struct omap_iommu_arch_data - omap iommu private data
- * @iommu_dev: handle of the iommu device
+ * @iommu_dev: handle of the OMAP iommu device
+ * @dev: handle of the iommu device
  *
  * This is an omap iommu private data object, which binds an iommu user
  * to its iommu device. This object should be placed at the iommu user's
@@ -91,6 +97,7 @@ struct omap_iommu {
  */
 struct omap_iommu_arch_data {
        struct omap_iommu *iommu_dev;
+       struct device *dev;
 };
 
 struct cr_regs {
index 34d0b97..c31e7bc 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/atomic.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/dma-iommu.h>
@@ -32,7 +33,7 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 
-#include "arm-smmu-regs.h"
+#include "arm-smmu.h"
 
 #define SMMU_INTR_SEL_NS     0x2000
 
@@ -155,7 +156,7 @@ static void qcom_iommu_tlb_inv_range_nosync(unsigned long iova, size_t size,
                struct qcom_iommu_ctx *ctx = to_ctx(fwspec, fwspec->ids[i]);
                size_t s = size;
 
-               iova &= ~12UL;
+               iova = (iova >> 12) << 12;
                iova |= ctx->asid;
                do {
                        iommu_writel(ctx, reg, iova);
@@ -164,10 +165,32 @@ static void qcom_iommu_tlb_inv_range_nosync(unsigned long iova, size_t size,
        }
 }
 
-static const struct iommu_gather_ops qcom_gather_ops = {
+static void qcom_iommu_tlb_flush_walk(unsigned long iova, size_t size,
+                                     size_t granule, void *cookie)
+{
+       qcom_iommu_tlb_inv_range_nosync(iova, size, granule, false, cookie);
+       qcom_iommu_tlb_sync(cookie);
+}
+
+static void qcom_iommu_tlb_flush_leaf(unsigned long iova, size_t size,
+                                     size_t granule, void *cookie)
+{
+       qcom_iommu_tlb_inv_range_nosync(iova, size, granule, true, cookie);
+       qcom_iommu_tlb_sync(cookie);
+}
+
+static void qcom_iommu_tlb_add_page(struct iommu_iotlb_gather *gather,
+                                   unsigned long iova, size_t granule,
+                                   void *cookie)
+{
+       qcom_iommu_tlb_inv_range_nosync(iova, granule, granule, true, cookie);
+}
+
+static const struct iommu_flush_ops qcom_flush_ops = {
        .tlb_flush_all  = qcom_iommu_tlb_inv_context,
-       .tlb_add_flush  = qcom_iommu_tlb_inv_range_nosync,
-       .tlb_sync       = qcom_iommu_tlb_sync,
+       .tlb_flush_walk = qcom_iommu_tlb_flush_walk,
+       .tlb_flush_leaf = qcom_iommu_tlb_flush_leaf,
+       .tlb_add_page   = qcom_iommu_tlb_add_page,
 };
 
 static irqreturn_t qcom_iommu_fault(int irq, void *dev)
@@ -215,7 +238,7 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
                .pgsize_bitmap  = qcom_iommu_ops.pgsize_bitmap,
                .ias            = 32,
                .oas            = 40,
-               .tlb            = &qcom_gather_ops,
+               .tlb            = &qcom_flush_ops,
                .iommu_dev      = qcom_iommu->dev,
        };
 
@@ -247,16 +270,16 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
                /* TTBRs */
                iommu_writeq(ctx, ARM_SMMU_CB_TTBR0,
                                pgtbl_cfg.arm_lpae_s1_cfg.ttbr[0] |
-                               ((u64)ctx->asid << TTBRn_ASID_SHIFT));
+                               FIELD_PREP(TTBRn_ASID, ctx->asid));
                iommu_writeq(ctx, ARM_SMMU_CB_TTBR1,
                                pgtbl_cfg.arm_lpae_s1_cfg.ttbr[1] |
-                               ((u64)ctx->asid << TTBRn_ASID_SHIFT));
+                               FIELD_PREP(TTBRn_ASID, ctx->asid));
 
-               /* TTBCR */
-               iommu_writel(ctx, ARM_SMMU_CB_TTBCR2,
+               /* TCR */
+               iommu_writel(ctx, ARM_SMMU_CB_TCR2,
                                (pgtbl_cfg.arm_lpae_s1_cfg.tcr >> 32) |
-                               TTBCR2_SEP_UPSTREAM);
-               iommu_writel(ctx, ARM_SMMU_CB_TTBCR,
+                               FIELD_PREP(TCR2_SEP, TCR2_SEP_UPSTREAM));
+               iommu_writel(ctx, ARM_SMMU_CB_TCR,
                                pgtbl_cfg.arm_lpae_s1_cfg.tcr);
 
                /* MAIRs (stage-1 only) */
@@ -417,7 +440,7 @@ static int qcom_iommu_map(struct iommu_domain *domain, unsigned long iova,
 }
 
 static size_t qcom_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
-                              size_t size)
+                              size_t size, struct iommu_iotlb_gather *gather)
 {
        size_t ret;
        unsigned long flags;
@@ -434,14 +457,14 @@ static size_t qcom_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
         */
        pm_runtime_get_sync(qcom_domain->iommu->dev);
        spin_lock_irqsave(&qcom_domain->pgtbl_lock, flags);
-       ret = ops->unmap(ops, iova, size);
+       ret = ops->unmap(ops, iova, size, gather);
        spin_unlock_irqrestore(&qcom_domain->pgtbl_lock, flags);
        pm_runtime_put_sync(qcom_domain->iommu->dev);
 
        return ret;
 }
 
-static void qcom_iommu_iotlb_sync(struct iommu_domain *domain)
+static void qcom_iommu_flush_iotlb_all(struct iommu_domain *domain)
 {
        struct qcom_iommu_domain *qcom_domain = to_qcom_iommu_domain(domain);
        struct io_pgtable *pgtable = container_of(qcom_domain->pgtbl_ops,
@@ -454,6 +477,12 @@ static void qcom_iommu_iotlb_sync(struct iommu_domain *domain)
        pm_runtime_put_sync(qcom_domain->iommu->dev);
 }
 
+static void qcom_iommu_iotlb_sync(struct iommu_domain *domain,
+                                 struct iommu_iotlb_gather *gather)
+{
+       qcom_iommu_flush_iotlb_all(domain);
+}
+
 static phys_addr_t qcom_iommu_iova_to_phys(struct iommu_domain *domain,
                                           dma_addr_t iova)
 {
@@ -581,7 +610,7 @@ static const struct iommu_ops qcom_iommu_ops = {
        .detach_dev     = qcom_iommu_detach_dev,
        .map            = qcom_iommu_map,
        .unmap          = qcom_iommu_unmap,
-       .flush_iotlb_all = qcom_iommu_iotlb_sync,
+       .flush_iotlb_all = qcom_iommu_flush_iotlb_all,
        .iotlb_sync     = qcom_iommu_iotlb_sync,
        .iova_to_phys   = qcom_iommu_iova_to_phys,
        .add_device     = qcom_iommu_add_device,
@@ -696,10 +725,8 @@ static int qcom_iommu_ctx_probe(struct platform_device *pdev)
                return PTR_ERR(ctx->base);
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(dev, "failed to get irq\n");
+       if (irq < 0)
                return -ENODEV;
-       }
 
        /* clear IRQs before registering fault handler, just in case the
         * boot-loader left us a surprise:
@@ -775,7 +802,7 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
        struct qcom_iommu_dev *qcom_iommu;
        struct device *dev = &pdev->dev;
        struct resource *res;
-       int ret, sz, max_asid = 0;
+       int ret, max_asid = 0;
 
        /* find the max asid (which is 1:1 to ctx bank idx), so we know how
         * many child ctx devices we have:
@@ -783,9 +810,8 @@ static int qcom_iommu_device_probe(struct platform_device *pdev)
        for_each_child_of_node(dev->of_node, child)
                max_asid = max(max_asid, get_asid(child));
 
-       sz = sizeof(*qcom_iommu) + (max_asid * sizeof(qcom_iommu->ctxs[0]));
-
-       qcom_iommu = devm_kzalloc(dev, sz, GFP_KERNEL);
+       qcom_iommu = devm_kzalloc(dev, struct_size(qcom_iommu, ctxs, max_asid),
+                                 GFP_KERNEL);
        if (!qcom_iommu)
                return -ENOMEM;
        qcom_iommu->num_ctxs = max_asid;
index dc26d74..26290f3 100644 (file)
@@ -794,7 +794,7 @@ static int rk_iommu_map(struct iommu_domain *domain, unsigned long _iova,
 }
 
 static size_t rk_iommu_unmap(struct iommu_domain *domain, unsigned long _iova,
-                            size_t size)
+                            size_t size, struct iommu_iotlb_gather *gather)
 {
        struct rk_iommu_domain *rk_domain = to_rk_domain(domain);
        unsigned long flags;
index 22d4db3..3b0b18e 100644 (file)
@@ -314,7 +314,8 @@ static phys_addr_t s390_iommu_iova_to_phys(struct iommu_domain *domain,
 }
 
 static size_t s390_iommu_unmap(struct iommu_domain *domain,
-                              unsigned long iova, size_t size)
+                              unsigned long iova, size_t size,
+                              struct iommu_iotlb_gather *gather)
 {
        struct s390_domain *s390_domain = to_s390_domain(domain);
        int flags = ZPCI_PTE_INVALID;
index 6d40bc1..3924f7c 100644 (file)
@@ -207,7 +207,7 @@ static inline int __gart_iommu_unmap(struct gart_device *gart,
 }
 
 static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
-                              size_t bytes)
+                              size_t bytes, struct iommu_iotlb_gather *gather)
 {
        struct gart_device *gart = gart_handle;
        int err;
@@ -273,11 +273,17 @@ static int gart_iommu_of_xlate(struct device *dev,
        return 0;
 }
 
-static void gart_iommu_sync(struct iommu_domain *domain)
+static void gart_iommu_sync_map(struct iommu_domain *domain)
 {
        FLUSH_GART_REGS(gart_handle);
 }
 
+static void gart_iommu_sync(struct iommu_domain *domain,
+                           struct iommu_iotlb_gather *gather)
+{
+       gart_iommu_sync_map(domain);
+}
+
 static const struct iommu_ops gart_iommu_ops = {
        .capable        = gart_iommu_capable,
        .domain_alloc   = gart_iommu_domain_alloc,
@@ -292,7 +298,7 @@ static const struct iommu_ops gart_iommu_ops = {
        .iova_to_phys   = gart_iommu_iova_to_phys,
        .pgsize_bitmap  = GART_IOMMU_PGSIZES,
        .of_xlate       = gart_iommu_of_xlate,
-       .iotlb_sync_map = gart_iommu_sync,
+       .iotlb_sync_map = gart_iommu_sync_map,
        .iotlb_sync     = gart_iommu_sync,
 };
 
index c4a652b..7293fc3 100644 (file)
@@ -680,7 +680,7 @@ static int tegra_smmu_map(struct iommu_domain *domain, unsigned long iova,
 }
 
 static size_t tegra_smmu_unmap(struct iommu_domain *domain, unsigned long iova,
-                              size_t size)
+                              size_t size, struct iommu_iotlb_gather *gather)
 {
        struct tegra_smmu_as *as = to_smmu_as(domain);
        dma_addr_t pte_dma;
index 80a740d..3ea9d76 100644 (file)
@@ -751,7 +751,7 @@ static int viommu_map(struct iommu_domain *domain, unsigned long iova,
 }
 
 static size_t viommu_unmap(struct iommu_domain *domain, unsigned long iova,
-                          size_t size)
+                          size_t size, struct iommu_iotlb_gather *gather)
 {
        int ret = 0;
        size_t unmapped;
@@ -797,7 +797,8 @@ static phys_addr_t viommu_iova_to_phys(struct iommu_domain *domain,
        return paddr;
 }
 
-static void viommu_iotlb_sync(struct iommu_domain *domain)
+static void viommu_iotlb_sync(struct iommu_domain *domain,
+                             struct iommu_iotlb_gather *gather)
 {
        struct viommu_domain *vdomain = to_viommu_domain(domain);
 
index cf75596..c72c036 100644 (file)
@@ -244,6 +244,7 @@ static int __init plic_init(struct device_node *node,
                struct plic_handler *handler;
                irq_hw_number_t hwirq;
                int cpu, hartid;
+               u32 threshold = 0;
 
                if (of_irq_parse_one(node, i, &parent)) {
                        pr_err("failed to parse parent for context %d.\n", i);
@@ -266,10 +267,16 @@ static int __init plic_init(struct device_node *node,
                        continue;
                }
 
+               /*
+                * When running in M-mode we need to ignore the S-mode handler.
+                * Here we assume it always comes later, but that might be a
+                * little fragile.
+                */
                handler = per_cpu_ptr(&plic_handlers, cpu);
                if (handler->present) {
                        pr_warn("handler already present for context %d.\n", i);
-                       continue;
+                       threshold = 0xffffffff;
+                       goto done;
                }
 
                handler->present = true;
@@ -279,8 +286,9 @@ static int __init plic_init(struct device_node *node,
                handler->enable_base =
                        plic_regs + ENABLE_BASE + i * ENABLE_PER_HART;
 
+done:
                /* priority must be > threshold to trigger an interrupt */
-               writel(0, handler->hart_base + CONTEXT_THRESHOLD);
+               writel(threshold, handler->hart_base + CONTEXT_THRESHOLD);
                for (hwirq = 1; hwirq <= nr_irqs; hwirq++)
                        plic_toggle(handler, hwirq, 0);
                nr_handlers++;
index 3c3ad42..c92b405 100644 (file)
@@ -688,6 +688,9 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
        if (!cdev->ap.applid)
                return -ENODEV;
 
+       if (count < CAPIMSG_BASELEN)
+               return -EINVAL;
+
        skb = alloc_skb(count, GFP_USER);
        if (!skb)
                return -ENOMEM;
@@ -698,7 +701,8 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
        }
        mlen = CAPIMSG_LEN(skb->data);
        if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
-               if ((size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
+               if (count < CAPI_DATA_B3_REQ_LEN ||
+                   (size_t)(mlen + CAPIMSG_DATALEN(skb->data)) != count) {
                        kfree_skb(skb);
                        return -EINVAL;
                }
@@ -711,6 +715,10 @@ capi_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos
        CAPIMSG_SETAPPID(skb->data, cdev->ap.applid);
 
        if (CAPIMSG_CMD(skb->data) == CAPI_DISCONNECT_B3_RESP) {
+               if (count < CAPI_DISCONNECT_B3_RESP_LEN) {
+                       kfree_skb(skb);
+                       return -EINVAL;
+               }
                mutex_lock(&cdev->lock);
                capincci_free(cdev, CAPIMSG_NCCI(skb->data));
                mutex_unlock(&cdev->lock);
index 42ab43a..439d7d8 100644 (file)
 #define SMI_LARB_NONSEC_CON(id)        (0x380 + ((id) * 4))
 #define F_MMU_EN               BIT(0)
 
+/* SMI COMMON */
+#define SMI_BUS_SEL                    0x220
+#define SMI_BUS_LARB_SHIFT(larbid)     ((larbid) << 1)
+/* All are MMU0 defaultly. Only specialize mmu1 here. */
+#define F_MMU1_LARB(larbid)            (0x1 << SMI_BUS_LARB_SHIFT(larbid))
+
+enum mtk_smi_gen {
+       MTK_SMI_GEN1,
+       MTK_SMI_GEN2
+};
+
+struct mtk_smi_common_plat {
+       enum mtk_smi_gen gen;
+       bool             has_gals;
+       u32              bus_sel; /* Balance some larbs to enter mmu0 or mmu1 */
+};
+
 struct mtk_smi_larb_gen {
-       bool need_larbid;
        int port_in_larb[MTK_LARB_NR_MAX + 1];
        void (*config_port)(struct device *);
+       unsigned int                    larb_direct_to_common_mask;
+       bool                            has_gals;
 };
 
 struct mtk_smi {
        struct device                   *dev;
        struct clk                      *clk_apb, *clk_smi;
+       struct clk                      *clk_gals0, *clk_gals1;
        struct clk                      *clk_async; /*only needed by mt2701*/
-       void __iomem                    *smi_ao_base;
+       union {
+               void __iomem            *smi_ao_base; /* only for gen1 */
+               void __iomem            *base;        /* only for gen2 */
+       };
+       const struct mtk_smi_common_plat *plat;
 };
 
 struct mtk_smi_larb { /* larb: local arbiter */
@@ -63,82 +86,56 @@ struct mtk_smi_larb { /* larb: local arbiter */
        u32                             *mmu;
 };
 
-enum mtk_smi_gen {
-       MTK_SMI_GEN1,
-       MTK_SMI_GEN2
-};
-
-static int mtk_smi_enable(const struct mtk_smi *smi)
+static int mtk_smi_clk_enable(const struct mtk_smi *smi)
 {
        int ret;
 
-       ret = pm_runtime_get_sync(smi->dev);
-       if (ret < 0)
-               return ret;
-
        ret = clk_prepare_enable(smi->clk_apb);
        if (ret)
-               goto err_put_pm;
+               return ret;
 
        ret = clk_prepare_enable(smi->clk_smi);
        if (ret)
                goto err_disable_apb;
 
+       ret = clk_prepare_enable(smi->clk_gals0);
+       if (ret)
+               goto err_disable_smi;
+
+       ret = clk_prepare_enable(smi->clk_gals1);
+       if (ret)
+               goto err_disable_gals0;
+
        return 0;
 
+err_disable_gals0:
+       clk_disable_unprepare(smi->clk_gals0);
+err_disable_smi:
+       clk_disable_unprepare(smi->clk_smi);
 err_disable_apb:
        clk_disable_unprepare(smi->clk_apb);
-err_put_pm:
-       pm_runtime_put_sync(smi->dev);
        return ret;
 }
 
-static void mtk_smi_disable(const struct mtk_smi *smi)
+static void mtk_smi_clk_disable(const struct mtk_smi *smi)
 {
+       clk_disable_unprepare(smi->clk_gals1);
+       clk_disable_unprepare(smi->clk_gals0);
        clk_disable_unprepare(smi->clk_smi);
        clk_disable_unprepare(smi->clk_apb);
-       pm_runtime_put_sync(smi->dev);
 }
 
 int mtk_smi_larb_get(struct device *larbdev)
 {
-       struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
-       const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
-       struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
-       int ret;
-
-       /* Enable the smi-common's power and clocks */
-       ret = mtk_smi_enable(common);
-       if (ret)
-               return ret;
+       int ret = pm_runtime_get_sync(larbdev);
 
-       /* Enable the larb's power and clocks */
-       ret = mtk_smi_enable(&larb->smi);
-       if (ret) {
-               mtk_smi_disable(common);
-               return ret;
-       }
-
-       /* Configure the iommu info for this larb */
-       larb_gen->config_port(larbdev);
-
-       return 0;
+       return (ret < 0) ? ret : 0;
 }
 EXPORT_SYMBOL_GPL(mtk_smi_larb_get);
 
 void mtk_smi_larb_put(struct device *larbdev)
 {
-       struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
-       struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
-
-       /*
-        * Don't de-configure the iommu info for this larb since there may be
-        * several modules in this larb.
-        * The iommu info will be reset after power off.
-        */
-
-       mtk_smi_disable(&larb->smi);
-       mtk_smi_disable(common);
+       pm_runtime_put_sync(larbdev);
 }
 EXPORT_SYMBOL_GPL(mtk_smi_larb_put);
 
@@ -146,39 +143,26 @@ static int
 mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
 {
        struct mtk_smi_larb *larb = dev_get_drvdata(dev);
-       struct mtk_smi_iommu *smi_iommu = data;
+       struct mtk_smi_larb_iommu *larb_mmu = data;
        unsigned int         i;
 
-       if (larb->larb_gen->need_larbid) {
-               larb->mmu = &smi_iommu->larb_imu[larb->larbid].mmu;
-               return 0;
-       }
-
-       /*
-        * If there is no larbid property, Loop to find the corresponding
-        * iommu information.
-        */
-       for (i = 0; i < smi_iommu->larb_nr; i++) {
-               if (dev == smi_iommu->larb_imu[i].dev) {
-                       /* The 'mmu' may be updated in iommu-attach/detach. */
-                       larb->mmu = &smi_iommu->larb_imu[i].mmu;
+       for (i = 0; i < MTK_LARB_NR_MAX; i++) {
+               if (dev == larb_mmu[i].dev) {
+                       larb->larbid = i;
+                       larb->mmu = &larb_mmu[i].mmu;
                        return 0;
                }
        }
        return -ENODEV;
 }
 
-static void mtk_smi_larb_config_port_mt2712(struct device *dev)
+static void mtk_smi_larb_config_port_gen2_general(struct device *dev)
 {
        struct mtk_smi_larb *larb = dev_get_drvdata(dev);
        u32 reg;
        int i;
 
-       /*
-        * larb 8/9 is the bdpsys larb, the iommu_en is enabled defaultly.
-        * Don't need to set it again.
-        */
-       if (larb->larbid == 8 || larb->larbid == 9)
+       if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask)
                return;
 
        for_each_set_bit(i, (unsigned long *)larb->mmu, 32) {
@@ -243,7 +227,6 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8173 = {
 };
 
 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = {
-       .need_larbid = true,
        .port_in_larb = {
                LARB0_PORT_OFFSET, LARB1_PORT_OFFSET,
                LARB2_PORT_OFFSET, LARB3_PORT_OFFSET
@@ -252,8 +235,15 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = {
 };
 
 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2712 = {
-       .need_larbid = true,
-       .config_port = mtk_smi_larb_config_port_mt2712,
+       .config_port                = mtk_smi_larb_config_port_gen2_general,
+       .larb_direct_to_common_mask = BIT(8) | BIT(9),      /* bdpsys */
+};
+
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
+       .has_gals                   = true,
+       .config_port                = mtk_smi_larb_config_port_gen2_general,
+       .larb_direct_to_common_mask = BIT(2) | BIT(3) | BIT(7),
+                                     /* IPU0 | IPU1 | CCU */
 };
 
 static const struct of_device_id mtk_smi_larb_of_ids[] = {
@@ -269,6 +259,10 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
                .compatible = "mediatek,mt2712-smi-larb",
                .data = &mtk_smi_larb_mt2712
        },
+       {
+               .compatible = "mediatek,mt8183-smi-larb",
+               .data = &mtk_smi_larb_mt8183
+       },
        {}
 };
 
@@ -279,7 +273,6 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct device_node *smi_node;
        struct platform_device *smi_pdev;
-       int err;
 
        larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
        if (!larb)
@@ -298,16 +291,16 @@ static int mtk_smi_larb_probe(struct platform_device *pdev)
        larb->smi.clk_smi = devm_clk_get(dev, "smi");
        if (IS_ERR(larb->smi.clk_smi))
                return PTR_ERR(larb->smi.clk_smi);
-       larb->smi.dev = dev;
 
-       if (larb->larb_gen->need_larbid) {
-               err = of_property_read_u32(dev->of_node, "mediatek,larb-id",
-                                          &larb->larbid);
-               if (err) {
-                       dev_err(dev, "missing larbid property\n");
-                       return err;
-               }
+       if (larb->larb_gen->has_gals) {
+               /* The larbs may still haven't gals even if the SoC support.*/
+               larb->smi.clk_gals0 = devm_clk_get(dev, "gals");
+               if (PTR_ERR(larb->smi.clk_gals0) == -ENOENT)
+                       larb->smi.clk_gals0 = NULL;
+               else if (IS_ERR(larb->smi.clk_gals0))
+                       return PTR_ERR(larb->smi.clk_gals0);
        }
+       larb->smi.dev = dev;
 
        smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
        if (!smi_node)
@@ -336,27 +329,86 @@ static int mtk_smi_larb_remove(struct platform_device *pdev)
        return 0;
 }
 
+static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
+{
+       struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+       const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
+       int ret;
+
+       /* Power on smi-common. */
+       ret = pm_runtime_get_sync(larb->smi_common_dev);
+       if (ret < 0) {
+               dev_err(dev, "Failed to pm get for smi-common(%d).\n", ret);
+               return ret;
+       }
+
+       ret = mtk_smi_clk_enable(&larb->smi);
+       if (ret < 0) {
+               dev_err(dev, "Failed to enable clock(%d).\n", ret);
+               pm_runtime_put_sync(larb->smi_common_dev);
+               return ret;
+       }
+
+       /* Configure the basic setting for this larb */
+       larb_gen->config_port(dev);
+
+       return 0;
+}
+
+static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
+{
+       struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+
+       mtk_smi_clk_disable(&larb->smi);
+       pm_runtime_put_sync(larb->smi_common_dev);
+       return 0;
+}
+
+static const struct dev_pm_ops smi_larb_pm_ops = {
+       SET_RUNTIME_PM_OPS(mtk_smi_larb_suspend, mtk_smi_larb_resume, NULL)
+};
+
 static struct platform_driver mtk_smi_larb_driver = {
        .probe  = mtk_smi_larb_probe,
        .remove = mtk_smi_larb_remove,
        .driver = {
                .name = "mtk-smi-larb",
                .of_match_table = mtk_smi_larb_of_ids,
+               .pm             = &smi_larb_pm_ops,
        }
 };
 
+static const struct mtk_smi_common_plat mtk_smi_common_gen1 = {
+       .gen = MTK_SMI_GEN1,
+};
+
+static const struct mtk_smi_common_plat mtk_smi_common_gen2 = {
+       .gen = MTK_SMI_GEN2,
+};
+
+static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = {
+       .gen      = MTK_SMI_GEN2,
+       .has_gals = true,
+       .bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(5) |
+                   F_MMU1_LARB(7),
+};
+
 static const struct of_device_id mtk_smi_common_of_ids[] = {
        {
                .compatible = "mediatek,mt8173-smi-common",
-               .data = (void *)MTK_SMI_GEN2
+               .data = &mtk_smi_common_gen2,
        },
        {
                .compatible = "mediatek,mt2701-smi-common",
-               .data = (void *)MTK_SMI_GEN1
+               .data = &mtk_smi_common_gen1,
        },
        {
                .compatible = "mediatek,mt2712-smi-common",
-               .data = (void *)MTK_SMI_GEN2
+               .data = &mtk_smi_common_gen2,
+       },
+       {
+               .compatible = "mediatek,mt8183-smi-common",
+               .data = &mtk_smi_common_mt8183,
        },
        {}
 };
@@ -366,13 +418,13 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct mtk_smi *common;
        struct resource *res;
-       enum mtk_smi_gen smi_gen;
        int ret;
 
        common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
        if (!common)
                return -ENOMEM;
        common->dev = dev;
+       common->plat = of_device_get_match_data(dev);
 
        common->clk_apb = devm_clk_get(dev, "apb");
        if (IS_ERR(common->clk_apb))
@@ -382,14 +434,23 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
        if (IS_ERR(common->clk_smi))
                return PTR_ERR(common->clk_smi);
 
+       if (common->plat->has_gals) {
+               common->clk_gals0 = devm_clk_get(dev, "gals0");
+               if (IS_ERR(common->clk_gals0))
+                       return PTR_ERR(common->clk_gals0);
+
+               common->clk_gals1 = devm_clk_get(dev, "gals1");
+               if (IS_ERR(common->clk_gals1))
+                       return PTR_ERR(common->clk_gals1);
+       }
+
        /*
         * for mtk smi gen 1, we need to get the ao(always on) base to config
         * m4u port, and we need to enable the aync clock for transform the smi
         * clock into emi clock domain, but for mtk smi gen2, there's no smi ao
         * base.
         */
-       smi_gen = (enum mtk_smi_gen)of_device_get_match_data(dev);
-       if (smi_gen == MTK_SMI_GEN1) {
+       if (common->plat->gen == MTK_SMI_GEN1) {
                res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
                common->smi_ao_base = devm_ioremap_resource(dev, res);
                if (IS_ERR(common->smi_ao_base))
@@ -402,6 +463,11 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
                ret = clk_prepare_enable(common->clk_async);
                if (ret)
                        return ret;
+       } else {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               common->base = devm_ioremap_resource(dev, res);
+               if (IS_ERR(common->base))
+                       return PTR_ERR(common->base);
        }
        pm_runtime_enable(dev);
        platform_set_drvdata(pdev, common);
@@ -414,12 +480,42 @@ static int mtk_smi_common_remove(struct platform_device *pdev)
        return 0;
 }
 
+static int __maybe_unused mtk_smi_common_resume(struct device *dev)
+{
+       struct mtk_smi *common = dev_get_drvdata(dev);
+       u32 bus_sel = common->plat->bus_sel;
+       int ret;
+
+       ret = mtk_smi_clk_enable(common);
+       if (ret) {
+               dev_err(common->dev, "Failed to enable clock(%d).\n", ret);
+               return ret;
+       }
+
+       if (common->plat->gen == MTK_SMI_GEN2 && bus_sel)
+               writel(bus_sel, common->base + SMI_BUS_SEL);
+       return 0;
+}
+
+static int __maybe_unused mtk_smi_common_suspend(struct device *dev)
+{
+       struct mtk_smi *common = dev_get_drvdata(dev);
+
+       mtk_smi_clk_disable(common);
+       return 0;
+}
+
+static const struct dev_pm_ops smi_common_pm_ops = {
+       SET_RUNTIME_PM_OPS(mtk_smi_common_suspend, mtk_smi_common_resume, NULL)
+};
+
 static struct platform_driver mtk_smi_common_driver = {
        .probe  = mtk_smi_common_probe,
        .remove = mtk_smi_common_remove,
        .driver = {
                .name = "mtk-smi-common",
                .of_match_table = mtk_smi_common_of_ids,
+               .pm             = &smi_common_pm_ops,
        }
 };
 
index 601cefb..050478c 100644 (file)
@@ -729,7 +729,7 @@ static int rk808_remove(struct i2c_client *client)
        return 0;
 }
 
-static int rk8xx_suspend(struct device *dev)
+static int __maybe_unused rk8xx_suspend(struct device *dev)
 {
        struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
        int ret = 0;
@@ -749,7 +749,7 @@ static int rk8xx_suspend(struct device *dev)
        return ret;
 }
 
-static int rk8xx_resume(struct device *dev)
+static int __maybe_unused rk8xx_resume(struct device *dev)
 {
        struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
        int ret = 0;
@@ -768,7 +768,7 @@ static int rk8xx_resume(struct device *dev)
 
        return ret;
 }
-SIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume);
+static SIMPLE_DEV_PM_OPS(rk8xx_pm_ops, rk8xx_suspend, rk8xx_resume);
 
 static struct i2c_driver rk808_i2c_driver = {
        .driver = {
index 1690035..45b61b8 100644 (file)
@@ -126,18 +126,6 @@ config INTEL_MID_PTI
          an Intel Atom (non-netbook) mobile device containing a MIPI
          P1149.7 standard implementation.
 
-config SGI_IOC4
-       tristate "SGI IOC4 Base IO support"
-       depends on PCI
-       ---help---
-         This option enables basic support for the IOC4 chip on certain
-         SGI IO controller cards (IO9, IO10, and PCI-RT).  This option
-         does not enable any specific functions on such a card, but provides
-         necessary infrastructure for other drivers to utilize.
-
-         If you have an SGI Altix with an IOC4-based card say Y.
-         Otherwise say N.
-
 config TIFM_CORE
        tristate "TI Flash Media interface support"
        depends on PCI
@@ -200,9 +188,8 @@ config ENCLOSURE_SERVICES
 config SGI_XP
        tristate "Support communication between SGI SSIs"
        depends on NET
-       depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_UV) && SMP
-       select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
-       select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
+       depends on (IA64_SGI_UV || X86_UV) && SMP
+       depends on X86_64 || BROKEN
        select SGI_GRU if X86_64 && SMP
        ---help---
          An SGI machine can be divided into multiple Single System
index abd8ae2..8dae0a9 100644 (file)
@@ -21,7 +21,6 @@ obj-$(CONFIG_QCOM_COINCELL)   += qcom-coincell.o
 obj-$(CONFIG_QCOM_FASTRPC)     += fastrpc.o
 obj-$(CONFIG_SENSORS_BH1770)   += bh1770glc.o
 obj-$(CONFIG_SENSORS_APDS990X) += apds990x.o
-obj-$(CONFIG_SGI_IOC4)         += ioc4.o
 obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
 obj-$(CONFIG_KGDB_TESTS)       += kgdbts.o
 obj-$(CONFIG_SGI_XP)           += sgi-xp/
diff --git a/drivers/misc/ioc4.c b/drivers/misc/ioc4.c
deleted file mode 100644 (file)
index 9d0445a..0000000
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2005-2006 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-/* This file contains the master driver module for use by SGI IOC4 subdrivers.
- *
- * It allocates any resources shared between multiple subdevices, and
- * provides accessor functions (where needed) and the like for those
- * resources.  It also provides a mechanism for the subdevice modules
- * to support loading and unloading.
- *
- * Non-shared resources (e.g. external interrupt A_INT_OUT register page
- * alias, serial port and UART registers) are handled by the subdevice
- * modules themselves.
- *
- * This is all necessary because IOC4 is not implemented as a multi-function
- * PCI device, but an amalgamation of disparate registers for several
- * types of device (ATA, serial, external interrupts).  The normal
- * resource management in the kernel doesn't have quite the right interfaces
- * to handle this situation (e.g. multiple modules can't claim the same
- * PCI ID), thus this IOC4 master module.
- */
-
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/ioc4.h>
-#include <linux/ktime.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-#include <linux/time.h>
-#include <asm/io.h>
-
-/***************
- * Definitions *
- ***************/
-
-/* Tweakable values */
-
-/* PCI bus speed detection/calibration */
-#define IOC4_CALIBRATE_COUNT 63                /* Calibration cycle period */
-#define IOC4_CALIBRATE_CYCLES 256      /* Average over this many cycles */
-#define IOC4_CALIBRATE_DISCARD 2       /* Discard first few cycles */
-#define IOC4_CALIBRATE_LOW_MHZ 25      /* Lower bound on bus speed sanity */
-#define IOC4_CALIBRATE_HIGH_MHZ 75     /* Upper bound on bus speed sanity */
-#define IOC4_CALIBRATE_DEFAULT_MHZ 66  /* Assumed if sanity check fails */
-
-/************************
- * Submodule management *
- ************************/
-
-static DEFINE_MUTEX(ioc4_mutex);
-
-static LIST_HEAD(ioc4_devices);
-static LIST_HEAD(ioc4_submodules);
-
-/* Register an IOC4 submodule */
-int
-ioc4_register_submodule(struct ioc4_submodule *is)
-{
-       struct ioc4_driver_data *idd;
-
-       mutex_lock(&ioc4_mutex);
-       list_add(&is->is_list, &ioc4_submodules);
-
-       /* Initialize submodule for each IOC4 */
-       if (!is->is_probe)
-               goto out;
-
-       list_for_each_entry(idd, &ioc4_devices, idd_list) {
-               if (is->is_probe(idd)) {
-                       printk(KERN_WARNING
-                              "%s: IOC4 submodule %s probe failed "
-                              "for pci_dev %s",
-                              __func__, module_name(is->is_owner),
-                              pci_name(idd->idd_pdev));
-               }
-       }
- out:
-       mutex_unlock(&ioc4_mutex);
-       return 0;
-}
-
-/* Unregister an IOC4 submodule */
-void
-ioc4_unregister_submodule(struct ioc4_submodule *is)
-{
-       struct ioc4_driver_data *idd;
-
-       mutex_lock(&ioc4_mutex);
-       list_del(&is->is_list);
-
-       /* Remove submodule for each IOC4 */
-       if (!is->is_remove)
-               goto out;
-
-       list_for_each_entry(idd, &ioc4_devices, idd_list) {
-               if (is->is_remove(idd)) {
-                       printk(KERN_WARNING
-                              "%s: IOC4 submodule %s remove failed "
-                              "for pci_dev %s.\n",
-                              __func__, module_name(is->is_owner),
-                              pci_name(idd->idd_pdev));
-               }
-       }
- out:
-       mutex_unlock(&ioc4_mutex);
-}
-
-/*********************
- * Device management *
- *********************/
-
-#define IOC4_CALIBRATE_LOW_LIMIT \
-       (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_LOW_MHZ)
-#define IOC4_CALIBRATE_HIGH_LIMIT \
-       (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_HIGH_MHZ)
-#define IOC4_CALIBRATE_DEFAULT \
-       (1000*IOC4_EXTINT_COUNT_DIVISOR/IOC4_CALIBRATE_DEFAULT_MHZ)
-
-#define IOC4_CALIBRATE_END \
-       (IOC4_CALIBRATE_CYCLES + IOC4_CALIBRATE_DISCARD)
-
-#define IOC4_INT_OUT_MODE_TOGGLE 0x7   /* Toggle INT_OUT every COUNT+1 ticks */
-
-/* Determines external interrupt output clock period of the PCI bus an
- * IOC4 is attached to.  This value can be used to determine the PCI
- * bus speed.
- *
- * IOC4 has a design feature that various internal timers are derived from
- * the PCI bus clock.  This causes IOC4 device drivers to need to take the
- * bus speed into account when setting various register values (e.g. INT_OUT
- * register COUNT field, UART divisors, etc).  Since this information is
- * needed by several subdrivers, it is determined by the main IOC4 driver,
- * even though the following code utilizes external interrupt registers
- * to perform the speed calculation.
- */
-static void
-ioc4_clock_calibrate(struct ioc4_driver_data *idd)
-{
-       union ioc4_int_out int_out;
-       union ioc4_gpcr gpcr;
-       unsigned int state, last_state;
-       uint64_t start, end, period;
-       unsigned int count;
-
-       /* Enable output */
-       gpcr.raw = 0;
-       gpcr.fields.dir = IOC4_GPCR_DIR_0;
-       gpcr.fields.int_out_en = 1;
-       writel(gpcr.raw, &idd->idd_misc_regs->gpcr_s.raw);
-
-       /* Reset to power-on state */
-       writel(0, &idd->idd_misc_regs->int_out.raw);
-
-       /* Set up square wave */
-       int_out.raw = 0;
-       int_out.fields.count = IOC4_CALIBRATE_COUNT;
-       int_out.fields.mode = IOC4_INT_OUT_MODE_TOGGLE;
-       int_out.fields.diag = 0;
-       writel(int_out.raw, &idd->idd_misc_regs->int_out.raw);
-
-       /* Check square wave period averaged over some number of cycles */
-       start = ktime_get_ns();
-       state = 1; /* make sure the first read isn't a rising edge */
-       for (count = 0; count <= IOC4_CALIBRATE_END; count++) {
-               do { /* wait for a rising edge */
-                       last_state = state;
-                       int_out.raw = readl(&idd->idd_misc_regs->int_out.raw);
-                       state = int_out.fields.int_out;
-               } while (last_state || !state);
-
-               /* discard the first few cycles */
-               if (count == IOC4_CALIBRATE_DISCARD)
-                       start = ktime_get_ns();
-       }
-       end = ktime_get_ns();
-
-       /* Calculation rearranged to preserve intermediate precision.
-        * Logically:
-        * 1. "end - start" gives us the measurement period over all
-        *    the square wave cycles.
-        * 2. Divide by number of square wave cycles to get the period
-        *    of a square wave cycle.
-        * 3. Divide by 2*(int_out.fields.count+1), which is the formula
-        *    by which the IOC4 generates the square wave, to get the
-        *    period of an IOC4 INT_OUT count.
-        */
-       period = (end - start) /
-               (IOC4_CALIBRATE_CYCLES * 2 * (IOC4_CALIBRATE_COUNT + 1));
-
-       /* Bounds check the result. */
-       if (period > IOC4_CALIBRATE_LOW_LIMIT ||
-           period < IOC4_CALIBRATE_HIGH_LIMIT) {
-               printk(KERN_INFO
-                      "IOC4 %s: Clock calibration failed.  Assuming"
-                      "PCI clock is %d ns.\n",
-                      pci_name(idd->idd_pdev),
-                      IOC4_CALIBRATE_DEFAULT / IOC4_EXTINT_COUNT_DIVISOR);
-               period = IOC4_CALIBRATE_DEFAULT;
-       } else {
-               u64 ns = period;
-
-               do_div(ns, IOC4_EXTINT_COUNT_DIVISOR);
-               printk(KERN_DEBUG
-                      "IOC4 %s: PCI clock is %llu ns.\n",
-                      pci_name(idd->idd_pdev), (unsigned long long)ns);
-       }
-
-       /* Remember results.  We store the extint clock period rather
-        * than the PCI clock period so that greater precision is
-        * retained.  Divide by IOC4_EXTINT_COUNT_DIVISOR to get
-        * PCI clock period.
-        */
-       idd->count_period = period;
-}
-
-/* There are three variants of IOC4 cards: IO9, IO10, and PCI-RT.
- * Each brings out different combinations of IOC4 signals, thus.
- * the IOC4 subdrivers need to know to which we're attached.
- *
- * We look for the presence of a SCSI (IO9) or SATA (IO10) controller
- * on the same PCI bus at slot number 3 to differentiate IO9 from IO10.
- * If neither is present, it's a PCI-RT.
- */
-static unsigned int
-ioc4_variant(struct ioc4_driver_data *idd)
-{
-       struct pci_dev *pdev = NULL;
-       int found = 0;
-
-       /* IO9: Look for a QLogic ISP 12160 at the same bus and slot 3. */
-       do {
-               pdev = pci_get_device(PCI_VENDOR_ID_QLOGIC,
-                                     PCI_DEVICE_ID_QLOGIC_ISP12160, pdev);
-               if (pdev &&
-                   idd->idd_pdev->bus->number == pdev->bus->number &&
-                   3 == PCI_SLOT(pdev->devfn))
-                       found = 1;
-       } while (pdev && !found);
-       if (NULL != pdev) {
-               pci_dev_put(pdev);
-               return IOC4_VARIANT_IO9;
-       }
-
-       /* IO10: Look for a Vitesse VSC 7174 at the same bus and slot 3. */
-       pdev = NULL;
-       do {
-               pdev = pci_get_device(PCI_VENDOR_ID_VITESSE,
-                                     PCI_DEVICE_ID_VITESSE_VSC7174, pdev);
-               if (pdev &&
-                   idd->idd_pdev->bus->number == pdev->bus->number &&
-                   3 == PCI_SLOT(pdev->devfn))
-                       found = 1;
-       } while (pdev && !found);
-       if (NULL != pdev) {
-               pci_dev_put(pdev);
-               return IOC4_VARIANT_IO10;
-       }
-
-       /* PCI-RT: No SCSI/SATA controller will be present */
-       return IOC4_VARIANT_PCI_RT;
-}
-
-static void
-ioc4_load_modules(struct work_struct *work)
-{
-       request_module("sgiioc4");
-}
-
-static DECLARE_WORK(ioc4_load_modules_work, ioc4_load_modules);
-
-/* Adds a new instance of an IOC4 card */
-static int
-ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
-{
-       struct ioc4_driver_data *idd;
-       struct ioc4_submodule *is;
-       uint32_t pcmd;
-       int ret;
-
-       /* Enable IOC4 and take ownership of it */
-       if ((ret = pci_enable_device(pdev))) {
-               printk(KERN_WARNING
-                      "%s: Failed to enable IOC4 device for pci_dev %s.\n",
-                      __func__, pci_name(pdev));
-               goto out;
-       }
-       pci_set_master(pdev);
-
-       /* Set up per-IOC4 data */
-       idd = kmalloc(sizeof(struct ioc4_driver_data), GFP_KERNEL);
-       if (!idd) {
-               printk(KERN_WARNING
-                      "%s: Failed to allocate IOC4 data for pci_dev %s.\n",
-                      __func__, pci_name(pdev));
-               ret = -ENODEV;
-               goto out_idd;
-       }
-       idd->idd_pdev = pdev;
-       idd->idd_pci_id = pci_id;
-
-       /* Map IOC4 misc registers.  These are shared between subdevices
-        * so the main IOC4 module manages them.
-        */
-       idd->idd_bar0 = pci_resource_start(idd->idd_pdev, 0);
-       if (!idd->idd_bar0) {
-               printk(KERN_WARNING
-                      "%s: Unable to find IOC4 misc resource "
-                      "for pci_dev %s.\n",
-                      __func__, pci_name(idd->idd_pdev));
-               ret = -ENODEV;
-               goto out_pci;
-       }
-       if (!request_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs),
-                           "ioc4_misc")) {
-               printk(KERN_WARNING
-                      "%s: Unable to request IOC4 misc region "
-                      "for pci_dev %s.\n",
-                      __func__, pci_name(idd->idd_pdev));
-               ret = -ENODEV;
-               goto out_pci;
-       }
-       idd->idd_misc_regs = ioremap(idd->idd_bar0,
-                                    sizeof(struct ioc4_misc_regs));
-       if (!idd->idd_misc_regs) {
-               printk(KERN_WARNING
-                      "%s: Unable to remap IOC4 misc region "
-                      "for pci_dev %s.\n",
-                      __func__, pci_name(idd->idd_pdev));
-               ret = -ENODEV;
-               goto out_misc_region;
-       }
-
-       /* Failsafe portion of per-IOC4 initialization */
-
-       /* Detect card variant */
-       idd->idd_variant = ioc4_variant(idd);
-       printk(KERN_INFO "IOC4 %s: %s card detected.\n", pci_name(pdev),
-              idd->idd_variant == IOC4_VARIANT_IO9 ? "IO9" :
-              idd->idd_variant == IOC4_VARIANT_PCI_RT ? "PCI-RT" :
-              idd->idd_variant == IOC4_VARIANT_IO10 ? "IO10" : "unknown");
-
-       /* Initialize IOC4 */
-       pci_read_config_dword(idd->idd_pdev, PCI_COMMAND, &pcmd);
-       pci_write_config_dword(idd->idd_pdev, PCI_COMMAND,
-                              pcmd | PCI_COMMAND_PARITY | PCI_COMMAND_SERR);
-
-       /* Determine PCI clock */
-       ioc4_clock_calibrate(idd);
-
-       /* Disable/clear all interrupts.  Need to do this here lest
-        * one submodule request the shared IOC4 IRQ, but interrupt
-        * is generated by a different subdevice.
-        */
-       /* Disable */
-       writel(~0, &idd->idd_misc_regs->other_iec.raw);
-       writel(~0, &idd->idd_misc_regs->sio_iec);
-       /* Clear (i.e. acknowledge) */
-       writel(~0, &idd->idd_misc_regs->other_ir.raw);
-       writel(~0, &idd->idd_misc_regs->sio_ir);
-
-       /* Track PCI-device specific data */
-       idd->idd_serial_data = NULL;
-       pci_set_drvdata(idd->idd_pdev, idd);
-
-       mutex_lock(&ioc4_mutex);
-       list_add_tail(&idd->idd_list, &ioc4_devices);
-
-       /* Add this IOC4 to all submodules */
-       list_for_each_entry(is, &ioc4_submodules, is_list) {
-               if (is->is_probe && is->is_probe(idd)) {
-                       printk(KERN_WARNING
-                              "%s: IOC4 submodule 0x%s probe failed "
-                              "for pci_dev %s.\n",
-                              __func__, module_name(is->is_owner),
-                              pci_name(idd->idd_pdev));
-               }
-       }
-       mutex_unlock(&ioc4_mutex);
-
-       /* Request sgiioc4 IDE driver on boards that bring that functionality
-        * off of IOC4.  The root filesystem may be hosted on a drive connected
-        * to IOC4, so we need to make sure the sgiioc4 driver is loaded as it
-        * won't be picked up by modprobes due to the ioc4 module owning the
-        * PCI device.
-        */
-       if (idd->idd_variant != IOC4_VARIANT_PCI_RT) {
-               /* Request the module from a work procedure as the modprobe
-                * goes out to a userland helper and that will hang if done
-                * directly from ioc4_probe().
-                */
-               printk(KERN_INFO "IOC4 loading sgiioc4 submodule\n");
-               schedule_work(&ioc4_load_modules_work);
-       }
-
-       return 0;
-
-out_misc_region:
-       release_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
-out_pci:
-       kfree(idd);
-out_idd:
-       pci_disable_device(pdev);
-out:
-       return ret;
-}
-
-/* Removes a particular instance of an IOC4 card. */
-static void
-ioc4_remove(struct pci_dev *pdev)
-{
-       struct ioc4_submodule *is;
-       struct ioc4_driver_data *idd;
-
-       idd = pci_get_drvdata(pdev);
-
-       /* Remove this IOC4 from all submodules */
-       mutex_lock(&ioc4_mutex);
-       list_for_each_entry(is, &ioc4_submodules, is_list) {
-               if (is->is_remove && is->is_remove(idd)) {
-                       printk(KERN_WARNING
-                              "%s: IOC4 submodule 0x%s remove failed "
-                              "for pci_dev %s.\n",
-                              __func__, module_name(is->is_owner),
-                              pci_name(idd->idd_pdev));
-               }
-       }
-       mutex_unlock(&ioc4_mutex);
-
-       /* Release resources */
-       iounmap(idd->idd_misc_regs);
-       if (!idd->idd_bar0) {
-               printk(KERN_WARNING
-                      "%s: Unable to get IOC4 misc mapping for pci_dev %s. "
-                      "Device removal may be incomplete.\n",
-                      __func__, pci_name(idd->idd_pdev));
-       }
-       release_mem_region(idd->idd_bar0, sizeof(struct ioc4_misc_regs));
-
-       /* Disable IOC4 and relinquish */
-       pci_disable_device(pdev);
-
-       /* Remove and free driver data */
-       mutex_lock(&ioc4_mutex);
-       list_del(&idd->idd_list);
-       mutex_unlock(&ioc4_mutex);
-       kfree(idd);
-}
-
-static const struct pci_device_id ioc4_id_table[] = {
-       {PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC4, PCI_ANY_ID,
-        PCI_ANY_ID, 0x0b4000, 0xFFFFFF},
-       {0}
-};
-
-static struct pci_driver ioc4_driver = {
-       .name = "IOC4",
-       .id_table = ioc4_id_table,
-       .probe = ioc4_probe,
-       .remove = ioc4_remove,
-};
-
-MODULE_DEVICE_TABLE(pci, ioc4_id_table);
-
-/*********************
- * Module management *
- *********************/
-
-/* Module load */
-static int __init
-ioc4_init(void)
-{
-       return pci_register_driver(&ioc4_driver);
-}
-
-/* Module unload */
-static void __exit
-ioc4_exit(void)
-{
-       /* Ensure ioc4_load_modules() has completed before exiting */
-       flush_work(&ioc4_load_modules_work);
-       pci_unregister_driver(&ioc4_driver);
-}
-
-module_init(ioc4_init);
-module_exit(ioc4_exit);
-
-MODULE_AUTHOR("Brent Casavant - Silicon Graphics, Inc. <bcasavan@sgi.com>");
-MODULE_DESCRIPTION("PCI driver master module for SGI IOC4 Base-IO Card");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(ioc4_register_submodule);
-EXPORT_SYMBOL(ioc4_unregister_submodule);
index 1606658..24245cc 100644 (file)
@@ -22,7 +22,7 @@ struct lkdtm_list {
  * recurse past the end of THREAD_SIZE by default.
  */
 #if defined(CONFIG_FRAME_WARN) && (CONFIG_FRAME_WARN > 0)
-#define REC_STACK_SIZE (CONFIG_FRAME_WARN / 2)
+#define REC_STACK_SIZE (_AC(CONFIG_FRAME_WARN, UL) / 2)
 #else
 #define REC_STACK_SIZE (THREAD_SIZE / 8)
 #endif
@@ -91,7 +91,7 @@ void lkdtm_LOOP(void)
 
 void lkdtm_EXHAUST_STACK(void)
 {
-       pr_info("Calling function with %d frame size to depth %d ...\n",
+       pr_info("Calling function with %lu frame size to depth %d ...\n",
                REC_STACK_SIZE, recur_count);
        recursive_loop(recur_count);
        pr_info("FAIL: survived without exhausting stack?!\n");
index 6c01737..77f7dff 100644 (file)
@@ -81,6 +81,8 @@
 
 #define MEI_DEV_ID_ICP_LP     0x34E0  /* Ice Lake Point LP */
 
+#define MEI_DEV_ID_TGP_LP     0xA0E0  /* Tiger Lake Point LP */
+
 #define MEI_DEV_ID_MCC        0x4B70  /* Mule Creek Canyon (EHL) */
 #define MEI_DEV_ID_MCC_4      0x4B75  /* Mule Creek Canyon 4 (EHL) */
 
index 57cb68f..541538e 100644 (file)
@@ -98,6 +98,8 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
 
        {MEI_PCI_DEVICE(MEI_DEV_ID_ICP_LP, MEI_ME_PCH12_CFG)},
 
+       {MEI_PCI_DEVICE(MEI_DEV_ID_TGP_LP, MEI_ME_PCH12_CFG)},
+
        {MEI_PCI_DEVICE(MEI_DEV_ID_MCC, MEI_ME_PCH12_CFG)},
        {MEI_PCI_DEVICE(MEI_DEV_ID_MCC_4, MEI_ME_PCH8_CFG)},
 
index bbb622c..34c55a4 100644 (file)
@@ -4,17 +4,10 @@
 #
 
 obj-$(CONFIG_SGI_XP)           += xp.o
-xp-y                           := xp_main.o
-xp-$(CONFIG_IA64_SGI_SN2)      += xp_sn2.o xp_nofault.o
-xp-$(CONFIG_IA64_GENERIC)      += xp_sn2.o xp_nofault.o
-xp-$(CONFIG_IA64_SGI_UV)       += xp_uv.o
-xp-$(CONFIG_X86_64)            += xp_uv.o
+xp-y                           := xp_main.o xp_uv.o
 
 obj-$(CONFIG_SGI_XP)           += xpc.o
-xpc-y                          := xpc_main.o xpc_channel.o xpc_partition.o
-xpc-$(CONFIG_IA64_SGI_SN2)     += xpc_sn2.o
-xpc-$(CONFIG_IA64_GENERIC)     += xpc_sn2.o
-xpc-$(CONFIG_IA64_SGI_UV)      += xpc_uv.o
-xpc-$(CONFIG_X86_64)           += xpc_uv.o
+xpc-y                          := xpc_main.o xpc_channel.o xpc_partition.o \
+                                  xpc_uv.o
 
 obj-$(CONFIG_SGI_XP)           += xpnet.o
index b8069ee..06469b1 100644 (file)
 #define is_uv()                0
 #endif
 
-#if defined CONFIG_IA64
-#include <asm/sn/arch.h>       /* defines is_shub1() and is_shub2() */
-#define is_shub()      ia64_platform_is("sn2")
-#endif
-
-#ifndef is_shub1
-#define is_shub1()     0
-#endif
-
-#ifndef is_shub2
-#define is_shub2()     0
-#endif
-
-#ifndef is_shub
-#define is_shub()      0
-#endif
-
 #ifdef USE_DBUG_ON
 #define DBUG_ON(condition)     BUG_ON(condition)
 #else
@@ -360,9 +343,7 @@ extern int xp_nofault_PIOR(void *);
 extern int xp_error_PIOR(void);
 
 extern struct device *xp;
-extern enum xp_retval xp_init_sn2(void);
 extern enum xp_retval xp_init_uv(void);
-extern void xp_exit_sn2(void);
 extern void xp_exit_uv(void);
 
 #endif /* _DRIVERS_MISC_SGIXP_XP_H */
index 6d7f557..5fd94d8 100644 (file)
@@ -233,9 +233,7 @@ xp_init(void)
        for (ch_number = 0; ch_number < XPC_MAX_NCHANNELS; ch_number++)
                mutex_init(&xpc_registrations[ch_number].mutex);
 
-       if (is_shub())
-               ret = xp_init_sn2();
-       else if (is_uv())
+       if (is_uv())
                ret = xp_init_uv();
        else
                ret = 0;
@@ -251,9 +249,7 @@ module_init(xp_init);
 void __exit
 xp_exit(void)
 {
-       if (is_shub())
-               xp_exit_sn2();
-       else if (is_uv())
+       if (is_uv())
                xp_exit_uv();
 }
 
diff --git a/drivers/misc/sgi-xp/xp_nofault.S b/drivers/misc/sgi-xp/xp_nofault.S
deleted file mode 100644 (file)
index e38d433..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2004-2008 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-/*
- * The xp_nofault_PIOR function takes a pointer to a remote PIO register
- * and attempts to load and consume a value from it.  This function
- * will be registered as a nofault code block.  In the event that the
- * PIO read fails, the MCA handler will force the error to look
- * corrected and vector to the xp_error_PIOR which will return an error.
- *
- * The definition of "consumption" and the time it takes for an MCA
- * to surface is processor implementation specific.  This code
- * is sufficient on Itanium through the Montvale processor family.
- * It may need to be adjusted for future processor implementations.
- *
- *     extern int xp_nofault_PIOR(void *remote_register);
- */
-
-       .global xp_nofault_PIOR
-xp_nofault_PIOR:
-       mov     r8=r0                   // Stage a success return value
-       ld8.acq r9=[r32];;              // PIO Read the specified register
-       adds    r9=1,r9;;               // Add to force consumption
-       srlz.i;;                        // Allow time for MCA to surface
-       br.ret.sptk.many b0;;           // Return success
-
-       .global xp_error_PIOR
-xp_error_PIOR:
-       mov     r8=1                    // Return value of 1
-       br.ret.sptk.many b0;;           // Return failure
diff --git a/drivers/misc/sgi-xp/xp_sn2.c b/drivers/misc/sgi-xp/xp_sn2.c
deleted file mode 100644 (file)
index d8e463f..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-/*
- * Cross Partition (XP) sn2-based functions.
- *
- *      Architecture specific implementation of common functions.
- */
-
-#include <linux/module.h>
-#include <linux/device.h>
-#include <asm/sn/bte.h>
-#include <asm/sn/sn_sal.h>
-#include "xp.h"
-
-/*
- * The export of xp_nofault_PIOR needs to happen here since it is defined
- * in drivers/misc/sgi-xp/xp_nofault.S. The target of the nofault read is
- * defined here.
- */
-EXPORT_SYMBOL_GPL(xp_nofault_PIOR);
-
-u64 xp_nofault_PIOR_target;
-EXPORT_SYMBOL_GPL(xp_nofault_PIOR_target);
-
-/*
- * Register a nofault code region which performs a cross-partition PIO read.
- * If the PIO read times out, the MCA handler will consume the error and
- * return to a kernel-provided instruction to indicate an error. This PIO read
- * exists because it is guaranteed to timeout if the destination is down
- * (amo operations do not timeout on at least some CPUs on Shubs <= v1.2,
- * which unfortunately we have to work around).
- */
-static enum xp_retval
-xp_register_nofault_code_sn2(void)
-{
-       int ret;
-       u64 func_addr;
-       u64 err_func_addr;
-
-       func_addr = *(u64 *)xp_nofault_PIOR;
-       err_func_addr = *(u64 *)xp_error_PIOR;
-       ret = sn_register_nofault_code(func_addr, err_func_addr, err_func_addr,
-                                      1, 1);
-       if (ret != 0) {
-               dev_err(xp, "can't register nofault code, error=%d\n", ret);
-               return xpSalError;
-       }
-       /*
-        * Setup the nofault PIO read target. (There is no special reason why
-        * SH_IPI_ACCESS was selected.)
-        */
-       if (is_shub1())
-               xp_nofault_PIOR_target = SH1_IPI_ACCESS;
-       else if (is_shub2())
-               xp_nofault_PIOR_target = SH2_IPI_ACCESS0;
-
-       return xpSuccess;
-}
-
-static void
-xp_unregister_nofault_code_sn2(void)
-{
-       u64 func_addr = *(u64 *)xp_nofault_PIOR;
-       u64 err_func_addr = *(u64 *)xp_error_PIOR;
-
-       /* unregister the PIO read nofault code region */
-       (void)sn_register_nofault_code(func_addr, err_func_addr,
-                                      err_func_addr, 1, 0);
-}
-
-/*
- * Convert a virtual memory address to a physical memory address.
- */
-static unsigned long
-xp_pa_sn2(void *addr)
-{
-       return __pa(addr);
-}
-
-/*
- * Convert a global physical to a socket physical address.
- */
-static unsigned long
-xp_socket_pa_sn2(unsigned long gpa)
-{
-       return gpa;
-}
-
-/*
- * Wrapper for bte_copy().
- *
- *     dst_pa - physical address of the destination of the transfer.
- *     src_pa - physical address of the source of the transfer.
- *     len - number of bytes to transfer from source to destination.
- *
- * Note: xp_remote_memcpy_sn2() should never be called while holding a spinlock.
- */
-static enum xp_retval
-xp_remote_memcpy_sn2(unsigned long dst_pa, const unsigned long src_pa,
-                    size_t len)
-{
-       bte_result_t ret;
-
-       ret = bte_copy(src_pa, dst_pa, len, (BTE_NOTIFY | BTE_WACQUIRE), NULL);
-       if (ret == BTE_SUCCESS)
-               return xpSuccess;
-
-       if (is_shub2()) {
-               dev_err(xp, "bte_copy() on shub2 failed, error=0x%x dst_pa="
-                       "0x%016lx src_pa=0x%016lx len=%ld\\n", ret, dst_pa,
-                       src_pa, len);
-       } else {
-               dev_err(xp, "bte_copy() failed, error=%d dst_pa=0x%016lx "
-                       "src_pa=0x%016lx len=%ld\\n", ret, dst_pa, src_pa, len);
-       }
-
-       return xpBteCopyError;
-}
-
-static int
-xp_cpu_to_nasid_sn2(int cpuid)
-{
-       return cpuid_to_nasid(cpuid);
-}
-
-static enum xp_retval
-xp_expand_memprotect_sn2(unsigned long phys_addr, unsigned long size)
-{
-       u64 nasid_array = 0;
-       int ret;
-
-       ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
-                                  &nasid_array);
-       if (ret != 0) {
-               dev_err(xp, "sn_change_memprotect(,, "
-                       "SN_MEMPROT_ACCESS_CLASS_1,) failed ret=%d\n", ret);
-               return xpSalError;
-       }
-       return xpSuccess;
-}
-
-static enum xp_retval
-xp_restrict_memprotect_sn2(unsigned long phys_addr, unsigned long size)
-{
-       u64 nasid_array = 0;
-       int ret;
-
-       ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
-                                  &nasid_array);
-       if (ret != 0) {
-               dev_err(xp, "sn_change_memprotect(,, "
-                       "SN_MEMPROT_ACCESS_CLASS_0,) failed ret=%d\n", ret);
-               return xpSalError;
-       }
-       return xpSuccess;
-}
-
-enum xp_retval
-xp_init_sn2(void)
-{
-       BUG_ON(!is_shub());
-
-       xp_max_npartitions = XP_MAX_NPARTITIONS_SN2;
-       xp_partition_id = sn_partition_id;
-       xp_region_size = sn_region_size;
-
-       xp_pa = xp_pa_sn2;
-       xp_socket_pa = xp_socket_pa_sn2;
-       xp_remote_memcpy = xp_remote_memcpy_sn2;
-       xp_cpu_to_nasid = xp_cpu_to_nasid_sn2;
-       xp_expand_memprotect = xp_expand_memprotect_sn2;
-       xp_restrict_memprotect = xp_restrict_memprotect_sn2;
-
-       return xp_register_nofault_code_sn2();
-}
-
-void
-xp_exit_sn2(void)
-{
-       BUG_ON(!is_shub());
-
-       xp_unregister_nofault_code_sn2();
-}
-
index a0d0932..f15a9f2 100644 (file)
@@ -17,7 +17,7 @@
 #include <asm/uv/uv_hub.h>
 #if defined CONFIG_X86_64
 #include <asm/uv/bios.h>
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+#elif defined CONFIG_IA64_SGI_UV
 #include <asm/sn/sn_sal.h>
 #endif
 #include "../sgi-gru/grukservices.h"
@@ -99,7 +99,7 @@ xp_expand_memprotect_uv(unsigned long phys_addr, unsigned long size)
                return xpBiosError;
        }
 
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+#elif defined CONFIG_IA64_SGI_UV
        u64 nasid_array;
 
        ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_1,
@@ -129,7 +129,7 @@ xp_restrict_memprotect_uv(unsigned long phys_addr, unsigned long size)
                return xpBiosError;
        }
 
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+#elif defined CONFIG_IA64_SGI_UV
        u64 nasid_array;
 
        ret = sn_change_memprotect(phys_addr, size, SN_MEMPROT_ACCESS_CLASS_0,
@@ -151,9 +151,10 @@ xp_init_uv(void)
        BUG_ON(!is_uv());
 
        xp_max_npartitions = XP_MAX_NPARTITIONS_UV;
+#ifdef CONFIG_X86
        xp_partition_id = sn_partition_id;
        xp_region_size = sn_region_size;
-
+#endif
        xp_pa = xp_pa_uv;
        xp_socket_pa = xp_socket_pa_uv;
        xp_remote_memcpy = xp_remote_memcpy_uv;
index b94d5f7..71db60e 100644 (file)
  *     'SAL_nasids_size'. (Local partition's mask pointers are xpc_part_nasids
  *     and xpc_mach_nasids.)
  *
- *   vars      (ia64-sn2 only)
- *   vars part (ia64-sn2 only)
- *
  *     Immediately following the mach_nasids mask are the XPC variables
  *     required by other partitions. First are those that are generic to all
  *     partitions (vars), followed on the next available cacheline by those
  *     which are partition specific (vars part). These are setup by XPC.
- *     (Local partition's vars pointers are xpc_vars and xpc_vars_part.)
  *
  * Note: Until 'ts_jiffies' is set non-zero, the partition XPC code has not been
  *       initialized.
@@ -93,9 +89,6 @@ struct xpc_rsvd_page {
        unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
        union {
                struct {
-                       unsigned long vars_pa;  /* phys addr */
-               } sn2;
-               struct {
                        unsigned long heartbeat_gpa; /* phys addr */
                        unsigned long activate_gru_mq_desc_gpa; /* phys addr */
                } uv;
@@ -106,84 +99,14 @@ struct xpc_rsvd_page {
 
 #define XPC_RP_VERSION _XPC_VERSION(3, 0) /* version 3.0 of the reserved page */
 
-/*
- * Define the structures by which XPC variables can be exported to other
- * partitions. (There are two: struct xpc_vars and struct xpc_vars_part)
- */
-
-/*
- * The following structure describes the partition generic variables
- * needed by other partitions in order to properly initialize.
- *
- * struct xpc_vars version number also applies to struct xpc_vars_part.
- * Changes to either structure and/or related functionality should be
- * reflected by incrementing either the major or minor version numbers
- * of struct xpc_vars.
- */
-struct xpc_vars_sn2 {
-       u8 version;
-       u64 heartbeat;
-       DECLARE_BITMAP(heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
-       u64 heartbeat_offline;  /* if 0, heartbeat should be changing */
-       int activate_IRQ_nasid;
-       int activate_IRQ_phys_cpuid;
-       unsigned long vars_part_pa;
-       unsigned long amos_page_pa;/* paddr of page of amos from MSPEC driver */
-       struct amo *amos_page;  /* vaddr of page of amos from MSPEC driver */
-};
-
-#define XPC_V_VERSION _XPC_VERSION(3, 1)    /* version 3.1 of the cross vars */
-
-/*
- * The following structure describes the per partition specific variables.
- *
- * An array of these structures, one per partition, will be defined. As a
- * partition becomes active XPC will copy the array entry corresponding to
- * itself from that partition. It is desirable that the size of this structure
- * evenly divides into a 128-byte cacheline, such that none of the entries in
- * this array crosses a 128-byte cacheline boundary. As it is now, each entry
- * occupies 64-bytes.
- */
-struct xpc_vars_part_sn2 {
-       u64 magic;
-
-       unsigned long openclose_args_pa; /* phys addr of open and close args */
-       unsigned long GPs_pa;   /* physical address of Get/Put values */
-
-       unsigned long chctl_amo_pa; /* physical address of chctl flags' amo */
-
-       int notify_IRQ_nasid;   /* nasid of where to send notify IRQs */
-       int notify_IRQ_phys_cpuid;      /* CPUID of where to send notify IRQs */
-
-       u8 nchannels;           /* #of defined channels supported */
-
-       u8 reserved[23];        /* pad to a full 64 bytes */
-};
-
-/*
- * The vars_part MAGIC numbers play a part in the first contact protocol.
- *
- * MAGIC1 indicates that the per partition specific variables for a remote
- * partition have been initialized by this partition.
- *
- * MAGIC2 indicates that this partition has pulled the remote partititions
- * per partition variables that pertain to this partition.
- */
-#define XPC_VP_MAGIC1_SN2 0x0053524156435058L /* 'XPCVARS\0'L (little endian) */
-#define XPC_VP_MAGIC2_SN2 0x0073726176435058L /* 'XPCvars\0'L (little endian) */
-
 /* the reserved page sizes and offsets */
 
 #define XPC_RP_HEADER_SIZE     L1_CACHE_ALIGN(sizeof(struct xpc_rsvd_page))
-#define XPC_RP_VARS_SIZE       L1_CACHE_ALIGN(sizeof(struct xpc_vars_sn2))
 
 #define XPC_RP_PART_NASIDS(_rp) ((unsigned long *)((u8 *)(_rp) + \
                                 XPC_RP_HEADER_SIZE))
 #define XPC_RP_MACH_NASIDS(_rp) (XPC_RP_PART_NASIDS(_rp) + \
                                 xpc_nasid_mask_nlongs)
-#define XPC_RP_VARS(_rp)       ((struct xpc_vars_sn2 *) \
-                                (XPC_RP_MACH_NASIDS(_rp) + \
-                                 xpc_nasid_mask_nlongs))
 
 
 /*
@@ -298,17 +221,6 @@ struct xpc_activate_mq_msg_chctl_opencomplete_uv {
 #define XPC_UNPACK_ARG2(_args) ((((u64)_args) >> 32) & 0xffffffff)
 
 /*
- * Define a Get/Put value pair (pointers) used with a message queue.
- */
-struct xpc_gp_sn2 {
-       s64 get;                /* Get value */
-       s64 put;                /* Put value */
-};
-
-#define XPC_GP_SIZE \
-               L1_CACHE_ALIGN(sizeof(struct xpc_gp_sn2) * XPC_MAX_NCHANNELS)
-
-/*
  * Define a structure that contains arguments associated with opening and
  * closing a channel.
  */
@@ -341,30 +253,6 @@ struct xpc_fifo_head_uv {
 };
 
 /*
- * Define a sn2 styled message.
- *
- * A user-defined message resides in the payload area. The max size of the
- * payload is defined by the user via xpc_connect().
- *
- * The size of a message entry (within a message queue) must be a 128-byte
- * cacheline sized multiple in order to facilitate the BTE transfer of messages
- * from one message queue to another.
- */
-struct xpc_msg_sn2 {
-       u8 flags;               /* FOR XPC INTERNAL USE ONLY */
-       u8 reserved[7];         /* FOR XPC INTERNAL USE ONLY */
-       s64 number;             /* FOR XPC INTERNAL USE ONLY */
-
-       u64 payload;            /* user defined portion of message */
-};
-
-/* struct xpc_msg_sn2 flags */
-
-#define        XPC_M_SN2_DONE          0x01    /* msg has been received/consumed */
-#define        XPC_M_SN2_READY         0x02    /* msg is ready to be sent */
-#define        XPC_M_SN2_INTERRUPT     0x04    /* send interrupt when msg consumed */
-
-/*
  * The format of a uv XPC notify_mq GRU message is as follows:
  *
  * A user-defined message resides in the payload area. The max size of the
@@ -390,20 +278,6 @@ struct xpc_notify_mq_msg_uv {
        unsigned long payload;
 };
 
-/*
- * Define sn2's notify entry.
- *
- * This is used to notify a message's sender that their message was received
- * and consumed by the intended recipient.
- */
-struct xpc_notify_sn2 {
-       u8 type;                /* type of notification */
-
-       /* the following two fields are only used if type == XPC_N_CALL */
-       xpc_notify_func func;   /* user's notify function */
-       void *key;              /* pointer to user's key */
-};
-
 /* struct xpc_notify_sn2 type of notification */
 
 #define        XPC_N_CALL      0x01    /* notify function provided by user */
@@ -431,102 +305,6 @@ struct xpc_send_msg_slot_uv {
  * of these structures for each potential channel connection to that partition.
  */
 
-/*
- * The following is sn2 only.
- *
- * Each channel structure manages two message queues (circular buffers).
- * They are allocated at the time a channel connection is made. One of
- * these message queues (local_msgqueue) holds the locally created messages
- * that are destined for the remote partition. The other of these message
- * queues (remote_msgqueue) is a locally cached copy of the remote partition's
- * own local_msgqueue.
- *
- * The following is a description of the Get/Put pointers used to manage these
- * two message queues. Consider the local_msgqueue to be on one partition
- * and the remote_msgqueue to be its cached copy on another partition. A
- * description of what each of the lettered areas contains is included.
- *
- *
- *                     local_msgqueue      remote_msgqueue
- *
- *                        |/////////|      |/////////|
- *    w_remote_GP.get --> +---------+      |/////////|
- *                        |    F    |      |/////////|
- *     remote_GP.get  --> +---------+      +---------+ <-- local_GP->get
- *                        |         |      |         |
- *                        |         |      |    E    |
- *                        |         |      |         |
- *                        |         |      +---------+ <-- w_local_GP.get
- *                        |    B    |      |/////////|
- *                        |         |      |////D////|
- *                        |         |      |/////////|
- *                        |         |      +---------+ <-- w_remote_GP.put
- *                        |         |      |////C////|
- *      local_GP->put --> +---------+      +---------+ <-- remote_GP.put
- *                        |         |      |/////////|
- *                        |    A    |      |/////////|
- *                        |         |      |/////////|
- *     w_local_GP.put --> +---------+      |/////////|
- *                        |/////////|      |/////////|
- *
- *
- *         ( remote_GP.[get|put] are cached copies of the remote
- *           partition's local_GP->[get|put], and thus their values can
- *           lag behind their counterparts on the remote partition. )
- *
- *
- *  A - Messages that have been allocated, but have not yet been sent to the
- *     remote partition.
- *
- *  B - Messages that have been sent, but have not yet been acknowledged by the
- *      remote partition as having been received.
- *
- *  C - Area that needs to be prepared for the copying of sent messages, by
- *     the clearing of the message flags of any previously received messages.
- *
- *  D - Area into which sent messages are to be copied from the remote
- *     partition's local_msgqueue and then delivered to their intended
- *     recipients. [ To allow for a multi-message copy, another pointer
- *     (next_msg_to_pull) has been added to keep track of the next message
- *     number needing to be copied (pulled). It chases after w_remote_GP.put.
- *     Any messages lying between w_local_GP.get and next_msg_to_pull have
- *     been copied and are ready to be delivered. ]
- *
- *  E - Messages that have been copied and delivered, but have not yet been
- *     acknowledged by the recipient as having been received.
- *
- *  F - Messages that have been acknowledged, but XPC has not yet notified the
- *     sender that the message was received by its intended recipient.
- *     This is also an area that needs to be prepared for the allocating of
- *     new messages, by the clearing of the message flags of the acknowledged
- *     messages.
- */
-
-struct xpc_channel_sn2 {
-       struct xpc_openclose_args *local_openclose_args; /* args passed on */
-                                            /* opening or closing of channel */
-
-       void *local_msgqueue_base;      /* base address of kmalloc'd space */
-       struct xpc_msg_sn2 *local_msgqueue;     /* local message queue */
-       void *remote_msgqueue_base;     /* base address of kmalloc'd space */
-       struct xpc_msg_sn2 *remote_msgqueue; /* cached copy of remote */
-                                          /* partition's local message queue */
-       unsigned long remote_msgqueue_pa; /* phys addr of remote partition's */
-                                         /* local message queue */
-
-       struct xpc_notify_sn2 *notify_queue;/* notify queue for messages sent */
-
-       /* various flavors of local and remote Get/Put values */
-
-       struct xpc_gp_sn2 *local_GP;    /* local Get/Put values */
-       struct xpc_gp_sn2 remote_GP;    /* remote Get/Put values */
-       struct xpc_gp_sn2 w_local_GP;   /* working local Get/Put values */
-       struct xpc_gp_sn2 w_remote_GP;  /* working remote Get/Put values */
-       s64 next_msg_to_pull;   /* Put value of next msg to pull */
-
-       struct mutex msg_to_pull_mutex; /* next msg to pull serialization */
-};
-
 struct xpc_channel_uv {
        void *cached_notify_gru_mq_desc; /* remote partition's notify mq's */
                                         /* gru mq descriptor */
@@ -579,7 +357,6 @@ struct xpc_channel {
        wait_queue_head_t idle_wq;      /* idle kthread wait queue */
 
        union {
-               struct xpc_channel_sn2 sn2;
                struct xpc_channel_uv uv;
        } sn;
 
@@ -666,43 +443,6 @@ xpc_any_msg_chctl_flags_set(union xpc_channel_ctl_flags *chctl)
        return 0;
 }
 
-/*
- * Manage channels on a partition basis. There is one of these structures
- * for each partition (a partition will never utilize the structure that
- * represents itself).
- */
-
-struct xpc_partition_sn2 {
-       unsigned long remote_amos_page_pa; /* paddr of partition's amos page */
-       int activate_IRQ_nasid; /* active partition's act/deact nasid */
-       int activate_IRQ_phys_cpuid;    /* active part's act/deact phys cpuid */
-
-       unsigned long remote_vars_pa;   /* phys addr of partition's vars */
-       unsigned long remote_vars_part_pa; /* paddr of partition's vars part */
-       u8 remote_vars_version; /* version# of partition's vars */
-
-       void *local_GPs_base;   /* base address of kmalloc'd space */
-       struct xpc_gp_sn2 *local_GPs;   /* local Get/Put values */
-       void *remote_GPs_base;  /* base address of kmalloc'd space */
-       struct xpc_gp_sn2 *remote_GPs;  /* copy of remote partition's local */
-                                       /* Get/Put values */
-       unsigned long remote_GPs_pa; /* phys addr of remote partition's local */
-                                    /* Get/Put values */
-
-       void *local_openclose_args_base;   /* base address of kmalloc'd space */
-       struct xpc_openclose_args *local_openclose_args;      /* local's args */
-       unsigned long remote_openclose_args_pa; /* phys addr of remote's args */
-
-       int notify_IRQ_nasid;   /* nasid of where to send notify IRQs */
-       int notify_IRQ_phys_cpuid;      /* CPUID of where to send notify IRQs */
-       char notify_IRQ_owner[8];       /* notify IRQ's owner's name */
-
-       struct amo *remote_chctl_amo_va; /* addr of remote chctl flags' amo */
-       struct amo *local_chctl_amo_va; /* address of chctl flags' amo */
-
-       struct timer_list dropped_notify_IRQ_timer;     /* dropped IRQ timer */
-};
-
 struct xpc_partition_uv {
        unsigned long heartbeat_gpa; /* phys addr of partition's heartbeat */
        struct xpc_heartbeat_uv cached_heartbeat; /* cached copy of */
@@ -774,7 +514,6 @@ struct xpc_partition {
        wait_queue_head_t channel_mgr_wq;       /* channel mgr's wait queue */
 
        union {
-               struct xpc_partition_sn2 sn2;
                struct xpc_partition_uv uv;
        } sn;
 
@@ -854,14 +593,6 @@ struct xpc_arch_operations {
 #define XPC_P_SS_WTEARDOWN     0x02    /* waiting to teardown infrastructure */
 #define XPC_P_SS_TORNDOWN      0x03    /* infrastructure is torndown */
 
-/*
- * struct xpc_partition_sn2's dropped notify IRQ timer is set to wait the
- * following interval #of seconds before checking for dropped notify IRQs.
- * These can occur whenever an IRQ's associated amo write doesn't complete
- * until after the IRQ was received.
- */
-#define XPC_DROPPED_NOTIFY_IRQ_WAIT_INTERVAL   (0.25 * HZ)
-
 /* number of seconds to wait for other partitions to disengage */
 #define XPC_DISENGAGE_DEFAULT_TIMELIMIT                90
 
@@ -888,10 +619,6 @@ extern void xpc_activate_kthreads(struct xpc_channel *, int);
 extern void xpc_create_kthreads(struct xpc_channel *, int, int);
 extern void xpc_disconnect_wait(int);
 
-/* found in xpc_sn2.c */
-extern int xpc_init_sn2(void);
-extern void xpc_exit_sn2(void);
-
 /* found in xpc_uv.c */
 extern int xpc_init_uv(void);
 extern void xpc_exit_uv(void);
index 83fc748..79a9631 100644 (file)
@@ -279,13 +279,6 @@ xpc_hb_checker(void *ignore)
 
                        dev_dbg(xpc_part, "checking remote heartbeats\n");
                        xpc_check_remote_hb();
-
-                       /*
-                        * On sn2 we need to periodically recheck to ensure no
-                        * IRQ/amo pairs have been missed.
-                        */
-                       if (is_shub())
-                               force_IRQ = 1;
                }
 
                /* check for outstanding IRQs */
@@ -1050,9 +1043,7 @@ xpc_do_exit(enum xp_retval reason)
 
        xpc_teardown_partitions();
 
-       if (is_shub())
-               xpc_exit_sn2();
-       else if (is_uv())
+       if (is_uv())
                xpc_exit_uv();
 }
 
@@ -1235,21 +1226,7 @@ xpc_init(void)
        dev_set_name(xpc_part, "part");
        dev_set_name(xpc_chan, "chan");
 
-       if (is_shub()) {
-               /*
-                * The ia64-sn2 architecture supports at most 64 partitions.
-                * And the inability to unregister remote amos restricts us
-                * further to only support exactly 64 partitions on this
-                * architecture, no less.
-                */
-               if (xp_max_npartitions != 64) {
-                       dev_err(xpc_part, "max #of partitions not set to 64\n");
-                       ret = -EINVAL;
-               } else {
-                       ret = xpc_init_sn2();
-               }
-
-       } else if (is_uv()) {
+       if (is_uv()) {
                ret = xpc_init_uv();
 
        } else {
@@ -1335,9 +1312,7 @@ out_2:
 
        xpc_teardown_partitions();
 out_1:
-       if (is_shub())
-               xpc_exit_sn2();
-       else if (is_uv())
+       if (is_uv())
                xpc_exit_uv();
        return ret;
 }
index 782ce95..21a04bc 100644 (file)
@@ -93,10 +93,6 @@ xpc_get_rsvd_page_pa(int nasid)
                if (ret != xpNeedMoreInfo)
                        break;
 
-               /* !!! L1_CACHE_ALIGN() is only a sn2-bte_copy requirement */
-               if (is_shub())
-                       len = L1_CACHE_ALIGN(len);
-
                if (len > buf_len) {
                        kfree(buf_base);
                        buf_len = L1_CACHE_ALIGN(len);
@@ -452,7 +448,6 @@ xpc_discovery(void)
                case 32:
                        max_regions *= 2;
                        region_size = 16;
-                       DBUG_ON(!is_shub2());
                }
        }
 
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
deleted file mode 100644 (file)
index 0ae69b9..0000000
+++ /dev/null
@@ -1,2459 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2008-2009 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-/*
- * Cross Partition Communication (XPC) sn2-based functions.
- *
- *     Architecture specific implementation of common functions.
- *
- */
-
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <asm/uncached.h>
-#include <asm/sn/mspec.h>
-#include <asm/sn/sn_sal.h>
-#include "xpc.h"
-
-/*
- * Define the number of u64s required to represent all the C-brick nasids
- * as a bitmap.  The cross-partition kernel modules deal only with
- * C-brick nasids, thus the need for bitmaps which don't account for
- * odd-numbered (non C-brick) nasids.
- */
-#define XPC_MAX_PHYSNODES_SN2  (MAX_NUMALINK_NODES / 2)
-#define XP_NASID_MASK_BYTES_SN2        ((XPC_MAX_PHYSNODES_SN2 + 7) / 8)
-#define XP_NASID_MASK_WORDS_SN2        ((XPC_MAX_PHYSNODES_SN2 + 63) / 64)
-
-/*
- * Memory for XPC's amo variables is allocated by the MSPEC driver. These
- * pages are located in the lowest granule. The lowest granule uses 4k pages
- * for cached references and an alternate TLB handler to never provide a
- * cacheable mapping for the entire region. This will prevent speculative
- * reading of cached copies of our lines from being issued which will cause
- * a PI FSB Protocol error to be generated by the SHUB. For XPC, we need 64
- * amo variables (based on XP_MAX_NPARTITIONS_SN2) to identify the senders of
- * NOTIFY IRQs, 128 amo variables (based on XP_NASID_MASK_WORDS_SN2) to identify
- * the senders of ACTIVATE IRQs, 1 amo variable to identify which remote
- * partitions (i.e., XPCs) consider themselves currently engaged with the
- * local XPC and 1 amo variable to request partition deactivation.
- */
-#define XPC_NOTIFY_IRQ_AMOS_SN2                0
-#define XPC_ACTIVATE_IRQ_AMOS_SN2      (XPC_NOTIFY_IRQ_AMOS_SN2 + \
-                                        XP_MAX_NPARTITIONS_SN2)
-#define XPC_ENGAGED_PARTITIONS_AMO_SN2 (XPC_ACTIVATE_IRQ_AMOS_SN2 + \
-                                        XP_NASID_MASK_WORDS_SN2)
-#define XPC_DEACTIVATE_REQUEST_AMO_SN2 (XPC_ENGAGED_PARTITIONS_AMO_SN2 + 1)
-
-/*
- * Buffer used to store a local copy of portions of a remote partition's
- * reserved page (either its header and part_nasids mask, or its vars).
- */
-static void *xpc_remote_copy_buffer_base_sn2;
-static char *xpc_remote_copy_buffer_sn2;
-
-static struct xpc_vars_sn2 *xpc_vars_sn2;
-static struct xpc_vars_part_sn2 *xpc_vars_part_sn2;
-
-static int
-xpc_setup_partitions_sn2(void)
-{
-       /* nothing needs to be done */
-       return 0;
-}
-
-static void
-xpc_teardown_partitions_sn2(void)
-{
-       /* nothing needs to be done */
-}
-
-/* SH_IPI_ACCESS shub register value on startup */
-static u64 xpc_sh1_IPI_access_sn2;
-static u64 xpc_sh2_IPI_access0_sn2;
-static u64 xpc_sh2_IPI_access1_sn2;
-static u64 xpc_sh2_IPI_access2_sn2;
-static u64 xpc_sh2_IPI_access3_sn2;
-
-/*
- * Change protections to allow IPI operations.
- */
-static void
-xpc_allow_IPI_ops_sn2(void)
-{
-       int node;
-       int nasid;
-
-       /* !!! The following should get moved into SAL. */
-       if (is_shub2()) {
-               xpc_sh2_IPI_access0_sn2 =
-                   (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS0));
-               xpc_sh2_IPI_access1_sn2 =
-                   (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS1));
-               xpc_sh2_IPI_access2_sn2 =
-                   (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS2));
-               xpc_sh2_IPI_access3_sn2 =
-                   (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH2_IPI_ACCESS3));
-
-               for_each_online_node(node) {
-                       nasid = cnodeid_to_nasid(node);
-                       HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0),
-                             -1UL);
-                       HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1),
-                             -1UL);
-                       HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2),
-                             -1UL);
-                       HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3),
-                             -1UL);
-               }
-       } else {
-               xpc_sh1_IPI_access_sn2 =
-                   (u64)HUB_L((u64 *)LOCAL_MMR_ADDR(SH1_IPI_ACCESS));
-
-               for_each_online_node(node) {
-                       nasid = cnodeid_to_nasid(node);
-                       HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS),
-                             -1UL);
-               }
-       }
-}
-
-/*
- * Restrict protections to disallow IPI operations.
- */
-static void
-xpc_disallow_IPI_ops_sn2(void)
-{
-       int node;
-       int nasid;
-
-       /* !!! The following should get moved into SAL. */
-       if (is_shub2()) {
-               for_each_online_node(node) {
-                       nasid = cnodeid_to_nasid(node);
-                       HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS0),
-                             xpc_sh2_IPI_access0_sn2);
-                       HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS1),
-                             xpc_sh2_IPI_access1_sn2);
-                       HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS2),
-                             xpc_sh2_IPI_access2_sn2);
-                       HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH2_IPI_ACCESS3),
-                             xpc_sh2_IPI_access3_sn2);
-               }
-       } else {
-               for_each_online_node(node) {
-                       nasid = cnodeid_to_nasid(node);
-                       HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid, SH1_IPI_ACCESS),
-                             xpc_sh1_IPI_access_sn2);
-               }
-       }
-}
-
-/*
- * The following set of functions are used for the sending and receiving of
- * IRQs (also known as IPIs). There are two flavors of IRQs, one that is
- * associated with partition activity (SGI_XPC_ACTIVATE) and the other that
- * is associated with channel activity (SGI_XPC_NOTIFY).
- */
-
-static u64
-xpc_receive_IRQ_amo_sn2(struct amo *amo)
-{
-       return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_CLEAR);
-}
-
-static enum xp_retval
-xpc_send_IRQ_sn2(struct amo *amo, u64 flag, int nasid, int phys_cpuid,
-                int vector)
-{
-       int ret = 0;
-       unsigned long irq_flags;
-
-       local_irq_save(irq_flags);
-
-       FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR, flag);
-       sn_send_IPI_phys(nasid, phys_cpuid, vector, 0);
-
-       /*
-        * We must always use the nofault function regardless of whether we
-        * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
-        * didn't, we'd never know that the other partition is down and would
-        * keep sending IRQs and amos to it until the heartbeat times out.
-        */
-       ret = xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->variable),
-                                                    xp_nofault_PIOR_target));
-
-       local_irq_restore(irq_flags);
-
-       return (ret == 0) ? xpSuccess : xpPioReadError;
-}
-
-static struct amo *
-xpc_init_IRQ_amo_sn2(int index)
-{
-       struct amo *amo = xpc_vars_sn2->amos_page + index;
-
-       (void)xpc_receive_IRQ_amo_sn2(amo);     /* clear amo variable */
-       return amo;
-}
-
-/*
- * Functions associated with SGI_XPC_ACTIVATE IRQ.
- */
-
-/*
- * Notify the heartbeat check thread that an activate IRQ has been received.
- */
-static irqreturn_t
-xpc_handle_activate_IRQ_sn2(int irq, void *dev_id)
-{
-       unsigned long irq_flags;
-
-       spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-       xpc_activate_IRQ_rcvd++;
-       spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
-       wake_up_interruptible(&xpc_activate_IRQ_wq);
-       return IRQ_HANDLED;
-}
-
-/*
- * Flag the appropriate amo variable and send an IRQ to the specified node.
- */
-static void
-xpc_send_activate_IRQ_sn2(unsigned long amos_page_pa, int from_nasid,
-                         int to_nasid, int to_phys_cpuid)
-{
-       struct amo *amos = (struct amo *)__va(amos_page_pa +
-                                             (XPC_ACTIVATE_IRQ_AMOS_SN2 *
-                                             sizeof(struct amo)));
-
-       (void)xpc_send_IRQ_sn2(&amos[BIT_WORD(from_nasid / 2)],
-                              BIT_MASK(from_nasid / 2), to_nasid,
-                              to_phys_cpuid, SGI_XPC_ACTIVATE);
-}
-
-static void
-xpc_send_local_activate_IRQ_sn2(int from_nasid)
-{
-       unsigned long irq_flags;
-       struct amo *amos = (struct amo *)__va(xpc_vars_sn2->amos_page_pa +
-                                             (XPC_ACTIVATE_IRQ_AMOS_SN2 *
-                                             sizeof(struct amo)));
-
-       /* fake the sending and receipt of an activate IRQ from remote nasid */
-       FETCHOP_STORE_OP(TO_AMO((u64)&amos[BIT_WORD(from_nasid / 2)].variable),
-                        FETCHOP_OR, BIT_MASK(from_nasid / 2));
-
-       spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-       xpc_activate_IRQ_rcvd++;
-       spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
-       wake_up_interruptible(&xpc_activate_IRQ_wq);
-}
-
-/*
- * Functions associated with SGI_XPC_NOTIFY IRQ.
- */
-
-/*
- * Check to see if any chctl flags were sent from the specified partition.
- */
-static void
-xpc_check_for_sent_chctl_flags_sn2(struct xpc_partition *part)
-{
-       union xpc_channel_ctl_flags chctl;
-       unsigned long irq_flags;
-
-       chctl.all_flags = xpc_receive_IRQ_amo_sn2(part->sn.sn2.
-                                                 local_chctl_amo_va);
-       if (chctl.all_flags == 0)
-               return;
-
-       spin_lock_irqsave(&part->chctl_lock, irq_flags);
-       part->chctl.all_flags |= chctl.all_flags;
-       spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
-
-       dev_dbg(xpc_chan, "received notify IRQ from partid=%d, chctl.all_flags="
-               "0x%llx\n", XPC_PARTID(part), chctl.all_flags);
-
-       xpc_wakeup_channel_mgr(part);
-}
-
-/*
- * Handle the receipt of a SGI_XPC_NOTIFY IRQ by seeing whether the specified
- * partition actually sent it. Since SGI_XPC_NOTIFY IRQs may be shared by more
- * than one partition, we use an amo structure per partition to indicate
- * whether a partition has sent an IRQ or not.  If it has, then wake up the
- * associated kthread to handle it.
- *
- * All SGI_XPC_NOTIFY IRQs received by XPC are the result of IRQs sent by XPC
- * running on other partitions.
- *
- * Noteworthy Arguments:
- *
- *     irq - Interrupt ReQuest number. NOT USED.
- *
- *     dev_id - partid of IRQ's potential sender.
- */
-static irqreturn_t
-xpc_handle_notify_IRQ_sn2(int irq, void *dev_id)
-{
-       short partid = (short)(u64)dev_id;
-       struct xpc_partition *part = &xpc_partitions[partid];
-
-       DBUG_ON(partid < 0 || partid >= XP_MAX_NPARTITIONS_SN2);
-
-       if (xpc_part_ref(part)) {
-               xpc_check_for_sent_chctl_flags_sn2(part);
-
-               xpc_part_deref(part);
-       }
-       return IRQ_HANDLED;
-}
-
-/*
- * Check to see if xpc_handle_notify_IRQ_sn2() dropped any IRQs on the floor
- * because the write to their associated amo variable completed after the IRQ
- * was received.
- */
-static void
-xpc_check_for_dropped_notify_IRQ_sn2(struct timer_list *t)
-{
-       struct xpc_partition *part =
-               from_timer(part, t, sn.sn2.dropped_notify_IRQ_timer);
-
-       if (xpc_part_ref(part)) {
-               xpc_check_for_sent_chctl_flags_sn2(part);
-
-               t->expires = jiffies + XPC_DROPPED_NOTIFY_IRQ_WAIT_INTERVAL;
-               add_timer(t);
-               xpc_part_deref(part);
-       }
-}
-
-/*
- * Send a notify IRQ to the remote partition that is associated with the
- * specified channel.
- */
-static void
-xpc_send_notify_IRQ_sn2(struct xpc_channel *ch, u8 chctl_flag,
-                       char *chctl_flag_string, unsigned long *irq_flags)
-{
-       struct xpc_partition *part = &xpc_partitions[ch->partid];
-       struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
-       union xpc_channel_ctl_flags chctl = { 0 };
-       enum xp_retval ret;
-
-       if (likely(part->act_state != XPC_P_AS_DEACTIVATING)) {
-               chctl.flags[ch->number] = chctl_flag;
-               ret = xpc_send_IRQ_sn2(part_sn2->remote_chctl_amo_va,
-                                      chctl.all_flags,
-                                      part_sn2->notify_IRQ_nasid,
-                                      part_sn2->notify_IRQ_phys_cpuid,
-                                      SGI_XPC_NOTIFY);
-               dev_dbg(xpc_chan, "%s sent to partid=%d, channel=%d, ret=%d\n",
-                       chctl_flag_string, ch->partid, ch->number, ret);
-               if (unlikely(ret != xpSuccess)) {
-                       if (irq_flags != NULL)
-                               spin_unlock_irqrestore(&ch->lock, *irq_flags);
-                       XPC_DEACTIVATE_PARTITION(part, ret);
-                       if (irq_flags != NULL)
-                               spin_lock_irqsave(&ch->lock, *irq_flags);
-               }
-       }
-}
-
-#define XPC_SEND_NOTIFY_IRQ_SN2(_ch, _ipi_f, _irq_f) \
-               xpc_send_notify_IRQ_sn2(_ch, _ipi_f, #_ipi_f, _irq_f)
-
-/*
- * Make it look like the remote partition, which is associated with the
- * specified channel, sent us a notify IRQ. This faked IRQ will be handled
- * by xpc_check_for_dropped_notify_IRQ_sn2().
- */
-static void
-xpc_send_local_notify_IRQ_sn2(struct xpc_channel *ch, u8 chctl_flag,
-                             char *chctl_flag_string)
-{
-       struct xpc_partition *part = &xpc_partitions[ch->partid];
-       union xpc_channel_ctl_flags chctl = { 0 };
-
-       chctl.flags[ch->number] = chctl_flag;
-       FETCHOP_STORE_OP(TO_AMO((u64)&part->sn.sn2.local_chctl_amo_va->
-                               variable), FETCHOP_OR, chctl.all_flags);
-       dev_dbg(xpc_chan, "%s sent local from partid=%d, channel=%d\n",
-               chctl_flag_string, ch->partid, ch->number);
-}
-
-#define XPC_SEND_LOCAL_NOTIFY_IRQ_SN2(_ch, _ipi_f) \
-               xpc_send_local_notify_IRQ_sn2(_ch, _ipi_f, #_ipi_f)
-
-static void
-xpc_send_chctl_closerequest_sn2(struct xpc_channel *ch,
-                               unsigned long *irq_flags)
-{
-       struct xpc_openclose_args *args = ch->sn.sn2.local_openclose_args;
-
-       args->reason = ch->reason;
-       XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_CLOSEREQUEST, irq_flags);
-}
-
-static void
-xpc_send_chctl_closereply_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
-{
-       XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_CLOSEREPLY, irq_flags);
-}
-
-static void
-xpc_send_chctl_openrequest_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
-{
-       struct xpc_openclose_args *args = ch->sn.sn2.local_openclose_args;
-
-       args->entry_size = ch->entry_size;
-       args->local_nentries = ch->local_nentries;
-       XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENREQUEST, irq_flags);
-}
-
-static void
-xpc_send_chctl_openreply_sn2(struct xpc_channel *ch, unsigned long *irq_flags)
-{
-       struct xpc_openclose_args *args = ch->sn.sn2.local_openclose_args;
-
-       args->remote_nentries = ch->remote_nentries;
-       args->local_nentries = ch->local_nentries;
-       args->local_msgqueue_pa = xp_pa(ch->sn.sn2.local_msgqueue);
-       XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENREPLY, irq_flags);
-}
-
-static void
-xpc_send_chctl_opencomplete_sn2(struct xpc_channel *ch,
-                               unsigned long *irq_flags)
-{
-       XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_OPENCOMPLETE, irq_flags);
-}
-
-static void
-xpc_send_chctl_msgrequest_sn2(struct xpc_channel *ch)
-{
-       XPC_SEND_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST, NULL);
-}
-
-static void
-xpc_send_chctl_local_msgrequest_sn2(struct xpc_channel *ch)
-{
-       XPC_SEND_LOCAL_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST);
-}
-
-static enum xp_retval
-xpc_save_remote_msgqueue_pa_sn2(struct xpc_channel *ch,
-                               unsigned long msgqueue_pa)
-{
-       ch->sn.sn2.remote_msgqueue_pa = msgqueue_pa;
-       return xpSuccess;
-}
-
-/*
- * This next set of functions are used to keep track of when a partition is
- * potentially engaged in accessing memory belonging to another partition.
- */
-
-static void
-xpc_indicate_partition_engaged_sn2(struct xpc_partition *part)
-{
-       unsigned long irq_flags;
-       struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa +
-                                            (XPC_ENGAGED_PARTITIONS_AMO_SN2 *
-                                            sizeof(struct amo)));
-
-       local_irq_save(irq_flags);
-
-       /* set bit corresponding to our partid in remote partition's amo */
-       FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
-                        BIT(sn_partition_id));
-
-       /*
-        * We must always use the nofault function regardless of whether we
-        * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
-        * didn't, we'd never know that the other partition is down and would
-        * keep sending IRQs and amos to it until the heartbeat times out.
-        */
-       (void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
-                                                              variable),
-                                                    xp_nofault_PIOR_target));
-
-       local_irq_restore(irq_flags);
-}
-
-static void
-xpc_indicate_partition_disengaged_sn2(struct xpc_partition *part)
-{
-       struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
-       unsigned long irq_flags;
-       struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa +
-                                            (XPC_ENGAGED_PARTITIONS_AMO_SN2 *
-                                            sizeof(struct amo)));
-
-       local_irq_save(irq_flags);
-
-       /* clear bit corresponding to our partid in remote partition's amo */
-       FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
-                        ~BIT(sn_partition_id));
-
-       /*
-        * We must always use the nofault function regardless of whether we
-        * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
-        * didn't, we'd never know that the other partition is down and would
-        * keep sending IRQs and amos to it until the heartbeat times out.
-        */
-       (void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
-                                                              variable),
-                                                    xp_nofault_PIOR_target));
-
-       local_irq_restore(irq_flags);
-
-       /*
-        * Send activate IRQ to get other side to see that we've cleared our
-        * bit in their engaged partitions amo.
-        */
-       xpc_send_activate_IRQ_sn2(part_sn2->remote_amos_page_pa,
-                                 cnodeid_to_nasid(0),
-                                 part_sn2->activate_IRQ_nasid,
-                                 part_sn2->activate_IRQ_phys_cpuid);
-}
-
-static void
-xpc_assume_partition_disengaged_sn2(short partid)
-{
-       struct amo *amo = xpc_vars_sn2->amos_page +
-                         XPC_ENGAGED_PARTITIONS_AMO_SN2;
-
-       /* clear bit(s) based on partid mask in our partition's amo */
-       FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
-                        ~BIT(partid));
-}
-
-static int
-xpc_partition_engaged_sn2(short partid)
-{
-       struct amo *amo = xpc_vars_sn2->amos_page +
-                         XPC_ENGAGED_PARTITIONS_AMO_SN2;
-
-       /* our partition's amo variable ANDed with partid mask */
-       return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
-               BIT(partid)) != 0;
-}
-
-static int
-xpc_any_partition_engaged_sn2(void)
-{
-       struct amo *amo = xpc_vars_sn2->amos_page +
-                         XPC_ENGAGED_PARTITIONS_AMO_SN2;
-
-       /* our partition's amo variable */
-       return FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) != 0;
-}
-
-/* original protection values for each node */
-static u64 xpc_prot_vec_sn2[MAX_NUMNODES];
-
-/*
- * Change protections to allow amo operations on non-Shub 1.1 systems.
- */
-static enum xp_retval
-xpc_allow_amo_ops_sn2(struct amo *amos_page)
-{
-       enum xp_retval ret = xpSuccess;
-
-       /*
-        * On SHUB 1.1, we cannot call sn_change_memprotect() since the BIST
-        * collides with memory operations. On those systems we call
-        * xpc_allow_amo_ops_shub_wars_1_1_sn2() instead.
-        */
-       if (!enable_shub_wars_1_1())
-               ret = xp_expand_memprotect(ia64_tpa((u64)amos_page), PAGE_SIZE);
-
-       return ret;
-}
-
-/*
- * Change protections to allow amo operations on Shub 1.1 systems.
- */
-static void
-xpc_allow_amo_ops_shub_wars_1_1_sn2(void)
-{
-       int node;
-       int nasid;
-
-       if (!enable_shub_wars_1_1())
-               return;
-
-       for_each_online_node(node) {
-               nasid = cnodeid_to_nasid(node);
-               /* save current protection values */
-               xpc_prot_vec_sn2[node] =
-                   (u64)HUB_L((u64 *)GLOBAL_MMR_ADDR(nasid,
-                                                 SH1_MD_DQLP_MMR_DIR_PRIVEC0));
-               /* open up everything */
-               HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid,
-                                            SH1_MD_DQLP_MMR_DIR_PRIVEC0),
-                     -1UL);
-               HUB_S((u64 *)GLOBAL_MMR_ADDR(nasid,
-                                            SH1_MD_DQRP_MMR_DIR_PRIVEC0),
-                     -1UL);
-       }
-}
-
-static enum xp_retval
-xpc_get_partition_rsvd_page_pa_sn2(void *buf, u64 *cookie, unsigned long *rp_pa,
-                                  size_t *len)
-{
-       s64 status;
-       enum xp_retval ret;
-
-       status = sn_partition_reserved_page_pa((u64)buf, cookie,
-                       (u64 *)rp_pa, (u64 *)len);
-       if (status == SALRET_OK)
-               ret = xpSuccess;
-       else if (status == SALRET_MORE_PASSES)
-               ret = xpNeedMoreInfo;
-       else
-               ret = xpSalError;
-
-       return ret;
-}
-
-
-static int
-xpc_setup_rsvd_page_sn2(struct xpc_rsvd_page *rp)
-{
-       struct amo *amos_page;
-       int i;
-       int ret;
-
-       xpc_vars_sn2 = XPC_RP_VARS(rp);
-
-       rp->sn.sn2.vars_pa = xp_pa(xpc_vars_sn2);
-
-       /* vars_part array follows immediately after vars */
-       xpc_vars_part_sn2 = (struct xpc_vars_part_sn2 *)((u8 *)XPC_RP_VARS(rp) +
-                                                        XPC_RP_VARS_SIZE);
-
-       /*
-        * Before clearing xpc_vars_sn2, see if a page of amos had been
-        * previously allocated. If not we'll need to allocate one and set
-        * permissions so that cross-partition amos are allowed.
-        *
-        * The allocated amo page needs MCA reporting to remain disabled after
-        * XPC has unloaded.  To make this work, we keep a copy of the pointer
-        * to this page (i.e., amos_page) in the struct xpc_vars_sn2 structure,
-        * which is pointed to by the reserved page, and re-use that saved copy
-        * on subsequent loads of XPC. This amo page is never freed, and its
-        * memory protections are never restricted.
-        */
-       amos_page = xpc_vars_sn2->amos_page;
-       if (amos_page == NULL) {
-               amos_page = (struct amo *)TO_AMO(uncached_alloc_page(0, 1));
-               if (amos_page == NULL) {
-                       dev_err(xpc_part, "can't allocate page of amos\n");
-                       return -ENOMEM;
-               }
-
-               /*
-                * Open up amo-R/W to cpu.  This is done on Shub 1.1 systems
-                * when xpc_allow_amo_ops_shub_wars_1_1_sn2() is called.
-                */
-               ret = xpc_allow_amo_ops_sn2(amos_page);
-               if (ret != xpSuccess) {
-                       dev_err(xpc_part, "can't allow amo operations\n");
-                       uncached_free_page(__IA64_UNCACHED_OFFSET |
-                                          TO_PHYS((u64)amos_page), 1);
-                       return -EPERM;
-               }
-       }
-
-       /* clear xpc_vars_sn2 */
-       memset(xpc_vars_sn2, 0, sizeof(struct xpc_vars_sn2));
-
-       xpc_vars_sn2->version = XPC_V_VERSION;
-       xpc_vars_sn2->activate_IRQ_nasid = cpuid_to_nasid(0);
-       xpc_vars_sn2->activate_IRQ_phys_cpuid = cpu_physical_id(0);
-       xpc_vars_sn2->vars_part_pa = xp_pa(xpc_vars_part_sn2);
-       xpc_vars_sn2->amos_page_pa = ia64_tpa((u64)amos_page);
-       xpc_vars_sn2->amos_page = amos_page;    /* save for next load of XPC */
-
-       /* clear xpc_vars_part_sn2 */
-       memset((u64 *)xpc_vars_part_sn2, 0, sizeof(struct xpc_vars_part_sn2) *
-              XP_MAX_NPARTITIONS_SN2);
-
-       /* initialize the activate IRQ related amo variables */
-       for (i = 0; i < xpc_nasid_mask_nlongs; i++)
-               (void)xpc_init_IRQ_amo_sn2(XPC_ACTIVATE_IRQ_AMOS_SN2 + i);
-
-       /* initialize the engaged remote partitions related amo variables */
-       (void)xpc_init_IRQ_amo_sn2(XPC_ENGAGED_PARTITIONS_AMO_SN2);
-       (void)xpc_init_IRQ_amo_sn2(XPC_DEACTIVATE_REQUEST_AMO_SN2);
-
-       return 0;
-}
-
-static int
-xpc_hb_allowed_sn2(short partid, void *heartbeating_to_mask)
-{
-       return test_bit(partid, heartbeating_to_mask);
-}
-
-static void
-xpc_allow_hb_sn2(short partid)
-{
-       DBUG_ON(xpc_vars_sn2 == NULL);
-       set_bit(partid, xpc_vars_sn2->heartbeating_to_mask);
-}
-
-static void
-xpc_disallow_hb_sn2(short partid)
-{
-       DBUG_ON(xpc_vars_sn2 == NULL);
-       clear_bit(partid, xpc_vars_sn2->heartbeating_to_mask);
-}
-
-static void
-xpc_disallow_all_hbs_sn2(void)
-{
-       DBUG_ON(xpc_vars_sn2 == NULL);
-       bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, xp_max_npartitions);
-}
-
-static void
-xpc_increment_heartbeat_sn2(void)
-{
-       xpc_vars_sn2->heartbeat++;
-}
-
-static void
-xpc_offline_heartbeat_sn2(void)
-{
-       xpc_increment_heartbeat_sn2();
-       xpc_vars_sn2->heartbeat_offline = 1;
-}
-
-static void
-xpc_online_heartbeat_sn2(void)
-{
-       xpc_increment_heartbeat_sn2();
-       xpc_vars_sn2->heartbeat_offline = 0;
-}
-
-static void
-xpc_heartbeat_init_sn2(void)
-{
-       DBUG_ON(xpc_vars_sn2 == NULL);
-
-       bitmap_zero(xpc_vars_sn2->heartbeating_to_mask, XP_MAX_NPARTITIONS_SN2);
-       xpc_online_heartbeat_sn2();
-}
-
-static void
-xpc_heartbeat_exit_sn2(void)
-{
-       xpc_offline_heartbeat_sn2();
-}
-
-static enum xp_retval
-xpc_get_remote_heartbeat_sn2(struct xpc_partition *part)
-{
-       struct xpc_vars_sn2 *remote_vars;
-       enum xp_retval ret;
-
-       remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer_sn2;
-
-       /* pull the remote vars structure that contains the heartbeat */
-       ret = xp_remote_memcpy(xp_pa(remote_vars),
-                              part->sn.sn2.remote_vars_pa,
-                              XPC_RP_VARS_SIZE);
-       if (ret != xpSuccess)
-               return ret;
-
-       dev_dbg(xpc_part, "partid=%d, heartbeat=%lld, last_heartbeat=%lld, "
-               "heartbeat_offline=%lld, HB_mask[0]=0x%lx\n", XPC_PARTID(part),
-               remote_vars->heartbeat, part->last_heartbeat,
-               remote_vars->heartbeat_offline,
-               remote_vars->heartbeating_to_mask[0]);
-
-       if ((remote_vars->heartbeat == part->last_heartbeat &&
-           !remote_vars->heartbeat_offline) ||
-           !xpc_hb_allowed_sn2(sn_partition_id,
-                               remote_vars->heartbeating_to_mask)) {
-               ret = xpNoHeartbeat;
-       } else {
-               part->last_heartbeat = remote_vars->heartbeat;
-       }
-
-       return ret;
-}
-
-/*
- * Get a copy of the remote partition's XPC variables from the reserved page.
- *
- * remote_vars points to a buffer that is cacheline aligned for BTE copies and
- * assumed to be of size XPC_RP_VARS_SIZE.
- */
-static enum xp_retval
-xpc_get_remote_vars_sn2(unsigned long remote_vars_pa,
-                       struct xpc_vars_sn2 *remote_vars)
-{
-       enum xp_retval ret;
-
-       if (remote_vars_pa == 0)
-               return xpVarsNotSet;
-
-       /* pull over the cross partition variables */
-       ret = xp_remote_memcpy(xp_pa(remote_vars), remote_vars_pa,
-                              XPC_RP_VARS_SIZE);
-       if (ret != xpSuccess)
-               return ret;
-
-       if (XPC_VERSION_MAJOR(remote_vars->version) !=
-           XPC_VERSION_MAJOR(XPC_V_VERSION)) {
-               return xpBadVersion;
-       }
-
-       return xpSuccess;
-}
-
-static void
-xpc_request_partition_activation_sn2(struct xpc_rsvd_page *remote_rp,
-                                    unsigned long remote_rp_pa, int nasid)
-{
-       xpc_send_local_activate_IRQ_sn2(nasid);
-}
-
-static void
-xpc_request_partition_reactivation_sn2(struct xpc_partition *part)
-{
-       xpc_send_local_activate_IRQ_sn2(part->sn.sn2.activate_IRQ_nasid);
-}
-
-static void
-xpc_request_partition_deactivation_sn2(struct xpc_partition *part)
-{
-       struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
-       unsigned long irq_flags;
-       struct amo *amo = (struct amo *)__va(part_sn2->remote_amos_page_pa +
-                                            (XPC_DEACTIVATE_REQUEST_AMO_SN2 *
-                                            sizeof(struct amo)));
-
-       local_irq_save(irq_flags);
-
-       /* set bit corresponding to our partid in remote partition's amo */
-       FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_OR,
-                        BIT(sn_partition_id));
-
-       /*
-        * We must always use the nofault function regardless of whether we
-        * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
-        * didn't, we'd never know that the other partition is down and would
-        * keep sending IRQs and amos to it until the heartbeat times out.
-        */
-       (void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
-                                                              variable),
-                                                    xp_nofault_PIOR_target));
-
-       local_irq_restore(irq_flags);
-
-       /*
-        * Send activate IRQ to get other side to see that we've set our
-        * bit in their deactivate request amo.
-        */
-       xpc_send_activate_IRQ_sn2(part_sn2->remote_amos_page_pa,
-                                 cnodeid_to_nasid(0),
-                                 part_sn2->activate_IRQ_nasid,
-                                 part_sn2->activate_IRQ_phys_cpuid);
-}
-
-static void
-xpc_cancel_partition_deactivation_request_sn2(struct xpc_partition *part)
-{
-       unsigned long irq_flags;
-       struct amo *amo = (struct amo *)__va(part->sn.sn2.remote_amos_page_pa +
-                                            (XPC_DEACTIVATE_REQUEST_AMO_SN2 *
-                                            sizeof(struct amo)));
-
-       local_irq_save(irq_flags);
-
-       /* clear bit corresponding to our partid in remote partition's amo */
-       FETCHOP_STORE_OP(TO_AMO((u64)&amo->variable), FETCHOP_AND,
-                        ~BIT(sn_partition_id));
-
-       /*
-        * We must always use the nofault function regardless of whether we
-        * are on a Shub 1.1 system or a Shub 1.2 slice 0xc processor. If we
-        * didn't, we'd never know that the other partition is down and would
-        * keep sending IRQs and amos to it until the heartbeat times out.
-        */
-       (void)xp_nofault_PIOR((u64 *)GLOBAL_MMR_ADDR(NASID_GET(&amo->
-                                                              variable),
-                                                    xp_nofault_PIOR_target));
-
-       local_irq_restore(irq_flags);
-}
-
-static int
-xpc_partition_deactivation_requested_sn2(short partid)
-{
-       struct amo *amo = xpc_vars_sn2->amos_page +
-                         XPC_DEACTIVATE_REQUEST_AMO_SN2;
-
-       /* our partition's amo variable ANDed with partid mask */
-       return (FETCHOP_LOAD_OP(TO_AMO((u64)&amo->variable), FETCHOP_LOAD) &
-               BIT(partid)) != 0;
-}
-
-/*
- * Update the remote partition's info.
- */
-static void
-xpc_update_partition_info_sn2(struct xpc_partition *part, u8 remote_rp_version,
-                             unsigned long *remote_rp_ts_jiffies,
-                             unsigned long remote_rp_pa,
-                             unsigned long remote_vars_pa,
-                             struct xpc_vars_sn2 *remote_vars)
-{
-       struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
-
-       part->remote_rp_version = remote_rp_version;
-       dev_dbg(xpc_part, "  remote_rp_version = 0x%016x\n",
-               part->remote_rp_version);
-
-       part->remote_rp_ts_jiffies = *remote_rp_ts_jiffies;
-       dev_dbg(xpc_part, "  remote_rp_ts_jiffies = 0x%016lx\n",
-               part->remote_rp_ts_jiffies);
-
-       part->remote_rp_pa = remote_rp_pa;
-       dev_dbg(xpc_part, "  remote_rp_pa = 0x%016lx\n", part->remote_rp_pa);
-
-       part_sn2->remote_vars_pa = remote_vars_pa;
-       dev_dbg(xpc_part, "  remote_vars_pa = 0x%016lx\n",
-               part_sn2->remote_vars_pa);
-
-       part->last_heartbeat = remote_vars->heartbeat - 1;
-       dev_dbg(xpc_part, "  last_heartbeat = 0x%016llx\n",
-               part->last_heartbeat);
-
-       part_sn2->remote_vars_part_pa = remote_vars->vars_part_pa;
-       dev_dbg(xpc_part, "  remote_vars_part_pa = 0x%016lx\n",
-               part_sn2->remote_vars_part_pa);
-
-       part_sn2->activate_IRQ_nasid = remote_vars->activate_IRQ_nasid;
-       dev_dbg(xpc_part, "  activate_IRQ_nasid = 0x%x\n",
-               part_sn2->activate_IRQ_nasid);
-
-       part_sn2->activate_IRQ_phys_cpuid =
-           remote_vars->activate_IRQ_phys_cpuid;
-       dev_dbg(xpc_part, "  activate_IRQ_phys_cpuid = 0x%x\n",
-               part_sn2->activate_IRQ_phys_cpuid);
-
-       part_sn2->remote_amos_page_pa = remote_vars->amos_page_pa;
-       dev_dbg(xpc_part, "  remote_amos_page_pa = 0x%lx\n",
-               part_sn2->remote_amos_page_pa);
-
-       part_sn2->remote_vars_version = remote_vars->version;
-       dev_dbg(xpc_part, "  remote_vars_version = 0x%x\n",
-               part_sn2->remote_vars_version);
-}
-
-/*
- * Prior code has determined the nasid which generated a activate IRQ.
- * Inspect that nasid to determine if its partition needs to be activated
- * or deactivated.
- *
- * A partition is considered "awaiting activation" if our partition
- * flags indicate it is not active and it has a heartbeat.  A
- * partition is considered "awaiting deactivation" if our partition
- * flags indicate it is active but it has no heartbeat or it is not
- * sending its heartbeat to us.
- *
- * To determine the heartbeat, the remote nasid must have a properly
- * initialized reserved page.
- */
-static void
-xpc_identify_activate_IRQ_req_sn2(int nasid)
-{
-       struct xpc_rsvd_page *remote_rp;
-       struct xpc_vars_sn2 *remote_vars;
-       unsigned long remote_rp_pa;
-       unsigned long remote_vars_pa;
-       int remote_rp_version;
-       int reactivate = 0;
-       unsigned long remote_rp_ts_jiffies = 0;
-       short partid;
-       struct xpc_partition *part;
-       struct xpc_partition_sn2 *part_sn2;
-       enum xp_retval ret;
-
-       /* pull over the reserved page structure */
-
-       remote_rp = (struct xpc_rsvd_page *)xpc_remote_copy_buffer_sn2;
-
-       ret = xpc_get_remote_rp(nasid, NULL, remote_rp, &remote_rp_pa);
-       if (ret != xpSuccess) {
-               dev_warn(xpc_part, "unable to get reserved page from nasid %d, "
-                        "which sent interrupt, reason=%d\n", nasid, ret);
-               return;
-       }
-
-       remote_vars_pa = remote_rp->sn.sn2.vars_pa;
-       remote_rp_version = remote_rp->version;
-       remote_rp_ts_jiffies = remote_rp->ts_jiffies;
-
-       partid = remote_rp->SAL_partid;
-       part = &xpc_partitions[partid];
-       part_sn2 = &part->sn.sn2;
-
-       /* pull over the cross partition variables */
-
-       remote_vars = (struct xpc_vars_sn2 *)xpc_remote_copy_buffer_sn2;
-
-       ret = xpc_get_remote_vars_sn2(remote_vars_pa, remote_vars);
-       if (ret != xpSuccess) {
-               dev_warn(xpc_part, "unable to get XPC variables from nasid %d, "
-                        "which sent interrupt, reason=%d\n", nasid, ret);
-
-               XPC_DEACTIVATE_PARTITION(part, ret);
-               return;
-       }
-
-       part->activate_IRQ_rcvd++;
-
-       dev_dbg(xpc_part, "partid for nasid %d is %d; IRQs = %d; HB = "
-               "%lld:0x%lx\n", (int)nasid, (int)partid,
-               part->activate_IRQ_rcvd,
-               remote_vars->heartbeat, remote_vars->heartbeating_to_mask[0]);
-
-       if (xpc_partition_disengaged(part) &&
-           part->act_state == XPC_P_AS_INACTIVE) {
-
-               xpc_update_partition_info_sn2(part, remote_rp_version,
-                                             &remote_rp_ts_jiffies,
-                                             remote_rp_pa, remote_vars_pa,
-                                             remote_vars);
-
-               if (xpc_partition_deactivation_requested_sn2(partid)) {
-                       /*
-                        * Other side is waiting on us to deactivate even though
-                        * we already have.
-                        */
-                       return;
-               }
-
-               xpc_activate_partition(part);
-               return;
-       }
-
-       DBUG_ON(part->remote_rp_version == 0);
-       DBUG_ON(part_sn2->remote_vars_version == 0);
-
-       if (remote_rp_ts_jiffies != part->remote_rp_ts_jiffies) {
-
-               /* the other side rebooted */
-
-               DBUG_ON(xpc_partition_engaged_sn2(partid));
-               DBUG_ON(xpc_partition_deactivation_requested_sn2(partid));
-
-               xpc_update_partition_info_sn2(part, remote_rp_version,
-                                             &remote_rp_ts_jiffies,
-                                             remote_rp_pa, remote_vars_pa,
-                                             remote_vars);
-               reactivate = 1;
-       }
-
-       if (part->disengage_timeout > 0 && !xpc_partition_disengaged(part)) {
-               /* still waiting on other side to disengage from us */
-               return;
-       }
-
-       if (reactivate)
-               XPC_DEACTIVATE_PARTITION(part, xpReactivating);
-       else if (xpc_partition_deactivation_requested_sn2(partid))
-               XPC_DEACTIVATE_PARTITION(part, xpOtherGoingDown);
-}
-
-/*
- * Loop through the activation amo variables and process any bits
- * which are set.  Each bit indicates a nasid sending a partition
- * activation or deactivation request.
- *
- * Return #of IRQs detected.
- */
-int
-xpc_identify_activate_IRQ_sender_sn2(void)
-{
-       int l;
-       int b;
-       unsigned long nasid_mask_long;
-       u64 nasid;              /* remote nasid */
-       int n_IRQs_detected = 0;
-       struct amo *act_amos;
-
-       act_amos = xpc_vars_sn2->amos_page + XPC_ACTIVATE_IRQ_AMOS_SN2;
-
-       /* scan through activate amo variables looking for non-zero entries */
-       for (l = 0; l < xpc_nasid_mask_nlongs; l++) {
-
-               if (xpc_exiting)
-                       break;
-
-               nasid_mask_long = xpc_receive_IRQ_amo_sn2(&act_amos[l]);
-
-               b = find_first_bit(&nasid_mask_long, BITS_PER_LONG);
-               if (b >= BITS_PER_LONG) {
-                       /* no IRQs from nasids in this amo variable */
-                       continue;
-               }
-
-               dev_dbg(xpc_part, "amo[%d] gave back 0x%lx\n", l,
-                       nasid_mask_long);
-
-               /*
-                * If this nasid has been added to the machine since
-                * our partition was reset, this will retain the
-                * remote nasid in our reserved pages machine mask.
-                * This is used in the event of module reload.
-                */
-               xpc_mach_nasids[l] |= nasid_mask_long;
-
-               /* locate the nasid(s) which sent interrupts */
-
-               do {
-                       n_IRQs_detected++;
-                       nasid = (l * BITS_PER_LONG + b) * 2;
-                       dev_dbg(xpc_part, "interrupt from nasid %lld\n", nasid);
-                       xpc_identify_activate_IRQ_req_sn2(nasid);
-
-                       b = find_next_bit(&nasid_mask_long, BITS_PER_LONG,
-                                         b + 1);
-               } while (b < BITS_PER_LONG);
-       }
-       return n_IRQs_detected;
-}
-
-static void
-xpc_process_activate_IRQ_rcvd_sn2(void)
-{
-       unsigned long irq_flags;
-       int n_IRQs_expected;
-       int n_IRQs_detected;
-
-       spin_lock_irqsave(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-       n_IRQs_expected = xpc_activate_IRQ_rcvd;
-       xpc_activate_IRQ_rcvd = 0;
-       spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
-
-       n_IRQs_detected = xpc_identify_activate_IRQ_sender_sn2();
-       if (n_IRQs_detected < n_IRQs_expected) {
-               /* retry once to help avoid missing amo */
-               (void)xpc_identify_activate_IRQ_sender_sn2();
-       }
-}
-
-/*
- * Setup the channel structures that are sn2 specific.
- */
-static enum xp_retval
-xpc_setup_ch_structures_sn2(struct xpc_partition *part)
-{
-       struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
-       struct xpc_channel_sn2 *ch_sn2;
-       enum xp_retval retval;
-       int ret;
-       int cpuid;
-       int ch_number;
-       struct timer_list *timer;
-       short partid = XPC_PARTID(part);
-
-       /* allocate all the required GET/PUT values */
-
-       part_sn2->local_GPs =
-           xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE, GFP_KERNEL,
-                                         &part_sn2->local_GPs_base);
-       if (part_sn2->local_GPs == NULL) {
-               dev_err(xpc_chan, "can't get memory for local get/put "
-                       "values\n");
-               return xpNoMemory;
-       }
-
-       part_sn2->remote_GPs =
-           xpc_kzalloc_cacheline_aligned(XPC_GP_SIZE, GFP_KERNEL,
-                                         &part_sn2->remote_GPs_base);
-       if (part_sn2->remote_GPs == NULL) {
-               dev_err(xpc_chan, "can't get memory for remote get/put "
-                       "values\n");
-               retval = xpNoMemory;
-               goto out_1;
-       }
-
-       part_sn2->remote_GPs_pa = 0;
-
-       /* allocate all the required open and close args */
-
-       part_sn2->local_openclose_args =
-           xpc_kzalloc_cacheline_aligned(XPC_OPENCLOSE_ARGS_SIZE,
-                                         GFP_KERNEL, &part_sn2->
-                                         local_openclose_args_base);
-       if (part_sn2->local_openclose_args == NULL) {
-               dev_err(xpc_chan, "can't get memory for local connect args\n");
-               retval = xpNoMemory;
-               goto out_2;
-       }
-
-       part_sn2->remote_openclose_args_pa = 0;
-
-       part_sn2->local_chctl_amo_va = xpc_init_IRQ_amo_sn2(partid);
-
-       part_sn2->notify_IRQ_nasid = 0;
-       part_sn2->notify_IRQ_phys_cpuid = 0;
-       part_sn2->remote_chctl_amo_va = NULL;
-
-       sprintf(part_sn2->notify_IRQ_owner, "xpc%02d", partid);
-       ret = request_irq(SGI_XPC_NOTIFY, xpc_handle_notify_IRQ_sn2,
-                         IRQF_SHARED, part_sn2->notify_IRQ_owner,
-                         (void *)(u64)partid);
-       if (ret != 0) {
-               dev_err(xpc_chan, "can't register NOTIFY IRQ handler, "
-                       "errno=%d\n", -ret);
-               retval = xpLackOfResources;
-               goto out_3;
-       }
-
-       /* Setup a timer to check for dropped notify IRQs */
-       timer = &part_sn2->dropped_notify_IRQ_timer;
-       timer_setup(timer, xpc_check_for_dropped_notify_IRQ_sn2, 0);
-       timer->expires = jiffies + XPC_DROPPED_NOTIFY_IRQ_WAIT_INTERVAL;
-       add_timer(timer);
-
-       for (ch_number = 0; ch_number < part->nchannels; ch_number++) {
-               ch_sn2 = &part->channels[ch_number].sn.sn2;
-
-               ch_sn2->local_GP = &part_sn2->local_GPs[ch_number];
-               ch_sn2->local_openclose_args =
-                   &part_sn2->local_openclose_args[ch_number];
-
-               mutex_init(&ch_sn2->msg_to_pull_mutex);
-       }
-
-       /*
-        * Setup the per partition specific variables required by the
-        * remote partition to establish channel connections with us.
-        *
-        * The setting of the magic # indicates that these per partition
-        * specific variables are ready to be used.
-        */
-       xpc_vars_part_sn2[partid].GPs_pa = xp_pa(part_sn2->local_GPs);
-       xpc_vars_part_sn2[partid].openclose_args_pa =
-           xp_pa(part_sn2->local_openclose_args);
-       xpc_vars_part_sn2[partid].chctl_amo_pa =
-           xp_pa(part_sn2->local_chctl_amo_va);
-       cpuid = raw_smp_processor_id(); /* any CPU in this partition will do */
-       xpc_vars_part_sn2[partid].notify_IRQ_nasid = cpuid_to_nasid(cpuid);
-       xpc_vars_part_sn2[partid].notify_IRQ_phys_cpuid =
-           cpu_physical_id(cpuid);
-       xpc_vars_part_sn2[partid].nchannels = part->nchannels;
-       xpc_vars_part_sn2[partid].magic = XPC_VP_MAGIC1_SN2;
-
-       return xpSuccess;
-
-       /* setup of ch structures failed */
-out_3:
-       kfree(part_sn2->local_openclose_args_base);
-       part_sn2->local_openclose_args = NULL;
-out_2:
-       kfree(part_sn2->remote_GPs_base);
-       part_sn2->remote_GPs = NULL;
-out_1:
-       kfree(part_sn2->local_GPs_base);
-       part_sn2->local_GPs = NULL;
-       return retval;
-}
-
-/*
- * Teardown the channel structures that are sn2 specific.
- */
-static void
-xpc_teardown_ch_structures_sn2(struct xpc_partition *part)
-{
-       struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
-       short partid = XPC_PARTID(part);
-
-       /*
-        * Indicate that the variables specific to the remote partition are no
-        * longer available for its use.
-        */
-       xpc_vars_part_sn2[partid].magic = 0;
-
-       /* in case we've still got outstanding timers registered... */
-       del_timer_sync(&part_sn2->dropped_notify_IRQ_timer);
-       free_irq(SGI_XPC_NOTIFY, (void *)(u64)partid);
-
-       kfree(part_sn2->local_openclose_args_base);
-       part_sn2->local_openclose_args = NULL;
-       kfree(part_sn2->remote_GPs_base);
-       part_sn2->remote_GPs = NULL;
-       kfree(part_sn2->local_GPs_base);
-       part_sn2->local_GPs = NULL;
-       part_sn2->local_chctl_amo_va = NULL;
-}
-
-/*
- * Create a wrapper that hides the underlying mechanism for pulling a cacheline
- * (or multiple cachelines) from a remote partition.
- *
- * src_pa must be a cacheline aligned physical address on the remote partition.
- * dst must be a cacheline aligned virtual address on this partition.
- * cnt must be cacheline sized
- */
-/* ??? Replace this function by call to xp_remote_memcpy() or bte_copy()? */
-static enum xp_retval
-xpc_pull_remote_cachelines_sn2(struct xpc_partition *part, void *dst,
-                              const unsigned long src_pa, size_t cnt)
-{
-       enum xp_retval ret;
-
-       DBUG_ON(src_pa != L1_CACHE_ALIGN(src_pa));
-       DBUG_ON((unsigned long)dst != L1_CACHE_ALIGN((unsigned long)dst));
-       DBUG_ON(cnt != L1_CACHE_ALIGN(cnt));
-
-       if (part->act_state == XPC_P_AS_DEACTIVATING)
-               return part->reason;
-
-       ret = xp_remote_memcpy(xp_pa(dst), src_pa, cnt);
-       if (ret != xpSuccess) {
-               dev_dbg(xpc_chan, "xp_remote_memcpy() from partition %d failed,"
-                       " ret=%d\n", XPC_PARTID(part), ret);
-       }
-       return ret;
-}
-
-/*
- * Pull the remote per partition specific variables from the specified
- * partition.
- */
-static enum xp_retval
-xpc_pull_remote_vars_part_sn2(struct xpc_partition *part)
-{
-       struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
-       u8 buffer[L1_CACHE_BYTES * 2];
-       struct xpc_vars_part_sn2 *pulled_entry_cacheline =
-           (struct xpc_vars_part_sn2 *)L1_CACHE_ALIGN((u64)buffer);
-       struct xpc_vars_part_sn2 *pulled_entry;
-       unsigned long remote_entry_cacheline_pa;
-       unsigned long remote_entry_pa;
-       short partid = XPC_PARTID(part);
-       enum xp_retval ret;
-
-       /* pull the cacheline that contains the variables we're interested in */
-
-       DBUG_ON(part_sn2->remote_vars_part_pa !=
-               L1_CACHE_ALIGN(part_sn2->remote_vars_part_pa));
-       DBUG_ON(sizeof(struct xpc_vars_part_sn2) != L1_CACHE_BYTES / 2);
-
-       remote_entry_pa = part_sn2->remote_vars_part_pa +
-           sn_partition_id * sizeof(struct xpc_vars_part_sn2);
-
-       remote_entry_cacheline_pa = (remote_entry_pa & ~(L1_CACHE_BYTES - 1));
-
-       pulled_entry = (struct xpc_vars_part_sn2 *)((u64)pulled_entry_cacheline
-                                                   + (remote_entry_pa &
-                                                   (L1_CACHE_BYTES - 1)));
-
-       ret = xpc_pull_remote_cachelines_sn2(part, pulled_entry_cacheline,
-                                            remote_entry_cacheline_pa,
-                                            L1_CACHE_BYTES);
-       if (ret != xpSuccess) {
-               dev_dbg(xpc_chan, "failed to pull XPC vars_part from "
-                       "partition %d, ret=%d\n", partid, ret);
-               return ret;
-       }
-
-       /* see if they've been set up yet */
-
-       if (pulled_entry->magic != XPC_VP_MAGIC1_SN2 &&
-           pulled_entry->magic != XPC_VP_MAGIC2_SN2) {
-
-               if (pulled_entry->magic != 0) {
-                       dev_dbg(xpc_chan, "partition %d's XPC vars_part for "
-                               "partition %d has bad magic value (=0x%llx)\n",
-                               partid, sn_partition_id, pulled_entry->magic);
-                       return xpBadMagic;
-               }
-
-               /* they've not been initialized yet */
-               return xpRetry;
-       }
-
-       if (xpc_vars_part_sn2[partid].magic == XPC_VP_MAGIC1_SN2) {
-
-               /* validate the variables */
-
-               if (pulled_entry->GPs_pa == 0 ||
-                   pulled_entry->openclose_args_pa == 0 ||
-                   pulled_entry->chctl_amo_pa == 0) {
-
-                       dev_err(xpc_chan, "partition %d's XPC vars_part for "
-                               "partition %d are not valid\n", partid,
-                               sn_partition_id);
-                       return xpInvalidAddress;
-               }
-
-               /* the variables we imported look to be valid */
-
-               part_sn2->remote_GPs_pa = pulled_entry->GPs_pa;
-               part_sn2->remote_openclose_args_pa =
-                   pulled_entry->openclose_args_pa;
-               part_sn2->remote_chctl_amo_va =
-                   (struct amo *)__va(pulled_entry->chctl_amo_pa);
-               part_sn2->notify_IRQ_nasid = pulled_entry->notify_IRQ_nasid;
-               part_sn2->notify_IRQ_phys_cpuid =
-                   pulled_entry->notify_IRQ_phys_cpuid;
-
-               if (part->nchannels > pulled_entry->nchannels)
-                       part->nchannels = pulled_entry->nchannels;
-
-               /* let the other side know that we've pulled their variables */
-
-               xpc_vars_part_sn2[partid].magic = XPC_VP_MAGIC2_SN2;
-       }
-
-       if (pulled_entry->magic == XPC_VP_MAGIC1_SN2)
-               return xpRetry;
-
-       return xpSuccess;
-}
-
-/*
- * Establish first contact with the remote partititon. This involves pulling
- * the XPC per partition variables from the remote partition and waiting for
- * the remote partition to pull ours.
- */
-static enum xp_retval
-xpc_make_first_contact_sn2(struct xpc_partition *part)
-{
-       struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
-       enum xp_retval ret;
-
-       /*
-        * Register the remote partition's amos with SAL so it can handle
-        * and cleanup errors within that address range should the remote
-        * partition go down. We don't unregister this range because it is
-        * difficult to tell when outstanding writes to the remote partition
-        * are finished and thus when it is safe to unregister. This should
-        * not result in wasted space in the SAL xp_addr_region table because
-        * we should get the same page for remote_amos_page_pa after module
-        * reloads and system reboots.
-        */
-       if (sn_register_xp_addr_region(part_sn2->remote_amos_page_pa,
-                                      PAGE_SIZE, 1) < 0) {
-               dev_warn(xpc_part, "xpc_activating(%d) failed to register "
-                        "xp_addr region\n", XPC_PARTID(part));
-
-               ret = xpPhysAddrRegFailed;
-               XPC_DEACTIVATE_PARTITION(part, ret);
-               return ret;
-       }
-
-       /*
-        * Send activate IRQ to get other side to activate if they've not
-        * already begun to do so.
-        */
-       xpc_send_activate_IRQ_sn2(part_sn2->remote_amos_page_pa,
-                                 cnodeid_to_nasid(0),
-                                 part_sn2->activate_IRQ_nasid,
-                                 part_sn2->activate_IRQ_phys_cpuid);
-
-       while ((ret = xpc_pull_remote_vars_part_sn2(part)) != xpSuccess) {
-               if (ret != xpRetry) {
-                       XPC_DEACTIVATE_PARTITION(part, ret);
-                       return ret;
-               }
-
-               dev_dbg(xpc_part, "waiting to make first contact with "
-                       "partition %d\n", XPC_PARTID(part));
-
-               /* wait a 1/4 of a second or so */
-               (void)msleep_interruptible(250);
-
-               if (part->act_state == XPC_P_AS_DEACTIVATING)
-                       return part->reason;
-       }
-
-       return xpSuccess;
-}
-
-/*
- * Get the chctl flags and pull the openclose args and/or remote GPs as needed.
- */
-static u64
-xpc_get_chctl_all_flags_sn2(struct xpc_partition *part)
-{
-       struct xpc_partition_sn2 *part_sn2 = &part->sn.sn2;
-       unsigned long irq_flags;
-       union xpc_channel_ctl_flags chctl;
-       enum xp_retval ret;
-
-       /*
-        * See if there are any chctl flags to be handled.
-        */
-
-       spin_lock_irqsave(&part->chctl_lock, irq_flags);
-       chctl = part->chctl;
-       if (chctl.all_flags != 0)
-               part->chctl.all_flags = 0;
-
-       spin_unlock_irqrestore(&part->chctl_lock, irq_flags);
-
-       if (xpc_any_openclose_chctl_flags_set(&chctl)) {
-               ret = xpc_pull_remote_cachelines_sn2(part, part->
-                                                    remote_openclose_args,
-                                                    part_sn2->
-                                                    remote_openclose_args_pa,
-                                                    XPC_OPENCLOSE_ARGS_SIZE);
-               if (ret != xpSuccess) {
-                       XPC_DEACTIVATE_PARTITION(part, ret);
-
-                       dev_dbg(xpc_chan, "failed to pull openclose args from "
-                               "partition %d, ret=%d\n", XPC_PARTID(part),
-                               ret);
-
-                       /* don't bother processing chctl flags anymore */
-                       chctl.all_flags = 0;
-               }
-       }
-
-       if (xpc_any_msg_chctl_flags_set(&chctl)) {
-               ret = xpc_pull_remote_cachelines_sn2(part, part_sn2->remote_GPs,
-                                                    part_sn2->remote_GPs_pa,
-                                                    XPC_GP_SIZE);
-               if (ret != xpSuccess) {
-                       XPC_DEACTIVATE_PARTITION(part, ret);
-
-                       dev_dbg(xpc_chan, "failed to pull GPs from partition "
-                               "%d, ret=%d\n", XPC_PARTID(part), ret);
-
-                       /* don't bother processing chctl flags anymore */
-                       chctl.all_flags = 0;
-               }
-       }
-
-       return chctl.all_flags;
-}
-
-/*
- * Allocate the local message queue and the notify queue.
- */
-static enum xp_retval
-xpc_allocate_local_msgqueue_sn2(struct xpc_channel *ch)
-{
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-       unsigned long irq_flags;
-       int nentries;
-       size_t nbytes;
-
-       for (nentries = ch->local_nentries; nentries > 0; nentries--) {
-
-               nbytes = nentries * ch->entry_size;
-               ch_sn2->local_msgqueue =
-                   xpc_kzalloc_cacheline_aligned(nbytes, GFP_KERNEL,
-                                                 &ch_sn2->local_msgqueue_base);
-               if (ch_sn2->local_msgqueue == NULL)
-                       continue;
-
-               nbytes = nentries * sizeof(struct xpc_notify_sn2);
-               ch_sn2->notify_queue = kzalloc(nbytes, GFP_KERNEL);
-               if (ch_sn2->notify_queue == NULL) {
-                       kfree(ch_sn2->local_msgqueue_base);
-                       ch_sn2->local_msgqueue = NULL;
-                       continue;
-               }
-
-               spin_lock_irqsave(&ch->lock, irq_flags);
-               if (nentries < ch->local_nentries) {
-                       dev_dbg(xpc_chan, "nentries=%d local_nentries=%d, "
-                               "partid=%d, channel=%d\n", nentries,
-                               ch->local_nentries, ch->partid, ch->number);
-
-                       ch->local_nentries = nentries;
-               }
-               spin_unlock_irqrestore(&ch->lock, irq_flags);
-               return xpSuccess;
-       }
-
-       dev_dbg(xpc_chan, "can't get memory for local message queue and notify "
-               "queue, partid=%d, channel=%d\n", ch->partid, ch->number);
-       return xpNoMemory;
-}
-
-/*
- * Allocate the cached remote message queue.
- */
-static enum xp_retval
-xpc_allocate_remote_msgqueue_sn2(struct xpc_channel *ch)
-{
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-       unsigned long irq_flags;
-       int nentries;
-       size_t nbytes;
-
-       DBUG_ON(ch->remote_nentries <= 0);
-
-       for (nentries = ch->remote_nentries; nentries > 0; nentries--) {
-
-               nbytes = nentries * ch->entry_size;
-               ch_sn2->remote_msgqueue =
-                   xpc_kzalloc_cacheline_aligned(nbytes, GFP_KERNEL, &ch_sn2->
-                                                 remote_msgqueue_base);
-               if (ch_sn2->remote_msgqueue == NULL)
-                       continue;
-
-               spin_lock_irqsave(&ch->lock, irq_flags);
-               if (nentries < ch->remote_nentries) {
-                       dev_dbg(xpc_chan, "nentries=%d remote_nentries=%d, "
-                               "partid=%d, channel=%d\n", nentries,
-                               ch->remote_nentries, ch->partid, ch->number);
-
-                       ch->remote_nentries = nentries;
-               }
-               spin_unlock_irqrestore(&ch->lock, irq_flags);
-               return xpSuccess;
-       }
-
-       dev_dbg(xpc_chan, "can't get memory for cached remote message queue, "
-               "partid=%d, channel=%d\n", ch->partid, ch->number);
-       return xpNoMemory;
-}
-
-/*
- * Allocate message queues and other stuff associated with a channel.
- *
- * Note: Assumes all of the channel sizes are filled in.
- */
-static enum xp_retval
-xpc_setup_msg_structures_sn2(struct xpc_channel *ch)
-{
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-       enum xp_retval ret;
-
-       DBUG_ON(ch->flags & XPC_C_SETUP);
-
-       ret = xpc_allocate_local_msgqueue_sn2(ch);
-       if (ret == xpSuccess) {
-
-               ret = xpc_allocate_remote_msgqueue_sn2(ch);
-               if (ret != xpSuccess) {
-                       kfree(ch_sn2->local_msgqueue_base);
-                       ch_sn2->local_msgqueue = NULL;
-                       kfree(ch_sn2->notify_queue);
-                       ch_sn2->notify_queue = NULL;
-               }
-       }
-       return ret;
-}
-
-/*
- * Free up message queues and other stuff that were allocated for the specified
- * channel.
- */
-static void
-xpc_teardown_msg_structures_sn2(struct xpc_channel *ch)
-{
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-
-       lockdep_assert_held(&ch->lock);
-
-       ch_sn2->remote_msgqueue_pa = 0;
-
-       ch_sn2->local_GP->get = 0;
-       ch_sn2->local_GP->put = 0;
-       ch_sn2->remote_GP.get = 0;
-       ch_sn2->remote_GP.put = 0;
-       ch_sn2->w_local_GP.get = 0;
-       ch_sn2->w_local_GP.put = 0;
-       ch_sn2->w_remote_GP.get = 0;
-       ch_sn2->w_remote_GP.put = 0;
-       ch_sn2->next_msg_to_pull = 0;
-
-       if (ch->flags & XPC_C_SETUP) {
-               dev_dbg(xpc_chan, "ch->flags=0x%x, partid=%d, channel=%d\n",
-                       ch->flags, ch->partid, ch->number);
-
-               kfree(ch_sn2->local_msgqueue_base);
-               ch_sn2->local_msgqueue = NULL;
-               kfree(ch_sn2->remote_msgqueue_base);
-               ch_sn2->remote_msgqueue = NULL;
-               kfree(ch_sn2->notify_queue);
-               ch_sn2->notify_queue = NULL;
-       }
-}
-
-/*
- * Notify those who wanted to be notified upon delivery of their message.
- */
-static void
-xpc_notify_senders_sn2(struct xpc_channel *ch, enum xp_retval reason, s64 put)
-{
-       struct xpc_notify_sn2 *notify;
-       u8 notify_type;
-       s64 get = ch->sn.sn2.w_remote_GP.get - 1;
-
-       while (++get < put && atomic_read(&ch->n_to_notify) > 0) {
-
-               notify = &ch->sn.sn2.notify_queue[get % ch->local_nentries];
-
-               /*
-                * See if the notify entry indicates it was associated with
-                * a message who's sender wants to be notified. It is possible
-                * that it is, but someone else is doing or has done the
-                * notification.
-                */
-               notify_type = notify->type;
-               if (notify_type == 0 ||
-                   cmpxchg(&notify->type, notify_type, 0) != notify_type) {
-                       continue;
-               }
-
-               DBUG_ON(notify_type != XPC_N_CALL);
-
-               atomic_dec(&ch->n_to_notify);
-
-               if (notify->func != NULL) {
-                       dev_dbg(xpc_chan, "notify->func() called, notify=0x%p "
-                               "msg_number=%lld partid=%d channel=%d\n",
-                               (void *)notify, get, ch->partid, ch->number);
-
-                       notify->func(reason, ch->partid, ch->number,
-                                    notify->key);
-
-                       dev_dbg(xpc_chan, "notify->func() returned, notify=0x%p"
-                               " msg_number=%lld partid=%d channel=%d\n",
-                               (void *)notify, get, ch->partid, ch->number);
-               }
-       }
-}
-
-static void
-xpc_notify_senders_of_disconnect_sn2(struct xpc_channel *ch)
-{
-       xpc_notify_senders_sn2(ch, ch->reason, ch->sn.sn2.w_local_GP.put);
-}
-
-/*
- * Clear some of the msg flags in the local message queue.
- */
-static inline void
-xpc_clear_local_msgqueue_flags_sn2(struct xpc_channel *ch)
-{
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-       struct xpc_msg_sn2 *msg;
-       s64 get;
-
-       get = ch_sn2->w_remote_GP.get;
-       do {
-               msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->local_msgqueue +
-                                            (get % ch->local_nentries) *
-                                            ch->entry_size);
-               DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
-               msg->flags = 0;
-       } while (++get < ch_sn2->remote_GP.get);
-}
-
-/*
- * Clear some of the msg flags in the remote message queue.
- */
-static inline void
-xpc_clear_remote_msgqueue_flags_sn2(struct xpc_channel *ch)
-{
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-       struct xpc_msg_sn2 *msg;
-       s64 put, remote_nentries = ch->remote_nentries;
-
-       /* flags are zeroed when the buffer is allocated */
-       if (ch_sn2->remote_GP.put < remote_nentries)
-               return;
-
-       put = max(ch_sn2->w_remote_GP.put, remote_nentries);
-       do {
-               msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue +
-                                            (put % remote_nentries) *
-                                            ch->entry_size);
-               DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
-               DBUG_ON(!(msg->flags & XPC_M_SN2_DONE));
-               DBUG_ON(msg->number != put - remote_nentries);
-               msg->flags = 0;
-       } while (++put < ch_sn2->remote_GP.put);
-}
-
-static int
-xpc_n_of_deliverable_payloads_sn2(struct xpc_channel *ch)
-{
-       return ch->sn.sn2.w_remote_GP.put - ch->sn.sn2.w_local_GP.get;
-}
-
-static void
-xpc_process_msg_chctl_flags_sn2(struct xpc_partition *part, int ch_number)
-{
-       struct xpc_channel *ch = &part->channels[ch_number];
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-       int npayloads_sent;
-
-       ch_sn2->remote_GP = part->sn.sn2.remote_GPs[ch_number];
-
-       /* See what, if anything, has changed for each connected channel */
-
-       xpc_msgqueue_ref(ch);
-
-       if (ch_sn2->w_remote_GP.get == ch_sn2->remote_GP.get &&
-           ch_sn2->w_remote_GP.put == ch_sn2->remote_GP.put) {
-               /* nothing changed since GPs were last pulled */
-               xpc_msgqueue_deref(ch);
-               return;
-       }
-
-       if (!(ch->flags & XPC_C_CONNECTED)) {
-               xpc_msgqueue_deref(ch);
-               return;
-       }
-
-       /*
-        * First check to see if messages recently sent by us have been
-        * received by the other side. (The remote GET value will have
-        * changed since we last looked at it.)
-        */
-
-       if (ch_sn2->w_remote_GP.get != ch_sn2->remote_GP.get) {
-
-               /*
-                * We need to notify any senders that want to be notified
-                * that their sent messages have been received by their
-                * intended recipients. We need to do this before updating
-                * w_remote_GP.get so that we don't allocate the same message
-                * queue entries prematurely (see xpc_allocate_msg()).
-                */
-               if (atomic_read(&ch->n_to_notify) > 0) {
-                       /*
-                        * Notify senders that messages sent have been
-                        * received and delivered by the other side.
-                        */
-                       xpc_notify_senders_sn2(ch, xpMsgDelivered,
-                                              ch_sn2->remote_GP.get);
-               }
-
-               /*
-                * Clear msg->flags in previously sent messages, so that
-                * they're ready for xpc_allocate_msg().
-                */
-               xpc_clear_local_msgqueue_flags_sn2(ch);
-
-               ch_sn2->w_remote_GP.get = ch_sn2->remote_GP.get;
-
-               dev_dbg(xpc_chan, "w_remote_GP.get changed to %lld, partid=%d, "
-                       "channel=%d\n", ch_sn2->w_remote_GP.get, ch->partid,
-                       ch->number);
-
-               /*
-                * If anyone was waiting for message queue entries to become
-                * available, wake them up.
-                */
-               if (atomic_read(&ch->n_on_msg_allocate_wq) > 0)
-                       wake_up(&ch->msg_allocate_wq);
-       }
-
-       /*
-        * Now check for newly sent messages by the other side. (The remote
-        * PUT value will have changed since we last looked at it.)
-        */
-
-       if (ch_sn2->w_remote_GP.put != ch_sn2->remote_GP.put) {
-               /*
-                * Clear msg->flags in previously received messages, so that
-                * they're ready for xpc_get_deliverable_payload_sn2().
-                */
-               xpc_clear_remote_msgqueue_flags_sn2(ch);
-
-               smp_wmb(); /* ensure flags have been cleared before bte_copy */
-               ch_sn2->w_remote_GP.put = ch_sn2->remote_GP.put;
-
-               dev_dbg(xpc_chan, "w_remote_GP.put changed to %lld, partid=%d, "
-                       "channel=%d\n", ch_sn2->w_remote_GP.put, ch->partid,
-                       ch->number);
-
-               npayloads_sent = xpc_n_of_deliverable_payloads_sn2(ch);
-               if (npayloads_sent > 0) {
-                       dev_dbg(xpc_chan, "msgs waiting to be copied and "
-                               "delivered=%d, partid=%d, channel=%d\n",
-                               npayloads_sent, ch->partid, ch->number);
-
-                       if (ch->flags & XPC_C_CONNECTEDCALLOUT_MADE)
-                               xpc_activate_kthreads(ch, npayloads_sent);
-               }
-       }
-
-       xpc_msgqueue_deref(ch);
-}
-
-static struct xpc_msg_sn2 *
-xpc_pull_remote_msg_sn2(struct xpc_channel *ch, s64 get)
-{
-       struct xpc_partition *part = &xpc_partitions[ch->partid];
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-       unsigned long remote_msg_pa;
-       struct xpc_msg_sn2 *msg;
-       u32 msg_index;
-       u32 nmsgs;
-       u64 msg_offset;
-       enum xp_retval ret;
-
-       if (mutex_lock_interruptible(&ch_sn2->msg_to_pull_mutex) != 0) {
-               /* we were interrupted by a signal */
-               return NULL;
-       }
-
-       while (get >= ch_sn2->next_msg_to_pull) {
-
-               /* pull as many messages as are ready and able to be pulled */
-
-               msg_index = ch_sn2->next_msg_to_pull % ch->remote_nentries;
-
-               DBUG_ON(ch_sn2->next_msg_to_pull >= ch_sn2->w_remote_GP.put);
-               nmsgs = ch_sn2->w_remote_GP.put - ch_sn2->next_msg_to_pull;
-               if (msg_index + nmsgs > ch->remote_nentries) {
-                       /* ignore the ones that wrap the msg queue for now */
-                       nmsgs = ch->remote_nentries - msg_index;
-               }
-
-               msg_offset = msg_index * ch->entry_size;
-               msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue +
-                   msg_offset);
-               remote_msg_pa = ch_sn2->remote_msgqueue_pa + msg_offset;
-
-               ret = xpc_pull_remote_cachelines_sn2(part, msg, remote_msg_pa,
-                                                    nmsgs * ch->entry_size);
-               if (ret != xpSuccess) {
-
-                       dev_dbg(xpc_chan, "failed to pull %d msgs starting with"
-                               " msg %lld from partition %d, channel=%d, "
-                               "ret=%d\n", nmsgs, ch_sn2->next_msg_to_pull,
-                               ch->partid, ch->number, ret);
-
-                       XPC_DEACTIVATE_PARTITION(part, ret);
-
-                       mutex_unlock(&ch_sn2->msg_to_pull_mutex);
-                       return NULL;
-               }
-
-               ch_sn2->next_msg_to_pull += nmsgs;
-       }
-
-       mutex_unlock(&ch_sn2->msg_to_pull_mutex);
-
-       /* return the message we were looking for */
-       msg_offset = (get % ch->remote_nentries) * ch->entry_size;
-       msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue + msg_offset);
-
-       return msg;
-}
-
-/*
- * Get the next deliverable message's payload.
- */
-static void *
-xpc_get_deliverable_payload_sn2(struct xpc_channel *ch)
-{
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-       struct xpc_msg_sn2 *msg;
-       void *payload = NULL;
-       s64 get;
-
-       do {
-               if (ch->flags & XPC_C_DISCONNECTING)
-                       break;
-
-               get = ch_sn2->w_local_GP.get;
-               smp_rmb();      /* guarantee that .get loads before .put */
-               if (get == ch_sn2->w_remote_GP.put)
-                       break;
-
-               /* There are messages waiting to be pulled and delivered.
-                * We need to try to secure one for ourselves. We'll do this
-                * by trying to increment w_local_GP.get and hope that no one
-                * else beats us to it. If they do, we'll we'll simply have
-                * to try again for the next one.
-                */
-
-               if (cmpxchg(&ch_sn2->w_local_GP.get, get, get + 1) == get) {
-                       /* we got the entry referenced by get */
-
-                       dev_dbg(xpc_chan, "w_local_GP.get changed to %lld, "
-                               "partid=%d, channel=%d\n", get + 1,
-                               ch->partid, ch->number);
-
-                       /* pull the message from the remote partition */
-
-                       msg = xpc_pull_remote_msg_sn2(ch, get);
-
-                       if (msg != NULL) {
-                               DBUG_ON(msg->number != get);
-                               DBUG_ON(msg->flags & XPC_M_SN2_DONE);
-                               DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
-
-                               payload = &msg->payload;
-                       }
-                       break;
-               }
-
-       } while (1);
-
-       return payload;
-}
-
-/*
- * Now we actually send the messages that are ready to be sent by advancing
- * the local message queue's Put value and then send a chctl msgrequest to the
- * recipient partition.
- */
-static void
-xpc_send_msgs_sn2(struct xpc_channel *ch, s64 initial_put)
-{
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-       struct xpc_msg_sn2 *msg;
-       s64 put = initial_put + 1;
-       int send_msgrequest = 0;
-
-       while (1) {
-
-               while (1) {
-                       if (put == ch_sn2->w_local_GP.put)
-                               break;
-
-                       msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->
-                                                    local_msgqueue + (put %
-                                                    ch->local_nentries) *
-                                                    ch->entry_size);
-
-                       if (!(msg->flags & XPC_M_SN2_READY))
-                               break;
-
-                       put++;
-               }
-
-               if (put == initial_put) {
-                       /* nothing's changed */
-                       break;
-               }
-
-               if (cmpxchg_rel(&ch_sn2->local_GP->put, initial_put, put) !=
-                   initial_put) {
-                       /* someone else beat us to it */
-                       DBUG_ON(ch_sn2->local_GP->put < initial_put);
-                       break;
-               }
-
-               /* we just set the new value of local_GP->put */
-
-               dev_dbg(xpc_chan, "local_GP->put changed to %lld, partid=%d, "
-                       "channel=%d\n", put, ch->partid, ch->number);
-
-               send_msgrequest = 1;
-
-               /*
-                * We need to ensure that the message referenced by
-                * local_GP->put is not XPC_M_SN2_READY or that local_GP->put
-                * equals w_local_GP.put, so we'll go have a look.
-                */
-               initial_put = put;
-       }
-
-       if (send_msgrequest)
-               xpc_send_chctl_msgrequest_sn2(ch);
-}
-
-/*
- * Allocate an entry for a message from the message queue associated with the
- * specified channel.
- */
-static enum xp_retval
-xpc_allocate_msg_sn2(struct xpc_channel *ch, u32 flags,
-                    struct xpc_msg_sn2 **address_of_msg)
-{
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-       struct xpc_msg_sn2 *msg;
-       enum xp_retval ret;
-       s64 put;
-
-       /*
-        * Get the next available message entry from the local message queue.
-        * If none are available, we'll make sure that we grab the latest
-        * GP values.
-        */
-       ret = xpTimeout;
-
-       while (1) {
-
-               put = ch_sn2->w_local_GP.put;
-               smp_rmb();      /* guarantee that .put loads before .get */
-               if (put - ch_sn2->w_remote_GP.get < ch->local_nentries) {
-
-                       /* There are available message entries. We need to try
-                        * to secure one for ourselves. We'll do this by trying
-                        * to increment w_local_GP.put as long as someone else
-                        * doesn't beat us to it. If they do, we'll have to
-                        * try again.
-                        */
-                       if (cmpxchg(&ch_sn2->w_local_GP.put, put, put + 1) ==
-                           put) {
-                               /* we got the entry referenced by put */
-                               break;
-                       }
-                       continue;       /* try again */
-               }
-
-               /*
-                * There aren't any available msg entries at this time.
-                *
-                * In waiting for a message entry to become available,
-                * we set a timeout in case the other side is not sending
-                * completion interrupts. This lets us fake a notify IRQ
-                * that will cause the notify IRQ handler to fetch the latest
-                * GP values as if an interrupt was sent by the other side.
-                */
-               if (ret == xpTimeout)
-                       xpc_send_chctl_local_msgrequest_sn2(ch);
-
-               if (flags & XPC_NOWAIT)
-                       return xpNoWait;
-
-               ret = xpc_allocate_msg_wait(ch);
-               if (ret != xpInterrupted && ret != xpTimeout)
-                       return ret;
-       }
-
-       /* get the message's address and initialize it */
-       msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->local_msgqueue +
-                                    (put % ch->local_nentries) *
-                                    ch->entry_size);
-
-       DBUG_ON(msg->flags != 0);
-       msg->number = put;
-
-       dev_dbg(xpc_chan, "w_local_GP.put changed to %lld; msg=0x%p, "
-               "msg_number=%lld, partid=%d, channel=%d\n", put + 1,
-               (void *)msg, msg->number, ch->partid, ch->number);
-
-       *address_of_msg = msg;
-       return xpSuccess;
-}
-
-/*
- * Common code that does the actual sending of the message by advancing the
- * local message queue's Put value and sends a chctl msgrequest to the
- * partition the message is being sent to.
- */
-static enum xp_retval
-xpc_send_payload_sn2(struct xpc_channel *ch, u32 flags, void *payload,
-                    u16 payload_size, u8 notify_type, xpc_notify_func func,
-                    void *key)
-{
-       enum xp_retval ret = xpSuccess;
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-       struct xpc_msg_sn2 *msg = msg;
-       struct xpc_notify_sn2 *notify = notify;
-       s64 msg_number;
-       s64 put;
-
-       DBUG_ON(notify_type == XPC_N_CALL && func == NULL);
-
-       if (XPC_MSG_SIZE(payload_size) > ch->entry_size)
-               return xpPayloadTooBig;
-
-       xpc_msgqueue_ref(ch);
-
-       if (ch->flags & XPC_C_DISCONNECTING) {
-               ret = ch->reason;
-               goto out_1;
-       }
-       if (!(ch->flags & XPC_C_CONNECTED)) {
-               ret = xpNotConnected;
-               goto out_1;
-       }
-
-       ret = xpc_allocate_msg_sn2(ch, flags, &msg);
-       if (ret != xpSuccess)
-               goto out_1;
-
-       msg_number = msg->number;
-
-       if (notify_type != 0) {
-               /*
-                * Tell the remote side to send an ACK interrupt when the
-                * message has been delivered.
-                */
-               msg->flags |= XPC_M_SN2_INTERRUPT;
-
-               atomic_inc(&ch->n_to_notify);
-
-               notify = &ch_sn2->notify_queue[msg_number % ch->local_nentries];
-               notify->func = func;
-               notify->key = key;
-               notify->type = notify_type;
-
-               /* ??? Is a mb() needed here? */
-
-               if (ch->flags & XPC_C_DISCONNECTING) {
-                       /*
-                        * An error occurred between our last error check and
-                        * this one. We will try to clear the type field from
-                        * the notify entry. If we succeed then
-                        * xpc_disconnect_channel() didn't already process
-                        * the notify entry.
-                        */
-                       if (cmpxchg(&notify->type, notify_type, 0) ==
-                           notify_type) {
-                               atomic_dec(&ch->n_to_notify);
-                               ret = ch->reason;
-                       }
-                       goto out_1;
-               }
-       }
-
-       memcpy(&msg->payload, payload, payload_size);
-
-       msg->flags |= XPC_M_SN2_READY;
-
-       /*
-        * The preceding store of msg->flags must occur before the following
-        * load of local_GP->put.
-        */
-       smp_mb();
-
-       /* see if the message is next in line to be sent, if so send it */
-
-       put = ch_sn2->local_GP->put;
-       if (put == msg_number)
-               xpc_send_msgs_sn2(ch, put);
-
-out_1:
-       xpc_msgqueue_deref(ch);
-       return ret;
-}
-
-/*
- * Now we actually acknowledge the messages that have been delivered and ack'd
- * by advancing the cached remote message queue's Get value and if requested
- * send a chctl msgrequest to the message sender's partition.
- *
- * If a message has XPC_M_SN2_INTERRUPT set, send an interrupt to the partition
- * that sent the message.
- */
-static void
-xpc_acknowledge_msgs_sn2(struct xpc_channel *ch, s64 initial_get, u8 msg_flags)
-{
-       struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
-       struct xpc_msg_sn2 *msg;
-       s64 get = initial_get + 1;
-       int send_msgrequest = 0;
-
-       while (1) {
-
-               while (1) {
-                       if (get == ch_sn2->w_local_GP.get)
-                               break;
-
-                       msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->
-                                                    remote_msgqueue + (get %
-                                                    ch->remote_nentries) *
-                                                    ch->entry_size);
-
-                       if (!(msg->flags & XPC_M_SN2_DONE))
-                               break;
-
-                       msg_flags |= msg->flags;
-                       get++;
-               }
-
-               if (get == initial_get) {
-                       /* nothing's changed */
-                       break;
-               }
-
-               if (cmpxchg_rel(&ch_sn2->local_GP->get, initial_get, get) !=
-                   initial_get) {
-                       /* someone else beat us to it */
-                       DBUG_ON(ch_sn2->local_GP->get <= initial_get);
-                       break;
-               }
-
-               /* we just set the new value of local_GP->get */
-
-               dev_dbg(xpc_chan, "local_GP->get changed to %lld, partid=%d, "
-                       "channel=%d\n", get, ch->partid, ch->number);
-
-               send_msgrequest = (msg_flags & XPC_M_SN2_INTERRUPT);
-
-               /*
-                * We need to ensure that the message referenced by
-                * local_GP->get is not XPC_M_SN2_DONE or that local_GP->get
-                * equals w_local_GP.get, so we'll go have a look.
-                */
-               initial_get = get;
-       }
-
-       if (send_msgrequest)
-               xpc_send_chctl_msgrequest_sn2(ch);
-}
-
-static void
-xpc_received_payload_sn2(struct xpc_channel *ch, void *payload)
-{
-       struct xpc_msg_sn2 *msg;
-       s64 msg_number;
-       s64 get;
-
-       msg = container_of(payload, struct xpc_msg_sn2, payload);
-       msg_number = msg->number;
-
-       dev_dbg(xpc_chan, "msg=0x%p, msg_number=%lld, partid=%d, channel=%d\n",
-               (void *)msg, msg_number, ch->partid, ch->number);
-
-       DBUG_ON((((u64)msg - (u64)ch->sn.sn2.remote_msgqueue) / ch->entry_size) !=
-               msg_number % ch->remote_nentries);
-       DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
-       DBUG_ON(msg->flags & XPC_M_SN2_DONE);
-
-       msg->flags |= XPC_M_SN2_DONE;
-
-       /*
-        * The preceding store of msg->flags must occur before the following
-        * load of local_GP->get.
-        */
-       smp_mb();
-
-       /*
-        * See if this message is next in line to be acknowledged as having
-        * been delivered.
-        */
-       get = ch->sn.sn2.local_GP->get;
-       if (get == msg_number)
-               xpc_acknowledge_msgs_sn2(ch, get, msg->flags);
-}
-
-static struct xpc_arch_operations xpc_arch_ops_sn2 = {
-       .setup_partitions = xpc_setup_partitions_sn2,
-       .teardown_partitions = xpc_teardown_partitions_sn2,
-       .process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_sn2,
-       .get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2,
-       .setup_rsvd_page = xpc_setup_rsvd_page_sn2,
-
-       .allow_hb = xpc_allow_hb_sn2,
-       .disallow_hb = xpc_disallow_hb_sn2,
-       .disallow_all_hbs = xpc_disallow_all_hbs_sn2,
-       .increment_heartbeat = xpc_increment_heartbeat_sn2,
-       .offline_heartbeat = xpc_offline_heartbeat_sn2,
-       .online_heartbeat = xpc_online_heartbeat_sn2,
-       .heartbeat_init = xpc_heartbeat_init_sn2,
-       .heartbeat_exit = xpc_heartbeat_exit_sn2,
-       .get_remote_heartbeat = xpc_get_remote_heartbeat_sn2,
-
-       .request_partition_activation =
-               xpc_request_partition_activation_sn2,
-       .request_partition_reactivation =
-               xpc_request_partition_reactivation_sn2,
-       .request_partition_deactivation =
-               xpc_request_partition_deactivation_sn2,
-       .cancel_partition_deactivation_request =
-               xpc_cancel_partition_deactivation_request_sn2,
-
-       .setup_ch_structures = xpc_setup_ch_structures_sn2,
-       .teardown_ch_structures = xpc_teardown_ch_structures_sn2,
-
-       .make_first_contact = xpc_make_first_contact_sn2,
-
-       .get_chctl_all_flags = xpc_get_chctl_all_flags_sn2,
-       .send_chctl_closerequest = xpc_send_chctl_closerequest_sn2,
-       .send_chctl_closereply = xpc_send_chctl_closereply_sn2,
-       .send_chctl_openrequest = xpc_send_chctl_openrequest_sn2,
-       .send_chctl_openreply = xpc_send_chctl_openreply_sn2,
-       .send_chctl_opencomplete = xpc_send_chctl_opencomplete_sn2,
-       .process_msg_chctl_flags = xpc_process_msg_chctl_flags_sn2,
-
-       .save_remote_msgqueue_pa = xpc_save_remote_msgqueue_pa_sn2,
-
-       .setup_msg_structures = xpc_setup_msg_structures_sn2,
-       .teardown_msg_structures = xpc_teardown_msg_structures_sn2,
-
-       .indicate_partition_engaged = xpc_indicate_partition_engaged_sn2,
-       .indicate_partition_disengaged = xpc_indicate_partition_disengaged_sn2,
-       .partition_engaged = xpc_partition_engaged_sn2,
-       .any_partition_engaged = xpc_any_partition_engaged_sn2,
-       .assume_partition_disengaged = xpc_assume_partition_disengaged_sn2,
-
-       .n_of_deliverable_payloads = xpc_n_of_deliverable_payloads_sn2,
-       .send_payload = xpc_send_payload_sn2,
-       .get_deliverable_payload = xpc_get_deliverable_payload_sn2,
-       .received_payload = xpc_received_payload_sn2,
-       .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_sn2,
-};
-
-int
-xpc_init_sn2(void)
-{
-       int ret;
-       size_t buf_size;
-
-       xpc_arch_ops = xpc_arch_ops_sn2;
-
-       if (offsetof(struct xpc_msg_sn2, payload) > XPC_MSG_HDR_MAX_SIZE) {
-               dev_err(xpc_part, "header portion of struct xpc_msg_sn2 is "
-                       "larger than %d\n", XPC_MSG_HDR_MAX_SIZE);
-               return -E2BIG;
-       }
-
-       buf_size = max(XPC_RP_VARS_SIZE,
-                      XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES_SN2);
-       xpc_remote_copy_buffer_sn2 = xpc_kmalloc_cacheline_aligned(buf_size,
-                                                                  GFP_KERNEL,
-                                             &xpc_remote_copy_buffer_base_sn2);
-       if (xpc_remote_copy_buffer_sn2 == NULL) {
-               dev_err(xpc_part, "can't get memory for remote copy buffer\n");
-               return -ENOMEM;
-       }
-
-       /* open up protections for IPI and [potentially] amo operations */
-       xpc_allow_IPI_ops_sn2();
-       xpc_allow_amo_ops_shub_wars_1_1_sn2();
-
-       /*
-        * This is safe to do before the xpc_hb_checker thread has started
-        * because the handler releases a wait queue.  If an interrupt is
-        * received before the thread is waiting, it will not go to sleep,
-        * but rather immediately process the interrupt.
-        */
-       ret = request_irq(SGI_XPC_ACTIVATE, xpc_handle_activate_IRQ_sn2, 0,
-                         "xpc hb", NULL);
-       if (ret != 0) {
-               dev_err(xpc_part, "can't register ACTIVATE IRQ handler, "
-                       "errno=%d\n", -ret);
-               xpc_disallow_IPI_ops_sn2();
-               kfree(xpc_remote_copy_buffer_base_sn2);
-       }
-       return ret;
-}
-
-void
-xpc_exit_sn2(void)
-{
-       free_irq(SGI_XPC_ACTIVATE, NULL);
-       xpc_disallow_IPI_ops_sn2();
-       kfree(xpc_remote_copy_buffer_base_sn2);
-}
index 0c6de97..09e2465 100644 (file)
@@ -27,7 +27,7 @@
 #if defined CONFIG_X86_64
 #include <asm/uv/bios.h>
 #include <asm/uv/uv_irq.h>
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+#elif defined CONFIG_IA64_SGI_UV
 #include <asm/sn/intr.h>
 #include <asm/sn/sn_sal.h>
 #endif
@@ -35,7 +35,7 @@
 #include "../sgi-gru/grukservices.h"
 #include "xpc.h"
 
-#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+#if defined CONFIG_IA64_SGI_UV
 struct uv_IO_APIC_route_entry {
        __u64   vector          :  8,
                delivery_mode   :  3,
@@ -48,6 +48,8 @@ struct uv_IO_APIC_route_entry {
                __reserved_2    : 15,
                dest            : 32;
 };
+
+#define sn_partition_id 0
 #endif
 
 static struct xpc_heartbeat_uv *xpc_heartbeat_uv;
@@ -119,7 +121,7 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
 
        mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset);
 
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+#elif defined CONFIG_IA64_SGI_UV
        if (strcmp(irq_name, XPC_ACTIVATE_IRQ_NAME) == 0)
                mq->irq = SGI_XPC_ACTIVATE;
        else if (strcmp(irq_name, XPC_NOTIFY_IRQ_NAME) == 0)
@@ -142,7 +144,7 @@ xpc_release_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq)
 #if defined CONFIG_X86_64
        uv_teardown_irq(mq->irq);
 
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+#elif defined CONFIG_IA64_SGI_UV
        int mmr_pnode;
        unsigned long mmr_value;
 
@@ -160,7 +162,7 @@ xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq)
 {
        int ret;
 
-#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+#if defined CONFIG_IA64_SGI_UV
        int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
 
        ret = sn_mq_watchlist_alloc(mmr_pnode, (void *)uv_gpa(mq->address),
@@ -195,7 +197,7 @@ xpc_gru_mq_watchlist_free_uv(struct xpc_gru_mq_uv *mq)
 #if defined CONFIG_X86_64
        ret = uv_bios_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
        BUG_ON(ret != BIOS_STATUS_SUCCESS);
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+#elif defined CONFIG_IA64_SGI_UV
        ret = sn_mq_watchlist_free(mmr_pnode, mq->watchlist_num);
        BUG_ON(ret != SALRET_OK);
 #else
@@ -794,7 +796,7 @@ xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa,
        else
                ret = xpBiosError;
 
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+#elif defined CONFIG_IA64_SGI_UV
        status = sn_partition_reserved_page_pa((u64)buf, cookie, rp_pa, len);
        if (status == SALRET_OK)
                ret = xpSuccess;
index 44d750d..f7d610a 100644 (file)
@@ -515,7 +515,7 @@ xpnet_init(void)
 {
        int result;
 
-       if (!is_shub() && !is_uv())
+       if (!is_uv())
                return -ENODEV;
 
        dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME);
index 8840299..5e6be15 100644 (file)
@@ -691,7 +691,6 @@ static int vmballoon_alloc_page_list(struct vmballoon *b,
                }
 
                if (page) {
-                       vmballoon_mark_page_offline(page, ctl->page_size);
                        /* Success. Add the page to the list and continue. */
                        list_add(&page->lru, &ctl->pages);
                        continue;
@@ -930,7 +929,6 @@ static void vmballoon_release_page_list(struct list_head *page_list,
 
        list_for_each_entry_safe(page, tmp, page_list, lru) {
                list_del(&page->lru);
-               vmballoon_mark_page_online(page, page_size);
                __free_pages(page, vmballoon_page_order(page_size));
        }
 
@@ -1005,6 +1003,7 @@ static void vmballoon_enqueue_page_list(struct vmballoon *b,
                                        enum vmballoon_page_size_type page_size)
 {
        unsigned long flags;
+       struct page *page;
 
        if (page_size == VMW_BALLOON_4K_PAGE) {
                balloon_page_list_enqueue(&b->b_dev_info, pages);
@@ -1014,6 +1013,11 @@ static void vmballoon_enqueue_page_list(struct vmballoon *b,
                 * for the balloon compaction mechanism.
                 */
                spin_lock_irqsave(&b->b_dev_info.pages_lock, flags);
+
+               list_for_each_entry(page, pages, lru) {
+                       vmballoon_mark_page_offline(page, VMW_BALLOON_2M_PAGE);
+               }
+
                list_splice_init(pages, &b->huge_pages);
                __count_vm_events(BALLOON_INFLATE, *n_pages *
                                  vmballoon_page_in_frames(VMW_BALLOON_2M_PAGE));
@@ -1056,6 +1060,8 @@ static void vmballoon_dequeue_page_list(struct vmballoon *b,
        /* 2MB pages */
        spin_lock_irqsave(&b->b_dev_info.pages_lock, flags);
        list_for_each_entry_safe(page, tmp, &b->huge_pages, lru) {
+               vmballoon_mark_page_online(page, VMW_BALLOON_2M_PAGE);
+
                list_move(&page->lru, pages);
                if (++i == n_req_pages)
                        break;
index bad89b6..345addd 100644 (file)
@@ -310,7 +310,8 @@ int vmci_dbell_host_context_notify(u32 src_cid, struct vmci_handle handle)
 
        entry = container_of(resource, struct dbell_entry, resource);
        if (entry->run_delayed) {
-               schedule_work(&entry->work);
+               if (!schedule_work(&entry->work))
+                       vmci_resource_put(resource);
        } else {
                entry->notify_cb(entry->client_data);
                vmci_resource_put(resource);
@@ -361,7 +362,8 @@ static void dbell_fire_entries(u32 notify_idx)
                    atomic_read(&dbell->active) == 1) {
                        if (dbell->run_delayed) {
                                vmci_resource_get(&dbell->resource);
-                               schedule_work(&dbell->work);
+                               if (!schedule_work(&dbell->work))
+                                       vmci_resource_put(&dbell->resource);
                        } else {
                                dbell->notify_cb(dbell->client_data);
                        }
index 74e4364..09113b9 100644 (file)
@@ -564,7 +564,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
        if (index == EXT_CSD_SANITIZE_START)
                cmd.sanitize_busy = true;
 
-       err = mmc_wait_for_cmd(host, &cmd, 0);
+       err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
        if (err)
                goto out;
 
index d681e8a..fe914ff 100644 (file)
@@ -1292,6 +1292,12 @@ int mmc_attach_sd(struct mmc_host *host)
                        goto err;
        }
 
+       /*
+        * Some SD cards claims an out of spec VDD voltage range. Let's treat
+        * these bits as being in-valid and especially also bit7.
+        */
+       ocr &= ~0x7FFF;
+
        rocr = mmc_select_voltage(host, ocr);
 
        /*
index 7e0d3a4..bb31e13 100644 (file)
@@ -597,7 +597,7 @@ static void bcm2835_finish_request(struct bcm2835_host *host)
        struct dma_chan *terminate_chan = NULL;
        struct mmc_request *mrq;
 
-       cancel_delayed_work_sync(&host->timeout_work);
+       cancel_delayed_work(&host->timeout_work);
 
        mrq = host->mrq;
 
index 64d3b5f..4a2872f 100644 (file)
@@ -774,8 +774,6 @@ int renesas_sdhi_probe(struct platform_device *pdev,
        /* All SDHI have SDIO status bits which must be 1 */
        mmc_data->flags |= TMIO_MMC_SDIO_STATUS_SETBITS;
 
-       pm_runtime_enable(&pdev->dev);
-
        ret = renesas_sdhi_clk_enable(host);
        if (ret)
                goto efree;
@@ -856,8 +854,6 @@ edisclk:
 efree:
        tmio_mmc_host_free(host);
 
-       pm_runtime_disable(&pdev->dev);
-
        return ret;
 }
 EXPORT_SYMBOL_GPL(renesas_sdhi_probe);
@@ -869,8 +865,6 @@ int renesas_sdhi_remove(struct platform_device *pdev)
        tmio_mmc_host_remove(host);
        renesas_sdhi_clk_disable(host);
 
-       pm_runtime_disable(&pdev->dev);
-
        return 0;
 }
 EXPORT_SYMBOL_GPL(renesas_sdhi_remove);
index 163d1cf..44139fc 100644 (file)
@@ -369,6 +369,7 @@ static int sdhci_cdns_probe(struct platform_device *pdev)
        host->mmc_host_ops.execute_tuning = sdhci_cdns_execute_tuning;
        host->mmc_host_ops.hs400_enhanced_strobe =
                                sdhci_cdns_hs400_enhanced_strobe;
+       sdhci_enable_v4_mode(host);
 
        sdhci_get_of_property(pdev);
 
index d4e7e8b..e7d1920 100644 (file)
@@ -357,6 +357,9 @@ static int sdhci_at91_probe(struct platform_device *pdev)
        pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
        pm_runtime_use_autosuspend(&pdev->dev);
 
+       /* HS200 is broken at this moment */
+       host->quirks2 = SDHCI_QUIRK2_BROKEN_HS200;
+
        ret = sdhci_add_host(host);
        if (ret)
                goto pm_runtime_disable;
index 9dc4548..19944b0 100644 (file)
@@ -432,7 +432,6 @@ int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
                                        mmc_hostname(host->mmc));
                                host->flags &= ~SDHCI_SIGNALING_330;
                                host->flags |= SDHCI_SIGNALING_180;
-                               host->quirks2 |= SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD;
                                host->mmc->caps2 |= MMC_CAP2_NO_SD;
                                host->mmc->caps2 |= MMC_CAP2_NO_SDIO;
                                pci_write_config_dword(chip->pdev,
@@ -682,6 +681,7 @@ static const struct sdhci_ops sdhci_pci_o2_ops = {
 const struct sdhci_pci_fixes sdhci_o2 = {
        .probe = sdhci_pci_o2_probe,
        .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
+       .quirks2 = SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD,
        .probe_slot = sdhci_pci_o2_probe_slot,
 #ifdef CONFIG_PM_SLEEP
        .resume = sdhci_pci_o2_resume,
index 83a4767..d07b979 100644 (file)
@@ -217,10 +217,11 @@ static inline void _sdhci_sprd_set_clock(struct sdhci_host *host,
        struct sdhci_sprd_host *sprd_host = TO_SPRD_HOST(host);
        u32 div, val, mask;
 
-       div = sdhci_sprd_calc_div(sprd_host->base_rate, clk);
+       sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
 
-       clk |= ((div & 0x300) >> 2) | ((div & 0xFF) << 8);
-       sdhci_enable_clk(host, clk);
+       div = sdhci_sprd_calc_div(sprd_host->base_rate, clk);
+       div = ((div & 0x300) >> 2) | ((div & 0xFF) << 8);
+       sdhci_enable_clk(host, div);
 
        /* enable auto gate sdhc_enable_auto_gate */
        val = sdhci_readl(host, SDHCI_SPRD_REG_32_BUSY_POSI);
@@ -373,6 +374,11 @@ static unsigned int sdhci_sprd_get_max_timeout_count(struct sdhci_host *host)
        return 1 << 31;
 }
 
+static unsigned int sdhci_sprd_get_ro(struct sdhci_host *host)
+{
+       return 0;
+}
+
 static struct sdhci_ops sdhci_sprd_ops = {
        .read_l = sdhci_sprd_readl,
        .write_l = sdhci_sprd_writel,
@@ -385,6 +391,7 @@ static struct sdhci_ops sdhci_sprd_ops = {
        .set_uhs_signaling = sdhci_sprd_set_uhs_signaling,
        .hw_reset = sdhci_sprd_hw_reset,
        .get_max_timeout_count = sdhci_sprd_get_max_timeout_count,
+       .get_ro = sdhci_sprd_get_ro,
 };
 
 static void sdhci_sprd_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -501,9 +508,12 @@ static void sdhci_sprd_phy_param_parse(struct sdhci_sprd_host *sprd_host,
 }
 
 static const struct sdhci_pltfm_data sdhci_sprd_pdata = {
-       .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK,
+       .quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+                 SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
+                 SDHCI_QUIRK_MISSING_CAPS,
        .quirks2 = SDHCI_QUIRK2_BROKEN_HS200 |
-                  SDHCI_QUIRK2_USE_32BIT_BLK_CNT,
+                  SDHCI_QUIRK2_USE_32BIT_BLK_CNT |
+                  SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
        .ops = &sdhci_sprd_ops,
 };
 
@@ -605,6 +615,16 @@ static int sdhci_sprd_probe(struct platform_device *pdev)
 
        sdhci_enable_v4_mode(host);
 
+       /*
+        * Supply the existing CAPS, but clear the UHS-I modes. This
+        * will allow these modes to be specified only by device
+        * tree properties through mmc_of_parse().
+        */
+       host->caps = sdhci_readl(host, SDHCI_CAPABILITIES);
+       host->caps1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
+       host->caps1 &= ~(SDHCI_SUPPORT_SDR50 | SDHCI_SUPPORT_SDR104 |
+                        SDHCI_SUPPORT_DDR50);
+
        ret = sdhci_setup_host(host);
        if (ret)
                goto pm_runtime_disable;
index f4d4761..02d8f52 100644 (file)
@@ -258,6 +258,16 @@ static void tegra210_sdhci_writew(struct sdhci_host *host, u16 val, int reg)
        }
 }
 
+static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host)
+{
+       /*
+        * Write-enable shall be assumed if GPIO is missing in a board's
+        * device-tree because SDHCI's WRITE_PROTECT bit doesn't work on
+        * Tegra.
+        */
+       return mmc_gpio_get_ro(host->mmc);
+}
+
 static bool tegra_sdhci_is_pad_and_regulator_valid(struct sdhci_host *host)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -1224,6 +1234,7 @@ static const struct cqhci_host_ops sdhci_tegra_cqhci_ops = {
 };
 
 static const struct sdhci_ops tegra_sdhci_ops = {
+       .get_ro     = tegra_sdhci_get_ro,
        .read_w     = tegra_sdhci_readw,
        .write_l    = tegra_sdhci_writel,
        .set_clock  = tegra_sdhci_set_clock,
@@ -1279,6 +1290,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra30 = {
 };
 
 static const struct sdhci_ops tegra114_sdhci_ops = {
+       .get_ro     = tegra_sdhci_get_ro,
        .read_w     = tegra_sdhci_readw,
        .write_w    = tegra_sdhci_writew,
        .write_l    = tegra_sdhci_writel,
@@ -1332,6 +1344,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra124 = {
 };
 
 static const struct sdhci_ops tegra210_sdhci_ops = {
+       .get_ro     = tegra_sdhci_get_ro,
        .read_w     = tegra_sdhci_readw,
        .write_w    = tegra210_sdhci_writew,
        .write_l    = tegra_sdhci_writel,
@@ -1366,6 +1379,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra210 = {
 };
 
 static const struct sdhci_ops tegra186_sdhci_ops = {
+       .get_ro     = tegra_sdhci_get_ro,
        .read_w     = tegra_sdhci_readw,
        .write_l    = tegra_sdhci_writel,
        .set_clock  = tegra_sdhci_set_clock,
index 8539e10..93e83ad 100644 (file)
@@ -172,8 +172,6 @@ static int tmio_mmc_probe(struct platform_device *pdev)
        host->mmc->f_max = pdata->hclk;
        host->mmc->f_min = pdata->hclk / 512;
 
-       pm_runtime_enable(&pdev->dev);
-
        ret = tmio_mmc_host_probe(host);
        if (ret)
                goto host_free;
@@ -193,7 +191,6 @@ host_remove:
        tmio_mmc_host_remove(host);
 host_free:
        tmio_mmc_host_free(host);
-       pm_runtime_disable(&pdev->dev);
 cell_disable:
        if (cell->disable)
                cell->disable(pdev);
@@ -210,8 +207,6 @@ static int tmio_mmc_remove(struct platform_device *pdev)
        if (cell->disable)
                cell->disable(pdev);
 
-       pm_runtime_disable(&pdev->dev);
-
        return 0;
 }
 
index c5ba13f..2f0b092 100644 (file)
@@ -163,6 +163,7 @@ struct tmio_mmc_host {
        unsigned long           last_req_ts;
        struct mutex            ios_lock;       /* protect set_ios() context */
        bool                    native_hotplug;
+       bool                    runtime_synced;
        bool                    sdio_irq_enabled;
 
        /* Mandatory callback */
index 2cb3f95..9b6e100 100644 (file)
@@ -1153,15 +1153,6 @@ void tmio_mmc_host_free(struct tmio_mmc_host *host)
 }
 EXPORT_SYMBOL_GPL(tmio_mmc_host_free);
 
-/**
- * tmio_mmc_host_probe() - Common probe for all implementations
- * @_host: Host to probe
- *
- * Perform tasks common to all implementations probe functions.
- *
- * The caller should have called pm_runtime_enable() prior to calling
- * the common probe function.
- */
 int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
 {
        struct platform_device *pdev = _host->pdev;
@@ -1257,19 +1248,22 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
        /* See if we also get DMA */
        tmio_mmc_request_dma(_host, pdata);
 
-       pm_runtime_set_active(&pdev->dev);
        pm_runtime_set_autosuspend_delay(&pdev->dev, 50);
        pm_runtime_use_autosuspend(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_get_sync(&pdev->dev);
 
        ret = mmc_add_host(mmc);
        if (ret)
                goto remove_host;
 
        dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
+       pm_runtime_put(&pdev->dev);
 
        return 0;
 
 remove_host:
+       pm_runtime_put_noidle(&pdev->dev);
        tmio_mmc_host_remove(_host);
        return ret;
 }
@@ -1280,12 +1274,11 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
        struct platform_device *pdev = host->pdev;
        struct mmc_host *mmc = host->mmc;
 
+       pm_runtime_get_sync(&pdev->dev);
+
        if (host->pdata->flags & TMIO_MMC_SDIO_IRQ)
                sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000);
 
-       if (!host->native_hotplug)
-               pm_runtime_get_sync(&pdev->dev);
-
        dev_pm_qos_hide_latency_limit(&pdev->dev);
 
        mmc_remove_host(mmc);
@@ -1294,7 +1287,10 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
        tmio_mmc_release_dma(host);
 
        pm_runtime_dont_use_autosuspend(&pdev->dev);
+       if (host->native_hotplug)
+               pm_runtime_put_noidle(&pdev->dev);
        pm_runtime_put_sync(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
 }
 EXPORT_SYMBOL_GPL(tmio_mmc_host_remove);
 
@@ -1337,6 +1333,11 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
 {
        struct tmio_mmc_host *host = dev_get_drvdata(dev);
 
+       if (!host->runtime_synced) {
+               host->runtime_synced = true;
+               return 0;
+       }
+
        tmio_mmc_clk_enable(host);
        tmio_mmc_hw_reset(host->mmc);
 
index 49aad9a..91a2be4 100644 (file)
@@ -631,7 +631,6 @@ static int uniphier_sd_probe(struct platform_device *pdev)
        host->clk_disable = uniphier_sd_clk_disable;
        host->set_clock = uniphier_sd_set_clock;
 
-       pm_runtime_enable(&pdev->dev);
        ret = uniphier_sd_clk_enable(host);
        if (ret)
                goto free_host;
@@ -653,7 +652,6 @@ static int uniphier_sd_probe(struct platform_device *pdev)
 
 free_host:
        tmio_mmc_host_free(host);
-       pm_runtime_disable(&pdev->dev);
 
        return ret;
 }
@@ -664,7 +662,6 @@ static int uniphier_sd_remove(struct platform_device *pdev)
 
        tmio_mmc_host_remove(host);
        uniphier_sd_clk_disable(host);
-       pm_runtime_disable(&pdev->dev);
 
        return 0;
 }
index b4e3caf..a4d8968 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig MTD_HYPERBUS
        tristate "HyperBus support"
+       depends on HAS_IOMEM
        select MTD_CFI
        select MTD_MAP_BANK_WIDTH_2
        select MTD_CFI_AMDSTD
index 3811fdb..28c963a 100644 (file)
@@ -478,6 +478,7 @@ static void bcm_sf2_sw_validate(struct dsa_switch *ds, int port,
                                unsigned long *supported,
                                struct phylink_link_state *state)
 {
+       struct bcm_sf2_priv *priv = bcm_sf2_to_priv(ds);
        __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
 
        if (!phy_interface_mode_is_rgmii(state->interface) &&
@@ -487,8 +488,10 @@ static void bcm_sf2_sw_validate(struct dsa_switch *ds, int port,
            state->interface != PHY_INTERFACE_MODE_INTERNAL &&
            state->interface != PHY_INTERFACE_MODE_MOCA) {
                bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
-               dev_err(ds->dev,
-                       "Unsupported interface: %d\n", state->interface);
+               if (port != core_readl(priv, CORE_IMP0_PRT_ID))
+                       dev_err(ds->dev,
+                               "Unsupported interface: %d for port %d\n",
+                               state->interface, port);
                return;
        }
 
@@ -526,6 +529,9 @@ static void bcm_sf2_sw_mac_config(struct dsa_switch *ds, int port,
        u32 id_mode_dis = 0, port_mode;
        u32 reg, offset;
 
+       if (port == core_readl(priv, CORE_IMP0_PRT_ID))
+               return;
+
        if (priv->type == BCM7445_DEVICE_ID)
                offset = CORE_STS_OVERRIDE_GMIIP_PORT(port);
        else
index 5a9e27b..098b01e 100644 (file)
@@ -81,6 +81,7 @@ static const struct of_device_id ksz9477_dt_ids[] = {
        { .compatible = "microchip,ksz9897" },
        { .compatible = "microchip,ksz9893" },
        { .compatible = "microchip,ksz9563" },
+       { .compatible = "microchip,ksz8563" },
        {},
 };
 MODULE_DEVICE_TABLE(of, ksz9477_dt_ids);
index ee7096d..72ec250 100644 (file)
@@ -128,6 +128,7 @@ static inline void ksz_pwrite32(struct ksz_device *dev, int port, int offset,
 
 #define KSZ_REGMAP_ENTRY(width, swp, regbits, regpad, regalign)                \
        {                                                               \
+               .name = #width,                                         \
                .val_bits = (width),                                    \
                .reg_stride = (width) / 8,                              \
                .reg_bits = (regbits) + (regalign),                     \
index 93a2d4d..dc9dee5 100644 (file)
@@ -151,7 +151,6 @@ config NET_NETX
          To compile this driver as a module, choose M here. The module
          will be called netx-eth.
 
-source "drivers/net/ethernet/nuvoton/Kconfig"
 source "drivers/net/ethernet/nvidia/Kconfig"
 source "drivers/net/ethernet/nxp/Kconfig"
 source "drivers/net/ethernet/oki-semi/Kconfig"
index fb9155c..4bc3c95 100644 (file)
@@ -65,7 +65,6 @@ obj-$(CONFIG_NET_VENDOR_NETERION) += neterion/
 obj-$(CONFIG_NET_VENDOR_NETRONOME) += netronome/
 obj-$(CONFIG_NET_VENDOR_NI) += ni/
 obj-$(CONFIG_NET_NETX) += netx-eth.o
-obj-$(CONFIG_NET_VENDOR_NUVOTON) += nuvoton/
 obj-$(CONFIG_NET_VENDOR_NVIDIA) += nvidia/
 obj-$(CONFIG_LPC_ENET) += nxp/
 obj-$(CONFIG_NET_VENDOR_OKI) += oki-semi/
index b41f236..7ce9c69 100644 (file)
@@ -469,13 +469,19 @@ static int __init xgbe_mod_init(void)
 
        ret = xgbe_platform_init();
        if (ret)
-               return ret;
+               goto err_platform_init;
 
        ret = xgbe_pci_init();
        if (ret)
-               return ret;
+               goto err_pci_init;
 
        return 0;
+
+err_pci_init:
+       xgbe_platform_exit();
+err_platform_init:
+       unregister_netdevice_notifier(&xgbe_netdev_notifier);
+       return ret;
 }
 
 static void __exit xgbe_mod_exit(void)
index 440690b..aee827f 100644 (file)
@@ -431,7 +431,8 @@ int aq_del_fvlan_by_vlan(struct aq_nic_s *aq_nic, u16 vlan_id)
                if (be16_to_cpu(rule->aq_fsp.h_ext.vlan_tci) == vlan_id)
                        break;
        }
-       if (rule && be16_to_cpu(rule->aq_fsp.h_ext.vlan_tci) == vlan_id) {
+       if (rule && rule->type == aq_rx_filter_vlan &&
+           be16_to_cpu(rule->aq_fsp.h_ext.vlan_tci) == vlan_id) {
                struct ethtool_rxnfc cmd;
 
                cmd.fs.location = rule->aq_fsp.location;
@@ -843,7 +844,7 @@ int aq_filters_vlans_update(struct aq_nic_s *aq_nic)
                return err;
 
        if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) {
-               if (hweight < AQ_VLAN_MAX_FILTERS && hweight > 0) {
+               if (hweight <= AQ_VLAN_MAX_FILTERS && hweight > 0) {
                        err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw,
                                !(aq_nic->packet_filter & IFF_PROMISC));
                        aq_nic->aq_nic_cfg.is_vlan_force_promisc = false;
index 100722a..b4a0fb2 100644 (file)
@@ -61,6 +61,10 @@ static int aq_ndev_open(struct net_device *ndev)
        if (err < 0)
                goto err_exit;
 
+       err = aq_filters_vlans_update(aq_nic);
+       if (err < 0)
+               goto err_exit;
+
        err = aq_nic_start(aq_nic);
        if (err < 0)
                goto err_exit;
index e139276..8f66e78 100644 (file)
@@ -393,7 +393,7 @@ int aq_nic_start(struct aq_nic_s *self)
                                                   self->aq_nic_cfg.link_irq_vec);
                        err = request_threaded_irq(irqvec, NULL,
                                                   aq_linkstate_threaded_isr,
-                                                  IRQF_SHARED,
+                                                  IRQF_SHARED | IRQF_ONESHOT,
                                                   self->ndev->name, self);
                        if (err < 0)
                                goto err_exit;
index 715685a..28892b8 100644 (file)
@@ -86,6 +86,7 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)
                        }
                }
 
+err_exit:
                if (!was_tx_cleaned)
                        work_done = budget;
 
@@ -95,7 +96,7 @@ static int aq_vec_poll(struct napi_struct *napi, int budget)
                                        1U << self->aq_ring_param.vec_idx);
                }
        }
-err_exit:
+
        return work_done;
 }
 
index d3a0b61..b221968 100644 (file)
@@ -1124,6 +1124,7 @@ static const struct ethtool_ops bcmgenet_ethtool_ops = {
        .set_coalesce           = bcmgenet_set_coalesce,
        .get_link_ksettings     = bcmgenet_get_link_ksettings,
        .set_link_ksettings     = bcmgenet_set_link_ksettings,
+       .get_ts_info            = ethtool_op_get_ts_info,
 };
 
 /* Power down the unimac, based on mode. */
index 5ca17e6..35b59b5 100644 (file)
@@ -4154,7 +4154,7 @@ static const struct of_device_id macb_dt_ids[] = {
        { .compatible = "cdns,emac", .data = &emac_config },
        { .compatible = "cdns,zynqmp-gem", .data = &zynqmp_config},
        { .compatible = "cdns,zynq-gem", .data = &zynq_config },
-       { .compatible = "sifive,fu540-macb", .data = &fu540_c000_config },
+       { .compatible = "sifive,fu540-c000-gem", .data = &fu540_c000_config },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, macb_dt_ids);
index 2fd2586..bc59489 100644 (file)
@@ -82,7 +82,7 @@ static int enetc_ptp_probe(struct pci_dev *pdev,
        n = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
        if (n != 1) {
                err = -EPERM;
-               goto err_irq;
+               goto err_irq_vectors;
        }
 
        ptp_qoriq->irq = pci_irq_vector(pdev, 0);
@@ -107,6 +107,8 @@ static int enetc_ptp_probe(struct pci_dev *pdev,
 err_no_clock:
        free_irq(ptp_qoriq->irq, ptp_qoriq);
 err_irq:
+       pci_free_irq_vectors(pdev);
+err_irq_vectors:
        iounmap(base);
 err_ioremap:
        kfree(ptp_qoriq);
@@ -125,6 +127,7 @@ static void enetc_ptp_remove(struct pci_dev *pdev)
 
        enetc_phc_index = -1;
        ptp_qoriq_free(ptp_qoriq);
+       pci_free_irq_vectors(pdev);
        kfree(ptp_qoriq);
 
        pci_release_mem_regions(pdev);
index 4972987..aca95f6 100644 (file)
@@ -50,7 +50,7 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s)
                                  u64_stats_fetch_begin(&priv->tx[ring].statss);
                                s->tx_packets += priv->tx[ring].pkt_done;
                                s->tx_bytes += priv->tx[ring].bytes_done;
-                       } while (u64_stats_fetch_retry(&priv->rx[ring].statss,
+                       } while (u64_stats_fetch_retry(&priv->tx[ring].statss,
                                                       start));
                }
        }
index 0a72438..85a3b06 100644 (file)
@@ -98,7 +98,7 @@ static const struct hclge_hw_error hclge_igu_egu_tnl_int[] = {
          .reset_level = HNAE3_GLOBAL_RESET },
        { .int_msk = BIT(1), .msg = "rx_stp_fifo_overflow",
          .reset_level = HNAE3_GLOBAL_RESET },
-       { .int_msk = BIT(2), .msg = "rx_stp_fifo_undeflow",
+       { .int_msk = BIT(2), .msg = "rx_stp_fifo_underflow",
          .reset_level = HNAE3_GLOBAL_RESET },
        { .int_msk = BIT(3), .msg = "tx_buf_overflow",
          .reset_level = HNAE3_GLOBAL_RESET },
index cebd20f..5cb55ea 100644 (file)
@@ -1983,6 +1983,13 @@ static void __ibmvnic_reset(struct work_struct *work)
 
        rwi = get_next_rwi(adapter);
        while (rwi) {
+               if (adapter->state == VNIC_REMOVING ||
+                   adapter->state == VNIC_REMOVED) {
+                       kfree(rwi);
+                       rc = EBUSY;
+                       break;
+               }
+
                if (adapter->force_reset_recovery) {
                        adapter->force_reset_recovery = false;
                        rc = do_hard_reset(adapter, rwi, reset_state);
index 7882148..51c696b 100644 (file)
@@ -36,6 +36,7 @@
 #include <net/vxlan.h>
 #include <net/mpls.h>
 #include <net/xdp_sock.h>
+#include <net/xfrm.h>
 
 #include "ixgbe.h"
 #include "ixgbe_common.h"
@@ -2621,7 +2622,7 @@ adjust_by_size:
                /* 16K ints/sec to 9.2K ints/sec */
                avg_wire_size *= 15;
                avg_wire_size += 11452;
-       } else if (avg_wire_size <= 1980) {
+       } else if (avg_wire_size < 1968) {
                /* 9.2K ints/sec to 8K ints/sec */
                avg_wire_size *= 5;
                avg_wire_size += 22420;
@@ -2654,6 +2655,8 @@ adjust_by_size:
        case IXGBE_LINK_SPEED_2_5GB_FULL:
        case IXGBE_LINK_SPEED_1GB_FULL:
        case IXGBE_LINK_SPEED_10_FULL:
+               if (avg_wire_size > 8064)
+                       avg_wire_size = 8064;
                itr += DIV_ROUND_UP(avg_wire_size,
                                    IXGBE_ITR_ADAPTIVE_MIN_INC * 64) *
                       IXGBE_ITR_ADAPTIVE_MIN_INC;
@@ -8695,7 +8698,7 @@ netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *skb,
 #endif /* IXGBE_FCOE */
 
 #ifdef CONFIG_IXGBE_IPSEC
-       if (secpath_exists(skb) &&
+       if (xfrm_offload(skb) &&
            !ixgbe_ipsec_tx(tx_ring, first, &ipsec_tx))
                goto out_drop;
 #endif
index 6b60955..a3b6d8c 100644 (file)
@@ -633,19 +633,17 @@ static void ixgbe_clean_xdp_tx_buffer(struct ixgbe_ring *tx_ring,
 bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector,
                            struct ixgbe_ring *tx_ring, int napi_budget)
 {
+       u16 ntc = tx_ring->next_to_clean, ntu = tx_ring->next_to_use;
        unsigned int total_packets = 0, total_bytes = 0;
-       u32 i = tx_ring->next_to_clean, xsk_frames = 0;
-       unsigned int budget = q_vector->tx.work_limit;
        struct xdp_umem *umem = tx_ring->xsk_umem;
        union ixgbe_adv_tx_desc *tx_desc;
        struct ixgbe_tx_buffer *tx_bi;
-       bool xmit_done;
+       u32 xsk_frames = 0;
 
-       tx_bi = &tx_ring->tx_buffer_info[i];
-       tx_desc = IXGBE_TX_DESC(tx_ring, i);
-       i -= tx_ring->count;
+       tx_bi = &tx_ring->tx_buffer_info[ntc];
+       tx_desc = IXGBE_TX_DESC(tx_ring, ntc);
 
-       do {
+       while (ntc != ntu) {
                if (!(tx_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)))
                        break;
 
@@ -661,22 +659,18 @@ bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector,
 
                tx_bi++;
                tx_desc++;
-               i++;
-               if (unlikely(!i)) {
-                       i -= tx_ring->count;
+               ntc++;
+               if (unlikely(ntc == tx_ring->count)) {
+                       ntc = 0;
                        tx_bi = tx_ring->tx_buffer_info;
                        tx_desc = IXGBE_TX_DESC(tx_ring, 0);
                }
 
                /* issue prefetch for next Tx descriptor */
                prefetch(tx_desc);
+       }
 
-               /* update budget accounting */
-               budget--;
-       } while (likely(budget));
-
-       i += tx_ring->count;
-       tx_ring->next_to_clean = i;
+       tx_ring->next_to_clean = ntc;
 
        u64_stats_update_begin(&tx_ring->syncp);
        tx_ring->stats.bytes += total_bytes;
@@ -688,8 +682,7 @@ bool ixgbe_clean_xdp_tx_irq(struct ixgbe_q_vector *q_vector,
        if (xsk_frames)
                xsk_umem_complete_tx(umem, xsk_frames);
 
-       xmit_done = ixgbe_xmit_zc(tx_ring, q_vector->tx.work_limit);
-       return budget > 0 && xmit_done;
+       return ixgbe_xmit_zc(tx_ring, q_vector->tx.work_limit);
 }
 
 int ixgbe_xsk_async_xmit(struct net_device *dev, u32 qid)
index d2b41f9..72872d6 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/bpf.h>
 #include <linux/bpf_trace.h>
 #include <linux/atomic.h>
+#include <net/xfrm.h>
 
 #include "ixgbevf.h"
 
@@ -4161,7 +4162,7 @@ static int ixgbevf_xmit_frame_ring(struct sk_buff *skb,
        first->protocol = vlan_get_protocol(skb);
 
 #ifdef CONFIG_IXGBEVF_IPSEC
-       if (secpath_exists(skb) && !ixgbevf_ipsec_tx(tx_ring, first, &ipsec_tx))
+       if (xfrm_offload(skb) && !ixgbevf_ipsec_tx(tx_ring, first, &ipsec_tx))
                goto out_drop;
 #endif
        tso = ixgbevf_tso(tx_ring, first, &hdr_len, &ipsec_tx);
index a01c75e..e036387 100644 (file)
@@ -4931,6 +4931,13 @@ static const struct dmi_system_id msi_blacklist[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "P6T"),
                },
        },
+       {
+               .ident = "ASUS P6X",
+               .matches = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
+                       DMI_MATCH(DMI_BOARD_NAME, "P6X"),
+               },
+       },
        {}
 };
 
index 1f6e16d..309470e 100644 (file)
@@ -2240,7 +2240,7 @@ static int mlx4_validate_optimized_steering(struct mlx4_dev *dev)
        for (i = 1; i <= dev->caps.num_ports; i++) {
                if (mlx4_dev_port(dev, i, &port_cap)) {
                        mlx4_err(dev,
-                                "QUERY_DEV_CAP command failed, can't veify DMFS high rate steering.\n");
+                                "QUERY_DEV_CAP command failed, can't verify DMFS high rate steering.\n");
                } else if ((dev->caps.dmfs_high_steer_mode !=
                            MLX4_STEERING_DMFS_A0_DEFAULT) &&
                           (port_cap.dmfs_optimized_state ==
index 8b93101..7833dde 100644 (file)
@@ -109,13 +109,15 @@ build_progress_params(struct mlx5e_tx_wqe *wqe, u16 pc, u32 sqn,
 
 static void tx_fill_wi(struct mlx5e_txqsq *sq,
                       u16 pi, u8 num_wqebbs,
-                      skb_frag_t *resync_dump_frag)
+                      skb_frag_t *resync_dump_frag,
+                      u32 num_bytes)
 {
        struct mlx5e_tx_wqe_info *wi = &sq->db.wqe_info[pi];
 
        wi->skb              = NULL;
        wi->num_wqebbs       = num_wqebbs;
        wi->resync_dump_frag = resync_dump_frag;
+       wi->num_bytes        = num_bytes;
 }
 
 void mlx5e_ktls_tx_offload_set_pending(struct mlx5e_ktls_offload_context_tx *priv_tx)
@@ -143,7 +145,7 @@ post_static_params(struct mlx5e_txqsq *sq,
 
        umr_wqe = mlx5e_sq_fetch_wqe(sq, MLX5E_KTLS_STATIC_UMR_WQE_SZ, &pi);
        build_static_params(umr_wqe, sq->pc, sq->sqn, priv_tx, fence);
-       tx_fill_wi(sq, pi, MLX5E_KTLS_STATIC_WQEBBS, NULL);
+       tx_fill_wi(sq, pi, MLX5E_KTLS_STATIC_WQEBBS, NULL, 0);
        sq->pc += MLX5E_KTLS_STATIC_WQEBBS;
 }
 
@@ -157,7 +159,7 @@ post_progress_params(struct mlx5e_txqsq *sq,
 
        wqe = mlx5e_sq_fetch_wqe(sq, MLX5E_KTLS_PROGRESS_WQE_SZ, &pi);
        build_progress_params(wqe, sq->pc, sq->sqn, priv_tx, fence);
-       tx_fill_wi(sq, pi, MLX5E_KTLS_PROGRESS_WQEBBS, NULL);
+       tx_fill_wi(sq, pi, MLX5E_KTLS_PROGRESS_WQEBBS, NULL, 0);
        sq->pc += MLX5E_KTLS_PROGRESS_WQEBBS;
 }
 
@@ -248,43 +250,37 @@ tx_post_resync_params(struct mlx5e_txqsq *sq,
        mlx5e_ktls_tx_post_param_wqes(sq, priv_tx, skip_static_post, true);
 }
 
+struct mlx5e_dump_wqe {
+       struct mlx5_wqe_ctrl_seg ctrl;
+       struct mlx5_wqe_data_seg data;
+};
+
 static int
 tx_post_resync_dump(struct mlx5e_txqsq *sq, struct sk_buff *skb,
                    skb_frag_t *frag, u32 tisn, bool first)
 {
        struct mlx5_wqe_ctrl_seg *cseg;
-       struct mlx5_wqe_eth_seg  *eseg;
        struct mlx5_wqe_data_seg *dseg;
-       struct mlx5e_tx_wqe *wqe;
+       struct mlx5e_dump_wqe *wqe;
        dma_addr_t dma_addr = 0;
-       u16 ds_cnt, ds_cnt_inl;
        u8  num_wqebbs;
-       u16 pi, ihs;
+       u16 ds_cnt;
        int fsz;
-
-       ds_cnt = sizeof(*wqe) / MLX5_SEND_WQE_DS;
-       ihs    = eth_get_headlen(skb->dev, skb->data, skb_headlen(skb));
-       ds_cnt_inl = DIV_ROUND_UP(ihs - INL_HDR_START_SZ, MLX5_SEND_WQE_DS);
-       ds_cnt += ds_cnt_inl;
-       ds_cnt += 1; /* one frag */
+       u16 pi;
 
        wqe = mlx5e_sq_fetch_wqe(sq, sizeof(*wqe), &pi);
 
+       ds_cnt = sizeof(*wqe) / MLX5_SEND_WQE_DS;
        num_wqebbs = DIV_ROUND_UP(ds_cnt, MLX5_SEND_WQEBB_NUM_DS);
 
        cseg = &wqe->ctrl;
-       eseg = &wqe->eth;
-       dseg =  wqe->data;
+       dseg = &wqe->data;
 
        cseg->opmod_idx_opcode = cpu_to_be32((sq->pc << 8)  | MLX5_OPCODE_DUMP);
        cseg->qpn_ds           = cpu_to_be32((sq->sqn << 8) | ds_cnt);
        cseg->tisn             = cpu_to_be32(tisn << 8);
        cseg->fm_ce_se         = first ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0;
 
-       eseg->inline_hdr.sz = cpu_to_be16(ihs);
-       memcpy(eseg->inline_hdr.start, skb->data, ihs);
-       dseg += ds_cnt_inl;
-
        fsz = skb_frag_size(frag);
        dma_addr = skb_frag_dma_map(sq->pdev, frag, 0, fsz,
                                    DMA_TO_DEVICE);
@@ -296,7 +292,7 @@ tx_post_resync_dump(struct mlx5e_txqsq *sq, struct sk_buff *skb,
        dseg->byte_count = cpu_to_be32(fsz);
        mlx5e_dma_push(sq, dma_addr, fsz, MLX5E_DMA_MAP_PAGE);
 
-       tx_fill_wi(sq, pi, num_wqebbs, frag);
+       tx_fill_wi(sq, pi, num_wqebbs, frag, fsz);
        sq->pc += num_wqebbs;
 
        WARN(num_wqebbs > MLX5E_KTLS_MAX_DUMP_WQEBBS,
@@ -323,7 +319,7 @@ static void tx_post_fence_nop(struct mlx5e_txqsq *sq)
        struct mlx5_wq_cyc *wq = &sq->wq;
        u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
 
-       tx_fill_wi(sq, pi, 1, NULL);
+       tx_fill_wi(sq, pi, 1, NULL, 0);
 
        mlx5e_post_nop_fence(wq, sq->sqn, &sq->pc);
 }
index 9314777..d685122 100644 (file)
@@ -590,7 +590,8 @@ mlx5_fw_fatal_reporter_dump(struct devlink_health_reporter *reporter,
                        data_size = crdump_size - offset;
                else
                        data_size = MLX5_CR_DUMP_CHUNK_SIZE;
-               err = devlink_fmsg_binary_put(fmsg, cr_data, data_size);
+               err = devlink_fmsg_binary_put(fmsg, (char *)cr_data + offset,
+                                             data_size);
                if (err)
                        goto free_data;
        }
@@ -700,6 +701,16 @@ static void poll_health(struct timer_list *t)
        if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
                goto out;
 
+       fatal_error = check_fatal_sensors(dev);
+
+       if (fatal_error && !health->fatal_error) {
+               mlx5_core_err(dev, "Fatal error %u detected\n", fatal_error);
+               dev->priv.health.fatal_error = fatal_error;
+               print_health_info(dev);
+               mlx5_trigger_health_work(dev);
+               goto out;
+       }
+
        count = ioread32be(health->health_counter);
        if (count == health->prev)
                ++health->miss_counter;
@@ -718,15 +729,6 @@ static void poll_health(struct timer_list *t)
        if (health->synd && health->synd != prev_synd)
                queue_work(health->wq, &health->report_work);
 
-       fatal_error = check_fatal_sensors(dev);
-
-       if (fatal_error && !health->fatal_error) {
-               mlx5_core_err(dev, "Fatal error %u detected\n", fatal_error);
-               dev->priv.health.fatal_error = fatal_error;
-               print_health_info(dev);
-               mlx5_trigger_health_work(dev);
-       }
-
 out:
        mod_timer(&health->timer, get_next_poll_jiffies());
 }
index 90a8c6b..b9c4d48 100644 (file)
@@ -6,8 +6,7 @@
 config NET_VENDOR_MICREL
        bool "Micrel devices"
        default y
-       depends on (HAS_IOMEM && DMA_ENGINE) || SPI || PCI || HAS_IOMEM || \
-                  (ARM && ARCH_KS8695)
+       depends on (HAS_IOMEM && DMA_ENGINE) || SPI || PCI || HAS_IOMEM
        ---help---
          If you have a network (Ethernet) card belonging to this class, say Y.
 
@@ -18,14 +17,6 @@ config NET_VENDOR_MICREL
 
 if NET_VENDOR_MICREL
 
-config ARM_KS8695_ETHER
-       tristate "KS8695 Ethernet support"
-       depends on ARM && ARCH_KS8695
-       select MII
-       ---help---
-         If you wish to compile a kernel for the KS8695 and want to
-         use the internal ethernet then you should answer Y to this.
-
 config KS8842
        tristate "Micrel KSZ8841/42 with generic bus interface"
        depends on HAS_IOMEM && DMA_ENGINE
index 848fc1c..6d8ac55 100644 (file)
@@ -3,7 +3,6 @@
 # Makefile for the Micrel network device drivers.
 #
 
-obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o
 obj-$(CONFIG_KS8842) += ks8842.o
 obj-$(CONFIG_KS8851) += ks8851.o
 obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o
diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c
deleted file mode 100644 (file)
index 1390ef5..0000000
+++ /dev/null
@@ -1,1632 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Micrel KS8695 (Centaur) Ethernet.
- *
- * Copyright 2008 Simtec Electronics
- *               Daniel Silverstone <dsilvers@simtec.co.uk>
- *               Vincent Sanders <vince@simtec.co.uk>
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/module.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/interrupt.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
-#include <linux/crc32.h>
-#include <linux/mii.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <asm/irq.h>
-
-#include <mach/regs-switch.h>
-#include <mach/regs-misc.h>
-#include <asm/mach/irq.h>
-#include <mach/regs-irq.h>
-
-#include "ks8695net.h"
-
-#define MODULENAME     "ks8695_ether"
-#define MODULEVERSION  "1.02"
-
-/*
- * Transmit and device reset timeout, default 5 seconds.
- */
-static int watchdog = 5000;
-
-/* Hardware structures */
-
-/**
- *     struct rx_ring_desc - Receive descriptor ring element
- *     @status: The status of the descriptor element (E.g. who owns it)
- *     @length: The number of bytes in the block pointed to by data_ptr
- *     @data_ptr: The physical address of the data block to receive into
- *     @next_desc: The physical address of the next descriptor element.
- */
-struct rx_ring_desc {
-       __le32  status;
-       __le32  length;
-       __le32  data_ptr;
-       __le32  next_desc;
-};
-
-/**
- *     struct tx_ring_desc - Transmit descriptor ring element
- *     @owner: Who owns the descriptor
- *     @status: The number of bytes in the block pointed to by data_ptr
- *     @data_ptr: The physical address of the data block to receive into
- *     @next_desc: The physical address of the next descriptor element.
- */
-struct tx_ring_desc {
-       __le32  owner;
-       __le32  status;
-       __le32  data_ptr;
-       __le32  next_desc;
-};
-
-/**
- *     struct ks8695_skbuff - sk_buff wrapper for rx/tx rings.
- *     @skb: The buffer in the ring
- *     @dma_ptr: The mapped DMA pointer of the buffer
- *     @length: The number of bytes mapped to dma_ptr
- */
-struct ks8695_skbuff {
-       struct sk_buff  *skb;
-       dma_addr_t      dma_ptr;
-       u32             length;
-};
-
-/* Private device structure */
-
-#define MAX_TX_DESC 8
-#define MAX_TX_DESC_MASK 0x7
-#define MAX_RX_DESC 16
-#define MAX_RX_DESC_MASK 0xf
-
-/*napi_weight have better more than rx DMA buffers*/
-#define NAPI_WEIGHT   64
-
-#define MAX_RXBUF_SIZE 0x700
-
-#define TX_RING_DMA_SIZE (sizeof(struct tx_ring_desc) * MAX_TX_DESC)
-#define RX_RING_DMA_SIZE (sizeof(struct rx_ring_desc) * MAX_RX_DESC)
-#define RING_DMA_SIZE (TX_RING_DMA_SIZE + RX_RING_DMA_SIZE)
-
-/**
- *     enum ks8695_dtype - Device type
- *     @KS8695_DTYPE_WAN: This device is a WAN interface
- *     @KS8695_DTYPE_LAN: This device is a LAN interface
- *     @KS8695_DTYPE_HPNA: This device is an HPNA interface
- */
-enum ks8695_dtype {
-       KS8695_DTYPE_WAN,
-       KS8695_DTYPE_LAN,
-       KS8695_DTYPE_HPNA,
-};
-
-/**
- *     struct ks8695_priv - Private data for the KS8695 Ethernet
- *     @in_suspend: Flag to indicate if we're suspending/resuming
- *     @ndev: The net_device for this interface
- *     @dev: The platform device object for this interface
- *     @dtype: The type of this device
- *     @io_regs: The ioremapped registers for this interface
- *      @napi : Add support NAPI for Rx
- *     @rx_irq_name: The textual name of the RX IRQ from the platform data
- *     @tx_irq_name: The textual name of the TX IRQ from the platform data
- *     @link_irq_name: The textual name of the link IRQ from the
- *                     platform data if available
- *     @rx_irq: The IRQ number for the RX IRQ
- *     @tx_irq: The IRQ number for the TX IRQ
- *     @link_irq: The IRQ number for the link IRQ if available
- *     @regs_req: The resource request for the registers region
- *     @phyiface_req: The resource request for the phy/switch region
- *                    if available
- *     @phyiface_regs: The ioremapped registers for the phy/switch if available
- *     @ring_base: The base pointer of the dma coherent memory for the rings
- *     @ring_base_dma: The DMA mapped equivalent of ring_base
- *     @tx_ring: The pointer in ring_base of the TX ring
- *     @tx_ring_used: The number of slots in the TX ring which are occupied
- *     @tx_ring_next_slot: The next slot to fill in the TX ring
- *     @tx_ring_dma: The DMA mapped equivalent of tx_ring
- *     @tx_buffers: The sk_buff mappings for the TX ring
- *     @txq_lock: A lock to protect the tx_buffers tx_ring_used etc variables
- *     @rx_ring: The pointer in ring_base of the RX ring
- *     @rx_ring_dma: The DMA mapped equivalent of rx_ring
- *     @rx_buffers: The sk_buff mappings for the RX ring
- *     @next_rx_desc_read: The next RX descriptor to read from on IRQ
- *      @rx_lock: A lock to protect Rx irq function
- *     @msg_enable: The flags for which messages to emit
- */
-struct ks8695_priv {
-       int in_suspend;
-       struct net_device *ndev;
-       struct device *dev;
-       enum ks8695_dtype dtype;
-       void __iomem *io_regs;
-
-       struct napi_struct      napi;
-
-       const char *rx_irq_name, *tx_irq_name, *link_irq_name;
-       int rx_irq, tx_irq, link_irq;
-
-       struct resource *regs_req, *phyiface_req;
-       void __iomem *phyiface_regs;
-
-       void *ring_base;
-       dma_addr_t ring_base_dma;
-
-       struct tx_ring_desc *tx_ring;
-       int tx_ring_used;
-       int tx_ring_next_slot;
-       dma_addr_t tx_ring_dma;
-       struct ks8695_skbuff tx_buffers[MAX_TX_DESC];
-       spinlock_t txq_lock;
-
-       struct rx_ring_desc *rx_ring;
-       dma_addr_t rx_ring_dma;
-       struct ks8695_skbuff rx_buffers[MAX_RX_DESC];
-       int next_rx_desc_read;
-       spinlock_t rx_lock;
-
-       int msg_enable;
-};
-
-/* Register access */
-
-/**
- *     ks8695_readreg - Read from a KS8695 ethernet register
- *     @ksp: The device to read from
- *     @reg: The register to read
- */
-static inline u32
-ks8695_readreg(struct ks8695_priv *ksp, int reg)
-{
-       return readl(ksp->io_regs + reg);
-}
-
-/**
- *     ks8695_writereg - Write to a KS8695 ethernet register
- *     @ksp: The device to write to
- *     @reg: The register to write
- *     @value: The value to write to the register
- */
-static inline void
-ks8695_writereg(struct ks8695_priv *ksp, int reg, u32 value)
-{
-       writel(value, ksp->io_regs + reg);
-}
-
-/* Utility functions */
-
-/**
- *     ks8695_port_type - Retrieve port-type as user-friendly string
- *     @ksp: The device to return the type for
- *
- *     Returns a string indicating which of the WAN, LAN or HPNA
- *     ports this device is likely to represent.
- */
-static const char *
-ks8695_port_type(struct ks8695_priv *ksp)
-{
-       switch (ksp->dtype) {
-       case KS8695_DTYPE_LAN:
-               return "LAN";
-       case KS8695_DTYPE_WAN:
-               return "WAN";
-       case KS8695_DTYPE_HPNA:
-               return "HPNA";
-       }
-
-       return "UNKNOWN";
-}
-
-/**
- *     ks8695_update_mac - Update the MAC registers in the device
- *     @ksp: The device to update
- *
- *     Updates the MAC registers in the KS8695 device from the address in the
- *     net_device structure associated with this interface.
- */
-static void
-ks8695_update_mac(struct ks8695_priv *ksp)
-{
-       /* Update the HW with the MAC from the net_device */
-       struct net_device *ndev = ksp->ndev;
-       u32 machigh, maclow;
-
-       maclow  = ((ndev->dev_addr[2] << 24) | (ndev->dev_addr[3] << 16) |
-                  (ndev->dev_addr[4] <<  8) | (ndev->dev_addr[5] <<  0));
-       machigh = ((ndev->dev_addr[0] <<  8) | (ndev->dev_addr[1] <<  0));
-
-       ks8695_writereg(ksp, KS8695_MAL, maclow);
-       ks8695_writereg(ksp, KS8695_MAH, machigh);
-
-}
-
-/**
- *     ks8695_refill_rxbuffers - Re-fill the RX buffer ring
- *     @ksp: The device to refill
- *
- *     Iterates the RX ring of the device looking for empty slots.
- *     For each empty slot, we allocate and map a new SKB and give it
- *     to the hardware.
- *     This can be called from interrupt context safely.
- */
-static void
-ks8695_refill_rxbuffers(struct ks8695_priv *ksp)
-{
-       /* Run around the RX ring, filling in any missing sk_buff's */
-       int buff_n;
-
-       for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
-               if (!ksp->rx_buffers[buff_n].skb) {
-                       struct sk_buff *skb =
-                               netdev_alloc_skb(ksp->ndev, MAX_RXBUF_SIZE);
-                       dma_addr_t mapping;
-
-                       ksp->rx_buffers[buff_n].skb = skb;
-                       if (skb == NULL) {
-                               /* Failed to allocate one, perhaps
-                                * we'll try again later.
-                                */
-                               break;
-                       }
-
-                       mapping = dma_map_single(ksp->dev, skb->data,
-                                                MAX_RXBUF_SIZE,
-                                                DMA_FROM_DEVICE);
-                       if (unlikely(dma_mapping_error(ksp->dev, mapping))) {
-                               /* Failed to DMA map this SKB, try later */
-                               dev_kfree_skb_irq(skb);
-                               ksp->rx_buffers[buff_n].skb = NULL;
-                               break;
-                       }
-                       ksp->rx_buffers[buff_n].dma_ptr = mapping;
-                       ksp->rx_buffers[buff_n].length = MAX_RXBUF_SIZE;
-
-                       /* Record this into the DMA ring */
-                       ksp->rx_ring[buff_n].data_ptr = cpu_to_le32(mapping);
-                       ksp->rx_ring[buff_n].length =
-                               cpu_to_le32(MAX_RXBUF_SIZE);
-
-                       wmb();
-
-                       /* And give ownership over to the hardware */
-                       ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
-               }
-       }
-}
-
-/* Maximum number of multicast addresses which the KS8695 HW supports */
-#define KS8695_NR_ADDRESSES    16
-
-/**
- *     ks8695_init_partial_multicast - Init the mcast addr registers
- *     @ksp: The device to initialise
- *     @addr: The multicast address list to use
- *     @nr_addr: The number of addresses in the list
- *
- *     This routine is a helper for ks8695_set_multicast - it writes
- *     the additional-address registers in the KS8695 ethernet device
- *     and cleans up any others left behind.
- */
-static void
-ks8695_init_partial_multicast(struct ks8695_priv *ksp,
-                             struct net_device *ndev)
-{
-       u32 low, high;
-       int i;
-       struct netdev_hw_addr *ha;
-
-       i = 0;
-       netdev_for_each_mc_addr(ha, ndev) {
-               /* Ran out of space in chip? */
-               BUG_ON(i == KS8695_NR_ADDRESSES);
-
-               low = (ha->addr[2] << 24) | (ha->addr[3] << 16) |
-                     (ha->addr[4] << 8) | (ha->addr[5]);
-               high = (ha->addr[0] << 8) | (ha->addr[1]);
-
-               ks8695_writereg(ksp, KS8695_AAL_(i), low);
-               ks8695_writereg(ksp, KS8695_AAH_(i), AAH_E | high);
-               i++;
-       }
-
-       /* Clear the remaining Additional Station Addresses */
-       for (; i < KS8695_NR_ADDRESSES; i++) {
-               ks8695_writereg(ksp, KS8695_AAL_(i), 0);
-               ks8695_writereg(ksp, KS8695_AAH_(i), 0);
-       }
-}
-
-/* Interrupt handling */
-
-/**
- *     ks8695_tx_irq - Transmit IRQ handler
- *     @irq: The IRQ which went off (ignored)
- *     @dev_id: The net_device for the interrupt
- *
- *     Process the TX ring, clearing out any transmitted slots.
- *     Allows the net_device to pass us new packets once slots are
- *     freed.
- */
-static irqreturn_t
-ks8695_tx_irq(int irq, void *dev_id)
-{
-       struct net_device *ndev = (struct net_device *)dev_id;
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-       int buff_n;
-
-       for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) {
-               if (ksp->tx_buffers[buff_n].skb &&
-                   !(ksp->tx_ring[buff_n].owner & cpu_to_le32(TDES_OWN))) {
-                       rmb();
-                       /* An SKB which is not owned by HW is present */
-                       /* Update the stats for the net_device */
-                       ndev->stats.tx_packets++;
-                       ndev->stats.tx_bytes += ksp->tx_buffers[buff_n].length;
-
-                       /* Free the packet from the ring */
-                       ksp->tx_ring[buff_n].data_ptr = 0;
-
-                       /* Free the sk_buff */
-                       dma_unmap_single(ksp->dev,
-                                        ksp->tx_buffers[buff_n].dma_ptr,
-                                        ksp->tx_buffers[buff_n].length,
-                                        DMA_TO_DEVICE);
-                       dev_consume_skb_irq(ksp->tx_buffers[buff_n].skb);
-                       ksp->tx_buffers[buff_n].skb = NULL;
-                       ksp->tx_ring_used--;
-               }
-       }
-
-       netif_wake_queue(ndev);
-
-       return IRQ_HANDLED;
-}
-
-/**
- *     ks8695_get_rx_enable_bit - Get rx interrupt enable/status bit
- *     @ksp: Private data for the KS8695 Ethernet
- *
- *    For KS8695 document:
- *    Interrupt Enable Register (offset 0xE204)
- *        Bit29 : WAN MAC Receive Interrupt Enable
- *        Bit16 : LAN MAC Receive Interrupt Enable
- *    Interrupt Status Register (Offset 0xF208)
- *        Bit29: WAN MAC Receive Status
- *        Bit16: LAN MAC Receive Status
- *    So, this Rx interrupt enable/status bit number is equal
- *    as Rx IRQ number.
- */
-static inline u32 ks8695_get_rx_enable_bit(struct ks8695_priv *ksp)
-{
-       return ksp->rx_irq;
-}
-
-/**
- *     ks8695_rx_irq - Receive IRQ handler
- *     @irq: The IRQ which went off (ignored)
- *     @dev_id: The net_device for the interrupt
- *
- *     Inform NAPI that packet reception needs to be scheduled
- */
-
-static irqreturn_t
-ks8695_rx_irq(int irq, void *dev_id)
-{
-       struct net_device *ndev = (struct net_device *)dev_id;
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-
-       spin_lock(&ksp->rx_lock);
-
-       if (napi_schedule_prep(&ksp->napi)) {
-               unsigned long status = readl(KS8695_IRQ_VA + KS8695_INTEN);
-               unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp);
-               /*disable rx interrupt*/
-               status &= ~mask_bit;
-               writel(status , KS8695_IRQ_VA + KS8695_INTEN);
-               __napi_schedule(&ksp->napi);
-       }
-
-       spin_unlock(&ksp->rx_lock);
-       return IRQ_HANDLED;
-}
-
-/**
- *     ks8695_rx - Receive packets called by NAPI poll method
- *     @ksp: Private data for the KS8695 Ethernet
- *     @budget: Number of packets allowed to process
- */
-static int ks8695_rx(struct ks8695_priv *ksp, int budget)
-{
-       struct net_device *ndev = ksp->ndev;
-       struct sk_buff *skb;
-       int buff_n;
-       u32 flags;
-       int pktlen;
-       int received = 0;
-
-       buff_n = ksp->next_rx_desc_read;
-       while (received < budget
-                       && ksp->rx_buffers[buff_n].skb
-                       && (!(ksp->rx_ring[buff_n].status &
-                                       cpu_to_le32(RDES_OWN)))) {
-                       rmb();
-                       flags = le32_to_cpu(ksp->rx_ring[buff_n].status);
-
-                       /* Found an SKB which we own, this means we
-                        * received a packet
-                        */
-                       if ((flags & (RDES_FS | RDES_LS)) !=
-                           (RDES_FS | RDES_LS)) {
-                               /* This packet is not the first and
-                                * the last segment.  Therefore it is
-                                * a "spanning" packet and we can't
-                                * handle it
-                                */
-                               goto rx_failure;
-                       }
-
-                       if (flags & (RDES_ES | RDES_RE)) {
-                               /* It's an error packet */
-                               ndev->stats.rx_errors++;
-                               if (flags & RDES_TL)
-                                       ndev->stats.rx_length_errors++;
-                               if (flags & RDES_RF)
-                                       ndev->stats.rx_length_errors++;
-                               if (flags & RDES_CE)
-                                       ndev->stats.rx_crc_errors++;
-                               if (flags & RDES_RE)
-                                       ndev->stats.rx_missed_errors++;
-
-                               goto rx_failure;
-                       }
-
-                       pktlen = flags & RDES_FLEN;
-                       pktlen -= 4; /* Drop the CRC */
-
-                       /* Retrieve the sk_buff */
-                       skb = ksp->rx_buffers[buff_n].skb;
-
-                       /* Clear it from the ring */
-                       ksp->rx_buffers[buff_n].skb = NULL;
-                       ksp->rx_ring[buff_n].data_ptr = 0;
-
-                       /* Unmap the SKB */
-                       dma_unmap_single(ksp->dev,
-                                        ksp->rx_buffers[buff_n].dma_ptr,
-                                        ksp->rx_buffers[buff_n].length,
-                                        DMA_FROM_DEVICE);
-
-                       /* Relinquish the SKB to the network layer */
-                       skb_put(skb, pktlen);
-                       skb->protocol = eth_type_trans(skb, ndev);
-                       napi_gro_receive(&ksp->napi, skb);
-
-                       /* Record stats */
-                       ndev->stats.rx_packets++;
-                       ndev->stats.rx_bytes += pktlen;
-                       goto rx_finished;
-
-rx_failure:
-                       /* This ring entry is an error, but we can
-                        * re-use the skb
-                        */
-                       /* Give the ring entry back to the hardware */
-                       ksp->rx_ring[buff_n].status = cpu_to_le32(RDES_OWN);
-rx_finished:
-                       received++;
-                       buff_n = (buff_n + 1) & MAX_RX_DESC_MASK;
-       }
-
-       /* And note which RX descriptor we last did */
-       ksp->next_rx_desc_read = buff_n;
-
-       /* And refill the buffers */
-       ks8695_refill_rxbuffers(ksp);
-
-       /* Kick the RX DMA engine, in case it became suspended */
-       ks8695_writereg(ksp, KS8695_DRSC, 0);
-
-       return received;
-}
-
-
-/**
- *     ks8695_poll - Receive packet by NAPI poll method
- *     @ksp: Private data for the KS8695 Ethernet
- *     @budget: The remaining number packets for network subsystem
- *
- *     Invoked by the network core when it requests for new
- *     packets from the driver
- */
-static int ks8695_poll(struct napi_struct *napi, int budget)
-{
-       struct ks8695_priv *ksp = container_of(napi, struct ks8695_priv, napi);
-       unsigned long isr = readl(KS8695_IRQ_VA + KS8695_INTEN);
-       unsigned long mask_bit = 1 << ks8695_get_rx_enable_bit(ksp);
-       int work_done;
-
-       work_done = ks8695_rx(ksp, budget);
-
-       if (work_done < budget && napi_complete_done(napi, work_done)) {
-               unsigned long flags;
-
-               spin_lock_irqsave(&ksp->rx_lock, flags);
-               /* enable rx interrupt */
-               writel(isr | mask_bit, KS8695_IRQ_VA + KS8695_INTEN);
-               spin_unlock_irqrestore(&ksp->rx_lock, flags);
-       }
-       return work_done;
-}
-
-/**
- *     ks8695_link_irq - Link change IRQ handler
- *     @irq: The IRQ which went off (ignored)
- *     @dev_id: The net_device for the interrupt
- *
- *     The WAN interface can generate an IRQ when the link changes,
- *     report this to the net layer and the user.
- */
-static irqreturn_t
-ks8695_link_irq(int irq, void *dev_id)
-{
-       struct net_device *ndev = (struct net_device *)dev_id;
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-       u32 ctrl;
-
-       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-       if (ctrl & WMC_WLS) {
-               netif_carrier_on(ndev);
-               if (netif_msg_link(ksp))
-                       dev_info(ksp->dev,
-                                "%s: Link is now up (10%sMbps/%s-duplex)\n",
-                                ndev->name,
-                                (ctrl & WMC_WSS) ? "0" : "",
-                                (ctrl & WMC_WDS) ? "Full" : "Half");
-       } else {
-               netif_carrier_off(ndev);
-               if (netif_msg_link(ksp))
-                       dev_info(ksp->dev, "%s: Link is now down.\n",
-                                ndev->name);
-       }
-
-       return IRQ_HANDLED;
-}
-
-
-/* KS8695 Device functions */
-
-/**
- *     ks8695_reset - Reset a KS8695 ethernet interface
- *     @ksp: The interface to reset
- *
- *     Perform an engine reset of the interface and re-program it
- *     with sensible defaults.
- */
-static void
-ks8695_reset(struct ks8695_priv *ksp)
-{
-       int reset_timeout = watchdog;
-       /* Issue the reset via the TX DMA control register */
-       ks8695_writereg(ksp, KS8695_DTXC, DTXC_TRST);
-       while (reset_timeout--) {
-               if (!(ks8695_readreg(ksp, KS8695_DTXC) & DTXC_TRST))
-                       break;
-               msleep(1);
-       }
-
-       if (reset_timeout < 0) {
-               dev_crit(ksp->dev,
-                        "Timeout waiting for DMA engines to reset\n");
-               /* And blithely carry on */
-       }
-
-       /* Definitely wait long enough before attempting to program
-        * the engines
-        */
-       msleep(10);
-
-       /* RX: unicast and broadcast */
-       ks8695_writereg(ksp, KS8695_DRXC, DRXC_RU | DRXC_RB);
-       /* TX: pad and add CRC */
-       ks8695_writereg(ksp, KS8695_DTXC, DTXC_TEP | DTXC_TAC);
-}
-
-/**
- *     ks8695_shutdown - Shut down a KS8695 ethernet interface
- *     @ksp: The interface to shut down
- *
- *     This disables packet RX/TX, cleans up IRQs, drains the rings,
- *     and basically places the interface into a clean shutdown
- *     state.
- */
-static void
-ks8695_shutdown(struct ks8695_priv *ksp)
-{
-       u32 ctrl;
-       int buff_n;
-
-       /* Disable packet transmission */
-       ctrl = ks8695_readreg(ksp, KS8695_DTXC);
-       ks8695_writereg(ksp, KS8695_DTXC, ctrl & ~DTXC_TE);
-
-       /* Disable packet reception */
-       ctrl = ks8695_readreg(ksp, KS8695_DRXC);
-       ks8695_writereg(ksp, KS8695_DRXC, ctrl & ~DRXC_RE);
-
-       /* Release the IRQs */
-       free_irq(ksp->rx_irq, ksp->ndev);
-       free_irq(ksp->tx_irq, ksp->ndev);
-       if (ksp->link_irq != -1)
-               free_irq(ksp->link_irq, ksp->ndev);
-
-       /* Throw away any pending TX packets */
-       for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) {
-               if (ksp->tx_buffers[buff_n].skb) {
-                       /* Remove this SKB from the TX ring */
-                       ksp->tx_ring[buff_n].owner = 0;
-                       ksp->tx_ring[buff_n].status = 0;
-                       ksp->tx_ring[buff_n].data_ptr = 0;
-
-                       /* Unmap and bin this SKB */
-                       dma_unmap_single(ksp->dev,
-                                        ksp->tx_buffers[buff_n].dma_ptr,
-                                        ksp->tx_buffers[buff_n].length,
-                                        DMA_TO_DEVICE);
-                       dev_kfree_skb_irq(ksp->tx_buffers[buff_n].skb);
-                       ksp->tx_buffers[buff_n].skb = NULL;
-               }
-       }
-
-       /* Purge the RX buffers */
-       for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
-               if (ksp->rx_buffers[buff_n].skb) {
-                       /* Remove the SKB from the RX ring */
-                       ksp->rx_ring[buff_n].status = 0;
-                       ksp->rx_ring[buff_n].data_ptr = 0;
-
-                       /* Unmap and bin the SKB */
-                       dma_unmap_single(ksp->dev,
-                                        ksp->rx_buffers[buff_n].dma_ptr,
-                                        ksp->rx_buffers[buff_n].length,
-                                        DMA_FROM_DEVICE);
-                       dev_kfree_skb_irq(ksp->rx_buffers[buff_n].skb);
-                       ksp->rx_buffers[buff_n].skb = NULL;
-               }
-       }
-}
-
-
-/**
- *     ks8695_setup_irq - IRQ setup helper function
- *     @irq: The IRQ number to claim
- *     @irq_name: The name to give the IRQ claimant
- *     @handler: The function to call to handle the IRQ
- *     @ndev: The net_device to pass in as the dev_id argument to the handler
- *
- *     Return 0 on success.
- */
-static int
-ks8695_setup_irq(int irq, const char *irq_name,
-                irq_handler_t handler, struct net_device *ndev)
-{
-       int ret;
-
-       ret = request_irq(irq, handler, IRQF_SHARED, irq_name, ndev);
-
-       if (ret) {
-               dev_err(&ndev->dev, "failure to request IRQ %d\n", irq);
-               return ret;
-       }
-
-       return 0;
-}
-
-/**
- *     ks8695_init_net - Initialise a KS8695 ethernet interface
- *     @ksp: The interface to initialise
- *
- *     This routine fills the RX ring, initialises the DMA engines,
- *     allocates the IRQs and then starts the packet TX and RX
- *     engines.
- */
-static int
-ks8695_init_net(struct ks8695_priv *ksp)
-{
-       int ret;
-       u32 ctrl;
-
-       ks8695_refill_rxbuffers(ksp);
-
-       /* Initialise the DMA engines */
-       ks8695_writereg(ksp, KS8695_RDLB, (u32) ksp->rx_ring_dma);
-       ks8695_writereg(ksp, KS8695_TDLB, (u32) ksp->tx_ring_dma);
-
-       /* Request the IRQs */
-       ret = ks8695_setup_irq(ksp->rx_irq, ksp->rx_irq_name,
-                              ks8695_rx_irq, ksp->ndev);
-       if (ret)
-               return ret;
-       ret = ks8695_setup_irq(ksp->tx_irq, ksp->tx_irq_name,
-                              ks8695_tx_irq, ksp->ndev);
-       if (ret)
-               return ret;
-       if (ksp->link_irq != -1) {
-               ret = ks8695_setup_irq(ksp->link_irq, ksp->link_irq_name,
-                                      ks8695_link_irq, ksp->ndev);
-               if (ret)
-                       return ret;
-       }
-
-       /* Set up the ring indices */
-       ksp->next_rx_desc_read = 0;
-       ksp->tx_ring_next_slot = 0;
-       ksp->tx_ring_used = 0;
-
-       /* Bring up transmission */
-       ctrl = ks8695_readreg(ksp, KS8695_DTXC);
-       /* Enable packet transmission */
-       ks8695_writereg(ksp, KS8695_DTXC, ctrl | DTXC_TE);
-
-       /* Bring up the reception */
-       ctrl = ks8695_readreg(ksp, KS8695_DRXC);
-       /* Enable packet reception */
-       ks8695_writereg(ksp, KS8695_DRXC, ctrl | DRXC_RE);
-       /* And start the DMA engine */
-       ks8695_writereg(ksp, KS8695_DRSC, 0);
-
-       /* All done */
-       return 0;
-}
-
-/**
- *     ks8695_release_device - HW resource release for KS8695 e-net
- *     @ksp: The device to be freed
- *
- *     This unallocates io memory regions, dma-coherent regions etc
- *     which were allocated in ks8695_probe.
- */
-static void
-ks8695_release_device(struct ks8695_priv *ksp)
-{
-       /* Unmap the registers */
-       iounmap(ksp->io_regs);
-       if (ksp->phyiface_regs)
-               iounmap(ksp->phyiface_regs);
-
-       /* And release the request */
-       release_resource(ksp->regs_req);
-       kfree(ksp->regs_req);
-       if (ksp->phyiface_req) {
-               release_resource(ksp->phyiface_req);
-               kfree(ksp->phyiface_req);
-       }
-
-       /* Free the ring buffers */
-       dma_free_coherent(ksp->dev, RING_DMA_SIZE,
-                         ksp->ring_base, ksp->ring_base_dma);
-}
-
-/* Ethtool support */
-
-/**
- *     ks8695_get_msglevel - Get the messages enabled for emission
- *     @ndev: The network device to read from
- */
-static u32
-ks8695_get_msglevel(struct net_device *ndev)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-
-       return ksp->msg_enable;
-}
-
-/**
- *     ks8695_set_msglevel - Set the messages enabled for emission
- *     @ndev: The network device to configure
- *     @value: The messages to set for emission
- */
-static void
-ks8695_set_msglevel(struct net_device *ndev, u32 value)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-
-       ksp->msg_enable = value;
-}
-
-/**
- *     ks8695_wan_get_link_ksettings - Get device-specific settings.
- *     @ndev: The network device to read settings from
- *     @cmd: The ethtool structure to read into
- */
-static int
-ks8695_wan_get_link_ksettings(struct net_device *ndev,
-                             struct ethtool_link_ksettings *cmd)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-       u32 ctrl;
-       u32 supported, advertising;
-
-       /* All ports on the KS8695 support these... */
-       supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
-                         SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
-                         SUPPORTED_TP | SUPPORTED_MII);
-
-       advertising = ADVERTISED_TP | ADVERTISED_MII;
-       cmd->base.port = PORT_MII;
-       supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause);
-       cmd->base.phy_address = 0;
-
-       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-       if ((ctrl & WMC_WAND) == 0) {
-               /* auto-negotiation is enabled */
-               advertising |= ADVERTISED_Autoneg;
-               if (ctrl & WMC_WANA100F)
-                       advertising |= ADVERTISED_100baseT_Full;
-               if (ctrl & WMC_WANA100H)
-                       advertising |= ADVERTISED_100baseT_Half;
-               if (ctrl & WMC_WANA10F)
-                       advertising |= ADVERTISED_10baseT_Full;
-               if (ctrl & WMC_WANA10H)
-                       advertising |= ADVERTISED_10baseT_Half;
-               if (ctrl & WMC_WANAP)
-                       advertising |= ADVERTISED_Pause;
-               cmd->base.autoneg = AUTONEG_ENABLE;
-
-               cmd->base.speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10;
-               cmd->base.duplex = (ctrl & WMC_WDS) ?
-                       DUPLEX_FULL : DUPLEX_HALF;
-       } else {
-               /* auto-negotiation is disabled */
-               cmd->base.autoneg = AUTONEG_DISABLE;
-
-               cmd->base.speed = (ctrl & WMC_WANF100) ?
-                                           SPEED_100 : SPEED_10;
-               cmd->base.duplex = (ctrl & WMC_WANFF) ?
-                       DUPLEX_FULL : DUPLEX_HALF;
-       }
-
-       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;
-}
-
-/**
- *     ks8695_wan_set_link_ksettings - Set device-specific settings.
- *     @ndev: The network device to configure
- *     @cmd: The settings to configure
- */
-static int
-ks8695_wan_set_link_ksettings(struct net_device *ndev,
-                             const struct ethtool_link_ksettings *cmd)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-       u32 ctrl;
-       u32 advertising;
-
-       ethtool_convert_link_mode_to_legacy_u32(&advertising,
-                                               cmd->link_modes.advertising);
-
-       if ((cmd->base.speed != SPEED_10) && (cmd->base.speed != SPEED_100))
-               return -EINVAL;
-       if ((cmd->base.duplex != DUPLEX_HALF) &&
-           (cmd->base.duplex != DUPLEX_FULL))
-               return -EINVAL;
-       if (cmd->base.port != PORT_MII)
-               return -EINVAL;
-       if ((cmd->base.autoneg != AUTONEG_DISABLE) &&
-           (cmd->base.autoneg != AUTONEG_ENABLE))
-               return -EINVAL;
-
-       if (cmd->base.autoneg == AUTONEG_ENABLE) {
-               if ((advertising & (ADVERTISED_10baseT_Half |
-                               ADVERTISED_10baseT_Full |
-                               ADVERTISED_100baseT_Half |
-                               ADVERTISED_100baseT_Full)) == 0)
-                       return -EINVAL;
-
-               ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
-               ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H |
-                         WMC_WANA10F | WMC_WANA10H);
-               if (advertising & ADVERTISED_100baseT_Full)
-                       ctrl |= WMC_WANA100F;
-               if (advertising & ADVERTISED_100baseT_Half)
-                       ctrl |= WMC_WANA100H;
-               if (advertising & ADVERTISED_10baseT_Full)
-                       ctrl |= WMC_WANA10F;
-               if (advertising & ADVERTISED_10baseT_Half)
-                       ctrl |= WMC_WANA10H;
-
-               /* force a re-negotiation */
-               ctrl |= WMC_WANR;
-               writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
-       } else {
-               ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
-               /* disable auto-negotiation */
-               ctrl |= WMC_WAND;
-               ctrl &= ~(WMC_WANF100 | WMC_WANFF);
-
-               if (cmd->base.speed == SPEED_100)
-                       ctrl |= WMC_WANF100;
-               if (cmd->base.duplex == DUPLEX_FULL)
-                       ctrl |= WMC_WANFF;
-
-               writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
-       }
-
-       return 0;
-}
-
-/**
- *     ks8695_wan_nwayreset - Restart the autonegotiation on the port.
- *     @ndev: The network device to restart autoneotiation on
- */
-static int
-ks8695_wan_nwayreset(struct net_device *ndev)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-       u32 ctrl;
-
-       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
-       if ((ctrl & WMC_WAND) == 0)
-               writel(ctrl | WMC_WANR,
-                      ksp->phyiface_regs + KS8695_WMC);
-       else
-               /* auto-negotiation not enabled */
-               return -EINVAL;
-
-       return 0;
-}
-
-/**
- *     ks8695_wan_get_pause - Retrieve network pause/flow-control advertising
- *     @ndev: The device to retrieve settings from
- *     @param: The structure to fill out with the information
- */
-static void
-ks8695_wan_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-       u32 ctrl;
-
-       ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
-
-       /* advertise Pause */
-       param->autoneg = (ctrl & WMC_WANAP);
-
-       /* current Rx Flow-control */
-       ctrl = ks8695_readreg(ksp, KS8695_DRXC);
-       param->rx_pause = (ctrl & DRXC_RFCE);
-
-       /* current Tx Flow-control */
-       ctrl = ks8695_readreg(ksp, KS8695_DTXC);
-       param->tx_pause = (ctrl & DTXC_TFCE);
-}
-
-/**
- *     ks8695_get_drvinfo - Retrieve driver information
- *     @ndev: The network device to retrieve info about
- *     @info: The info structure to fill out.
- */
-static void
-ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
-{
-       strlcpy(info->driver, MODULENAME, sizeof(info->driver));
-       strlcpy(info->version, MODULEVERSION, sizeof(info->version));
-       strlcpy(info->bus_info, dev_name(ndev->dev.parent),
-               sizeof(info->bus_info));
-}
-
-static const struct ethtool_ops ks8695_ethtool_ops = {
-       .get_msglevel   = ks8695_get_msglevel,
-       .set_msglevel   = ks8695_set_msglevel,
-       .get_drvinfo    = ks8695_get_drvinfo,
-};
-
-static const struct ethtool_ops ks8695_wan_ethtool_ops = {
-       .get_msglevel   = ks8695_get_msglevel,
-       .set_msglevel   = ks8695_set_msglevel,
-       .nway_reset     = ks8695_wan_nwayreset,
-       .get_link       = ethtool_op_get_link,
-       .get_pauseparam = ks8695_wan_get_pause,
-       .get_drvinfo    = ks8695_get_drvinfo,
-       .get_link_ksettings = ks8695_wan_get_link_ksettings,
-       .set_link_ksettings = ks8695_wan_set_link_ksettings,
-};
-
-/* Network device interface functions */
-
-/**
- *     ks8695_set_mac - Update MAC in net dev and HW
- *     @ndev: The network device to update
- *     @addr: The new MAC address to set
- */
-static int
-ks8695_set_mac(struct net_device *ndev, void *addr)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-       struct sockaddr *address = addr;
-
-       if (!is_valid_ether_addr(address->sa_data))
-               return -EADDRNOTAVAIL;
-
-       memcpy(ndev->dev_addr, address->sa_data, ndev->addr_len);
-
-       ks8695_update_mac(ksp);
-
-       dev_dbg(ksp->dev, "%s: Updated MAC address to %pM\n",
-               ndev->name, ndev->dev_addr);
-
-       return 0;
-}
-
-/**
- *     ks8695_set_multicast - Set up the multicast behaviour of the interface
- *     @ndev: The net_device to configure
- *
- *     This routine, called by the net layer, configures promiscuity
- *     and multicast reception behaviour for the interface.
- */
-static void
-ks8695_set_multicast(struct net_device *ndev)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-       u32 ctrl;
-
-       ctrl = ks8695_readreg(ksp, KS8695_DRXC);
-
-       if (ndev->flags & IFF_PROMISC) {
-               /* enable promiscuous mode */
-               ctrl |= DRXC_RA;
-       } else if (ndev->flags & ~IFF_PROMISC) {
-               /* disable promiscuous mode */
-               ctrl &= ~DRXC_RA;
-       }
-
-       if (ndev->flags & IFF_ALLMULTI) {
-               /* enable all multicast mode */
-               ctrl |= DRXC_RM;
-       } else if (netdev_mc_count(ndev) > KS8695_NR_ADDRESSES) {
-               /* more specific multicast addresses than can be
-                * handled in hardware
-                */
-               ctrl |= DRXC_RM;
-       } else {
-               /* enable specific multicasts */
-               ctrl &= ~DRXC_RM;
-               ks8695_init_partial_multicast(ksp, ndev);
-       }
-
-       ks8695_writereg(ksp, KS8695_DRXC, ctrl);
-}
-
-/**
- *     ks8695_timeout - Handle a network tx/rx timeout.
- *     @ndev: The net_device which timed out.
- *
- *     A network transaction timed out, reset the device.
- */
-static void
-ks8695_timeout(struct net_device *ndev)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-
-       netif_stop_queue(ndev);
-       ks8695_shutdown(ksp);
-
-       ks8695_reset(ksp);
-
-       ks8695_update_mac(ksp);
-
-       /* We ignore the return from this since it managed to init
-        * before it probably will be okay to init again.
-        */
-       ks8695_init_net(ksp);
-
-       /* Reconfigure promiscuity etc */
-       ks8695_set_multicast(ndev);
-
-       /* And start the TX queue once more */
-       netif_start_queue(ndev);
-}
-
-/**
- *     ks8695_start_xmit - Start a packet transmission
- *     @skb: The packet to transmit
- *     @ndev: The network device to send the packet on
- *
- *     This routine, called by the net layer, takes ownership of the
- *     sk_buff and adds it to the TX ring. It then kicks the TX DMA
- *     engine to ensure transmission begins.
- */
-static netdev_tx_t
-ks8695_start_xmit(struct sk_buff *skb, struct net_device *ndev)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-       int buff_n;
-       dma_addr_t dmap;
-
-       spin_lock_irq(&ksp->txq_lock);
-
-       if (ksp->tx_ring_used == MAX_TX_DESC) {
-               /* Somehow we got entered when we have no room */
-               spin_unlock_irq(&ksp->txq_lock);
-               return NETDEV_TX_BUSY;
-       }
-
-       buff_n = ksp->tx_ring_next_slot;
-
-       BUG_ON(ksp->tx_buffers[buff_n].skb);
-
-       dmap = dma_map_single(ksp->dev, skb->data, skb->len, DMA_TO_DEVICE);
-       if (unlikely(dma_mapping_error(ksp->dev, dmap))) {
-               /* Failed to DMA map this SKB, give it back for now */
-               spin_unlock_irq(&ksp->txq_lock);
-               dev_dbg(ksp->dev, "%s: Could not map DMA memory for "\
-                       "transmission, trying later\n", ndev->name);
-               return NETDEV_TX_BUSY;
-       }
-
-       ksp->tx_buffers[buff_n].dma_ptr = dmap;
-       /* Mapped okay, store the buffer pointer and length for later */
-       ksp->tx_buffers[buff_n].skb = skb;
-       ksp->tx_buffers[buff_n].length = skb->len;
-
-       /* Fill out the TX descriptor */
-       ksp->tx_ring[buff_n].data_ptr =
-               cpu_to_le32(ksp->tx_buffers[buff_n].dma_ptr);
-       ksp->tx_ring[buff_n].status =
-               cpu_to_le32(TDES_IC | TDES_FS | TDES_LS |
-                           (skb->len & TDES_TBS));
-
-       wmb();
-
-       /* Hand it over to the hardware */
-       ksp->tx_ring[buff_n].owner = cpu_to_le32(TDES_OWN);
-
-       if (++ksp->tx_ring_used == MAX_TX_DESC)
-               netif_stop_queue(ndev);
-
-       /* Kick the TX DMA in case it decided to go IDLE */
-       ks8695_writereg(ksp, KS8695_DTSC, 0);
-
-       /* And update the next ring slot */
-       ksp->tx_ring_next_slot = (buff_n + 1) & MAX_TX_DESC_MASK;
-
-       spin_unlock_irq(&ksp->txq_lock);
-       return NETDEV_TX_OK;
-}
-
-/**
- *     ks8695_stop - Stop (shutdown) a KS8695 ethernet interface
- *     @ndev: The net_device to stop
- *
- *     This disables the TX queue and cleans up a KS8695 ethernet
- *     device.
- */
-static int
-ks8695_stop(struct net_device *ndev)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-
-       netif_stop_queue(ndev);
-       napi_disable(&ksp->napi);
-
-       ks8695_shutdown(ksp);
-
-       return 0;
-}
-
-/**
- *     ks8695_open - Open (bring up) a KS8695 ethernet interface
- *     @ndev: The net_device to open
- *
- *     This resets, configures the MAC, initialises the RX ring and
- *     DMA engines and starts the TX queue for a KS8695 ethernet
- *     device.
- */
-static int
-ks8695_open(struct net_device *ndev)
-{
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-       int ret;
-
-       ks8695_reset(ksp);
-
-       ks8695_update_mac(ksp);
-
-       ret = ks8695_init_net(ksp);
-       if (ret) {
-               ks8695_shutdown(ksp);
-               return ret;
-       }
-
-       napi_enable(&ksp->napi);
-       netif_start_queue(ndev);
-
-       return 0;
-}
-
-/* Platform device driver */
-
-/**
- *     ks8695_init_switch - Init LAN switch to known good defaults.
- *     @ksp: The device to initialise
- *
- *     This initialises the LAN switch in the KS8695 to a known-good
- *     set of defaults.
- */
-static void
-ks8695_init_switch(struct ks8695_priv *ksp)
-{
-       u32 ctrl;
-
-       /* Default value for SEC0 according to datasheet */
-       ctrl = 0x40819e00;
-
-       /* LED0 = Speed  LED1 = Link/Activity */
-       ctrl &= ~(SEC0_LLED1S | SEC0_LLED0S);
-       ctrl |= (LLED0S_LINK | LLED1S_LINK_ACTIVITY);
-
-       /* Enable Switch */
-       ctrl |= SEC0_ENABLE;
-
-       writel(ctrl, ksp->phyiface_regs + KS8695_SEC0);
-
-       /* Defaults for SEC1 */
-       writel(0x9400100, ksp->phyiface_regs + KS8695_SEC1);
-}
-
-/**
- *     ks8695_init_wan_phy - Initialise the WAN PHY to sensible defaults
- *     @ksp: The device to initialise
- *
- *     This initialises a KS8695's WAN phy to sensible values for
- *     autonegotiation etc.
- */
-static void
-ks8695_init_wan_phy(struct ks8695_priv *ksp)
-{
-       u32 ctrl;
-
-       /* Support auto-negotiation */
-       ctrl = (WMC_WANAP | WMC_WANA100F | WMC_WANA100H |
-               WMC_WANA10F | WMC_WANA10H);
-
-       /* LED0 = Activity , LED1 = Link */
-       ctrl |= (WLED0S_ACTIVITY | WLED1S_LINK);
-
-       /* Restart Auto-negotiation */
-       ctrl |= WMC_WANR;
-
-       writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
-
-       writel(0, ksp->phyiface_regs + KS8695_WPPM);
-       writel(0, ksp->phyiface_regs + KS8695_PPS);
-}
-
-static const struct net_device_ops ks8695_netdev_ops = {
-       .ndo_open               = ks8695_open,
-       .ndo_stop               = ks8695_stop,
-       .ndo_start_xmit         = ks8695_start_xmit,
-       .ndo_tx_timeout         = ks8695_timeout,
-       .ndo_set_mac_address    = ks8695_set_mac,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_rx_mode        = ks8695_set_multicast,
-};
-
-/**
- *     ks8695_probe - Probe and initialise a KS8695 ethernet interface
- *     @pdev: The platform device to probe
- *
- *     Initialise a KS8695 ethernet device from platform data.
- *
- *     This driver requires at least one IORESOURCE_MEM for the
- *     registers and two IORESOURCE_IRQ for the RX and TX IRQs
- *     respectively. It can optionally take an additional
- *     IORESOURCE_MEM for the switch or phy in the case of the lan or
- *     wan ports, and an IORESOURCE_IRQ for the link IRQ for the wan
- *     port.
- */
-static int
-ks8695_probe(struct platform_device *pdev)
-{
-       struct ks8695_priv *ksp;
-       struct net_device *ndev;
-       struct resource *regs_res, *phyiface_res;
-       struct resource *rxirq_res, *txirq_res, *linkirq_res;
-       int ret = 0;
-       int buff_n;
-       bool inv_mac_addr = false;
-       u32 machigh, maclow;
-
-       /* Initialise a net_device */
-       ndev = alloc_etherdev(sizeof(struct ks8695_priv));
-       if (!ndev)
-               return -ENOMEM;
-
-       SET_NETDEV_DEV(ndev, &pdev->dev);
-
-       dev_dbg(&pdev->dev, "ks8695_probe() called\n");
-
-       /* Configure our private structure a little */
-       ksp = netdev_priv(ndev);
-
-       ksp->dev = &pdev->dev;
-       ksp->ndev = ndev;
-       ksp->msg_enable = NETIF_MSG_LINK;
-
-       /* Retrieve resources */
-       regs_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       phyiface_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-
-       rxirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       txirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
-       linkirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 2);
-
-       if (!(regs_res && rxirq_res && txirq_res)) {
-               dev_err(ksp->dev, "insufficient resources\n");
-               ret = -ENOENT;
-               goto failure;
-       }
-
-       ksp->regs_req = request_mem_region(regs_res->start,
-                                          resource_size(regs_res),
-                                          pdev->name);
-
-       if (!ksp->regs_req) {
-               dev_err(ksp->dev, "cannot claim register space\n");
-               ret = -EIO;
-               goto failure;
-       }
-
-       ksp->io_regs = ioremap(regs_res->start, resource_size(regs_res));
-
-       if (!ksp->io_regs) {
-               dev_err(ksp->dev, "failed to ioremap registers\n");
-               ret = -EINVAL;
-               goto failure;
-       }
-
-       if (phyiface_res) {
-               ksp->phyiface_req =
-                       request_mem_region(phyiface_res->start,
-                                          resource_size(phyiface_res),
-                                          phyiface_res->name);
-
-               if (!ksp->phyiface_req) {
-                       dev_err(ksp->dev,
-                               "cannot claim switch register space\n");
-                       ret = -EIO;
-                       goto failure;
-               }
-
-               ksp->phyiface_regs = ioremap(phyiface_res->start,
-                                            resource_size(phyiface_res));
-
-               if (!ksp->phyiface_regs) {
-                       dev_err(ksp->dev,
-                               "failed to ioremap switch registers\n");
-                       ret = -EINVAL;
-                       goto failure;
-               }
-       }
-
-       ksp->rx_irq = rxirq_res->start;
-       ksp->rx_irq_name = rxirq_res->name ? rxirq_res->name : "Ethernet RX";
-       ksp->tx_irq = txirq_res->start;
-       ksp->tx_irq_name = txirq_res->name ? txirq_res->name : "Ethernet TX";
-       ksp->link_irq = (linkirq_res ? linkirq_res->start : -1);
-       ksp->link_irq_name = (linkirq_res && linkirq_res->name) ?
-               linkirq_res->name : "Ethernet Link";
-
-       /* driver system setup */
-       ndev->netdev_ops = &ks8695_netdev_ops;
-       ndev->watchdog_timeo     = msecs_to_jiffies(watchdog);
-
-       netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT);
-
-       /* Retrieve the default MAC addr from the chip. */
-       /* The bootloader should have left it in there for us. */
-
-       machigh = ks8695_readreg(ksp, KS8695_MAH);
-       maclow = ks8695_readreg(ksp, KS8695_MAL);
-
-       ndev->dev_addr[0] = (machigh >> 8) & 0xFF;
-       ndev->dev_addr[1] = machigh & 0xFF;
-       ndev->dev_addr[2] = (maclow >> 24) & 0xFF;
-       ndev->dev_addr[3] = (maclow >> 16) & 0xFF;
-       ndev->dev_addr[4] = (maclow >> 8) & 0xFF;
-       ndev->dev_addr[5] = maclow & 0xFF;
-
-       if (!is_valid_ether_addr(ndev->dev_addr))
-               inv_mac_addr = true;
-
-       /* In order to be efficient memory-wise, we allocate both
-        * rings in one go.
-        */
-       ksp->ring_base = dma_alloc_coherent(&pdev->dev, RING_DMA_SIZE,
-                                           &ksp->ring_base_dma, GFP_KERNEL);
-       if (!ksp->ring_base) {
-               ret = -ENOMEM;
-               goto failure;
-       }
-
-       /* Specify the TX DMA ring buffer */
-       ksp->tx_ring = ksp->ring_base;
-       ksp->tx_ring_dma = ksp->ring_base_dma;
-
-       /* And initialise the queue's lock */
-       spin_lock_init(&ksp->txq_lock);
-       spin_lock_init(&ksp->rx_lock);
-
-       /* Specify the RX DMA ring buffer */
-       ksp->rx_ring = ksp->ring_base + TX_RING_DMA_SIZE;
-       ksp->rx_ring_dma = ksp->ring_base_dma + TX_RING_DMA_SIZE;
-
-       /* Zero the descriptor rings */
-       memset(ksp->tx_ring, 0, TX_RING_DMA_SIZE);
-       memset(ksp->rx_ring, 0, RX_RING_DMA_SIZE);
-
-       /* Build the rings */
-       for (buff_n = 0; buff_n < MAX_TX_DESC; ++buff_n) {
-               ksp->tx_ring[buff_n].next_desc =
-                       cpu_to_le32(ksp->tx_ring_dma +
-                                   (sizeof(struct tx_ring_desc) *
-                                    ((buff_n + 1) & MAX_TX_DESC_MASK)));
-       }
-
-       for (buff_n = 0; buff_n < MAX_RX_DESC; ++buff_n) {
-               ksp->rx_ring[buff_n].next_desc =
-                       cpu_to_le32(ksp->rx_ring_dma +
-                                   (sizeof(struct rx_ring_desc) *
-                                    ((buff_n + 1) & MAX_RX_DESC_MASK)));
-       }
-
-       /* Initialise the port (physically) */
-       if (ksp->phyiface_regs && ksp->link_irq == -1) {
-               ks8695_init_switch(ksp);
-               ksp->dtype = KS8695_DTYPE_LAN;
-               ndev->ethtool_ops = &ks8695_ethtool_ops;
-       } else if (ksp->phyiface_regs && ksp->link_irq != -1) {
-               ks8695_init_wan_phy(ksp);
-               ksp->dtype = KS8695_DTYPE_WAN;
-               ndev->ethtool_ops = &ks8695_wan_ethtool_ops;
-       } else {
-               /* No initialisation since HPNA does not have a PHY */
-               ksp->dtype = KS8695_DTYPE_HPNA;
-               ndev->ethtool_ops = &ks8695_ethtool_ops;
-       }
-
-       /* And bring up the net_device with the net core */
-       platform_set_drvdata(pdev, ndev);
-       ret = register_netdev(ndev);
-
-       if (ret == 0) {
-               if (inv_mac_addr)
-                       dev_warn(ksp->dev, "%s: Invalid ethernet MAC address. Please set using ip\n",
-                                ndev->name);
-               dev_info(ksp->dev, "ks8695 ethernet (%s) MAC: %pM\n",
-                        ks8695_port_type(ksp), ndev->dev_addr);
-       } else {
-               /* Report the failure to register the net_device */
-               dev_err(ksp->dev, "ks8695net: failed to register netdev.\n");
-               goto failure;
-       }
-
-       /* All is well */
-       return 0;
-
-       /* Error exit path */
-failure:
-       ks8695_release_device(ksp);
-       free_netdev(ndev);
-
-       return ret;
-}
-
-/**
- *     ks8695_drv_suspend - Suspend a KS8695 ethernet platform device.
- *     @pdev: The device to suspend
- *     @state: The suspend state
- *
- *     This routine detaches and shuts down a KS8695 ethernet device.
- */
-static int
-ks8695_drv_suspend(struct platform_device *pdev, pm_message_t state)
-{
-       struct net_device *ndev = platform_get_drvdata(pdev);
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-
-       ksp->in_suspend = 1;
-
-       if (netif_running(ndev)) {
-               netif_device_detach(ndev);
-               ks8695_shutdown(ksp);
-       }
-
-       return 0;
-}
-
-/**
- *     ks8695_drv_resume - Resume a KS8695 ethernet platform device.
- *     @pdev: The device to resume
- *
- *     This routine re-initialises and re-attaches a KS8695 ethernet
- *     device.
- */
-static int
-ks8695_drv_resume(struct platform_device *pdev)
-{
-       struct net_device *ndev = platform_get_drvdata(pdev);
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-
-       if (netif_running(ndev)) {
-               ks8695_reset(ksp);
-               ks8695_init_net(ksp);
-               ks8695_set_multicast(ndev);
-               netif_device_attach(ndev);
-       }
-
-       ksp->in_suspend = 0;
-
-       return 0;
-}
-
-/**
- *     ks8695_drv_remove - Remove a KS8695 net device on driver unload.
- *     @pdev: The platform device to remove
- *
- *     This unregisters and releases a KS8695 ethernet device.
- */
-static int
-ks8695_drv_remove(struct platform_device *pdev)
-{
-       struct net_device *ndev = platform_get_drvdata(pdev);
-       struct ks8695_priv *ksp = netdev_priv(ndev);
-
-       netif_napi_del(&ksp->napi);
-
-       unregister_netdev(ndev);
-       ks8695_release_device(ksp);
-       free_netdev(ndev);
-
-       dev_dbg(&pdev->dev, "released and freed device\n");
-       return 0;
-}
-
-static struct platform_driver ks8695_driver = {
-       .driver = {
-               .name   = MODULENAME,
-       },
-       .probe          = ks8695_probe,
-       .remove         = ks8695_drv_remove,
-       .suspend        = ks8695_drv_suspend,
-       .resume         = ks8695_drv_resume,
-};
-
-module_platform_driver(ks8695_driver);
-
-MODULE_AUTHOR("Simtec Electronics");
-MODULE_DESCRIPTION("Micrel KS8695 (Centaur) Ethernet driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" MODULENAME);
-
-module_param(watchdog, int, 0400);
-MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
diff --git a/drivers/net/ethernet/micrel/ks8695net.h b/drivers/net/ethernet/micrel/ks8695net.h
deleted file mode 100644 (file)
index b18fad4..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Micrel KS8695 (Centaur) Ethernet.
- *
- * Copyright 2008 Simtec Electronics
- *               Daniel Silverstone <dsilvers@simtec.co.uk>
- *               Vincent Sanders <vince@simtec.co.uk>
- */
-
-#ifndef KS8695NET_H
-#define KS8695NET_H
-
-/* Receive descriptor flags */
-#define RDES_OWN       (1 << 31)       /* Ownership */
-#define RDES_FS                (1 << 30)       /* First Descriptor */
-#define RDES_LS                (1 << 29)       /* Last Descriptor */
-#define RDES_IPE       (1 << 28)       /* IP Checksum error */
-#define RDES_TCPE      (1 << 27)       /* TCP Checksum error */
-#define RDES_UDPE      (1 << 26)       /* UDP Checksum error */
-#define RDES_ES                (1 << 25)       /* Error summary */
-#define RDES_MF                (1 << 24)       /* Multicast Frame */
-#define RDES_RE                (1 << 19)       /* MII Error reported */
-#define RDES_TL                (1 << 18)       /* Frame too Long */
-#define RDES_RF                (1 << 17)       /* Runt Frame */
-#define RDES_CE                (1 << 16)       /* CRC error */
-#define RDES_FT                (1 << 15)       /* Frame Type */
-#define RDES_FLEN      (0x7ff)         /* Frame Length */
-
-#define RDES_RER       (1 << 25)       /* Receive End of Ring */
-#define RDES_RBS       (0x7ff)         /* Receive Buffer Size */
-
-/* Transmit descriptor flags */
-
-#define TDES_OWN       (1 << 31)       /* Ownership */
-
-#define TDES_IC                (1 << 31)       /* Interrupt on Completion */
-#define TDES_FS                (1 << 30)       /* First Segment */
-#define TDES_LS                (1 << 29)       /* Last Segment */
-#define TDES_IPCKG     (1 << 28)       /* IP Checksum generate */
-#define TDES_TCPCKG    (1 << 27)       /* TCP Checksum generate */
-#define TDES_UDPCKG    (1 << 26)       /* UDP Checksum generate */
-#define TDES_TER       (1 << 25)       /* Transmit End of Ring */
-#define TDES_TBS       (0x7ff)         /* Transmit Buffer Size */
-
-/*
- * Network controller register offsets
- */
-#define KS8695_DTXC            (0x00)          /* DMA Transmit Control */
-#define KS8695_DRXC            (0x04)          /* DMA Receive Control */
-#define KS8695_DTSC            (0x08)          /* DMA Transmit Start Command */
-#define KS8695_DRSC            (0x0c)          /* DMA Receive Start Command */
-#define KS8695_TDLB            (0x10)          /* Transmit Descriptor List
-                                                * Base Address
-                                                */
-#define KS8695_RDLB            (0x14)          /* Receive Descriptor List
-                                                * Base Address
-                                                */
-#define KS8695_MAL             (0x18)          /* MAC Station Address Low */
-#define KS8695_MAH             (0x1c)          /* MAC Station Address High */
-#define KS8695_AAL_(n)         (0x80 + ((n)*8))        /* MAC Additional
-                                                        * Station Address
-                                                        * (0..15) Low
-                                                        */
-#define KS8695_AAH_(n)         (0x84 + ((n)*8))        /* MAC Additional
-                                                        * Station Address
-                                                        * (0..15) High
-                                                        */
-
-
-/* DMA Transmit Control Register */
-#define DTXC_TRST              (1    << 31)    /* Soft Reset */
-#define DTXC_TBS               (0x3f << 24)    /* Transmit Burst Size */
-#define DTXC_TUCG              (1    << 18)    /* Transmit UDP
-                                                * Checksum Generate
-                                                */
-#define DTXC_TTCG              (1    << 17)    /* Transmit TCP
-                                                * Checksum Generate
-                                                */
-#define DTXC_TICG              (1    << 16)    /* Transmit IP
-                                                * Checksum Generate
-                                                */
-#define DTXC_TFCE              (1    <<  9)    /* Transmit Flow
-                                                * Control Enable
-                                                */
-#define DTXC_TLB               (1    <<  8)    /* Loopback mode */
-#define DTXC_TEP               (1    <<  2)    /* Transmit Enable Padding */
-#define DTXC_TAC               (1    <<  1)    /* Transmit Add CRC */
-#define DTXC_TE                        (1    <<  0)    /* TX Enable */
-
-/* DMA Receive Control Register */
-#define DRXC_RBS               (0x3f << 24)    /* Receive Burst Size */
-#define DRXC_RUCC              (1    << 18)    /* Receive UDP Checksum check */
-#define DRXC_RTCG              (1    << 17)    /* Receive TCP Checksum check */
-#define DRXC_RICG              (1    << 16)    /* Receive IP Checksum check */
-#define DRXC_RFCE              (1    <<  9)    /* Receive Flow Control
-                                                * Enable
-                                                */
-#define DRXC_RB                        (1    <<  6)    /* Receive Broadcast */
-#define DRXC_RM                        (1    <<  5)    /* Receive Multicast */
-#define DRXC_RU                        (1    <<  4)    /* Receive Unicast */
-#define DRXC_RERR              (1    <<  3)    /* Receive Error Frame */
-#define DRXC_RA                        (1    <<  2)    /* Receive All */
-#define DRXC_RE                        (1    <<  0)    /* RX Enable */
-
-/* Additional Station Address High */
-#define AAH_E                  (1    << 31)    /* Address Enabled */
-
-#endif /* KS8695NET_H */
index 39aca1a..86fc6e6 100644 (file)
@@ -317,7 +317,7 @@ static void is2_action_set(struct vcap_data *data,
                break;
        case OCELOT_ACL_ACTION_TRAP:
                VCAP_ACT_SET(PORT_MASK, 0x0);
-               VCAP_ACT_SET(MASK_MODE, 0x0);
+               VCAP_ACT_SET(MASK_MODE, 0x1);
                VCAP_ACT_SET(POLICE_ENA, 0x0);
                VCAP_ACT_SET(POLICE_IDX, 0x0);
                VCAP_ACT_SET(CPU_QU_NUM, 0x0);
index d0a01e8..b339125 100644 (file)
@@ -232,9 +232,9 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
 
        laddr = dma_map_single(lp->device, skb->data, length, DMA_TO_DEVICE);
        if (!laddr) {
-               printk(KERN_ERR "%s: failed to map tx DMA buffer.\n", dev->name);
-               dev_kfree_skb(skb);
-               return NETDEV_TX_BUSY;
+               pr_err_ratelimited("%s: failed to map tx DMA buffer.\n", dev->name);
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
        }
 
        sonic_tda_put(dev, entry, SONIC_TD_STATUS, 0);       /* clear status */
index 4054b70..5afcb3c 100644 (file)
@@ -1163,7 +1163,7 @@ mem_op_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
             bool clr_gpr, lmem_step step)
 {
        s32 off = nfp_prog->stack_frame_depth + meta->insn.off + ptr_off;
-       bool first = true, last;
+       bool first = true, narrow_ld, last;
        bool needs_inc = false;
        swreg stack_off_reg;
        u8 prev_gpr = 255;
@@ -1209,13 +1209,22 @@ mem_op_stack(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta,
 
                needs_inc = true;
        }
+
+       narrow_ld = clr_gpr && size < 8;
+
        if (lm3) {
+               unsigned int nop_cnt;
+
                emit_csr_wr(nfp_prog, imm_b(nfp_prog), NFP_CSR_ACT_LM_ADDR3);
-               /* For size < 4 one slot will be filled by zeroing of upper. */
-               wrp_nops(nfp_prog, clr_gpr && size < 8 ? 2 : 3);
+               /* For size < 4 one slot will be filled by zeroing of upper,
+                * but be careful, that zeroing could be eliminated by zext
+                * optimization.
+                */
+               nop_cnt = narrow_ld && meta->flags & FLAG_INSN_DO_ZEXT ? 2 : 3;
+               wrp_nops(nfp_prog, nop_cnt);
        }
 
-       if (clr_gpr && size < 8)
+       if (narrow_ld)
                wrp_zext(nfp_prog, meta, gpr);
 
        while (size) {
index d5bbe3d..05981b5 100644 (file)
@@ -260,9 +260,6 @@ nfp_flower_cmsg_process_one_rx(struct nfp_app *app, struct sk_buff *skb)
 
        type = cmsg_hdr->type;
        switch (type) {
-       case NFP_FLOWER_CMSG_TYPE_PORT_REIFY:
-               nfp_flower_cmsg_portreify_rx(app, skb);
-               break;
        case NFP_FLOWER_CMSG_TYPE_PORT_MOD:
                nfp_flower_cmsg_portmod_rx(app, skb);
                break;
@@ -328,8 +325,7 @@ nfp_flower_queue_ctl_msg(struct nfp_app *app, struct sk_buff *skb, int type)
        struct nfp_flower_priv *priv = app->priv;
        struct sk_buff_head *skb_head;
 
-       if (type == NFP_FLOWER_CMSG_TYPE_PORT_REIFY ||
-           type == NFP_FLOWER_CMSG_TYPE_PORT_MOD)
+       if (type == NFP_FLOWER_CMSG_TYPE_PORT_MOD)
                skb_head = &priv->cmsg_skbs_high;
        else
                skb_head = &priv->cmsg_skbs_low;
@@ -368,6 +364,10 @@ void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
        } else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_TUN_NEIGH) {
                /* Acks from the NFP that the route is added - ignore. */
                dev_consume_skb_any(skb);
+       } else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_PORT_REIFY) {
+               /* Handle REIFY acks outside wq to prevent RTNL conflict. */
+               nfp_flower_cmsg_portreify_rx(app, skb);
+               dev_consume_skb_any(skb);
        } else {
                nfp_flower_queue_ctl_msg(app, skb, cmsg_hdr->type);
        }
index e209f15..457bdc6 100644 (file)
@@ -1409,13 +1409,21 @@ nfp_flower_setup_indr_tc_block(struct net_device *netdev, struct nfp_app *app,
        struct nfp_flower_priv *priv = app->priv;
        struct flow_block_cb *block_cb;
 
-       if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS &&
-           !(f->binder_type == FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS &&
-             nfp_flower_internal_port_can_offload(app, netdev)))
+       if ((f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS &&
+            !nfp_flower_internal_port_can_offload(app, netdev)) ||
+           (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_EGRESS &&
+            nfp_flower_internal_port_can_offload(app, netdev)))
                return -EOPNOTSUPP;
 
        switch (f->command) {
        case FLOW_BLOCK_BIND:
+               cb_priv = nfp_flower_indr_block_cb_priv_lookup(app, netdev);
+               if (cb_priv &&
+                   flow_block_cb_is_busy(nfp_flower_setup_indr_block_cb,
+                                         cb_priv,
+                                         &nfp_block_cb_list))
+                       return -EBUSY;
+
                cb_priv = kmalloc(sizeof(*cb_priv), GFP_KERNEL);
                if (!cb_priv)
                        return -ENOMEM;
index a7a80f4..f0ee982 100644 (file)
@@ -328,13 +328,13 @@ nfp_tun_neigh_event_handler(struct notifier_block *nb, unsigned long event,
 
        flow.daddr = *(__be32 *)n->primary_key;
 
-       /* Only concerned with route changes for representors. */
-       if (!nfp_netdev_is_nfp_repr(n->dev))
-               return NOTIFY_DONE;
-
        app_priv = container_of(nb, struct nfp_flower_priv, tun.neigh_nb);
        app = app_priv->app;
 
+       if (!nfp_netdev_is_nfp_repr(n->dev) &&
+           !nfp_flower_internal_port_can_offload(app, n->dev))
+               return NOTIFY_DONE;
+
        /* Only concerned with changes to routes already added to NFP. */
        if (!nfp_tun_has_route(app, flow.daddr))
                return NOTIFY_DONE;
diff --git a/drivers/net/ethernet/nuvoton/Kconfig b/drivers/net/ethernet/nuvoton/Kconfig
deleted file mode 100644 (file)
index 325e26c..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Nuvoton network device configuration
-#
-
-config NET_VENDOR_NUVOTON
-       bool "Nuvoton devices"
-       default y
-       depends on ARM && ARCH_W90X900
-       ---help---
-         If you have a network (Ethernet) card belonging to this class, say Y.
-
-         Note that the answer to this question doesn't directly affect the
-         kernel: saying N will just cause the configurator to skip all
-         the questions about Nuvoton cards. If you say Y, you will be asked
-         for your specific card in the following questions.
-
-if NET_VENDOR_NUVOTON
-
-config W90P910_ETH
-       tristate "Nuvoton w90p910 Ethernet support"
-       depends on ARM && ARCH_W90X900
-       select PHYLIB
-       select MII
-       ---help---
-         Say Y here if you want to use built-in Ethernet ports
-         on w90p910 processor.
-
-endif # NET_VENDOR_NUVOTON
diff --git a/drivers/net/ethernet/nuvoton/Makefile b/drivers/net/ethernet/nuvoton/Makefile
deleted file mode 100644 (file)
index 66f6e72..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the Nuvoton network device drivers.
-#
-
-obj-$(CONFIG_W90P910_ETH) += w90p910_ether.o
diff --git a/drivers/net/ethernet/nuvoton/w90p910_ether.c b/drivers/net/ethernet/nuvoton/w90p910_ether.c
deleted file mode 100644 (file)
index 3d73970..0000000
+++ /dev/null
@@ -1,1082 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2008-2009 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/mii.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/ethtool.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/gfp.h>
-
-#define DRV_MODULE_NAME                "w90p910-emc"
-#define DRV_MODULE_VERSION     "0.1"
-
-/* Ethernet MAC Registers */
-#define REG_CAMCMR             0x00
-#define REG_CAMEN              0x04
-#define REG_CAMM_BASE          0x08
-#define REG_CAML_BASE          0x0c
-#define REG_TXDLSA             0x88
-#define REG_RXDLSA             0x8C
-#define REG_MCMDR              0x90
-#define REG_MIID               0x94
-#define REG_MIIDA              0x98
-#define REG_FFTCR              0x9C
-#define REG_TSDR               0xa0
-#define REG_RSDR               0xa4
-#define REG_DMARFC             0xa8
-#define REG_MIEN               0xac
-#define REG_MISTA              0xb0
-#define REG_CTXDSA             0xcc
-#define REG_CTXBSA             0xd0
-#define REG_CRXDSA             0xd4
-#define REG_CRXBSA             0xd8
-
-/* mac controller bit */
-#define MCMDR_RXON             0x01
-#define MCMDR_ACP              (0x01 << 3)
-#define MCMDR_SPCRC            (0x01 << 5)
-#define MCMDR_TXON             (0x01 << 8)
-#define MCMDR_FDUP             (0x01 << 18)
-#define MCMDR_ENMDC            (0x01 << 19)
-#define MCMDR_OPMOD            (0x01 << 20)
-#define SWR                    (0x01 << 24)
-
-/* cam command regiser */
-#define CAMCMR_AUP             0x01
-#define CAMCMR_AMP             (0x01 << 1)
-#define CAMCMR_ABP             (0x01 << 2)
-#define CAMCMR_CCAM            (0x01 << 3)
-#define CAMCMR_ECMP            (0x01 << 4)
-#define CAM0EN                 0x01
-
-/* mac mii controller bit */
-#define MDCCR                  (0x0a << 20)
-#define PHYAD                  (0x01 << 8)
-#define PHYWR                  (0x01 << 16)
-#define PHYBUSY                        (0x01 << 17)
-#define PHYPRESP               (0x01 << 18)
-#define CAM_ENTRY_SIZE         0x08
-
-/* rx and tx status */
-#define TXDS_TXCP              (0x01 << 19)
-#define RXDS_CRCE              (0x01 << 17)
-#define RXDS_PTLE              (0x01 << 19)
-#define RXDS_RXGD              (0x01 << 20)
-#define RXDS_ALIE              (0x01 << 21)
-#define RXDS_RP                        (0x01 << 22)
-
-/* mac interrupt status*/
-#define MISTA_EXDEF            (0x01 << 19)
-#define MISTA_TXBERR           (0x01 << 24)
-#define MISTA_TDU              (0x01 << 23)
-#define MISTA_RDU              (0x01 << 10)
-#define MISTA_RXBERR           (0x01 << 11)
-
-#define ENSTART                        0x01
-#define ENRXINTR               0x01
-#define ENRXGD                 (0x01 << 4)
-#define ENRXBERR               (0x01 << 11)
-#define ENTXINTR               (0x01 << 16)
-#define ENTXCP                 (0x01 << 18)
-#define ENTXABT                        (0x01 << 21)
-#define ENTXBERR               (0x01 << 24)
-#define ENMDC                  (0x01 << 19)
-#define PHYBUSY                        (0x01 << 17)
-#define MDCCR_VAL              0xa00000
-
-/* rx and tx owner bit */
-#define RX_OWEN_DMA            (0x01 << 31)
-#define RX_OWEN_CPU            (~(0x03 << 30))
-#define TX_OWEN_DMA            (0x01 << 31)
-#define TX_OWEN_CPU            (~(0x01 << 31))
-
-/* tx frame desc controller bit */
-#define MACTXINTEN             0x04
-#define CRCMODE                        0x02
-#define PADDINGMODE            0x01
-
-/* fftcr controller bit */
-#define TXTHD                  (0x03 << 8)
-#define BLENGTH                        (0x01 << 20)
-
-/* global setting for driver */
-#define RX_DESC_SIZE           50
-#define TX_DESC_SIZE           10
-#define MAX_RBUFF_SZ           0x600
-#define MAX_TBUFF_SZ           0x600
-#define TX_TIMEOUT             (HZ/2)
-#define DELAY                  1000
-#define CAM0                   0x0
-
-static int w90p910_mdio_read(struct net_device *dev, int phy_id, int reg);
-
-struct w90p910_rxbd {
-       unsigned int sl;
-       unsigned int buffer;
-       unsigned int reserved;
-       unsigned int next;
-};
-
-struct w90p910_txbd {
-       unsigned int mode;
-       unsigned int buffer;
-       unsigned int sl;
-       unsigned int next;
-};
-
-struct recv_pdesc {
-       struct w90p910_rxbd desclist[RX_DESC_SIZE];
-       char recv_buf[RX_DESC_SIZE][MAX_RBUFF_SZ];
-};
-
-struct tran_pdesc {
-       struct w90p910_txbd desclist[TX_DESC_SIZE];
-       char tran_buf[TX_DESC_SIZE][MAX_TBUFF_SZ];
-};
-
-struct  w90p910_ether {
-       struct recv_pdesc *rdesc;
-       struct tran_pdesc *tdesc;
-       dma_addr_t rdesc_phys;
-       dma_addr_t tdesc_phys;
-       struct platform_device *pdev;
-       struct resource *res;
-       struct sk_buff *skb;
-       struct clk *clk;
-       struct clk *rmiiclk;
-       struct mii_if_info mii;
-       struct timer_list check_timer;
-       void __iomem *reg;
-       int rxirq;
-       int txirq;
-       unsigned int cur_tx;
-       unsigned int cur_rx;
-       unsigned int finish_tx;
-       unsigned int rx_packets;
-       unsigned int rx_bytes;
-       unsigned int start_tx_ptr;
-       unsigned int start_rx_ptr;
-       unsigned int linkflag;
-};
-
-static void update_linkspeed_register(struct net_device *dev,
-                               unsigned int speed, unsigned int duplex)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       unsigned int val;
-
-       val = __raw_readl(ether->reg + REG_MCMDR);
-
-       if (speed == SPEED_100) {
-               /* 100 full/half duplex */
-               if (duplex == DUPLEX_FULL) {
-                       val |= (MCMDR_OPMOD | MCMDR_FDUP);
-               } else {
-                       val |= MCMDR_OPMOD;
-                       val &= ~MCMDR_FDUP;
-               }
-       } else {
-               /* 10 full/half duplex */
-               if (duplex == DUPLEX_FULL) {
-                       val |= MCMDR_FDUP;
-                       val &= ~MCMDR_OPMOD;
-               } else {
-                       val &= ~(MCMDR_FDUP | MCMDR_OPMOD);
-               }
-       }
-
-       __raw_writel(val, ether->reg + REG_MCMDR);
-}
-
-static void update_linkspeed(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       struct platform_device *pdev;
-       unsigned int bmsr, bmcr, lpa, speed, duplex;
-
-       pdev = ether->pdev;
-
-       if (!mii_link_ok(&ether->mii)) {
-               ether->linkflag = 0x0;
-               netif_carrier_off(dev);
-               dev_warn(&pdev->dev, "%s: Link down.\n", dev->name);
-               return;
-       }
-
-       if (ether->linkflag == 1)
-               return;
-
-       bmsr = w90p910_mdio_read(dev, ether->mii.phy_id, MII_BMSR);
-       bmcr = w90p910_mdio_read(dev, ether->mii.phy_id, MII_BMCR);
-
-       if (bmcr & BMCR_ANENABLE) {
-               if (!(bmsr & BMSR_ANEGCOMPLETE))
-                       return;
-
-               lpa = w90p910_mdio_read(dev, ether->mii.phy_id, MII_LPA);
-
-               if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF))
-                       speed = SPEED_100;
-               else
-                       speed = SPEED_10;
-
-               if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL))
-                       duplex = DUPLEX_FULL;
-               else
-                       duplex = DUPLEX_HALF;
-
-       } else {
-               speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
-               duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
-       }
-
-       update_linkspeed_register(dev, speed, duplex);
-
-       dev_info(&pdev->dev, "%s: Link now %i-%s\n", dev->name, speed,
-                       (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex");
-       ether->linkflag = 0x01;
-
-       netif_carrier_on(dev);
-}
-
-static void w90p910_check_link(struct timer_list *t)
-{
-       struct w90p910_ether *ether = from_timer(ether, t, check_timer);
-       struct net_device *dev = ether->mii.dev;
-
-       update_linkspeed(dev);
-       mod_timer(&ether->check_timer, jiffies + msecs_to_jiffies(1000));
-}
-
-static void w90p910_write_cam(struct net_device *dev,
-                               unsigned int x, unsigned char *pval)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       unsigned int msw, lsw;
-
-       msw = (pval[0] << 24) | (pval[1] << 16) | (pval[2] << 8) | pval[3];
-
-       lsw = (pval[4] << 24) | (pval[5] << 16);
-
-       __raw_writel(lsw, ether->reg + REG_CAML_BASE + x * CAM_ENTRY_SIZE);
-       __raw_writel(msw, ether->reg + REG_CAMM_BASE + x * CAM_ENTRY_SIZE);
-}
-
-static int w90p910_init_desc(struct net_device *dev)
-{
-       struct w90p910_ether *ether;
-       struct w90p910_txbd  *tdesc;
-       struct w90p910_rxbd  *rdesc;
-       struct platform_device *pdev;
-       unsigned int i;
-
-       ether = netdev_priv(dev);
-       pdev = ether->pdev;
-
-       ether->tdesc = dma_alloc_coherent(&pdev->dev, sizeof(struct tran_pdesc),
-                                         &ether->tdesc_phys, GFP_KERNEL);
-       if (!ether->tdesc)
-               return -ENOMEM;
-
-       ether->rdesc = dma_alloc_coherent(&pdev->dev, sizeof(struct recv_pdesc),
-                                         &ether->rdesc_phys, GFP_KERNEL);
-       if (!ether->rdesc) {
-               dma_free_coherent(&pdev->dev, sizeof(struct tran_pdesc),
-                                 ether->tdesc, ether->tdesc_phys);
-               return -ENOMEM;
-       }
-
-       for (i = 0; i < TX_DESC_SIZE; i++) {
-               unsigned int offset;
-
-               tdesc = &(ether->tdesc->desclist[i]);
-
-               if (i == TX_DESC_SIZE - 1)
-                       offset = offsetof(struct tran_pdesc, desclist[0]);
-               else
-                       offset = offsetof(struct tran_pdesc, desclist[i + 1]);
-
-               tdesc->next = ether->tdesc_phys + offset;
-               tdesc->buffer = ether->tdesc_phys +
-                       offsetof(struct tran_pdesc, tran_buf[i]);
-               tdesc->sl = 0;
-               tdesc->mode = 0;
-       }
-
-       ether->start_tx_ptr = ether->tdesc_phys;
-
-       for (i = 0; i < RX_DESC_SIZE; i++) {
-               unsigned int offset;
-
-               rdesc = &(ether->rdesc->desclist[i]);
-
-               if (i == RX_DESC_SIZE - 1)
-                       offset = offsetof(struct recv_pdesc, desclist[0]);
-               else
-                       offset = offsetof(struct recv_pdesc, desclist[i + 1]);
-
-               rdesc->next = ether->rdesc_phys + offset;
-               rdesc->sl = RX_OWEN_DMA;
-               rdesc->buffer = ether->rdesc_phys +
-                       offsetof(struct recv_pdesc, recv_buf[i]);
-         }
-
-       ether->start_rx_ptr = ether->rdesc_phys;
-
-       return 0;
-}
-
-static void w90p910_set_fifo_threshold(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       unsigned int val;
-
-       val = TXTHD | BLENGTH;
-       __raw_writel(val, ether->reg + REG_FFTCR);
-}
-
-static void w90p910_return_default_idle(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       unsigned int val;
-
-       val = __raw_readl(ether->reg + REG_MCMDR);
-       val |= SWR;
-       __raw_writel(val, ether->reg + REG_MCMDR);
-}
-
-static void w90p910_trigger_rx(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-
-       __raw_writel(ENSTART, ether->reg + REG_RSDR);
-}
-
-static void w90p910_trigger_tx(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-
-       __raw_writel(ENSTART, ether->reg + REG_TSDR);
-}
-
-static void w90p910_enable_mac_interrupt(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       unsigned int val;
-
-       val = ENTXINTR | ENRXINTR | ENRXGD | ENTXCP;
-       val |= ENTXBERR | ENRXBERR | ENTXABT;
-
-       __raw_writel(val, ether->reg + REG_MIEN);
-}
-
-static void w90p910_get_and_clear_int(struct net_device *dev,
-                                                       unsigned int *val)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-
-       *val = __raw_readl(ether->reg + REG_MISTA);
-       __raw_writel(*val, ether->reg + REG_MISTA);
-}
-
-static void w90p910_set_global_maccmd(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       unsigned int val;
-
-       val = __raw_readl(ether->reg + REG_MCMDR);
-       val |= MCMDR_SPCRC | MCMDR_ENMDC | MCMDR_ACP | ENMDC;
-       __raw_writel(val, ether->reg + REG_MCMDR);
-}
-
-static void w90p910_enable_cam(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       unsigned int val;
-
-       w90p910_write_cam(dev, CAM0, dev->dev_addr);
-
-       val = __raw_readl(ether->reg + REG_CAMEN);
-       val |= CAM0EN;
-       __raw_writel(val, ether->reg + REG_CAMEN);
-}
-
-static void w90p910_enable_cam_command(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       unsigned int val;
-
-       val = CAMCMR_ECMP | CAMCMR_ABP | CAMCMR_AMP;
-       __raw_writel(val, ether->reg + REG_CAMCMR);
-}
-
-static void w90p910_enable_tx(struct net_device *dev, unsigned int enable)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       unsigned int val;
-
-       val = __raw_readl(ether->reg + REG_MCMDR);
-
-       if (enable)
-               val |= MCMDR_TXON;
-       else
-               val &= ~MCMDR_TXON;
-
-       __raw_writel(val, ether->reg + REG_MCMDR);
-}
-
-static void w90p910_enable_rx(struct net_device *dev, unsigned int enable)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       unsigned int val;
-
-       val = __raw_readl(ether->reg + REG_MCMDR);
-
-       if (enable)
-               val |= MCMDR_RXON;
-       else
-               val &= ~MCMDR_RXON;
-
-       __raw_writel(val, ether->reg + REG_MCMDR);
-}
-
-static void w90p910_set_curdest(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-
-       __raw_writel(ether->start_rx_ptr, ether->reg + REG_RXDLSA);
-       __raw_writel(ether->start_tx_ptr, ether->reg + REG_TXDLSA);
-}
-
-static void w90p910_reset_mac(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-
-       w90p910_enable_tx(dev, 0);
-       w90p910_enable_rx(dev, 0);
-       w90p910_set_fifo_threshold(dev);
-       w90p910_return_default_idle(dev);
-
-       if (!netif_queue_stopped(dev))
-               netif_stop_queue(dev);
-
-       w90p910_init_desc(dev);
-
-       netif_trans_update(dev); /* prevent tx timeout */
-       ether->cur_tx = 0x0;
-       ether->finish_tx = 0x0;
-       ether->cur_rx = 0x0;
-
-       w90p910_set_curdest(dev);
-       w90p910_enable_cam(dev);
-       w90p910_enable_cam_command(dev);
-       w90p910_enable_mac_interrupt(dev);
-       w90p910_enable_tx(dev, 1);
-       w90p910_enable_rx(dev, 1);
-       w90p910_trigger_tx(dev);
-       w90p910_trigger_rx(dev);
-
-       netif_trans_update(dev); /* prevent tx timeout */
-
-       if (netif_queue_stopped(dev))
-               netif_wake_queue(dev);
-}
-
-static void w90p910_mdio_write(struct net_device *dev,
-                                       int phy_id, int reg, int data)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       struct platform_device *pdev;
-       unsigned int val, i;
-
-       pdev = ether->pdev;
-
-       __raw_writel(data, ether->reg + REG_MIID);
-
-       val = (phy_id << 0x08) | reg;
-       val |= PHYBUSY | PHYWR | MDCCR_VAL;
-       __raw_writel(val, ether->reg + REG_MIIDA);
-
-       for (i = 0; i < DELAY; i++) {
-               if ((__raw_readl(ether->reg + REG_MIIDA) & PHYBUSY) == 0)
-                       break;
-       }
-
-       if (i == DELAY)
-               dev_warn(&pdev->dev, "mdio write timed out\n");
-}
-
-static int w90p910_mdio_read(struct net_device *dev, int phy_id, int reg)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       struct platform_device *pdev;
-       unsigned int val, i, data;
-
-       pdev = ether->pdev;
-
-       val = (phy_id << 0x08) | reg;
-       val |= PHYBUSY | MDCCR_VAL;
-       __raw_writel(val, ether->reg + REG_MIIDA);
-
-       for (i = 0; i < DELAY; i++) {
-               if ((__raw_readl(ether->reg + REG_MIIDA) & PHYBUSY) == 0)
-                       break;
-       }
-
-       if (i == DELAY) {
-               dev_warn(&pdev->dev, "mdio read timed out\n");
-               data = 0xffff;
-       } else {
-               data = __raw_readl(ether->reg + REG_MIID);
-       }
-
-       return data;
-}
-
-static int w90p910_set_mac_address(struct net_device *dev, void *addr)
-{
-       struct sockaddr *address = addr;
-
-       if (!is_valid_ether_addr(address->sa_data))
-               return -EADDRNOTAVAIL;
-
-       memcpy(dev->dev_addr, address->sa_data, dev->addr_len);
-       w90p910_write_cam(dev, CAM0, dev->dev_addr);
-
-       return 0;
-}
-
-static int w90p910_ether_close(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       struct platform_device *pdev;
-
-       pdev = ether->pdev;
-
-       dma_free_coherent(&pdev->dev, sizeof(struct recv_pdesc),
-                                       ether->rdesc, ether->rdesc_phys);
-       dma_free_coherent(&pdev->dev, sizeof(struct tran_pdesc),
-                                       ether->tdesc, ether->tdesc_phys);
-
-       netif_stop_queue(dev);
-
-       del_timer_sync(&ether->check_timer);
-       clk_disable(ether->rmiiclk);
-       clk_disable(ether->clk);
-
-       free_irq(ether->txirq, dev);
-       free_irq(ether->rxirq, dev);
-
-       return 0;
-}
-
-static int w90p910_send_frame(struct net_device *dev,
-                                       unsigned char *data, int length)
-{
-       struct w90p910_ether *ether;
-       struct w90p910_txbd *txbd;
-       struct platform_device *pdev;
-       unsigned char *buffer;
-
-       ether = netdev_priv(dev);
-       pdev = ether->pdev;
-
-       txbd = &ether->tdesc->desclist[ether->cur_tx];
-       buffer = ether->tdesc->tran_buf[ether->cur_tx];
-
-       if (length > 1514) {
-               dev_err(&pdev->dev, "send data %d bytes, check it\n", length);
-               length = 1514;
-       }
-
-       txbd->sl = length & 0xFFFF;
-
-       memcpy(buffer, data, length);
-
-       txbd->mode = TX_OWEN_DMA | PADDINGMODE | CRCMODE | MACTXINTEN;
-
-       w90p910_enable_tx(dev, 1);
-
-       w90p910_trigger_tx(dev);
-
-       if (++ether->cur_tx >= TX_DESC_SIZE)
-               ether->cur_tx = 0;
-
-       txbd = &ether->tdesc->desclist[ether->cur_tx];
-
-       if (txbd->mode & TX_OWEN_DMA)
-               netif_stop_queue(dev);
-
-       return 0;
-}
-
-static int w90p910_ether_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-
-       if (!(w90p910_send_frame(dev, skb->data, skb->len))) {
-               ether->skb = skb;
-               dev_consume_skb_irq(skb);
-               return 0;
-       }
-       return -EAGAIN;
-}
-
-static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id)
-{
-       struct w90p910_ether *ether;
-       struct w90p910_txbd  *txbd;
-       struct platform_device *pdev;
-       struct net_device *dev;
-       unsigned int cur_entry, entry, status;
-
-       dev = dev_id;
-       ether = netdev_priv(dev);
-       pdev = ether->pdev;
-
-       w90p910_get_and_clear_int(dev, &status);
-
-       cur_entry = __raw_readl(ether->reg + REG_CTXDSA);
-
-       entry = ether->tdesc_phys +
-               offsetof(struct tran_pdesc, desclist[ether->finish_tx]);
-
-       while (entry != cur_entry) {
-               txbd = &ether->tdesc->desclist[ether->finish_tx];
-
-               if (++ether->finish_tx >= TX_DESC_SIZE)
-                       ether->finish_tx = 0;
-
-               if (txbd->sl & TXDS_TXCP) {
-                       dev->stats.tx_packets++;
-                       dev->stats.tx_bytes += txbd->sl & 0xFFFF;
-               } else {
-                       dev->stats.tx_errors++;
-               }
-
-               txbd->sl = 0x0;
-               txbd->mode = 0x0;
-
-               if (netif_queue_stopped(dev))
-                       netif_wake_queue(dev);
-
-               entry = ether->tdesc_phys +
-                       offsetof(struct tran_pdesc, desclist[ether->finish_tx]);
-       }
-
-       if (status & MISTA_EXDEF) {
-               dev_err(&pdev->dev, "emc defer exceed interrupt\n");
-       } else if (status & MISTA_TXBERR) {
-               dev_err(&pdev->dev, "emc bus error interrupt\n");
-               w90p910_reset_mac(dev);
-       } else if (status & MISTA_TDU) {
-               if (netif_queue_stopped(dev))
-                       netif_wake_queue(dev);
-       }
-
-       return IRQ_HANDLED;
-}
-
-static void netdev_rx(struct net_device *dev)
-{
-       struct w90p910_ether *ether;
-       struct w90p910_rxbd *rxbd;
-       struct platform_device *pdev;
-       struct sk_buff *skb;
-       unsigned char *data;
-       unsigned int length, status, val, entry;
-
-       ether = netdev_priv(dev);
-       pdev = ether->pdev;
-
-       rxbd = &ether->rdesc->desclist[ether->cur_rx];
-
-       do {
-               val = __raw_readl(ether->reg + REG_CRXDSA);
-
-               entry = ether->rdesc_phys +
-                       offsetof(struct recv_pdesc, desclist[ether->cur_rx]);
-
-               if (val == entry)
-                       break;
-
-               status = rxbd->sl;
-               length = status & 0xFFFF;
-
-               if (status & RXDS_RXGD) {
-                       data = ether->rdesc->recv_buf[ether->cur_rx];
-                       skb = netdev_alloc_skb(dev, length + 2);
-                       if (!skb) {
-                               dev->stats.rx_dropped++;
-                               return;
-                       }
-
-                       skb_reserve(skb, 2);
-                       skb_put(skb, length);
-                       skb_copy_to_linear_data(skb, data, length);
-                       skb->protocol = eth_type_trans(skb, dev);
-                       dev->stats.rx_packets++;
-                       dev->stats.rx_bytes += length;
-                       netif_rx(skb);
-               } else {
-                       dev->stats.rx_errors++;
-
-                       if (status & RXDS_RP) {
-                               dev_err(&pdev->dev, "rx runt err\n");
-                               dev->stats.rx_length_errors++;
-                       } else if (status & RXDS_CRCE) {
-                               dev_err(&pdev->dev, "rx crc err\n");
-                               dev->stats.rx_crc_errors++;
-                       } else if (status & RXDS_ALIE) {
-                               dev_err(&pdev->dev, "rx alignment err\n");
-                               dev->stats.rx_frame_errors++;
-                       } else if (status & RXDS_PTLE) {
-                               dev_err(&pdev->dev, "rx longer err\n");
-                               dev->stats.rx_over_errors++;
-                       }
-               }
-
-               rxbd->sl = RX_OWEN_DMA;
-               rxbd->reserved = 0x0;
-
-               if (++ether->cur_rx >= RX_DESC_SIZE)
-                       ether->cur_rx = 0;
-
-               rxbd = &ether->rdesc->desclist[ether->cur_rx];
-
-       } while (1);
-}
-
-static irqreturn_t w90p910_rx_interrupt(int irq, void *dev_id)
-{
-       struct net_device *dev;
-       struct w90p910_ether  *ether;
-       struct platform_device *pdev;
-       unsigned int status;
-
-       dev = dev_id;
-       ether = netdev_priv(dev);
-       pdev = ether->pdev;
-
-       w90p910_get_and_clear_int(dev, &status);
-
-       if (status & MISTA_RDU) {
-               netdev_rx(dev);
-               w90p910_trigger_rx(dev);
-
-               return IRQ_HANDLED;
-       } else if (status & MISTA_RXBERR) {
-               dev_err(&pdev->dev, "emc rx bus error\n");
-               w90p910_reset_mac(dev);
-       }
-
-       netdev_rx(dev);
-       return IRQ_HANDLED;
-}
-
-static int w90p910_ether_open(struct net_device *dev)
-{
-       struct w90p910_ether *ether;
-       struct platform_device *pdev;
-
-       ether = netdev_priv(dev);
-       pdev = ether->pdev;
-
-       w90p910_reset_mac(dev);
-       w90p910_set_fifo_threshold(dev);
-       w90p910_set_curdest(dev);
-       w90p910_enable_cam(dev);
-       w90p910_enable_cam_command(dev);
-       w90p910_enable_mac_interrupt(dev);
-       w90p910_set_global_maccmd(dev);
-       w90p910_enable_rx(dev, 1);
-
-       clk_enable(ether->rmiiclk);
-       clk_enable(ether->clk);
-
-       ether->rx_packets = 0x0;
-       ether->rx_bytes = 0x0;
-
-       if (request_irq(ether->txirq, w90p910_tx_interrupt,
-                                               0x0, pdev->name, dev)) {
-               dev_err(&pdev->dev, "register irq tx failed\n");
-               return -EAGAIN;
-       }
-
-       if (request_irq(ether->rxirq, w90p910_rx_interrupt,
-                                               0x0, pdev->name, dev)) {
-               dev_err(&pdev->dev, "register irq rx failed\n");
-               free_irq(ether->txirq, dev);
-               return -EAGAIN;
-       }
-
-       mod_timer(&ether->check_timer, jiffies + msecs_to_jiffies(1000));
-       netif_start_queue(dev);
-       w90p910_trigger_rx(dev);
-
-       dev_info(&pdev->dev, "%s is OPENED\n", dev->name);
-
-       return 0;
-}
-
-static void w90p910_ether_set_multicast_list(struct net_device *dev)
-{
-       struct w90p910_ether *ether;
-       unsigned int rx_mode;
-
-       ether = netdev_priv(dev);
-
-       if (dev->flags & IFF_PROMISC)
-               rx_mode = CAMCMR_AUP | CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP;
-       else if ((dev->flags & IFF_ALLMULTI) || !netdev_mc_empty(dev))
-               rx_mode = CAMCMR_AMP | CAMCMR_ABP | CAMCMR_ECMP;
-       else
-               rx_mode = CAMCMR_ECMP | CAMCMR_ABP;
-       __raw_writel(rx_mode, ether->reg + REG_CAMCMR);
-}
-
-static int w90p910_ether_ioctl(struct net_device *dev,
-                                               struct ifreq *ifr, int cmd)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       struct mii_ioctl_data *data = if_mii(ifr);
-
-       return generic_mii_ioctl(&ether->mii, data, cmd, NULL);
-}
-
-static void w90p910_get_drvinfo(struct net_device *dev,
-                                       struct ethtool_drvinfo *info)
-{
-       strlcpy(info->driver, DRV_MODULE_NAME, sizeof(info->driver));
-       strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
-}
-
-static int w90p910_get_link_ksettings(struct net_device *dev,
-                                     struct ethtool_link_ksettings *cmd)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-
-       mii_ethtool_get_link_ksettings(&ether->mii, cmd);
-
-       return 0;
-}
-
-static int w90p910_set_link_ksettings(struct net_device *dev,
-                                     const struct ethtool_link_ksettings *cmd)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       return mii_ethtool_set_link_ksettings(&ether->mii, cmd);
-}
-
-static int w90p910_nway_reset(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       return mii_nway_restart(&ether->mii);
-}
-
-static u32 w90p910_get_link(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       return mii_link_ok(&ether->mii);
-}
-
-static const struct ethtool_ops w90p910_ether_ethtool_ops = {
-       .get_drvinfo    = w90p910_get_drvinfo,
-       .nway_reset     = w90p910_nway_reset,
-       .get_link       = w90p910_get_link,
-       .get_link_ksettings = w90p910_get_link_ksettings,
-       .set_link_ksettings = w90p910_set_link_ksettings,
-};
-
-static const struct net_device_ops w90p910_ether_netdev_ops = {
-       .ndo_open               = w90p910_ether_open,
-       .ndo_stop               = w90p910_ether_close,
-       .ndo_start_xmit         = w90p910_ether_start_xmit,
-       .ndo_set_rx_mode        = w90p910_ether_set_multicast_list,
-       .ndo_set_mac_address    = w90p910_set_mac_address,
-       .ndo_do_ioctl           = w90p910_ether_ioctl,
-       .ndo_validate_addr      = eth_validate_addr,
-};
-
-static void get_mac_address(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-       struct platform_device *pdev;
-       char addr[ETH_ALEN];
-
-       pdev = ether->pdev;
-
-       addr[0] = 0x00;
-       addr[1] = 0x02;
-       addr[2] = 0xac;
-       addr[3] = 0x55;
-       addr[4] = 0x88;
-       addr[5] = 0xa8;
-
-       if (is_valid_ether_addr(addr))
-               memcpy(dev->dev_addr, &addr, ETH_ALEN);
-       else
-               dev_err(&pdev->dev, "invalid mac address\n");
-}
-
-static int w90p910_ether_setup(struct net_device *dev)
-{
-       struct w90p910_ether *ether = netdev_priv(dev);
-
-       dev->netdev_ops = &w90p910_ether_netdev_ops;
-       dev->ethtool_ops = &w90p910_ether_ethtool_ops;
-
-       dev->tx_queue_len = 16;
-       dev->dma = 0x0;
-       dev->watchdog_timeo = TX_TIMEOUT;
-
-       get_mac_address(dev);
-
-       ether->cur_tx = 0x0;
-       ether->cur_rx = 0x0;
-       ether->finish_tx = 0x0;
-       ether->linkflag = 0x0;
-       ether->mii.phy_id = 0x01;
-       ether->mii.phy_id_mask = 0x1f;
-       ether->mii.reg_num_mask = 0x1f;
-       ether->mii.dev = dev;
-       ether->mii.mdio_read = w90p910_mdio_read;
-       ether->mii.mdio_write = w90p910_mdio_write;
-
-       timer_setup(&ether->check_timer, w90p910_check_link, 0);
-
-       return 0;
-}
-
-static int w90p910_ether_probe(struct platform_device *pdev)
-{
-       struct w90p910_ether *ether;
-       struct net_device *dev;
-       int error;
-
-       dev = alloc_etherdev(sizeof(struct w90p910_ether));
-       if (!dev)
-               return -ENOMEM;
-
-       ether = netdev_priv(dev);
-
-       ether->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (ether->res == NULL) {
-               dev_err(&pdev->dev, "failed to get I/O memory\n");
-               error = -ENXIO;
-               goto failed_free;
-       }
-
-       if (!request_mem_region(ether->res->start,
-                               resource_size(ether->res), pdev->name)) {
-               dev_err(&pdev->dev, "failed to request I/O memory\n");
-               error = -EBUSY;
-               goto failed_free;
-       }
-
-       ether->reg = ioremap(ether->res->start, resource_size(ether->res));
-       if (ether->reg == NULL) {
-               dev_err(&pdev->dev, "failed to remap I/O memory\n");
-               error = -ENXIO;
-               goto failed_free_mem;
-       }
-
-       ether->txirq = platform_get_irq(pdev, 0);
-       if (ether->txirq < 0) {
-               dev_err(&pdev->dev, "failed to get ether tx irq\n");
-               error = -ENXIO;
-               goto failed_free_io;
-       }
-
-       ether->rxirq = platform_get_irq(pdev, 1);
-       if (ether->rxirq < 0) {
-               dev_err(&pdev->dev, "failed to get ether rx irq\n");
-               error = -ENXIO;
-               goto failed_free_io;
-       }
-
-       platform_set_drvdata(pdev, dev);
-
-       ether->clk = clk_get(&pdev->dev, NULL);
-       if (IS_ERR(ether->clk)) {
-               dev_err(&pdev->dev, "failed to get ether clock\n");
-               error = PTR_ERR(ether->clk);
-               goto failed_free_io;
-       }
-
-       ether->rmiiclk = clk_get(&pdev->dev, "RMII");
-       if (IS_ERR(ether->rmiiclk)) {
-               dev_err(&pdev->dev, "failed to get ether clock\n");
-               error = PTR_ERR(ether->rmiiclk);
-               goto failed_put_clk;
-       }
-
-       ether->pdev = pdev;
-
-       w90p910_ether_setup(dev);
-
-       error = register_netdev(dev);
-       if (error != 0) {
-               dev_err(&pdev->dev, "Register EMC w90p910 FAILED\n");
-               error = -ENODEV;
-               goto failed_put_rmiiclk;
-       }
-
-       return 0;
-failed_put_rmiiclk:
-       clk_put(ether->rmiiclk);
-failed_put_clk:
-       clk_put(ether->clk);
-failed_free_io:
-       iounmap(ether->reg);
-failed_free_mem:
-       release_mem_region(ether->res->start, resource_size(ether->res));
-failed_free:
-       free_netdev(dev);
-       return error;
-}
-
-static int w90p910_ether_remove(struct platform_device *pdev)
-{
-       struct net_device *dev = platform_get_drvdata(pdev);
-       struct w90p910_ether *ether = netdev_priv(dev);
-
-       unregister_netdev(dev);
-
-       clk_put(ether->rmiiclk);
-       clk_put(ether->clk);
-
-       iounmap(ether->reg);
-       release_mem_region(ether->res->start, resource_size(ether->res));
-
-       del_timer_sync(&ether->check_timer);
-
-       free_netdev(dev);
-       return 0;
-}
-
-static struct platform_driver w90p910_ether_driver = {
-       .probe          = w90p910_ether_probe,
-       .remove         = w90p910_ether_remove,
-       .driver         = {
-               .name   = "nuc900-emc",
-       },
-};
-
-module_platform_driver(w90p910_ether_driver);
-
-MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
-MODULE_DESCRIPTION("w90p910 MAC driver!");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:nuc900-emc");
-
index b327b29..a6b4bfa 100644 (file)
@@ -713,6 +713,21 @@ struct nv_skb_map {
        struct nv_skb_map *next_tx_ctx;
 };
 
+struct nv_txrx_stats {
+       u64 stat_rx_packets;
+       u64 stat_rx_bytes; /* not always available in HW */
+       u64 stat_rx_missed_errors;
+       u64 stat_rx_dropped;
+       u64 stat_tx_packets; /* not always available in HW */
+       u64 stat_tx_bytes;
+       u64 stat_tx_dropped;
+};
+
+#define nv_txrx_stats_inc(member) \
+               __this_cpu_inc(np->txrx_stats->member)
+#define nv_txrx_stats_add(member, count) \
+               __this_cpu_add(np->txrx_stats->member, (count))
+
 /*
  * SMP locking:
  * All hardware access under netdev_priv(dev)->lock, except the performance
@@ -797,10 +812,7 @@ struct fe_priv {
 
        /* RX software stats */
        struct u64_stats_sync swstats_rx_syncp;
-       u64 stat_rx_packets;
-       u64 stat_rx_bytes; /* not always available in HW */
-       u64 stat_rx_missed_errors;
-       u64 stat_rx_dropped;
+       struct nv_txrx_stats __percpu *txrx_stats;
 
        /* media detection workaround.
         * Locking: Within irq hander or disable_irq+spin_lock(&np->lock);
@@ -826,9 +838,6 @@ struct fe_priv {
 
        /* TX software stats */
        struct u64_stats_sync swstats_tx_syncp;
-       u64 stat_tx_packets; /* not always available in HW */
-       u64 stat_tx_bytes;
-       u64 stat_tx_dropped;
 
        /* msi/msi-x fields */
        u32 msi_flags;
@@ -1721,6 +1730,39 @@ static void nv_update_stats(struct net_device *dev)
        }
 }
 
+static void nv_get_stats(int cpu, struct fe_priv *np,
+                        struct rtnl_link_stats64 *storage)
+{
+       struct nv_txrx_stats *src = per_cpu_ptr(np->txrx_stats, cpu);
+       unsigned int syncp_start;
+       u64 rx_packets, rx_bytes, rx_dropped, rx_missed_errors;
+       u64 tx_packets, tx_bytes, tx_dropped;
+
+       do {
+               syncp_start = u64_stats_fetch_begin_irq(&np->swstats_rx_syncp);
+               rx_packets       = src->stat_rx_packets;
+               rx_bytes         = src->stat_rx_bytes;
+               rx_dropped       = src->stat_rx_dropped;
+               rx_missed_errors = src->stat_rx_missed_errors;
+       } while (u64_stats_fetch_retry_irq(&np->swstats_rx_syncp, syncp_start));
+
+       storage->rx_packets       += rx_packets;
+       storage->rx_bytes         += rx_bytes;
+       storage->rx_dropped       += rx_dropped;
+       storage->rx_missed_errors += rx_missed_errors;
+
+       do {
+               syncp_start = u64_stats_fetch_begin_irq(&np->swstats_tx_syncp);
+               tx_packets  = src->stat_tx_packets;
+               tx_bytes    = src->stat_tx_bytes;
+               tx_dropped  = src->stat_tx_dropped;
+       } while (u64_stats_fetch_retry_irq(&np->swstats_tx_syncp, syncp_start));
+
+       storage->tx_packets += tx_packets;
+       storage->tx_bytes   += tx_bytes;
+       storage->tx_dropped += tx_dropped;
+}
+
 /*
  * nv_get_stats64: dev->ndo_get_stats64 function
  * Get latest stats value from the nic.
@@ -1733,7 +1775,7 @@ nv_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage)
        __releases(&netdev_priv(dev)->hwstats_lock)
 {
        struct fe_priv *np = netdev_priv(dev);
-       unsigned int syncp_start;
+       int cpu;
 
        /*
         * Note: because HW stats are not always available and for
@@ -1746,20 +1788,8 @@ nv_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage)
         */
 
        /* software stats */
-       do {
-               syncp_start = u64_stats_fetch_begin_irq(&np->swstats_rx_syncp);
-               storage->rx_packets       = np->stat_rx_packets;
-               storage->rx_bytes         = np->stat_rx_bytes;
-               storage->rx_dropped       = np->stat_rx_dropped;
-               storage->rx_missed_errors = np->stat_rx_missed_errors;
-       } while (u64_stats_fetch_retry_irq(&np->swstats_rx_syncp, syncp_start));
-
-       do {
-               syncp_start = u64_stats_fetch_begin_irq(&np->swstats_tx_syncp);
-               storage->tx_packets = np->stat_tx_packets;
-               storage->tx_bytes   = np->stat_tx_bytes;
-               storage->tx_dropped = np->stat_tx_dropped;
-       } while (u64_stats_fetch_retry_irq(&np->swstats_tx_syncp, syncp_start));
+       for_each_online_cpu(cpu)
+               nv_get_stats(cpu, np, storage);
 
        /* If the nic supports hw counters then retrieve latest values */
        if (np->driver_data & DEV_HAS_STATISTICS_V123) {
@@ -1827,7 +1857,7 @@ static int nv_alloc_rx(struct net_device *dev)
                } else {
 packet_dropped:
                        u64_stats_update_begin(&np->swstats_rx_syncp);
-                       np->stat_rx_dropped++;
+                       nv_txrx_stats_inc(stat_rx_dropped);
                        u64_stats_update_end(&np->swstats_rx_syncp);
                        return 1;
                }
@@ -1869,7 +1899,7 @@ static int nv_alloc_rx_optimized(struct net_device *dev)
                } else {
 packet_dropped:
                        u64_stats_update_begin(&np->swstats_rx_syncp);
-                       np->stat_rx_dropped++;
+                       nv_txrx_stats_inc(stat_rx_dropped);
                        u64_stats_update_end(&np->swstats_rx_syncp);
                        return 1;
                }
@@ -2013,7 +2043,7 @@ static void nv_drain_tx(struct net_device *dev)
                }
                if (nv_release_txskb(np, &np->tx_skb[i])) {
                        u64_stats_update_begin(&np->swstats_tx_syncp);
-                       np->stat_tx_dropped++;
+                       nv_txrx_stats_inc(stat_tx_dropped);
                        u64_stats_update_end(&np->swstats_tx_syncp);
                }
                np->tx_skb[i].dma = 0;
@@ -2227,7 +2257,7 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        /* on DMA mapping error - drop the packet */
                        dev_kfree_skb_any(skb);
                        u64_stats_update_begin(&np->swstats_tx_syncp);
-                       np->stat_tx_dropped++;
+                       nv_txrx_stats_inc(stat_tx_dropped);
                        u64_stats_update_end(&np->swstats_tx_syncp);
                        return NETDEV_TX_OK;
                }
@@ -2273,7 +2303,7 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                dev_kfree_skb_any(skb);
                                np->put_tx_ctx = start_tx_ctx;
                                u64_stats_update_begin(&np->swstats_tx_syncp);
-                               np->stat_tx_dropped++;
+                               nv_txrx_stats_inc(stat_tx_dropped);
                                u64_stats_update_end(&np->swstats_tx_syncp);
                                return NETDEV_TX_OK;
                        }
@@ -2384,7 +2414,7 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
                        /* on DMA mapping error - drop the packet */
                        dev_kfree_skb_any(skb);
                        u64_stats_update_begin(&np->swstats_tx_syncp);
-                       np->stat_tx_dropped++;
+                       nv_txrx_stats_inc(stat_tx_dropped);
                        u64_stats_update_end(&np->swstats_tx_syncp);
                        return NETDEV_TX_OK;
                }
@@ -2431,7 +2461,7 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
                                dev_kfree_skb_any(skb);
                                np->put_tx_ctx = start_tx_ctx;
                                u64_stats_update_begin(&np->swstats_tx_syncp);
-                               np->stat_tx_dropped++;
+                               nv_txrx_stats_inc(stat_tx_dropped);
                                u64_stats_update_end(&np->swstats_tx_syncp);
                                return NETDEV_TX_OK;
                        }
@@ -2560,9 +2590,12 @@ static int nv_tx_done(struct net_device *dev, int limit)
                                            && !(flags & NV_TX_RETRYCOUNT_MASK))
                                                nv_legacybackoff_reseed(dev);
                                } else {
+                                       unsigned int len;
+
                                        u64_stats_update_begin(&np->swstats_tx_syncp);
-                                       np->stat_tx_packets++;
-                                       np->stat_tx_bytes += np->get_tx_ctx->skb->len;
+                                       nv_txrx_stats_inc(stat_tx_packets);
+                                       len = np->get_tx_ctx->skb->len;
+                                       nv_txrx_stats_add(stat_tx_bytes, len);
                                        u64_stats_update_end(&np->swstats_tx_syncp);
                                }
                                bytes_compl += np->get_tx_ctx->skb->len;
@@ -2577,9 +2610,12 @@ static int nv_tx_done(struct net_device *dev, int limit)
                                            && !(flags & NV_TX2_RETRYCOUNT_MASK))
                                                nv_legacybackoff_reseed(dev);
                                } else {
+                                       unsigned int len;
+
                                        u64_stats_update_begin(&np->swstats_tx_syncp);
-                                       np->stat_tx_packets++;
-                                       np->stat_tx_bytes += np->get_tx_ctx->skb->len;
+                                       nv_txrx_stats_inc(stat_tx_packets);
+                                       len = np->get_tx_ctx->skb->len;
+                                       nv_txrx_stats_add(stat_tx_bytes, len);
                                        u64_stats_update_end(&np->swstats_tx_syncp);
                                }
                                bytes_compl += np->get_tx_ctx->skb->len;
@@ -2627,9 +2663,12 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)
                                                nv_legacybackoff_reseed(dev);
                                }
                        } else {
+                               unsigned int len;
+
                                u64_stats_update_begin(&np->swstats_tx_syncp);
-                               np->stat_tx_packets++;
-                               np->stat_tx_bytes += np->get_tx_ctx->skb->len;
+                               nv_txrx_stats_inc(stat_tx_packets);
+                               len = np->get_tx_ctx->skb->len;
+                               nv_txrx_stats_add(stat_tx_bytes, len);
                                u64_stats_update_end(&np->swstats_tx_syncp);
                        }
 
@@ -2806,6 +2845,15 @@ static int nv_getlen(struct net_device *dev, void *packet, int datalen)
        }
 }
 
+static void rx_missing_handler(u32 flags, struct fe_priv *np)
+{
+       if (flags & NV_RX_MISSEDFRAME) {
+               u64_stats_update_begin(&np->swstats_rx_syncp);
+               nv_txrx_stats_inc(stat_rx_missed_errors);
+               u64_stats_update_end(&np->swstats_rx_syncp);
+       }
+}
+
 static int nv_rx_process(struct net_device *dev, int limit)
 {
        struct fe_priv *np = netdev_priv(dev);
@@ -2848,11 +2896,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
                                        }
                                        /* the rest are hard errors */
                                        else {
-                                               if (flags & NV_RX_MISSEDFRAME) {
-                                                       u64_stats_update_begin(&np->swstats_rx_syncp);
-                                                       np->stat_rx_missed_errors++;
-                                                       u64_stats_update_end(&np->swstats_rx_syncp);
-                                               }
+                                               rx_missing_handler(flags, np);
                                                dev_kfree_skb(skb);
                                                goto next_pkt;
                                        }
@@ -2896,8 +2940,8 @@ static int nv_rx_process(struct net_device *dev, int limit)
                skb->protocol = eth_type_trans(skb, dev);
                napi_gro_receive(&np->napi, skb);
                u64_stats_update_begin(&np->swstats_rx_syncp);
-               np->stat_rx_packets++;
-               np->stat_rx_bytes += len;
+               nv_txrx_stats_inc(stat_rx_packets);
+               nv_txrx_stats_add(stat_rx_bytes, len);
                u64_stats_update_end(&np->swstats_rx_syncp);
 next_pkt:
                if (unlikely(np->get_rx.orig++ == np->last_rx.orig))
@@ -2982,8 +3026,8 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
                        }
                        napi_gro_receive(&np->napi, skb);
                        u64_stats_update_begin(&np->swstats_rx_syncp);
-                       np->stat_rx_packets++;
-                       np->stat_rx_bytes += len;
+                       nv_txrx_stats_inc(stat_rx_packets);
+                       nv_txrx_stats_add(stat_rx_bytes, len);
                        u64_stats_update_end(&np->swstats_rx_syncp);
                } else {
                        dev_kfree_skb(skb);
@@ -5651,6 +5695,12 @@ static int nv_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
        SET_NETDEV_DEV(dev, &pci_dev->dev);
        u64_stats_init(&np->swstats_rx_syncp);
        u64_stats_init(&np->swstats_tx_syncp);
+       np->txrx_stats = alloc_percpu(struct nv_txrx_stats);
+       if (!np->txrx_stats) {
+               pr_err("np->txrx_stats, alloc memory error.\n");
+               err = -ENOMEM;
+               goto out_alloc_percpu;
+       }
 
        timer_setup(&np->oom_kick, nv_do_rx_refill, 0);
        timer_setup(&np->nic_poll, nv_do_nic_poll, 0);
@@ -6060,6 +6110,8 @@ out_relreg:
 out_disable:
        pci_disable_device(pci_dev);
 out_free:
+       free_percpu(np->txrx_stats);
+out_alloc_percpu:
        free_netdev(dev);
 out:
        return err;
@@ -6105,6 +6157,9 @@ static void nv_restore_mac_addr(struct pci_dev *pci_dev)
 static void nv_remove(struct pci_dev *pci_dev)
 {
        struct net_device *dev = pci_get_drvdata(pci_dev);
+       struct fe_priv *np = netdev_priv(dev);
+
+       free_percpu(np->txrx_stats);
 
        unregister_netdev(dev);
 
index 261f107..418afb8 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config LPC_ENET
         tristate "NXP ethernet MAC on LPC devices"
-        depends on ARCH_LPC32XX
+        depends on ARCH_LPC32XX || COMPILE_TEST
         select PHYLIB
         help
          Say Y or M here if you want to use the NXP ethernet MAC included on
index f7e11f1..141571e 100644 (file)
 #include <linux/crc32.h>
 #include <linux/etherdevice.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/of_net.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
-
-#include <mach/board.h>
-#include <mach/hardware.h>
-#include <mach/platform.h>
+#include <linux/soc/nxp/lpc32xx-misc.h>
 
 #define MODNAME "lpc-eth"
 #define DRV_VERSION "1.00"
@@ -1237,16 +1235,9 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
        dma_addr_t dma_handle;
        struct resource *res;
        int irq, ret;
-       u32 tmp;
 
        /* Setup network interface for RMII or MII mode */
-       tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL);
-       tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK;
-       if (lpc_phy_interface_mode(dev) == PHY_INTERFACE_MODE_MII)
-               tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS;
-       else
-               tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS;
-       __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL);
+       lpc32xx_set_phy_interface_mode(lpc_phy_interface_mode(dev));
 
        /* Get platform resources */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1311,19 +1302,18 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
        /* Get size of DMA buffers/descriptors region */
        pldat->dma_buff_size = (ENET_TX_DESC + ENET_RX_DESC) * (ENET_MAXF_SIZE +
                sizeof(struct txrx_desc_t) + sizeof(struct rx_status_t));
-       pldat->dma_buff_base_v = 0;
 
        if (use_iram_for_net(dev)) {
-               dma_handle = LPC32XX_IRAM_BASE;
-               if (pldat->dma_buff_size <= lpc32xx_return_iram_size())
-                       pldat->dma_buff_base_v =
-                               io_p2v(LPC32XX_IRAM_BASE);
-               else
+               if (pldat->dma_buff_size >
+                   lpc32xx_return_iram(&pldat->dma_buff_base_v, &dma_handle)) {
+                       pldat->dma_buff_base_v = NULL;
+                       pldat->dma_buff_size = 0;
                        netdev_err(ndev,
                                "IRAM not big enough for net buffers, using SDRAM instead.\n");
+               }
        }
 
-       if (pldat->dma_buff_base_v == 0) {
+       if (pldat->dma_buff_base_v == NULL) {
                ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32));
                if (ret)
                        goto err_out_free_irq;
@@ -1344,13 +1334,14 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
        pldat->dma_buff_base_p = dma_handle;
 
        netdev_dbg(ndev, "IO address space     :%pR\n", res);
-       netdev_dbg(ndev, "IO address size      :%d\n", resource_size(res));
+       netdev_dbg(ndev, "IO address size      :%zd\n",
+                       (size_t)resource_size(res));
        netdev_dbg(ndev, "IO address (mapped)  :0x%p\n",
                        pldat->net_base);
        netdev_dbg(ndev, "IRQ number           :%d\n", ndev->irq);
-       netdev_dbg(ndev, "DMA buffer size      :%d\n", pldat->dma_buff_size);
-       netdev_dbg(ndev, "DMA buffer P address :0x%08x\n",
-                       pldat->dma_buff_base_p);
+       netdev_dbg(ndev, "DMA buffer size      :%zd\n", pldat->dma_buff_size);
+       netdev_dbg(ndev, "DMA buffer P address :%pad\n",
+                       &pldat->dma_buff_base_p);
        netdev_dbg(ndev, "DMA buffer V address :0x%p\n",
                        pldat->dma_buff_base_v);
 
@@ -1397,8 +1388,8 @@ static int lpc_eth_drv_probe(struct platform_device *pdev)
        if (ret)
                goto err_out_unregister_netdev;
 
-       netdev_info(ndev, "LPC mac at 0x%08x irq %d\n",
-              res->start, ndev->irq);
+       netdev_info(ndev, "LPC mac at 0x%08lx irq %d\n",
+              (unsigned long)res->start, ndev->irq);
 
        device_init_wakeup(dev, 1);
        device_set_wakeup_enable(dev, 0);
@@ -1409,7 +1400,7 @@ err_out_unregister_netdev:
        unregister_netdev(ndev);
 err_out_dma_unmap:
        if (!use_iram_for_net(dev) ||
-           pldat->dma_buff_size > lpc32xx_return_iram_size())
+           pldat->dma_buff_size > lpc32xx_return_iram(NULL, NULL))
                dma_free_coherent(dev, pldat->dma_buff_size,
                                  pldat->dma_buff_base_v,
                                  pldat->dma_buff_base_p);
@@ -1436,7 +1427,7 @@ static int lpc_eth_drv_remove(struct platform_device *pdev)
        unregister_netdev(ndev);
 
        if (!use_iram_for_net(&pldat->pdev->dev) ||
-           pldat->dma_buff_size > lpc32xx_return_iram_size())
+           pldat->dma_buff_size > lpc32xx_return_iram(NULL, NULL))
                dma_free_coherent(&pldat->pdev->dev, pldat->dma_buff_size,
                                  pldat->dma_buff_base_v,
                                  pldat->dma_buff_base_p);
index 829dd60..1efff7f 100644 (file)
@@ -1325,7 +1325,7 @@ static int qed_slowpath_start(struct qed_dev *cdev,
                                              &drv_version);
                if (rc) {
                        DP_NOTICE(cdev, "Failed sending drv version command\n");
-                       return rc;
+                       goto err4;
                }
        }
 
@@ -1333,6 +1333,8 @@ static int qed_slowpath_start(struct qed_dev *cdev,
 
        return 0;
 
+err4:
+       qed_ll2_dealloc_if(cdev);
 err3:
        qed_hw_stop(cdev);
 err2:
index e1dd6ea..bae0074 100644 (file)
@@ -5921,6 +5921,7 @@ static struct sk_buff *rtl8169_try_rx_copy(void *data,
        skb = napi_alloc_skb(&tp->napi, pkt_size);
        if (skb)
                skb_copy_to_linear_data(skb, data, pkt_size);
+       dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE);
 
        return skb;
 }
index 7a5e6c5..276c7ca 100644 (file)
@@ -794,15 +794,16 @@ static int sgiseeq_probe(struct platform_device *pdev)
                printk(KERN_ERR "Sgiseeq: Cannot register net device, "
                       "aborting.\n");
                err = -ENODEV;
-               goto err_out_free_page;
+               goto err_out_free_attrs;
        }
 
        printk(KERN_INFO "%s: %s %pM\n", dev->name, sgiseeqstr, dev->dev_addr);
 
        return 0;
 
-err_out_free_page:
-       free_page((unsigned long) sp->srings);
+err_out_free_attrs:
+       dma_free_attrs(&pdev->dev, sizeof(*sp->srings), sp->srings,
+                      sp->srings_dma, DMA_ATTR_NON_CONSISTENT);
 err_out_free_dev:
        free_netdev(dev);
 
index 4644b2a..e2e469c 100644 (file)
@@ -1194,10 +1194,8 @@ static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
        int ret;
        struct device *dev = &bsp_priv->pdev->dev;
 
-       if (!ldo) {
-               dev_err(dev, "no regulator found\n");
-               return -1;
-       }
+       if (!ldo)
+               return 0;
 
        if (enable) {
                ret = regulator_enable(ldo);
index 4083019..f97a409 100644 (file)
@@ -873,7 +873,12 @@ static int sun8i_dwmac_set_syscon(struct stmmac_priv *priv)
        int ret;
        u32 reg, val;
 
-       regmap_field_read(gmac->regmap_field, &val);
+       ret = regmap_field_read(gmac->regmap_field, &val);
+       if (ret) {
+               dev_err(priv->device, "Fail to read from regmap field.\n");
+               return ret;
+       }
+
        reg = gmac->variant->default_syscon_value;
        if (reg != val)
                dev_warn(priv->device,
index 32a8974..a46b8b2 100644 (file)
@@ -2775,6 +2775,7 @@ static int cpsw_probe(struct platform_device *pdev)
        if (!cpsw)
                return -ENOMEM;
 
+       platform_set_drvdata(pdev, cpsw);
        cpsw->dev = dev;
 
        mode = devm_gpiod_get_array_optional(dev, "mode", GPIOD_OUT_LOW);
@@ -2879,7 +2880,6 @@ static int cpsw_probe(struct platform_device *pdev)
                goto clean_cpts;
        }
 
-       platform_set_drvdata(pdev, cpsw);
        priv = netdev_priv(ndev);
        priv->cpsw = cpsw;
        priv->ndev = ndev;
index 331c16d..23281ae 100644 (file)
@@ -344,10 +344,10 @@ static void sp_bump(struct sixpack *sp, char cmd)
 
        sp->dev->stats.rx_bytes += count;
 
-       if ((skb = dev_alloc_skb(count)) == NULL)
+       if ((skb = dev_alloc_skb(count + 1)) == NULL)
                goto out_mem;
 
-       ptr = skb_put(skb, count);
+       ptr = skb_put(skb, count + 1);
        *ptr++ = cmd;   /* KISS command */
 
        memcpy(ptr, sp->cooked_buf + 1, count);
index b41696e..c20e7ef 100644 (file)
@@ -802,7 +802,7 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev,
                err = hwsim_subscribe_all_others(phy);
                if (err < 0) {
                        mutex_unlock(&hwsim_phys_lock);
-                       goto err_reg;
+                       goto err_subscribe;
                }
        }
        list_add_tail(&phy->list, &hwsim_phys);
@@ -812,6 +812,8 @@ static int hwsim_add_one(struct genl_info *info, struct device *dev,
 
        return idx;
 
+err_subscribe:
+       ieee802154_unregister_hw(phy->hw);
 err_reg:
        kfree(pib);
 err_pib:
@@ -901,9 +903,9 @@ static __init int hwsim_init_module(void)
        return 0;
 
 platform_drv:
-       genl_unregister_family(&hwsim_genl_family);
-platform_dev:
        platform_device_unregister(mac802154hwsim_dev);
+platform_dev:
+       genl_unregister_family(&hwsim_genl_family);
        return rc;
 }
 
index 58bb25e..7935593 100644 (file)
@@ -523,6 +523,32 @@ int genphy_c45_read_status(struct phy_device *phydev)
 }
 EXPORT_SYMBOL_GPL(genphy_c45_read_status);
 
+/**
+ * genphy_c45_config_aneg - restart auto-negotiation or forced setup
+ * @phydev: target phy_device struct
+ *
+ * Description: If auto-negotiation is enabled, we configure the
+ *   advertising, and then restart auto-negotiation.  If it is not
+ *   enabled, then we force a configuration.
+ */
+int genphy_c45_config_aneg(struct phy_device *phydev)
+{
+       bool changed = false;
+       int ret;
+
+       if (phydev->autoneg == AUTONEG_DISABLE)
+               return genphy_c45_pma_setup_forced(phydev);
+
+       ret = genphy_c45_an_config_aneg(phydev);
+       if (ret < 0)
+               return ret;
+       if (ret > 0)
+               changed = true;
+
+       return genphy_c45_check_and_restart_aneg(phydev, changed);
+}
+EXPORT_SYMBOL_GPL(genphy_c45_config_aneg);
+
 /* The gen10g_* functions are the old Clause 45 stub */
 
 int gen10g_config_aneg(struct phy_device *phydev)
index ef7aa73..6b0f893 100644 (file)
@@ -507,7 +507,7 @@ static int phy_config_aneg(struct phy_device *phydev)
         * allowed to call genphy_config_aneg()
         */
        if (phydev->is_c45 && !(phydev->c45_ids.devices_in_package & BIT(0)))
-               return -EOPNOTSUPP;
+               return genphy_c45_config_aneg(phydev);
 
        return genphy_config_aneg(phydev);
 }
index a45c5de..a5a57ca 100644 (file)
@@ -376,8 +376,8 @@ static void phylink_get_fixed_state(struct phylink *pl, struct phylink_link_stat
  *  Local device  Link partner
  *  Pause AsymDir Pause AsymDir Result
  *    1     X       1     X     TX+RX
- *    0     1       1     1     RX
- *    1     1       0     1     TX
+ *    0     1       1     1     TX
+ *    1     1       0     1     RX
  */
 static void phylink_resolve_flow(struct phylink *pl,
                                 struct phylink_link_state *state)
@@ -398,7 +398,7 @@ static void phylink_resolve_flow(struct phylink *pl,
                        new_pause = MLO_PAUSE_TX | MLO_PAUSE_RX;
                else if (pause & MLO_PAUSE_ASYM)
                        new_pause = state->pause & MLO_PAUSE_SYM ?
-                                MLO_PAUSE_RX : MLO_PAUSE_TX;
+                                MLO_PAUSE_TX : MLO_PAUSE_RX;
        } else {
                new_pause = pl->link_config.pause & MLO_PAUSE_TXRX_MASK;
        }
index db16d7a..aab0be4 100644 (file)
@@ -787,7 +787,8 @@ static void tun_detach_all(struct net_device *dev)
 }
 
 static int tun_attach(struct tun_struct *tun, struct file *file,
-                     bool skip_filter, bool napi, bool napi_frags)
+                     bool skip_filter, bool napi, bool napi_frags,
+                     bool publish_tun)
 {
        struct tun_file *tfile = file->private_data;
        struct net_device *dev = tun->dev;
@@ -870,7 +871,8 @@ static int tun_attach(struct tun_struct *tun, struct file *file,
         * initialized tfile; otherwise we risk using half-initialized
         * object.
         */
-       rcu_assign_pointer(tfile->tun, tun);
+       if (publish_tun)
+               rcu_assign_pointer(tfile->tun, tun);
        rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile);
        tun->numqueues++;
        tun_set_real_num_queues(tun);
@@ -2730,7 +2732,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 
                err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER,
                                 ifr->ifr_flags & IFF_NAPI,
-                                ifr->ifr_flags & IFF_NAPI_FRAGS);
+                                ifr->ifr_flags & IFF_NAPI_FRAGS, true);
                if (err < 0)
                        return err;
 
@@ -2829,13 +2831,17 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 
                INIT_LIST_HEAD(&tun->disabled);
                err = tun_attach(tun, file, false, ifr->ifr_flags & IFF_NAPI,
-                                ifr->ifr_flags & IFF_NAPI_FRAGS);
+                                ifr->ifr_flags & IFF_NAPI_FRAGS, false);
                if (err < 0)
                        goto err_free_flow;
 
                err = register_netdevice(tun->dev);
                if (err < 0)
                        goto err_detach;
+               /* free_netdev() won't check refcnt, to aovid race
+                * with dev_put() we need publish tun after registration.
+                */
+               rcu_assign_pointer(tfile->tun, tun);
        }
 
        netif_carrier_on(tun->dev);
@@ -2978,7 +2984,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
                if (ret < 0)
                        goto unlock;
                ret = tun_attach(tun, file, false, tun->flags & IFF_NAPI,
-                                tun->flags & IFF_NAPI_FRAGS);
+                                tun->flags & IFF_NAPI_FRAGS, true);
        } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
                tun = rtnl_dereference(tfile->tun);
                if (!tun || !(tun->flags & IFF_MULTI_QUEUE) || tfile->detached)
index 8458e88..32f53de 100644 (file)
@@ -206,7 +206,15 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
                goto bad_desc;
        }
 skip:
-       if (rndis && header.usb_cdc_acm_descriptor &&
+       /* Communcation class functions with bmCapabilities are not
+        * RNDIS.  But some Wireless class RNDIS functions use
+        * bmCapabilities for their own purpose. The failsafe is
+        * therefore applied only to Communication class RNDIS
+        * functions.  The rndis test is redundant, but a cheap
+        * optimization.
+        */
+       if (rndis && is_rndis(&intf->cur_altsetting->desc) &&
+           header.usb_cdc_acm_descriptor &&
            header.usb_cdc_acm_descriptor->bmCapabilities) {
                dev_dbg(&intf->dev,
                        "ACM capabilities %02x, not really RNDIS?\n",
index 0cc03a9..04137ac 100644 (file)
@@ -799,8 +799,11 @@ int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
        ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0),
                              RTL8152_REQ_GET_REGS, RTL8152_REQT_READ,
                              value, index, tmp, size, 500);
+       if (ret < 0)
+               memset(data, 0xff, size);
+       else
+               memcpy(data, tmp, size);
 
-       memcpy(data, tmp, size);
        kfree(tmp);
 
        return ret;
@@ -4018,8 +4021,7 @@ static int rtl8152_close(struct net_device *netdev)
 #ifdef CONFIG_PM_SLEEP
        unregister_pm_notifier(&tp->pm_notifier);
 #endif
-       if (!test_bit(RTL8152_UNPLUG, &tp->flags))
-               napi_disable(&tp->napi);
+       napi_disable(&tp->napi);
        clear_bit(WORK_ENABLE, &tp->flags);
        usb_kill_urb(tp->intr_urb);
        cancel_delayed_work_sync(&tp->schedule);
@@ -5350,7 +5352,6 @@ static int rtl8152_probe(struct usb_interface *intf,
        return 0;
 
 out1:
-       netif_napi_del(&tp->napi);
        usb_set_intfdata(intf, NULL);
 out:
        free_netdev(netdev);
@@ -5365,7 +5366,6 @@ static void rtl8152_disconnect(struct usb_interface *intf)
        if (tp) {
                rtl_set_unplug(tp);
 
-               netif_napi_del(&tp->napi);
                unregister_netdev(tp->netdev);
                cancel_delayed_work_sync(&tp->hw_phy_work);
                tp->rtl_ops.unload(tp);
index 4f3de0a..ba98e09 100644 (file)
@@ -1331,7 +1331,7 @@ static int virtnet_receive(struct receive_queue *rq, int budget,
                }
        }
 
-       if (rq->vq->num_free > virtqueue_get_vring_size(rq->vq) / 2) {
+       if (rq->vq->num_free > min((unsigned int)budget, virtqueue_get_vring_size(rq->vq)) / 2) {
                if (!try_fill_recv(vi, rq, GFP_ATOMIC))
                        schedule_delayed_work(&vi->refill, 0);
        }
index d743496..0e6a515 100644 (file)
@@ -1115,7 +1115,7 @@ static void lmc_running_reset (struct net_device *dev) /*fold00*/
     sc->lmc_cmdmode |= (TULIP_CMD_TXRUN | TULIP_CMD_RXRUN);
     LMC_CSR_WRITE (sc, csr_command, sc->lmc_cmdmode);
 
-    lmc_trace(dev, "lmc_runnin_reset_out");
+    lmc_trace(dev, "lmc_running_reset_out");
 }
 
 
index 6642bcb..8efb493 100644 (file)
@@ -127,6 +127,7 @@ int i2400m_op_rfkill_sw_toggle(struct wimax_dev *wimax_dev,
                        "%d\n", result);
        result = 0;
 error_cmd:
+       kfree(cmd);
        kfree_skb(ack_skb);
 error_msg_to_dev:
 error_alloc:
index 1f500cd..55b7132 100644 (file)
@@ -556,6 +556,30 @@ const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0 = {
        .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
 };
 
+const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0 = {
+       .name = "Killer(R) Wi-Fi 6 AX1650i 160MHz Wireless Network Adapter (201NGW)",
+       .fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
+       IWL_DEVICE_22500,
+       /*
+        * This device doesn't support receiving BlockAck with a large bitmap
+        * so we need to restrict the size of transmitted aggregation to the
+        * HT size; mac80211 would otherwise pick the HE max (256) by default.
+        */
+       .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
+};
+
+const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0 = {
+       .name = "Killer(R) Wi-Fi 6 AX1650s 160MHz Wireless Network Adapter (201D2W)",
+       .fw_name_pre = IWL_QU_C_HR_B_FW_PRE,
+       IWL_DEVICE_22500,
+       /*
+        * This device doesn't support receiving BlockAck with a large bitmap
+        * so we need to restrict the size of transmitted aggregation to the
+        * HT size; mac80211 would otherwise pick the HE max (256) by default.
+        */
+       .max_tx_agg_size = IEEE80211_MAX_AMPDU_BUF_HT,
+};
+
 const struct iwl_cfg iwl22000_2ax_cfg_jf = {
        .name = "Intel(R) Dual Band Wireless AX 22000",
        .fw_name_pre = IWL_QU_B_JF_B_FW_PRE,
index 1c1bf1b..6c04f82 100644 (file)
@@ -577,6 +577,8 @@ extern const struct iwl_cfg iwl_ax1650i_cfg_quz_hr;
 extern const struct iwl_cfg iwl_ax1650s_cfg_quz_hr;
 extern const struct iwl_cfg killer1650s_2ax_cfg_qu_b0_hr_b0;
 extern const struct iwl_cfg killer1650i_2ax_cfg_qu_b0_hr_b0;
+extern const struct iwl_cfg killer1650s_2ax_cfg_qu_c0_hr_b0;
+extern const struct iwl_cfg killer1650i_2ax_cfg_qu_c0_hr_b0;
 extern const struct iwl_cfg killer1650x_2ax_cfg;
 extern const struct iwl_cfg killer1650w_2ax_cfg;
 extern const struct iwl_cfg iwl9461_2ac_cfg_qu_b0_jf_b0;
index cb22d44..fe776e3 100644 (file)
@@ -554,7 +554,7 @@ static void iwl_mvm_mac_ctxt_cmd_common(struct iwl_mvm *mvm,
                cpu_to_le32(vif->bss_conf.use_short_slot ?
                            MAC_FLG_SHORT_SLOT : 0);
 
-       cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP);
+       cmd->filter_flags = 0;
 
        for (i = 0; i < IEEE80211_NUM_ACS; i++) {
                u8 txf = iwl_mvm_mac_ac_to_tx_fifo(mvm, i);
@@ -623,6 +623,8 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
        /* We need the dtim_period to set the MAC as associated */
        if (vif->bss_conf.assoc && vif->bss_conf.dtim_period &&
            !force_assoc_off) {
+               struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+               u8 ap_sta_id = mvmvif->ap_sta_id;
                u32 dtim_offs;
 
                /*
@@ -658,6 +660,29 @@ static int iwl_mvm_mac_ctxt_cmd_sta(struct iwl_mvm *mvm,
                               dtim_offs);
 
                ctxt_sta->is_assoc = cpu_to_le32(1);
+
+               /*
+                * allow multicast data frames only as long as the station is
+                * authorized, i.e., GTK keys are already installed (if needed)
+                */
+               if (ap_sta_id < IWL_MVM_STATION_COUNT) {
+                       struct ieee80211_sta *sta;
+
+                       rcu_read_lock();
+
+                       sta = rcu_dereference(mvm->fw_id_to_mac_id[ap_sta_id]);
+                       if (!IS_ERR_OR_NULL(sta)) {
+                               struct iwl_mvm_sta *mvmsta =
+                                       iwl_mvm_sta_from_mac80211(sta);
+
+                               if (mvmsta->sta_state ==
+                                   IEEE80211_STA_AUTHORIZED)
+                                       cmd.filter_flags |=
+                                               cpu_to_le32(MAC_FILTER_ACCEPT_GRP);
+                       }
+
+                       rcu_read_unlock();
+               }
        } else {
                ctxt_sta->is_assoc = cpu_to_le32(0);
 
@@ -703,7 +728,8 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
                                       MAC_FILTER_IN_CONTROL_AND_MGMT |
                                       MAC_FILTER_IN_BEACON |
                                       MAC_FILTER_IN_PROBE_REQUEST |
-                                      MAC_FILTER_IN_CRC32);
+                                      MAC_FILTER_IN_CRC32 |
+                                      MAC_FILTER_ACCEPT_GRP);
        ieee80211_hw_set(mvm->hw, RX_INCLUDES_FCS);
 
        /* Allocate sniffer station */
@@ -727,7 +753,8 @@ static int iwl_mvm_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm,
        iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, NULL, action);
 
        cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON |
-                                      MAC_FILTER_IN_PROBE_REQUEST);
+                                      MAC_FILTER_IN_PROBE_REQUEST |
+                                      MAC_FILTER_ACCEPT_GRP);
 
        /* cmd.ibss.beacon_time/cmd.ibss.beacon_tsf are curently ignored */
        cmd.ibss.bi = cpu_to_le32(vif->bss_conf.beacon_int);
index 1c904b5..a7bc00d 100644 (file)
@@ -3327,10 +3327,20 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
                /* enable beacon filtering */
                WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, 0));
 
+               /*
+                * Now that the station is authorized, i.e., keys were already
+                * installed, need to indicate to the FW that
+                * multicast data frames can be forwarded to the driver
+                */
+               iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
+
                iwl_mvm_rs_rate_init(mvm, sta, mvmvif->phy_ctxt->channel->band,
                                     true);
        } else if (old_state == IEEE80211_STA_AUTHORIZED &&
                   new_state == IEEE80211_STA_ASSOC) {
+               /* Multicast data frames are no longer allowed */
+               iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
+
                /* disable beacon filtering */
                ret = iwl_mvm_disable_beacon_filter(mvm, vif, 0);
                WARN_ON(ret &&
index de711c1..3b12e7a 100644 (file)
@@ -1062,7 +1062,28 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                        iwl_trans->cfg = &iwl9560_2ac_cfg_qu_c0_jf_b0;
                else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0)
                        iwl_trans->cfg = &iwl9560_2ac_160_cfg_qu_c0_jf_b0;
+               else if (iwl_trans->cfg == &killer1650s_2ax_cfg_qu_b0_hr_b0)
+                       iwl_trans->cfg = &killer1650s_2ax_cfg_qu_c0_hr_b0;
+               else if (iwl_trans->cfg == &killer1650i_2ax_cfg_qu_b0_hr_b0)
+                       iwl_trans->cfg = &killer1650i_2ax_cfg_qu_c0_hr_b0;
        }
+
+       /* same thing for QuZ... */
+       if (iwl_trans->hw_rev == CSR_HW_REV_TYPE_QUZ) {
+               if (iwl_trans->cfg == &iwl_ax101_cfg_qu_hr)
+                       iwl_trans->cfg = &iwl_ax101_cfg_quz_hr;
+               else if (iwl_trans->cfg == &iwl_ax201_cfg_qu_hr)
+                       iwl_trans->cfg = &iwl_ax201_cfg_quz_hr;
+               else if (iwl_trans->cfg == &iwl9461_2ac_cfg_qu_b0_jf_b0)
+                       iwl_trans->cfg = &iwl9461_2ac_cfg_quz_a0_jf_b0_soc;
+               else if (iwl_trans->cfg == &iwl9462_2ac_cfg_qu_b0_jf_b0)
+                       iwl_trans->cfg = &iwl9462_2ac_cfg_quz_a0_jf_b0_soc;
+               else if (iwl_trans->cfg == &iwl9560_2ac_cfg_qu_b0_jf_b0)
+                       iwl_trans->cfg = &iwl9560_2ac_cfg_quz_a0_jf_b0_soc;
+               else if (iwl_trans->cfg == &iwl9560_2ac_160_cfg_qu_b0_jf_b0)
+                       iwl_trans->cfg = &iwl9560_2ac_160_cfg_quz_a0_jf_b0_soc;
+       }
+
 #endif
 
        pci_set_drvdata(pdev, iwl_trans);
index f5df5b3..db62c83 100644 (file)
@@ -3602,11 +3602,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
                }
        } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
                   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
-                  ((trans->cfg != &iwl_ax200_cfg_cc &&
-                    trans->cfg != &killer1650x_2ax_cfg &&
-                    trans->cfg != &killer1650w_2ax_cfg &&
-                    trans->cfg != &iwl_ax201_cfg_quz_hr) ||
-                   trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
+                  trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) {
                u32 hw_status;
 
                hw_status = iwl_read_prph(trans, UMAG_GEN_HW_STATUS);
index 38d1103..9ef6b8f 100644 (file)
@@ -99,10 +99,7 @@ void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie,
        u16 len = byte_cnt;
        __le16 bc_ent;
 
-       if (trans_pcie->bc_table_dword)
-               len = DIV_ROUND_UP(len, 4);
-
-       if (WARN_ON(len > 0xFFF || idx >= txq->n_window))
+       if (WARN(idx >= txq->n_window, "%d >= %d\n", idx, txq->n_window))
                return;
 
        filled_tfd_size = offsetof(struct iwl_tfh_tfd, tbs) +
@@ -117,11 +114,20 @@ void iwl_pcie_gen2_update_byte_tbl(struct iwl_trans_pcie *trans_pcie,
         */
        num_fetch_chunks = DIV_ROUND_UP(filled_tfd_size, 64) - 1;
 
-       bc_ent = cpu_to_le16(len | (num_fetch_chunks << 12));
-       if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560)
+       if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_22560) {
+               /* Starting from 22560, the HW expects bytes */
+               WARN_ON(trans_pcie->bc_table_dword);
+               WARN_ON(len > 0x3FFF);
+               bc_ent = cpu_to_le16(len | (num_fetch_chunks << 14));
                scd_bc_tbl_gen3->tfd_offset[idx] = bc_ent;
-       else
+       } else {
+               /* Until 22560, the HW expects DW */
+               WARN_ON(!trans_pcie->bc_table_dword);
+               len = DIV_ROUND_UP(len, 4);
+               WARN_ON(len > 0xFFF);
+               bc_ent = cpu_to_le16(len | (num_fetch_chunks << 12));
                scd_bc_tbl->tfd_offset[idx] = bc_ent;
+       }
 }
 
 /*
index 653d347..580387f 100644 (file)
@@ -241,6 +241,9 @@ static int mwifiex_update_vs_ie(const u8 *ies, int ies_len,
                }
 
                vs_ie = (struct ieee_types_header *)vendor_ie;
+               if (le16_to_cpu(ie->ie_length) + vs_ie->len + 2 >
+                       IEEE_MAX_IE_SIZE)
+                       return -EINVAL;
                memcpy(ie->ie_buffer + le16_to_cpu(ie->ie_length),
                       vs_ie, vs_ie->len + 2);
                le16_unaligned_add_cpu(&ie->ie_length, vs_ie->len + 2);
index 18f7d9b..0939a8c 100644 (file)
@@ -265,6 +265,8 @@ mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
 
        rate_ie = (void *)cfg80211_find_ie(WLAN_EID_SUPP_RATES, var_pos, len);
        if (rate_ie) {
+               if (rate_ie->len > MWIFIEX_SUPPORTED_RATES)
+                       return;
                memcpy(bss_cfg->rates, rate_ie + 1, rate_ie->len);
                rate_len = rate_ie->len;
        }
@@ -272,8 +274,11 @@ mwifiex_set_uap_rates(struct mwifiex_uap_bss_param *bss_cfg,
        rate_ie = (void *)cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES,
                                           params->beacon.tail,
                                           params->beacon.tail_len);
-       if (rate_ie)
+       if (rate_ie) {
+               if (rate_ie->len > MWIFIEX_SUPPORTED_RATES - rate_len)
+                       return;
                memcpy(bss_cfg->rates + rate_len, rate_ie + 1, rate_ie->len);
+       }
 
        return;
 }
@@ -391,6 +396,8 @@ mwifiex_set_wmm_params(struct mwifiex_private *priv,
                                            params->beacon.tail_len);
        if (vendor_ie) {
                wmm_ie = vendor_ie;
+               if (*(wmm_ie + 1) > sizeof(struct mwifiex_types_wmm_info))
+                       return;
                memcpy(&bss_cfg->wmm_info, wmm_ie +
                       sizeof(struct ieee_types_header), *(wmm_ie + 1));
                priv->wmm_enabled = 1;
index 40c0d53..9d4426f 100644 (file)
@@ -59,6 +59,11 @@ static void mt76x0_set_chip_cap(struct mt76x02_dev *dev)
                dev_dbg(dev->mt76.dev, "mask out 2GHz support\n");
        }
 
+       if (is_mt7630(dev)) {
+               dev->mt76.cap.has_5ghz = false;
+               dev_dbg(dev->mt76.dev, "mask out 5GHz support\n");
+       }
+
        if (!mt76x02_field_valid(nic_conf1 & 0xff))
                nic_conf1 &= 0xff00;
 
index 4585e1b..6117e6c 100644 (file)
@@ -62,6 +62,19 @@ static void mt76x0e_stop(struct ieee80211_hw *hw)
        mt76x0e_stop_hw(dev);
 }
 
+static int
+mt76x0e_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+               struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+               struct ieee80211_key_conf *key)
+{
+       struct mt76x02_dev *dev = hw->priv;
+
+       if (is_mt7630(dev))
+               return -EOPNOTSUPP;
+
+       return mt76x02_set_key(hw, cmd, vif, sta, key);
+}
+
 static void
 mt76x0e_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
              u32 queues, bool drop)
@@ -78,7 +91,7 @@ static const struct ieee80211_ops mt76x0e_ops = {
        .configure_filter = mt76x02_configure_filter,
        .bss_info_changed = mt76x02_bss_info_changed,
        .sta_state = mt76_sta_state,
-       .set_key = mt76x02_set_key,
+       .set_key = mt76x0e_set_key,
        .conf_tx = mt76x02_conf_tx,
        .sw_scan_start = mt76x02_sw_scan,
        .sw_scan_complete = mt76x02_sw_scan_complete,
index 627ed1f..645f4d1 100644 (file)
@@ -136,11 +136,11 @@ static const struct ieee80211_ops mt76x0u_ops = {
        .release_buffered_frames = mt76_release_buffered_frames,
 };
 
-static int mt76x0u_init_hardware(struct mt76x02_dev *dev)
+static int mt76x0u_init_hardware(struct mt76x02_dev *dev, bool reset)
 {
        int err;
 
-       mt76x0_chip_onoff(dev, true, true);
+       mt76x0_chip_onoff(dev, true, reset);
 
        if (!mt76x02_wait_for_mac(&dev->mt76))
                return -ETIMEDOUT;
@@ -173,7 +173,7 @@ static int mt76x0u_register_device(struct mt76x02_dev *dev)
        if (err < 0)
                goto out_err;
 
-       err = mt76x0u_init_hardware(dev);
+       err = mt76x0u_init_hardware(dev, true);
        if (err < 0)
                goto out_err;
 
@@ -309,7 +309,7 @@ static int __maybe_unused mt76x0_resume(struct usb_interface *usb_intf)
        if (ret < 0)
                goto err;
 
-       ret = mt76x0u_init_hardware(dev);
+       ret = mt76x0u_init_hardware(dev, false);
        if (ret)
                goto err;
 
index c9b957a..f1cdcd6 100644 (file)
@@ -1654,13 +1654,18 @@ static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
 
        offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
 
-       rt2800_register_multiread(rt2x00dev, offset,
-                                 &iveiv_entry, sizeof(iveiv_entry));
-       if ((crypto->cipher == CIPHER_TKIP) ||
-           (crypto->cipher == CIPHER_TKIP_NO_MIC) ||
-           (crypto->cipher == CIPHER_AES))
-               iveiv_entry.iv[3] |= 0x20;
-       iveiv_entry.iv[3] |= key->keyidx << 6;
+       if (crypto->cmd == SET_KEY) {
+               rt2800_register_multiread(rt2x00dev, offset,
+                                         &iveiv_entry, sizeof(iveiv_entry));
+               if ((crypto->cipher == CIPHER_TKIP) ||
+                   (crypto->cipher == CIPHER_TKIP_NO_MIC) ||
+                   (crypto->cipher == CIPHER_AES))
+                       iveiv_entry.iv[3] |= 0x20;
+               iveiv_entry.iv[3] |= key->keyidx << 6;
+       } else {
+               memset(&iveiv_entry, 0, sizeof(iveiv_entry));
+       }
+
        rt2800_register_multiwrite(rt2x00dev, offset,
                                   &iveiv_entry, sizeof(iveiv_entry));
 }
@@ -4237,24 +4242,18 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
        switch (rt2x00dev->default_ant.rx_chain_num) {
        case 3:
                /* Turn on tertiary LNAs */
-               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN,
-                                  rf->channel > 14);
-               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN,
-                                  rf->channel <= 14);
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, 1);
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, 1);
                /* fall-through */
        case 2:
                /* Turn on secondary LNAs */
-               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN,
-                                  rf->channel > 14);
-               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN,
-                                  rf->channel <= 14);
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1);
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1);
                /* fall-through */
        case 1:
                /* Turn on primary LNAs */
-               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN,
-                                  rf->channel > 14);
-               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN,
-                                  rf->channel <= 14);
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
                break;
        }
 
@@ -6095,6 +6094,15 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
        }
 
        /*
+        * Clear encryption initialization vectors on start, but keep them
+        * for watchdog reset. Otherwise we will have wrong IVs and not be
+        * able to keep connections after reset.
+        */
+       if (!test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags))
+               for (i = 0; i < 256; i++)
+                       rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
+
+       /*
         * Clear all beacons
         */
        for (i = 0; i < 8; i++)
index 7e43690..2b216ed 100644 (file)
@@ -658,6 +658,7 @@ enum rt2x00_state_flags {
        DEVICE_STATE_ENABLED_RADIO,
        DEVICE_STATE_SCANNING,
        DEVICE_STATE_FLUSHING,
+       DEVICE_STATE_RESET,
 
        /*
         * Driver configuration
index 35414f9..9d15823 100644 (file)
@@ -1256,13 +1256,14 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
 
 int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
 {
-       int retval;
+       int retval = 0;
 
        if (test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) {
                /*
                 * This is special case for ieee80211_restart_hw(), otherwise
                 * mac80211 never call start() two times in row without stop();
                 */
+               set_bit(DEVICE_STATE_RESET, &rt2x00dev->flags);
                rt2x00dev->ops->lib->pre_reset_hw(rt2x00dev);
                rt2x00lib_stop(rt2x00dev);
        }
@@ -1273,14 +1274,14 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
         */
        retval = rt2x00lib_load_firmware(rt2x00dev);
        if (retval)
-               return retval;
+               goto out;
 
        /*
         * Initialize the device.
         */
        retval = rt2x00lib_initialize(rt2x00dev);
        if (retval)
-               return retval;
+               goto out;
 
        rt2x00dev->intf_ap_count = 0;
        rt2x00dev->intf_sta_count = 0;
@@ -1289,11 +1290,13 @@ int rt2x00lib_start(struct rt2x00_dev *rt2x00dev)
        /* Enable the radio */
        retval = rt2x00lib_enable_radio(rt2x00dev);
        if (retval)
-               return retval;
+               goto out;
 
        set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags);
 
-       return 0;
+out:
+       clear_bit(DEVICE_STATE_RESET, &rt2x00dev->flags);
+       return retval;
 }
 
 void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev)
index f5048d4..760eaff 100644 (file)
@@ -645,7 +645,6 @@ fail_rx:
        kfree(rsi_dev->tx_buffer);
 
 fail_eps:
-       kfree(rsi_dev);
 
        return status;
 }
index e428500..7eda62a 100644 (file)
@@ -316,7 +316,7 @@ static int st95hf_echo_command(struct st95hf_context *st95context)
                                          &echo_response);
        if (result) {
                dev_err(&st95context->spicontext.spidev->dev,
-                       "err: echo response receieve error = 0x%x\n", result);
+                       "err: echo response receive error = 0x%x\n", result);
                return result;
        }
 
index 3e7b11c..cb98b8f 100644 (file)
@@ -655,6 +655,7 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
        resource_size_t start, size;
        struct nd_region *nd_region;
        unsigned long npfns, align;
+       u32 end_trunc;
        struct nd_pfn_sb *pfn_sb;
        phys_addr_t offset;
        const char *sig;
@@ -696,6 +697,7 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
        size = resource_size(&nsio->res);
        npfns = PHYS_PFN(size - SZ_8K);
        align = max(nd_pfn->align, (1UL << SUBSECTION_SHIFT));
+       end_trunc = start + size - ALIGN_DOWN(start + size, align);
        if (nd_pfn->mode == PFN_MODE_PMEM) {
                /*
                 * The altmap should be padded out to the block size used
@@ -714,7 +716,7 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
                return -ENXIO;
        }
 
-       npfns = PHYS_PFN(size - offset);
+       npfns = PHYS_PFN(size - offset - end_trunc);
        pfn_sb->mode = cpu_to_le32(nd_pfn->mode);
        pfn_sb->dataoff = cpu_to_le64(offset);
        pfn_sb->npfns = cpu_to_le64(npfns);
@@ -723,6 +725,7 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
        memcpy(pfn_sb->parent_uuid, nd_dev_to_uuid(&ndns->dev), 16);
        pfn_sb->version_major = cpu_to_le16(1);
        pfn_sb->version_minor = cpu_to_le16(3);
+       pfn_sb->end_trunc = cpu_to_le32(end_trunc);
        pfn_sb->align = cpu_to_le32(nd_pfn->align);
        checksum = nd_sb_checksum((struct nd_gen_sb *) pfn_sb);
        pfn_sb->checksum = cpu_to_le64(checksum);
index 9cdf14b..223d617 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/debugfs.h>
 #include <linux/serial_core.h>
 #include <linux/sysfs.h>
+#include <linux/random.h>
 
 #include <asm/setup.h>  /* for COMMAND_LINE_SIZE */
 #include <asm/page.h>
@@ -1044,6 +1045,7 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 {
        int l;
        const char *p;
+       const void *rng_seed;
 
        pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
 
@@ -1078,6 +1080,18 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname,
 
        pr_debug("Command line is: %s\n", (char*)data);
 
+       rng_seed = of_get_flat_dt_prop(node, "rng-seed", &l);
+       if (rng_seed && l > 0) {
+               add_bootloader_randomness(rng_seed, l);
+
+               /* try to clear seed so it won't be found. */
+               fdt_nop_property(initial_boot_params, node, "rng-seed");
+
+               /* update CRC check value */
+               of_fdt_crc32 = crc32_be(~0, initial_boot_params,
+                               fdt_totalsize(initial_boot_params));
+       }
+
        /* break now */
        return 1;
 }
index 3c73010..2f1cac8 100644 (file)
@@ -6,7 +6,7 @@
 **     (c) Copyright 1999 SuSE GmbH
 **     (c) Copyright 1999,2000 Hewlett-Packard Company
 **     (c) Copyright 2000 Grant Grundler
-**     (c) Copyright 2006 Helge Deller
+**     (c) Copyright 2006-2019 Helge Deller
 **
 **
 **     This module provides access to Dino PCI bus (config/IOport spaces)
@@ -156,6 +156,15 @@ static inline struct dino_device *DINO_DEV(struct pci_hba_data *hba)
        return container_of(hba, struct dino_device, hba);
 }
 
+/* Check if PCI device is behind a Card-mode Dino. */
+static int pci_dev_is_behind_card_dino(struct pci_dev *dev)
+{
+       struct dino_device *dino_dev;
+
+       dino_dev = DINO_DEV(parisc_walk_tree(dev->bus->bridge));
+       return is_card_dino(&dino_dev->hba.dev->id);
+}
+
 /*
  * Dino Configuration Space Accessor Functions
  */
@@ -437,6 +446,21 @@ static void quirk_cirrus_cardbus(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CIRRUS_6832, quirk_cirrus_cardbus );
 
+#ifdef CONFIG_TULIP
+static void pci_fixup_tulip(struct pci_dev *dev)
+{
+       if (!pci_dev_is_behind_card_dino(dev))
+               return;
+       if (!(pci_resource_flags(dev, 1) & IORESOURCE_MEM))
+               return;
+       pr_warn("%s: HP HSC-PCI Cards with card-mode Dino not yet supported.\n",
+               pci_name(dev));
+       /* Disable this card by zeroing the PCI resources */
+       memset(&dev->resource[0], 0, sizeof(dev->resource[0]));
+       memset(&dev->resource[1], 0, sizeof(dev->resource[1]));
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_DEC, PCI_ANY_ID, pci_fixup_tulip);
+#endif /* CONFIG_TULIP */
 
 static void __init
 dino_bios_init(void)
@@ -863,14 +887,14 @@ static int __init dino_common_init(struct parisc_device *dev,
 #define CUJO_RAVEN_BADPAGE     0x01003000UL
 #define CUJO_FIREHAWK_BADPAGE  0x01607000UL
 
-static const char *dino_vers[] = {
+static const char dino_vers[][4] = {
        "2.0",
        "2.1",
        "3.0",
        "3.1"
 };
 
-static const char *cujo_vers[] = {
+static const char cujo_vers[][4] = {
        "1.0",
        "2.0"
 };
index 9c08222..f54a6f4 100644 (file)
@@ -93,7 +93,7 @@ static int configure_memory(const unsigned char *buf,
                        res->start = mem_parent->start + get_24(buf+len+2);
                        res->end = res->start + get_16(buf+len+5)*1024;
                        res->flags = IORESOURCE_MEM;
-                       printk("memory %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
+                       pr_cont("memory %pR ", res);
                        result = request_resource(mem_parent, res);
                        if (result < 0) {
                                printk(KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
@@ -123,7 +123,7 @@ static int configure_irq(const unsigned char *buf)
        for (i=0;i<HPEE_IRQ_MAX_ENT;i++) {
                c = get_8(buf+len);
                
-               printk("IRQ %d ", c & HPEE_IRQ_CHANNEL_MASK);
+               pr_cont("IRQ %d ", c & HPEE_IRQ_CHANNEL_MASK);
                if (c & HPEE_IRQ_TRIG_LEVEL) {
                        eisa_make_irq_level(c & HPEE_IRQ_CHANNEL_MASK);
                } else {
@@ -153,7 +153,7 @@ static int configure_dma(const unsigned char *buf)
        
        for (i=0;i<HPEE_DMA_MAX_ENT;i++) {
                c = get_8(buf+len);
-               printk("DMA %d ", c&HPEE_DMA_CHANNEL_MASK);
+               pr_cont("DMA %d ", c&HPEE_DMA_CHANNEL_MASK);
                /* fixme: maybe initialize the dma channel withthe timing ? */
                len+=2;      
                if (!(c & HPEE_DMA_MORE)) {
@@ -183,7 +183,7 @@ static int configure_port(const unsigned char *buf, struct resource *io_parent,
                        res->start = get_16(buf+len+1);
                        res->end = get_16(buf+len+1)+(c&HPEE_PORT_SIZE_MASK)+1;
                        res->flags = IORESOURCE_IO;
-                       printk("ioports %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
+                       pr_cont("ioports %pR ", res);
                        result = request_resource(io_parent, res);
                        if (result < 0) {
                                printk(KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
@@ -401,7 +401,7 @@ static int parse_slot_config(int slot,
                }
                pos = p0 + function_len;
        }
-       printk("\n");
+       pr_cont("\n");
        if (!id_string_used) {
                kfree(board);
        }
index 44e12c8..e60e686 100644 (file)
@@ -61,8 +61,6 @@ static int __init hppb_probe(struct parisc_device *dev)
                }
                card = card->next;
        }
-       printk(KERN_INFO "Found GeckoBoa at 0x%llx\n",
-                       (unsigned long long) dev->hpa.start);
 
        card->hpa = dev->hpa.start;
        card->mmio_region.name = "HP-PB Bus";
@@ -72,10 +70,11 @@ static int __init hppb_probe(struct parisc_device *dev)
        card->mmio_region.end = gsc_readl(dev->hpa.start + IO_IO_HIGH) - 1;
 
        status = ccio_request_resource(dev, &card->mmio_region);
-       if(status < 0) {
-               printk(KERN_ERR "%s: failed to claim HP-PB bus space (%pR)\n",
-                       __FILE__, &card->mmio_region);
-       }
+
+       pr_info("Found GeckoBoa at %pap, bus space %pR,%s claimed.\n",
+                       &dev->hpa.start,
+                       &card->mmio_region,
+                       (status < 0) ? " not":"" );
 
         return 0;
 }
index e9f78eb..e7b493c 100644 (file)
@@ -147,15 +147,6 @@ config HOTPLUG_PCI_RPA_DLPAR
 
          When in doubt, say N.
 
-config HOTPLUG_PCI_SGI
-       tristate "SGI PCI Hotplug Support"
-       depends on IA64_SGI_SN2 || IA64_GENERIC
-       help
-         Say Y here if you want to use the SGI Altix Hotplug
-         Driver for PCI devices.
-
-         When in doubt, say N.
-
 config HOTPLUG_PCI_S390
        bool "System z PCI Hotplug Support"
        depends on S390 && 64BIT
index 7e33316..5196983 100644 (file)
@@ -18,7 +18,6 @@ obj-$(CONFIG_HOTPLUG_PCI_SHPC)                += shpchp.o
 obj-$(CONFIG_HOTPLUG_PCI_POWERNV)      += pnv-php.o
 obj-$(CONFIG_HOTPLUG_PCI_RPA)          += rpaphp.o
 obj-$(CONFIG_HOTPLUG_PCI_RPA_DLPAR)    += rpadlpar_io.o
-obj-$(CONFIG_HOTPLUG_PCI_SGI)          += sgi_hotplug.o
 obj-$(CONFIG_HOTPLUG_PCI_ACPI)         += acpiphp.o
 obj-$(CONFIG_HOTPLUG_PCI_S390)         += s390_pci_hpc.o
 
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
deleted file mode 100644 (file)
index 231f5bd..0000000
+++ /dev/null
@@ -1,700 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2005-2006 Silicon Graphics, Inc. All rights reserved.
- *
- * This work was based on the 2.4/2.6 kernel development by Dick Reigner.
- * Work to add BIOS PROM support was completed by Mike Habeck.
- */
-
-#include <linux/acpi.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/pci_hotplug.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/mutex.h>
-
-#include <asm/sn/addrs.h>
-#include <asm/sn/geo.h>
-#include <asm/sn/l1.h>
-#include <asm/sn/module.h>
-#include <asm/sn/pcibr_provider.h>
-#include <asm/sn/pcibus_provider_defs.h>
-#include <asm/sn/pcidev.h>
-#include <asm/sn/sn_feature_sets.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/types.h>
-#include <asm/sn/acpi.h>
-
-#include "../pci.h"
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("SGI (prarit@sgi.com, dickie@sgi.com, habeck@sgi.com)");
-MODULE_DESCRIPTION("SGI Altix Hot Plug PCI Controller Driver");
-
-
-/* SAL call error codes. Keep in sync with prom header io/include/pcibr.h */
-#define PCI_SLOT_ALREADY_UP            2       /* slot already up */
-#define PCI_SLOT_ALREADY_DOWN          3       /* slot already down */
-#define PCI_L1_ERR                     7       /* L1 console command error */
-#define PCI_EMPTY_33MHZ                        15      /* empty 33 MHz bus */
-
-
-#define PCIIO_ASIC_TYPE_TIOCA          4
-#define PCI_L1_QSIZE                   128     /* our L1 message buffer size */
-#define SN_MAX_HP_SLOTS                        32      /* max hotplug slots */
-#define SN_SLOT_NAME_SIZE              33      /* size of name string */
-
-/* internal list head */
-static struct list_head sn_hp_list;
-
-/* hotplug_slot struct's private pointer */
-struct slot {
-       int device_num;
-       struct pci_bus *pci_bus;
-       /* this struct for glue internal only */
-       struct hotplug_slot hotplug_slot;
-       struct list_head hp_list;
-       char physical_path[SN_SLOT_NAME_SIZE];
-};
-
-struct pcibr_slot_enable_resp {
-       int resp_sub_errno;
-       char resp_l1_msg[PCI_L1_QSIZE + 1];
-};
-
-struct pcibr_slot_disable_resp {
-       int resp_sub_errno;
-       char resp_l1_msg[PCI_L1_QSIZE + 1];
-};
-
-enum sn_pci_req_e {
-       PCI_REQ_SLOT_ELIGIBLE,
-       PCI_REQ_SLOT_DISABLE
-};
-
-static int enable_slot(struct hotplug_slot *slot);
-static int disable_slot(struct hotplug_slot *slot);
-static inline int get_power_status(struct hotplug_slot *slot, u8 *value);
-
-static const struct hotplug_slot_ops sn_hotplug_slot_ops = {
-       .enable_slot            = enable_slot,
-       .disable_slot           = disable_slot,
-       .get_power_status       = get_power_status,
-};
-
-static DEFINE_MUTEX(sn_hotplug_mutex);
-
-static struct slot *to_slot(struct hotplug_slot *bss_hotplug_slot)
-{
-       return container_of(bss_hotplug_slot, struct slot, hotplug_slot);
-}
-
-static ssize_t path_show(struct pci_slot *pci_slot, char *buf)
-{
-       int retval = -ENOENT;
-       struct slot *slot = to_slot(pci_slot->hotplug);
-
-       if (!slot)
-               return retval;
-
-       retval = sprintf(buf, "%s\n", slot->physical_path);
-       return retval;
-}
-
-static struct pci_slot_attribute sn_slot_path_attr = __ATTR_RO(path);
-
-static int sn_pci_slot_valid(struct pci_bus *pci_bus, int device)
-{
-       struct pcibus_info *pcibus_info;
-       u16 busnum, segment, ioboard_type;
-
-       pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
-
-       /* Check to see if this is a valid slot on 'pci_bus' */
-       if (!(pcibus_info->pbi_valid_devices & (1 << device)))
-               return -EPERM;
-
-       ioboard_type = sn_ioboard_to_pci_bus(pci_bus);
-       busnum = pcibus_info->pbi_buscommon.bs_persist_busnum;
-       segment = pci_domain_nr(pci_bus) & 0xf;
-
-       /* Do not allow hotplug operations on base I/O cards */
-       if ((ioboard_type == L1_BRICKTYPE_IX ||
-            ioboard_type == L1_BRICKTYPE_IA) &&
-           (segment == 1 && busnum == 0 && device != 1))
-               return -EPERM;
-
-       return 1;
-}
-
-static int sn_pci_bus_valid(struct pci_bus *pci_bus)
-{
-       struct pcibus_info *pcibus_info;
-       u32 asic_type;
-       u16 ioboard_type;
-
-       /* Don't register slots hanging off the TIOCA bus */
-       pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
-       asic_type = pcibus_info->pbi_buscommon.bs_asic_type;
-       if (asic_type == PCIIO_ASIC_TYPE_TIOCA)
-               return -EPERM;
-
-       /* Only register slots in I/O Bricks that support hotplug */
-       ioboard_type = sn_ioboard_to_pci_bus(pci_bus);
-       switch (ioboard_type) {
-               case L1_BRICKTYPE_IX:
-               case L1_BRICKTYPE_PX:
-               case L1_BRICKTYPE_IA:
-               case L1_BRICKTYPE_PA:
-               case L1_BOARDTYPE_PCIX3SLOT:
-                       return 1;
-                       break;
-               default:
-                       return -EPERM;
-                       break;
-       }
-
-       return -EIO;
-}
-
-static int sn_hp_slot_private_alloc(struct hotplug_slot **bss_hotplug_slot,
-                                   struct pci_bus *pci_bus, int device,
-                                   char *name)
-{
-       struct pcibus_info *pcibus_info;
-       struct slot *slot;
-
-       pcibus_info = SN_PCIBUS_BUSSOFT_INFO(pci_bus);
-
-       slot = kzalloc(sizeof(*slot), GFP_KERNEL);
-       if (!slot)
-               return -ENOMEM;
-
-       slot->device_num = device;
-       slot->pci_bus = pci_bus;
-       sprintf(name, "%04x:%02x:%02x",
-               pci_domain_nr(pci_bus),
-               ((u16)pcibus_info->pbi_buscommon.bs_persist_busnum),
-               device + 1);
-
-       sn_generate_path(pci_bus, slot->physical_path);
-
-       list_add(&slot->hp_list, &sn_hp_list);
-       *bss_hotplug_slot = &slot->hotplug_slot;
-
-       return 0;
-}
-
-static struct hotplug_slot *sn_hp_destroy(void)
-{
-       struct slot *slot;
-       struct pci_slot *pci_slot;
-       struct hotplug_slot *bss_hotplug_slot = NULL;
-
-       list_for_each_entry(slot, &sn_hp_list, hp_list) {
-               bss_hotplug_slot = &slot->hotplug_slot;
-               pci_slot = bss_hotplug_slot->pci_slot;
-               list_del(&slot->hp_list);
-               sysfs_remove_file(&pci_slot->kobj,
-                                 &sn_slot_path_attr.attr);
-               break;
-       }
-       return bss_hotplug_slot;
-}
-
-static void sn_bus_free_data(struct pci_dev *dev)
-{
-       struct pci_bus *subordinate_bus;
-       struct pci_dev *child;
-
-       /* Recursively clean up sn_irq_info structs */
-       if (dev->subordinate) {
-               subordinate_bus = dev->subordinate;
-               list_for_each_entry(child, &subordinate_bus->devices, bus_list)
-                       sn_bus_free_data(child);
-       }
-       /*
-        * Some drivers may use dma accesses during the
-        * driver remove function. We release the sysdata
-        * areas after the driver remove functions have
-        * been called.
-        */
-       sn_bus_store_sysdata(dev);
-       sn_pci_unfixup_slot(dev);
-}
-
-static int sn_slot_enable(struct hotplug_slot *bss_hotplug_slot,
-                         int device_num, char **ssdt)
-{
-       struct slot *slot = to_slot(bss_hotplug_slot);
-       struct pcibus_info *pcibus_info;
-       struct pcibr_slot_enable_resp resp;
-       int rc;
-
-       pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
-
-       /*
-        * Power-on and initialize the slot in the SN
-        * PCI infrastructure.
-        */
-       rc = sal_pcibr_slot_enable(pcibus_info, device_num, &resp, ssdt);
-
-
-       if (rc == PCI_SLOT_ALREADY_UP) {
-               pci_dbg(slot->pci_bus->self, "is already active\n");
-               return 1; /* return 1 to user */
-       }
-
-       if (rc == PCI_L1_ERR) {
-               pci_dbg(slot->pci_bus->self, "L1 failure %d with message: %s",
-                       resp.resp_sub_errno, resp.resp_l1_msg);
-               return -EPERM;
-       }
-
-       if (rc) {
-               pci_dbg(slot->pci_bus->self, "insert failed with error %d sub-error %d\n",
-                       rc, resp.resp_sub_errno);
-               return -EIO;
-       }
-
-       pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
-       pcibus_info->pbi_enabled_devices |= (1 << device_num);
-
-       return 0;
-}
-
-static int sn_slot_disable(struct hotplug_slot *bss_hotplug_slot,
-                          int device_num, int action)
-{
-       struct slot *slot = to_slot(bss_hotplug_slot);
-       struct pcibus_info *pcibus_info;
-       struct pcibr_slot_disable_resp resp;
-       int rc;
-
-       pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
-
-       rc = sal_pcibr_slot_disable(pcibus_info, device_num, action, &resp);
-
-       if ((action == PCI_REQ_SLOT_ELIGIBLE) &&
-           (rc == PCI_SLOT_ALREADY_DOWN)) {
-               pci_dbg(slot->pci_bus->self, "Slot %s already inactive\n", slot->physical_path);
-               return 1; /* return 1 to user */
-       }
-
-       if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_EMPTY_33MHZ)) {
-               pci_dbg(slot->pci_bus->self, "Cannot remove last 33MHz card\n");
-               return -EPERM;
-       }
-
-       if ((action == PCI_REQ_SLOT_ELIGIBLE) && (rc == PCI_L1_ERR)) {
-               pci_dbg(slot->pci_bus->self, "L1 failure %d with message \n%s\n",
-                       resp.resp_sub_errno, resp.resp_l1_msg);
-               return -EPERM;
-       }
-
-       if ((action == PCI_REQ_SLOT_ELIGIBLE) && rc) {
-               pci_dbg(slot->pci_bus->self, "remove failed with error %d sub-error %d\n",
-                       rc, resp.resp_sub_errno);
-               return -EIO;
-       }
-
-       if ((action == PCI_REQ_SLOT_ELIGIBLE) && !rc)
-               return 0;
-
-       if ((action == PCI_REQ_SLOT_DISABLE) && !rc) {
-               pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
-               pcibus_info->pbi_enabled_devices &= ~(1 << device_num);
-               pci_dbg(slot->pci_bus->self, "remove successful\n");
-               return 0;
-       }
-
-       if ((action == PCI_REQ_SLOT_DISABLE) && rc) {
-               pci_dbg(slot->pci_bus->self, "remove failed rc = %d\n", rc);
-       }
-
-       return rc;
-}
-
-/*
- * Power up and configure the slot via a SAL call to PROM.
- * Scan slot (and any children), do any platform specific fixup,
- * and find device driver.
- */
-static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
-{
-       struct slot *slot = to_slot(bss_hotplug_slot);
-       struct pci_bus *new_bus = NULL;
-       struct pci_dev *dev;
-       int num_funcs;
-       int new_ppb = 0;
-       int rc;
-       char *ssdt = NULL;
-       void pcibios_fixup_device_resources(struct pci_dev *);
-
-       /* Serialize the Linux PCI infrastructure */
-       mutex_lock(&sn_hotplug_mutex);
-
-       /*
-        * Power-on and initialize the slot in the SN
-        * PCI infrastructure. Also, retrieve the ACPI SSDT
-        * table for the slot (if ACPI capable PROM).
-        */
-       rc = sn_slot_enable(bss_hotplug_slot, slot->device_num, &ssdt);
-       if (rc) {
-               mutex_unlock(&sn_hotplug_mutex);
-               return rc;
-       }
-
-       if (ssdt)
-               ssdt = __va(ssdt);
-       /* Add the new SSDT for the slot to the ACPI namespace */
-       if (SN_ACPI_BASE_SUPPORT() && ssdt) {
-               acpi_status ret;
-
-               ret = acpi_load_table((struct acpi_table_header *)ssdt);
-               if (ACPI_FAILURE(ret)) {
-                       printk(KERN_ERR "%s: acpi_load_table failed (0x%x)\n",
-                              __func__, ret);
-                       /* try to continue on */
-               }
-       }
-
-       num_funcs = pci_scan_slot(slot->pci_bus,
-                                 PCI_DEVFN(slot->device_num + 1, 0));
-       if (!num_funcs) {
-               pci_dbg(slot->pci_bus->self, "no device in slot\n");
-               mutex_unlock(&sn_hotplug_mutex);
-               return -ENODEV;
-       }
-
-       /*
-        * Map SN resources for all functions on the card
-        * to the Linux PCI interface and tell the drivers
-        * about them.
-        */
-       list_for_each_entry(dev, &slot->pci_bus->devices, bus_list) {
-               if (PCI_SLOT(dev->devfn) != slot->device_num + 1)
-                       continue;
-
-               /* Need to do slot fixup on PPB before fixup of children
-                * (PPB's pcidev_info needs to be in pcidev_info list
-                * before child's SN_PCIDEV_INFO() call to setup
-                * pdi_host_pcidev_info).
-                */
-               pcibios_fixup_device_resources(dev);
-               if (SN_ACPI_BASE_SUPPORT())
-                       sn_acpi_slot_fixup(dev);
-               else
-                       sn_io_slot_fixup(dev);
-               if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-                       pci_hp_add_bridge(dev);
-                       if (dev->subordinate) {
-                               new_bus = dev->subordinate;
-                               new_ppb = 1;
-                       }
-               }
-       }
-
-       /*
-        * Add the slot's devices to the ACPI infrastructure */
-       if (SN_ACPI_BASE_SUPPORT() && ssdt) {
-               unsigned long long adr;
-               struct acpi_device *pdevice;
-               acpi_handle phandle;
-               acpi_handle chandle = NULL;
-               acpi_handle rethandle;
-               acpi_status ret;
-
-               phandle = acpi_device_handle(PCI_CONTROLLER(slot->pci_bus)->companion);
-
-               if (acpi_bus_get_device(phandle, &pdevice)) {
-                       pci_dbg(slot->pci_bus->self, "no parent device, assuming NULL\n");
-                       pdevice = NULL;
-               }
-
-               acpi_scan_lock_acquire();
-               /*
-                * Walk the rootbus node's immediate children looking for
-                * the slot's device node(s). There can be more than
-                * one for multifunction devices.
-                */
-               for (;;) {
-                       rethandle = NULL;
-                       ret = acpi_get_next_object(ACPI_TYPE_DEVICE,
-                                                  phandle, chandle,
-                                                  &rethandle);
-
-                       if (ret == AE_NOT_FOUND || rethandle == NULL)
-                               break;
-
-                       chandle = rethandle;
-
-                       ret = acpi_evaluate_integer(chandle, METHOD_NAME__ADR,
-                                                   NULL, &adr);
-
-                       if (ACPI_SUCCESS(ret) &&
-                           (adr>>16) == (slot->device_num + 1)) {
-
-                               ret = acpi_bus_scan(chandle);
-                               if (ACPI_FAILURE(ret)) {
-                                       printk(KERN_ERR "%s: acpi_bus_scan failed (0x%x) for slot %d func %d\n",
-                                              __func__, ret, (int)(adr>>16),
-                                              (int)(adr&0xffff));
-                                       /* try to continue on */
-                               }
-                       }
-               }
-               acpi_scan_lock_release();
-       }
-
-       pci_lock_rescan_remove();
-
-       /* Call the driver for the new device */
-       pci_bus_add_devices(slot->pci_bus);
-       /* Call the drivers for the new devices subordinate to PPB */
-       if (new_ppb)
-               pci_bus_add_devices(new_bus);
-
-       pci_unlock_rescan_remove();
-       mutex_unlock(&sn_hotplug_mutex);
-
-       if (rc == 0)
-               pci_dbg(slot->pci_bus->self, "insert operation successful\n");
-       else
-               pci_dbg(slot->pci_bus->self, "insert operation failed rc = %d\n", rc);
-
-       return rc;
-}
-
-static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
-{
-       struct slot *slot = to_slot(bss_hotplug_slot);
-       struct pci_dev *dev, *temp;
-       int rc;
-       acpi_handle ssdt_hdl = NULL;
-
-       /* Acquire update access to the bus */
-       mutex_lock(&sn_hotplug_mutex);
-
-       /* is it okay to bring this slot down? */
-       rc = sn_slot_disable(bss_hotplug_slot, slot->device_num,
-                            PCI_REQ_SLOT_ELIGIBLE);
-       if (rc)
-               goto leaving;
-
-       /* free the ACPI resources for the slot */
-       if (SN_ACPI_BASE_SUPPORT() &&
-               PCI_CONTROLLER(slot->pci_bus)->companion) {
-               unsigned long long adr;
-               struct acpi_device *device;
-               acpi_handle phandle;
-               acpi_handle chandle = NULL;
-               acpi_handle rethandle;
-               acpi_status ret;
-
-               /* Get the rootbus node pointer */
-               phandle = acpi_device_handle(PCI_CONTROLLER(slot->pci_bus)->companion);
-
-               acpi_scan_lock_acquire();
-               /*
-                * Walk the rootbus node's immediate children looking for
-                * the slot's device node(s). There can be more than
-                * one for multifunction devices.
-                */
-               for (;;) {
-                       rethandle = NULL;
-                       ret = acpi_get_next_object(ACPI_TYPE_DEVICE,
-                                                  phandle, chandle,
-                                                  &rethandle);
-
-                       if (ret == AE_NOT_FOUND || rethandle == NULL)
-                               break;
-
-                       chandle = rethandle;
-
-                       ret = acpi_evaluate_integer(chandle,
-                                                   METHOD_NAME__ADR,
-                                                   NULL, &adr);
-                       if (ACPI_SUCCESS(ret) &&
-                           (adr>>16) == (slot->device_num + 1)) {
-                               /* retain the owner id */
-                               ssdt_hdl = chandle;
-
-                               ret = acpi_bus_get_device(chandle,
-                                                         &device);
-                               if (ACPI_SUCCESS(ret))
-                                       acpi_bus_trim(device);
-                       }
-               }
-               acpi_scan_lock_release();
-       }
-
-       pci_lock_rescan_remove();
-       /* Free the SN resources assigned to the Linux device.*/
-       list_for_each_entry_safe(dev, temp, &slot->pci_bus->devices, bus_list) {
-               if (PCI_SLOT(dev->devfn) != slot->device_num + 1)
-                       continue;
-
-               pci_dev_get(dev);
-               sn_bus_free_data(dev);
-               pci_stop_and_remove_bus_device(dev);
-               pci_dev_put(dev);
-       }
-       pci_unlock_rescan_remove();
-
-       /* Remove the SSDT for the slot from the ACPI namespace */
-       if (SN_ACPI_BASE_SUPPORT() && ssdt_hdl) {
-               acpi_status ret;
-               ret = acpi_unload_parent_table(ssdt_hdl);
-               if (ACPI_FAILURE(ret)) {
-                       acpi_handle_err(ssdt_hdl,
-                                       "%s: acpi_unload_parent_table failed (0x%x)\n",
-                                       __func__, ret);
-                       /* try to continue on */
-               }
-       }
-
-       /* free the collected sysdata pointers */
-       sn_bus_free_sysdata();
-
-       /* Deactivate slot */
-       rc = sn_slot_disable(bss_hotplug_slot, slot->device_num,
-                            PCI_REQ_SLOT_DISABLE);
- leaving:
-       /* Release the bus lock */
-       mutex_unlock(&sn_hotplug_mutex);
-
-       return rc;
-}
-
-static inline int get_power_status(struct hotplug_slot *bss_hotplug_slot,
-                                  u8 *value)
-{
-       struct slot *slot = to_slot(bss_hotplug_slot);
-       struct pcibus_info *pcibus_info;
-       u32 power;
-
-       pcibus_info = SN_PCIBUS_BUSSOFT_INFO(slot->pci_bus);
-       mutex_lock(&sn_hotplug_mutex);
-       power = pcibus_info->pbi_enabled_devices & (1 << slot->device_num);
-       *value = power ? 1 : 0;
-       mutex_unlock(&sn_hotplug_mutex);
-       return 0;
-}
-
-static void sn_release_slot(struct hotplug_slot *bss_hotplug_slot)
-{
-       kfree(to_slot(bss_hotplug_slot));
-}
-
-static int sn_hotplug_slot_register(struct pci_bus *pci_bus)
-{
-       int device;
-       struct pci_slot *pci_slot;
-       struct hotplug_slot *bss_hotplug_slot;
-       char name[SN_SLOT_NAME_SIZE];
-       int rc = 0;
-
-       /*
-        * Currently only four devices are supported,
-        * in the future there maybe more -- up to 32.
-        */
-
-       for (device = 0; device < SN_MAX_HP_SLOTS ; device++) {
-               if (sn_pci_slot_valid(pci_bus, device) != 1)
-                       continue;
-
-               if (sn_hp_slot_private_alloc(&bss_hotplug_slot,
-                                            pci_bus, device, name)) {
-                       rc = -ENOMEM;
-                       goto alloc_err;
-               }
-               bss_hotplug_slot->ops = &sn_hotplug_slot_ops;
-
-               rc = pci_hp_register(bss_hotplug_slot, pci_bus, device, name);
-               if (rc)
-                       goto register_err;
-
-               pci_slot = bss_hotplug_slot->pci_slot;
-               rc = sysfs_create_file(&pci_slot->kobj,
-                                      &sn_slot_path_attr.attr);
-               if (rc)
-                       goto alloc_err;
-       }
-       pci_dbg(pci_bus->self, "Registered bus with hotplug\n");
-       return rc;
-
-register_err:
-       pci_dbg(pci_bus->self, "bus failed to register with err = %d\n",
-               rc);
-
-       /* destroy THIS element */
-       sn_hp_destroy();
-       sn_release_slot(bss_hotplug_slot);
-
-alloc_err:
-       /* destroy anything else on the list */
-       while ((bss_hotplug_slot = sn_hp_destroy())) {
-               pci_hp_deregister(bss_hotplug_slot);
-               sn_release_slot(bss_hotplug_slot);
-       }
-
-       return rc;
-}
-
-static int __init sn_pci_hotplug_init(void)
-{
-       struct pci_bus *pci_bus = NULL;
-       int rc;
-       int registered = 0;
-
-       if (!sn_prom_feature_available(PRF_HOTPLUG_SUPPORT)) {
-               printk(KERN_ERR "%s: PROM version does not support hotplug.\n",
-                      __func__);
-               return -EPERM;
-       }
-
-       INIT_LIST_HEAD(&sn_hp_list);
-
-       while ((pci_bus = pci_find_next_bus(pci_bus))) {
-               if (!pci_bus->sysdata)
-                       continue;
-
-               rc = sn_pci_bus_valid(pci_bus);
-               if (rc != 1) {
-                       pci_dbg(pci_bus->self, "not a valid hotplug bus\n");
-                       continue;
-               }
-               pci_dbg(pci_bus->self, "valid hotplug bus\n");
-
-               rc = sn_hotplug_slot_register(pci_bus);
-               if (!rc) {
-                       registered = 1;
-               } else {
-                       registered = 0;
-                       break;
-               }
-       }
-
-       return registered == 1 ? 0 : -ENODEV;
-}
-
-static void __exit sn_pci_hotplug_exit(void)
-{
-       struct hotplug_slot *bss_hotplug_slot;
-
-       while ((bss_hotplug_slot = sn_hp_destroy())) {
-               pci_hp_deregister(bss_hotplug_slot);
-               sn_release_slot(bss_hotplug_slot);
-       }
-
-       if (!list_empty(&sn_hp_list))
-               printk(KERN_ERR "%s: internal list is not empty\n", __FILE__);
-}
-
-module_init(sn_pci_hotplug_init);
-module_exit(sn_pci_hotplug_exit);
index da71c74..abcf54f 100644 (file)
@@ -113,8 +113,6 @@ struct smmu_pmu {
        u64 counter_mask;
        u32 options;
        bool global_filter;
-       u32 global_filter_span;
-       u32 global_filter_sid;
 };
 
 #define to_smmu_pmu(p) (container_of(p, struct smmu_pmu, pmu))
@@ -260,6 +258,19 @@ static void smmu_pmu_set_event_filter(struct perf_event *event,
        smmu_pmu_set_smr(smmu_pmu, idx, sid);
 }
 
+static bool smmu_pmu_check_global_filter(struct perf_event *curr,
+                                        struct perf_event *new)
+{
+       if (get_filter_enable(new) != get_filter_enable(curr))
+               return false;
+
+       if (!get_filter_enable(new))
+               return true;
+
+       return get_filter_span(new) == get_filter_span(curr) &&
+              get_filter_stream_id(new) == get_filter_stream_id(curr);
+}
+
 static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu,
                                       struct perf_event *event, int idx)
 {
@@ -279,17 +290,14 @@ static int smmu_pmu_apply_event_filter(struct smmu_pmu *smmu_pmu,
        }
 
        /* Requested settings same as current global settings*/
-       if (span == smmu_pmu->global_filter_span &&
-           sid == smmu_pmu->global_filter_sid)
+       idx = find_first_bit(smmu_pmu->used_counters, num_ctrs);
+       if (idx == num_ctrs ||
+           smmu_pmu_check_global_filter(smmu_pmu->events[idx], event)) {
+               smmu_pmu_set_event_filter(event, 0, span, sid);
                return 0;
+       }
 
-       if (!bitmap_empty(smmu_pmu->used_counters, num_ctrs))
-               return -EAGAIN;
-
-       smmu_pmu_set_event_filter(event, 0, span, sid);
-       smmu_pmu->global_filter_span = span;
-       smmu_pmu->global_filter_sid = sid;
-       return 0;
+       return -EAGAIN;
 }
 
 static int smmu_pmu_get_event_idx(struct smmu_pmu *smmu_pmu,
@@ -312,6 +320,19 @@ static int smmu_pmu_get_event_idx(struct smmu_pmu *smmu_pmu,
        return idx;
 }
 
+static bool smmu_pmu_events_compatible(struct perf_event *curr,
+                                      struct perf_event *new)
+{
+       if (new->pmu != curr->pmu)
+               return false;
+
+       if (to_smmu_pmu(new->pmu)->global_filter &&
+           !smmu_pmu_check_global_filter(curr, new))
+               return false;
+
+       return true;
+}
+
 /*
  * Implementation of abstract pmu functionality required by
  * the core perf events code.
@@ -323,6 +344,7 @@ static int smmu_pmu_event_init(struct perf_event *event)
        struct smmu_pmu *smmu_pmu = to_smmu_pmu(event->pmu);
        struct device *dev = smmu_pmu->dev;
        struct perf_event *sibling;
+       int group_num_events = 1;
        u16 event_id;
 
        if (event->attr.type != event->pmu->type)
@@ -347,18 +369,23 @@ static int smmu_pmu_event_init(struct perf_event *event)
        }
 
        /* Don't allow groups with mixed PMUs, except for s/w events */
-       if (event->group_leader->pmu != event->pmu &&
-           !is_software_event(event->group_leader)) {
-               dev_dbg(dev, "Can't create mixed PMU group\n");
-               return -EINVAL;
+       if (!is_software_event(event->group_leader)) {
+               if (!smmu_pmu_events_compatible(event->group_leader, event))
+                       return -EINVAL;
+
+               if (++group_num_events > smmu_pmu->num_counters)
+                       return -EINVAL;
        }
 
        for_each_sibling_event(sibling, event->group_leader) {
-               if (sibling->pmu != event->pmu &&
-                   !is_software_event(sibling)) {
-                       dev_dbg(dev, "Can't create mixed PMU group\n");
+               if (is_software_event(sibling))
+                       continue;
+
+               if (!smmu_pmu_events_compatible(sibling, event))
+                       return -EINVAL;
+
+               if (++group_num_events > smmu_pmu->num_counters)
                        return -EINVAL;
-               }
        }
 
        hwc->idx = -1;
index 63fe216..ce73457 100644 (file)
@@ -35,6 +35,8 @@
 #define EVENT_CYCLES_COUNTER   0
 #define NUM_COUNTERS           4
 
+#define AXI_MASKING_REVERT     0xffff0000      /* AXI_MASKING(MSB 16bits) + AXI_ID(LSB 16bits) */
+
 #define to_ddr_pmu(p)          container_of(p, struct ddr_pmu, pmu)
 
 #define DDR_PERF_DEV_NAME      "imx8_ddr"
 
 static DEFINE_IDA(ddr_ida);
 
+/* DDR Perf hardware feature */
+#define DDR_CAP_AXI_ID_FILTER          0x1     /* support AXI ID filter */
+
+struct fsl_ddr_devtype_data {
+       unsigned int quirks;    /* quirks needed for different DDR Perf core */
+};
+
+static const struct fsl_ddr_devtype_data imx8_devtype_data;
+
+static const struct fsl_ddr_devtype_data imx8m_devtype_data = {
+       .quirks = DDR_CAP_AXI_ID_FILTER,
+};
+
 static const struct of_device_id imx_ddr_pmu_dt_ids[] = {
-       { .compatible = "fsl,imx8-ddr-pmu",},
-       { .compatible = "fsl,imx8m-ddr-pmu",},
+       { .compatible = "fsl,imx8-ddr-pmu", .data = &imx8_devtype_data},
+       { .compatible = "fsl,imx8m-ddr-pmu", .data = &imx8m_devtype_data},
        { /* sentinel */ }
 };
+MODULE_DEVICE_TABLE(of, imx_ddr_pmu_dt_ids);
 
 struct ddr_pmu {
        struct pmu pmu;
@@ -57,6 +73,7 @@ struct ddr_pmu {
        struct perf_event *events[NUM_COUNTERS];
        int active_events;
        enum cpuhp_state cpuhp_state;
+       const struct fsl_ddr_devtype_data *devtype_data;
        int irq;
        int id;
 };
@@ -128,6 +145,8 @@ static struct attribute *ddr_perf_events_attrs[] = {
        IMX8_DDR_PMU_EVENT_ATTR(refresh, 0x37),
        IMX8_DDR_PMU_EVENT_ATTR(write, 0x38),
        IMX8_DDR_PMU_EVENT_ATTR(raw-hazard, 0x39),
+       IMX8_DDR_PMU_EVENT_ATTR(axid-read, 0x41),
+       IMX8_DDR_PMU_EVENT_ATTR(axid-write, 0x42),
        NULL,
 };
 
@@ -137,9 +156,13 @@ static struct attribute_group ddr_perf_events_attr_group = {
 };
 
 PMU_FORMAT_ATTR(event, "config:0-7");
+PMU_FORMAT_ATTR(axi_id, "config1:0-15");
+PMU_FORMAT_ATTR(axi_mask, "config1:16-31");
 
 static struct attribute *ddr_perf_format_attrs[] = {
        &format_attr_event.attr,
+       &format_attr_axi_id.attr,
+       &format_attr_axi_mask.attr,
        NULL,
 };
 
@@ -189,6 +212,26 @@ static u32 ddr_perf_read_counter(struct ddr_pmu *pmu, int counter)
        return readl_relaxed(pmu->base + COUNTER_READ + counter * 4);
 }
 
+static bool ddr_perf_is_filtered(struct perf_event *event)
+{
+       return event->attr.config == 0x41 || event->attr.config == 0x42;
+}
+
+static u32 ddr_perf_filter_val(struct perf_event *event)
+{
+       return event->attr.config1;
+}
+
+static bool ddr_perf_filters_compatible(struct perf_event *a,
+                                       struct perf_event *b)
+{
+       if (!ddr_perf_is_filtered(a))
+               return true;
+       if (!ddr_perf_is_filtered(b))
+               return true;
+       return ddr_perf_filter_val(a) == ddr_perf_filter_val(b);
+}
+
 static int ddr_perf_event_init(struct perf_event *event)
 {
        struct ddr_pmu *pmu = to_ddr_pmu(event->pmu);
@@ -215,6 +258,15 @@ static int ddr_perf_event_init(struct perf_event *event)
                        !is_software_event(event->group_leader))
                return -EINVAL;
 
+       if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER) {
+               if (!ddr_perf_filters_compatible(event, event->group_leader))
+                       return -EINVAL;
+               for_each_sibling_event(sibling, event->group_leader) {
+                       if (!ddr_perf_filters_compatible(event, sibling))
+                               return -EINVAL;
+               }
+       }
+
        for_each_sibling_event(sibling, event->group_leader) {
                if (sibling->pmu != event->pmu &&
                                !is_software_event(sibling))
@@ -287,6 +339,23 @@ static int ddr_perf_event_add(struct perf_event *event, int flags)
        struct hw_perf_event *hwc = &event->hw;
        int counter;
        int cfg = event->attr.config;
+       int cfg1 = event->attr.config1;
+
+       if (pmu->devtype_data->quirks & DDR_CAP_AXI_ID_FILTER) {
+               int i;
+
+               for (i = 1; i < NUM_COUNTERS; i++) {
+                       if (pmu->events[i] &&
+                           !ddr_perf_filters_compatible(event, pmu->events[i]))
+                               return -EINVAL;
+               }
+
+               if (ddr_perf_is_filtered(event)) {
+                       /* revert axi id masking(axi_mask) value */
+                       cfg1 ^= AXI_MASKING_REVERT;
+                       writel(cfg1, pmu->base + COUNTER_DPCR1);
+               }
+       }
 
        counter = ddr_perf_alloc_counter(pmu, cfg);
        if (counter < 0) {
@@ -472,6 +541,8 @@ static int ddr_perf_probe(struct platform_device *pdev)
        if (!name)
                return -ENOMEM;
 
+       pmu->devtype_data = of_device_get_match_data(&pdev->dev);
+
        pmu->cpu = raw_smp_processor_id();
        ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
                                      DDR_CPUHP_CB_NAME,
index 6ad0823..e42d446 100644 (file)
@@ -217,10 +217,8 @@ static int hisi_ddrc_pmu_init_irq(struct hisi_pmu *ddrc_pmu,
 
        /* Read and init IRQ */
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(&pdev->dev, "DDRC PMU get irq fail; irq:%d\n", irq);
+       if (irq < 0)
                return irq;
-       }
 
        ret = devm_request_irq(&pdev->dev, irq, hisi_ddrc_pmu_isr,
                               IRQF_NOBALANCING | IRQF_NO_THREAD,
index 4f2917f..f280638 100644 (file)
@@ -207,10 +207,8 @@ static int hisi_hha_pmu_init_irq(struct hisi_pmu *hha_pmu,
 
        /* Read and init IRQ */
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(&pdev->dev, "HHA PMU get irq fail; irq:%d\n", irq);
+       if (irq < 0)
                return irq;
-       }
 
        ret = devm_request_irq(&pdev->dev, irq, hisi_hha_pmu_isr,
                              IRQF_NOBALANCING | IRQF_NO_THREAD,
index 9153e09..078b8dc 100644 (file)
@@ -206,10 +206,8 @@ static int hisi_l3c_pmu_init_irq(struct hisi_pmu *l3c_pmu,
 
        /* Read and init IRQ */
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(&pdev->dev, "L3C PMU get irq fail; irq:%d\n", irq);
+       if (irq < 0)
                return irq;
-       }
 
        ret = devm_request_irq(&pdev->dev, irq, hisi_l3c_pmu_isr,
                               IRQF_NOBALANCING | IRQF_NO_THREAD,
index d06182f..21d6991 100644 (file)
@@ -909,12 +909,8 @@ static int l2_cache_pmu_probe_cluster(struct device *dev, void *data)
        cluster->cluster_id = fw_cluster_id;
 
        irq = platform_get_irq(sdev, 0);
-       if (irq < 0) {
-               dev_err(&pdev->dev,
-                       "Failed to get valid irq for cluster %ld\n",
-                       fw_cluster_id);
+       if (irq < 0)
                return irq;
-       }
        irq_set_status_flags(irq, IRQ_NOAUTOEN);
        cluster->irq = irq;
 
index 3259e2e..7e328d6 100644 (file)
@@ -1901,10 +1901,8 @@ static int xgene_pmu_probe(struct platform_device *pdev)
        }
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(&pdev->dev, "No IRQ resource\n");
+       if (irq < 0)
                return -EINVAL;
-       }
 
        rc = devm_request_irq(&pdev->dev, irq, xgene_pmu_isr,
                                IRQF_NOBALANCING | IRQF_NO_THREAD,
index ba6438a..ff84d1a 100644 (file)
@@ -2552,7 +2552,7 @@ static struct regmap *aspeed_g5_acquire_regmap(struct aspeed_pinmux_data *ctx,
                        if (IS_ERR(map))
                                return map;
                } else
-                       map = ERR_PTR(-ENODEV);
+                       return ERR_PTR(-ENODEV);
 
                ctx->maps[ASPEED_IP_LPC] = map;
                dev_dbg(ctx->dev, "Acquired LPC regmap");
@@ -2562,6 +2562,33 @@ static struct regmap *aspeed_g5_acquire_regmap(struct aspeed_pinmux_data *ctx,
        return ERR_PTR(-EINVAL);
 }
 
+static int aspeed_g5_sig_expr_eval(struct aspeed_pinmux_data *ctx,
+                                  const struct aspeed_sig_expr *expr,
+                                  bool enabled)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < expr->ndescs; i++) {
+               const struct aspeed_sig_desc *desc = &expr->descs[i];
+               struct regmap *map;
+
+               map = aspeed_g5_acquire_regmap(ctx, desc->ip);
+               if (IS_ERR(map)) {
+                       dev_err(ctx->dev,
+                               "Failed to acquire regmap for IP block %d\n",
+                               desc->ip);
+                       return PTR_ERR(map);
+               }
+
+               ret = aspeed_sig_desc_eval(desc, enabled, ctx->maps[desc->ip]);
+               if (ret <= 0)
+                       return ret;
+       }
+
+       return 1;
+}
+
 /**
  * Configure a pin's signal by applying an expression's descriptor state for
  * all descriptors in the expression.
@@ -2647,6 +2674,7 @@ static int aspeed_g5_sig_expr_set(struct aspeed_pinmux_data *ctx,
 }
 
 static const struct aspeed_pinmux_ops aspeed_g5_ops = {
+       .eval = aspeed_g5_sig_expr_eval,
        .set = aspeed_g5_sig_expr_set,
 };
 
index 839c01b..57305ca 100644 (file)
@@ -78,11 +78,14 @@ int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc,
  * neither the enabled nor disabled state. Thus we must explicitly test for
  * either condition as required.
  */
-int aspeed_sig_expr_eval(const struct aspeed_pinmux_data *ctx,
+int aspeed_sig_expr_eval(struct aspeed_pinmux_data *ctx,
                         const struct aspeed_sig_expr *expr, bool enabled)
 {
-       int i;
        int ret;
+       int i;
+
+       if (ctx->ops->eval)
+               return ctx->ops->eval(ctx, expr, enabled);
 
        for (i = 0; i < expr->ndescs; i++) {
                const struct aspeed_sig_desc *desc = &expr->descs[i];
index 52d299b..db3457c 100644 (file)
@@ -702,6 +702,8 @@ struct aspeed_pin_function {
 struct aspeed_pinmux_data;
 
 struct aspeed_pinmux_ops {
+       int (*eval)(struct aspeed_pinmux_data *ctx,
+                   const struct aspeed_sig_expr *expr, bool enabled);
        int (*set)(struct aspeed_pinmux_data *ctx,
                   const struct aspeed_sig_expr *expr, bool enabled);
 };
@@ -722,9 +724,8 @@ struct aspeed_pinmux_data {
 int aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc, bool enabled,
                         struct regmap *map);
 
-int aspeed_sig_expr_eval(const struct aspeed_pinmux_data *ctx,
-                        const struct aspeed_sig_expr *expr,
-                        bool enabled);
+int aspeed_sig_expr_eval(struct aspeed_pinmux_data *ctx,
+                        const struct aspeed_sig_expr *expr, bool enabled);
 
 static inline int aspeed_sig_expr_set(struct aspeed_pinmux_data *ctx,
                                      const struct aspeed_sig_expr *expr,
index e5a112a..297b7b5 100644 (file)
@@ -1455,6 +1455,20 @@ static void byt_gpio_irq_handler(struct irq_desc *desc)
        chip->irq_eoi(data);
 }
 
+static void byt_init_irq_valid_mask(struct gpio_chip *chip,
+                                   unsigned long *valid_mask,
+                                   unsigned int ngpios)
+{
+       /*
+        * FIXME: currently the valid_mask is filled in as part of
+        * initializing the irq_chip below in byt_gpio_irq_init_hw().
+        * when converting this driver to the new way of passing the
+        * gpio_irq_chip along when adding the gpio_chip, move the
+        * mask initialization into this callback instead. Right now
+        * this callback is here to make sure the mask gets allocated.
+        */
+}
+
 static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
 {
        struct gpio_chip *gc = &vg->chip;
@@ -1525,7 +1539,7 @@ static int byt_gpio_probe(struct byt_gpio *vg)
        gc->can_sleep   = false;
        gc->parent      = &vg->pdev->dev;
        gc->ngpio       = vg->soc_data->npins;
-       gc->irq.need_valid_mask = true;
+       gc->irq.init_valid_mask = byt_init_irq_valid_mask;
 
 #ifdef CONFIG_PM_SLEEP
        vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio,
index 03ec7a5..ab681d1 100644 (file)
@@ -1543,6 +1543,30 @@ static const struct dmi_system_id chv_no_valid_mask[] = {
        {}
 };
 
+static void chv_init_irq_valid_mask(struct gpio_chip *chip,
+                                   unsigned long *valid_mask,
+                                   unsigned int ngpios)
+{
+       struct chv_pinctrl *pctrl = gpiochip_get_data(chip);
+       const struct chv_community *community = pctrl->community;
+       int i;
+
+       /* Do not add GPIOs that can only generate GPEs to the IRQ domain */
+       for (i = 0; i < community->npins; i++) {
+               const struct pinctrl_pin_desc *desc;
+               u32 intsel;
+
+               desc = &community->pins[i];
+
+               intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0));
+               intsel &= CHV_PADCTRL0_INTSEL_MASK;
+               intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
+
+               if (intsel >= community->nirqs)
+                       clear_bit(i, valid_mask);
+       }
+}
+
 static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
 {
        const struct chv_gpio_pinrange *range;
@@ -1557,7 +1581,8 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
        chip->label = dev_name(pctrl->dev);
        chip->parent = pctrl->dev;
        chip->base = -1;
-       chip->irq.need_valid_mask = need_valid_mask;
+       if (need_valid_mask)
+               chip->irq.init_valid_mask = chv_init_irq_valid_mask;
 
        ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl);
        if (ret) {
@@ -1576,21 +1601,6 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq)
                }
        }
 
-       /* Do not add GPIOs that can only generate GPEs to the IRQ domain */
-       for (i = 0; i < community->npins; i++) {
-               const struct pinctrl_pin_desc *desc;
-               u32 intsel;
-
-               desc = &community->pins[i];
-
-               intsel = readl(chv_padreg(pctrl, desc->number, CHV_PADCTRL0));
-               intsel &= CHV_PADCTRL0_INTSEL_MASK;
-               intsel >>= CHV_PADCTRL0_INTSEL_SHIFT;
-
-               if (need_valid_mask && intsel >= community->nirqs)
-                       clear_bit(i, chip->irq.valid_mask);
-       }
-
        /*
         * The same set of machines in chv_no_valid_mask[] have incorrectly
         * configured GPIOs that generate spurious interrupts so we use
index d3332da..dd5aa9a 100644 (file)
@@ -585,12 +585,24 @@ static int stmfx_pinctrl_gpio_function_enable(struct stmfx_pinctrl *pctl)
        return stmfx_function_enable(pctl->stmfx, func);
 }
 
+static int stmfx_pinctrl_gpio_init_valid_mask(struct gpio_chip *gc,
+                                             unsigned long *valid_mask,
+                                             unsigned int ngpios)
+{
+       struct stmfx_pinctrl *pctl = gpiochip_get_data(gc);
+       u32 n;
+
+       for_each_clear_bit(n, &pctl->gpio_valid_mask, ngpios)
+               clear_bit(n, valid_mask);
+
+       return 0;
+}
+
 static int stmfx_pinctrl_probe(struct platform_device *pdev)
 {
        struct stmfx *stmfx = dev_get_drvdata(pdev->dev.parent);
        struct device_node *np = pdev->dev.of_node;
        struct stmfx_pinctrl *pctl;
-       u32 n;
        int irq, ret;
 
        pctl = devm_kzalloc(stmfx->dev, sizeof(*pctl), GFP_KERNEL);
@@ -650,7 +662,7 @@ static int stmfx_pinctrl_probe(struct platform_device *pdev)
        pctl->gpio_chip.ngpio = pctl->pctl_desc.npins;
        pctl->gpio_chip.can_sleep = true;
        pctl->gpio_chip.of_node = np;
-       pctl->gpio_chip.need_valid_mask = true;
+       pctl->gpio_chip.init_valid_mask = stmfx_pinctrl_gpio_init_valid_mask;
 
        ret = devm_gpiochip_add_data(pctl->dev, &pctl->gpio_chip, pctl);
        if (ret) {
@@ -668,8 +680,6 @@ static int stmfx_pinctrl_probe(struct platform_device *pdev)
        pctl->irq_chip.irq_set_type = stmfx_pinctrl_irq_set_type;
        pctl->irq_chip.irq_bus_lock = stmfx_pinctrl_irq_bus_lock;
        pctl->irq_chip.irq_bus_sync_unlock = stmfx_pinctrl_irq_bus_sync_unlock;
-       for_each_clear_bit(n, &pctl->gpio_valid_mask, pctl->gpio_chip.ngpio)
-               clear_bit(n, pctl->gpio_chip.valid_mask);
 
        ret = gpiochip_irqchip_add_nested(&pctl->gpio_chip, &pctl->irq_chip,
                                          0, handle_bad_irq, IRQ_TYPE_NONE);
index 8e14a5f..fa2c878 100644 (file)
@@ -138,6 +138,7 @@ config PINCTRL_QCOM_SPMI_PMIC
        select PINMUX
        select PINCONF
        select GENERIC_PINCONF
+       select GPIOLIB_IRQCHIP
        select IRQ_DOMAIN_HIERARCHY
        help
          This is the pinctrl, pinmux, pinconf and gpiolib driver for the
index 7f35c19..b8a1c43 100644 (file)
@@ -593,24 +593,25 @@ static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 #define msm_gpio_dbg_show NULL
 #endif
 
-static int msm_gpio_init_valid_mask(struct gpio_chip *chip)
+static int msm_gpio_init_valid_mask(struct gpio_chip *gc,
+                                   unsigned long *valid_mask,
+                                   unsigned int ngpios)
 {
-       struct msm_pinctrl *pctrl = gpiochip_get_data(chip);
+       struct msm_pinctrl *pctrl = gpiochip_get_data(gc);
        int ret;
        unsigned int len, i;
-       unsigned int max_gpios = pctrl->soc->ngpios;
        const int *reserved = pctrl->soc->reserved_gpios;
        u16 *tmp;
 
        /* Driver provided reserved list overrides DT and ACPI */
        if (reserved) {
-               bitmap_fill(chip->valid_mask, max_gpios);
+               bitmap_fill(valid_mask, ngpios);
                for (i = 0; reserved[i] >= 0; i++) {
-                       if (i >= max_gpios || reserved[i] >= max_gpios) {
+                       if (i >= ngpios || reserved[i] >= ngpios) {
                                dev_err(pctrl->dev, "invalid list of reserved GPIOs\n");
                                return -EINVAL;
                        }
-                       clear_bit(reserved[i], chip->valid_mask);
+                       clear_bit(reserved[i], valid_mask);
                }
 
                return 0;
@@ -622,7 +623,7 @@ static int msm_gpio_init_valid_mask(struct gpio_chip *chip)
        if (ret < 0)
                return 0;
 
-       if (ret > max_gpios)
+       if (ret > ngpios)
                return -EINVAL;
 
        tmp = kmalloc_array(len, sizeof(*tmp), GFP_KERNEL);
@@ -635,9 +636,9 @@ static int msm_gpio_init_valid_mask(struct gpio_chip *chip)
                goto out;
        }
 
-       bitmap_zero(chip->valid_mask, max_gpios);
+       bitmap_zero(valid_mask, ngpios);
        for (i = 0; i < len; i++)
-               set_bit(tmp[i], chip->valid_mask);
+               set_bit(tmp[i], valid_mask);
 
 out:
        kfree(tmp);
@@ -653,7 +654,6 @@ static const struct gpio_chip msm_gpio_template = {
        .request          = gpiochip_generic_request,
        .free             = gpiochip_generic_free,
        .dbg_show         = msm_gpio_dbg_show,
-       .init_valid_mask  = msm_gpio_init_valid_mask,
 };
 
 /* For dual-edge interrupts in software, since some hardware has no
@@ -1015,7 +1015,8 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)
        chip->parent = pctrl->dev;
        chip->owner = THIS_MODULE;
        chip->of_node = pctrl->dev->of_node;
-       chip->need_valid_mask = msm_gpio_needs_valid_mask(pctrl);
+       if (msm_gpio_needs_valid_mask(pctrl))
+               chip->init_valid_mask = msm_gpio_init_valid_mask;
 
        pctrl->irq_chip.name = "msmgpio";
        pctrl->irq_chip.irq_enable = msm_gpio_irq_enable;
index f39da87..442db15 100644 (file)
@@ -170,8 +170,6 @@ struct pmic_gpio_state {
        struct regmap   *map;
        struct pinctrl_dev *ctrl;
        struct gpio_chip chip;
-       struct fwnode_handle *fwnode;
-       struct irq_domain *domain;
 };
 
 static const struct pinconf_generic_params pmic_gpio_bindings[] = {
@@ -751,23 +749,6 @@ static int pmic_gpio_of_xlate(struct gpio_chip *chip,
        return gpio_desc->args[0] - PMIC_GPIO_PHYSICAL_OFFSET;
 }
 
-static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned pin)
-{
-       struct pmic_gpio_state *state = gpiochip_get_data(chip);
-       struct irq_fwspec fwspec;
-
-       fwspec.fwnode = state->fwnode;
-       fwspec.param_count = 2;
-       fwspec.param[0] = pin + PMIC_GPIO_PHYSICAL_OFFSET;
-       /*
-        * Set the type to a safe value temporarily. This will be overwritten
-        * later with the proper value by irq_set_type.
-        */
-       fwspec.param[1] = IRQ_TYPE_EDGE_RISING;
-
-       return irq_create_fwspec_mapping(&fwspec);
-}
-
 static void pmic_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
 {
        struct pmic_gpio_state *state = gpiochip_get_data(chip);
@@ -787,7 +768,6 @@ static const struct gpio_chip pmic_gpio_gpio_template = {
        .request                = gpiochip_generic_request,
        .free                   = gpiochip_generic_free,
        .of_xlate               = pmic_gpio_of_xlate,
-       .to_irq                 = pmic_gpio_to_irq,
        .dbg_show               = pmic_gpio_dbg_show,
 };
 
@@ -964,46 +944,24 @@ static int pmic_gpio_domain_translate(struct irq_domain *domain,
        return 0;
 }
 
-static int pmic_gpio_domain_alloc(struct irq_domain *domain, unsigned int virq,
-                                 unsigned int nr_irqs, void *data)
+static unsigned int pmic_gpio_child_offset_to_irq(struct gpio_chip *chip,
+                                                 unsigned int offset)
 {
-       struct pmic_gpio_state *state = container_of(domain->host_data,
-                                                    struct pmic_gpio_state,
-                                                    chip);
-       struct irq_fwspec *fwspec = data;
-       struct irq_fwspec parent_fwspec;
-       irq_hw_number_t hwirq;
-       unsigned int type;
-       int ret, i;
-
-       ret = pmic_gpio_domain_translate(domain, fwspec, &hwirq, &type);
-       if (ret)
-               return ret;
-
-       for (i = 0; i < nr_irqs; i++)
-               irq_domain_set_info(domain, virq + i, hwirq + i,
-                                   &pmic_gpio_irq_chip, state,
-                                   handle_level_irq, NULL, NULL);
+       return offset + PMIC_GPIO_PHYSICAL_OFFSET;
+}
 
-       parent_fwspec.fwnode = domain->parent->fwnode;
-       parent_fwspec.param_count = 4;
-       parent_fwspec.param[0] = 0;
-       parent_fwspec.param[1] = hwirq + 0xc0;
-       parent_fwspec.param[2] = 0;
-       parent_fwspec.param[3] = fwspec->param[1];
+static int pmic_gpio_child_to_parent_hwirq(struct gpio_chip *chip,
+                                          unsigned int child_hwirq,
+                                          unsigned int child_type,
+                                          unsigned int *parent_hwirq,
+                                          unsigned int *parent_type)
+{
+       *parent_hwirq = child_hwirq + 0xc0;
+       *parent_type = child_type;
 
-       return irq_domain_alloc_irqs_parent(domain, virq, nr_irqs,
-                                           &parent_fwspec);
+       return 0;
 }
 
-static const struct irq_domain_ops pmic_gpio_domain_ops = {
-       .activate = gpiochip_irq_domain_activate,
-       .alloc = pmic_gpio_domain_alloc,
-       .deactivate = gpiochip_irq_domain_deactivate,
-       .free = irq_domain_free_irqs_common,
-       .translate = pmic_gpio_domain_translate,
-};
-
 static int pmic_gpio_probe(struct platform_device *pdev)
 {
        struct irq_domain *parent_domain;
@@ -1013,6 +971,7 @@ static int pmic_gpio_probe(struct platform_device *pdev)
        struct pinctrl_desc *pctrldesc;
        struct pmic_gpio_pad *pad, *pads;
        struct pmic_gpio_state *state;
+       struct gpio_irq_chip *girq;
        int ret, npins, i;
        u32 reg;
 
@@ -1092,19 +1051,21 @@ static int pmic_gpio_probe(struct platform_device *pdev)
        if (!parent_domain)
                return -ENXIO;
 
-       state->fwnode = of_node_to_fwnode(state->dev->of_node);
-       state->domain = irq_domain_create_hierarchy(parent_domain, 0,
-                                                   state->chip.ngpio,
-                                                   state->fwnode,
-                                                   &pmic_gpio_domain_ops,
-                                                   &state->chip);
-       if (!state->domain)
-               return -ENODEV;
+       girq = &state->chip.irq;
+       girq->chip = &pmic_gpio_irq_chip;
+       girq->default_type = IRQ_TYPE_NONE;
+       girq->handler = handle_level_irq;
+       girq->fwnode = of_node_to_fwnode(state->dev->of_node);
+       girq->parent_domain = parent_domain;
+       girq->child_to_parent_hwirq = pmic_gpio_child_to_parent_hwirq;
+       girq->populate_parent_fwspec = gpiochip_populate_parent_fwspec_fourcell;
+       girq->child_offset_to_irq = pmic_gpio_child_offset_to_irq;
+       girq->child_irq_domain_ops.translate = pmic_gpio_domain_translate;
 
        ret = gpiochip_add_data(&state->chip, state);
        if (ret) {
                dev_err(state->dev, "can't add gpio chip\n");
-               goto err_chip_add_data;
+               return ret;
        }
 
        /*
@@ -1130,8 +1091,6 @@ static int pmic_gpio_probe(struct platform_device *pdev)
 
 err_range:
        gpiochip_remove(&state->chip);
-err_chip_add_data:
-       irq_domain_remove(state->domain);
        return ret;
 }
 
@@ -1140,7 +1099,6 @@ static int pmic_gpio_remove(struct platform_device *pdev)
        struct pmic_gpio_state *state = platform_get_drvdata(pdev);
 
        gpiochip_remove(&state->chip);
-       irq_domain_remove(state->domain);
        return 0;
 }
 
index 006a8ff..714306b 100644 (file)
@@ -706,7 +706,7 @@ static int cros_ec_spi_devm_high_pri_alloc(struct device *dev,
                                           struct cros_ec_spi *ec_spi)
 {
        struct sched_param sched_priority = {
-               .sched_priority = MAX_RT_PRIO - 1,
+               .sched_priority = MAX_RT_PRIO / 2,
        };
        int err;
 
index d9542c6..f57bbbe 100644 (file)
@@ -152,6 +152,13 @@ static const struct x86_cpu_id int0002_cpu_ids[] = {
        {}
 };
 
+static void int0002_init_irq_valid_mask(struct gpio_chip *chip,
+                                       unsigned long *valid_mask,
+                                       unsigned int ngpios)
+{
+       bitmap_clear(valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN);
+}
+
 static int int0002_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -184,7 +191,7 @@ static int int0002_probe(struct platform_device *pdev)
        chip->direction_output = int0002_gpio_direction_output;
        chip->base = -1;
        chip->ngpio = GPE0A_PME_B0_VIRT_GPIO_PIN + 1;
-       chip->irq.need_valid_mask = true;
+       chip->irq.init_valid_mask = int0002_init_irq_valid_mask;
 
        ret = devm_gpiochip_add_data(&pdev->dev, chip, NULL);
        if (ret) {
@@ -192,8 +199,6 @@ static int int0002_probe(struct platform_device *pdev)
                return ret;
        }
 
-       bitmap_clear(chip->irq.valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN);
-
        /*
         * We manually request the irq here instead of passing a flow-handler
         * to gpiochip_set_chained_irqchip, because the irq is shared.
index ef6777e..6f0404f 100644 (file)
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
-obj-$(CONFIG_RAS)      += ras.o debugfs.o
+obj-$(CONFIG_RAS)      += ras.o
+obj-$(CONFIG_DEBUG_FS) += debugfs.o
 obj-$(CONFIG_RAS_CEC)  += cec.o
index 5d54580..c09cf55 100644 (file)
@@ -4,6 +4,7 @@
  */
 #include <linux/mm.h>
 #include <linux/gfp.h>
+#include <linux/ras.h>
 #include <linux/kernel.h>
 #include <linux/workqueue.h>
 
index 9c1b717..0d4f985 100644 (file)
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include <linux/debugfs.h>
+#include <linux/ras.h>
+#include "debugfs.h"
 
 struct dentry *ras_debugfs_dir;
 
index b57093d..3ee6353 100644 (file)
@@ -83,6 +83,7 @@ config REGULATOR_88PM8607
 config REGULATOR_ACT8865
        tristate "Active-semi act8865 voltage regulator"
        depends on I2C
+       depends on POWER_SUPPLY
        select REGMAP_I2C
        help
          This driver controls a active-semi act8865 voltage output
@@ -618,6 +619,15 @@ config REGULATOR_MT6323
          This driver supports the control of different power rails of device
          through regulator interface.
 
+config REGULATOR_MT6358
+       tristate "MediaTek MT6358 PMIC"
+       depends on MFD_MT6397 && BROKEN
+       help
+         Say y here to select this option to enable the power regulator of
+         MediaTek MT6358 PMIC.
+         This driver supports the control of different power rails of device
+         through regulator interface.
+
 config REGULATOR_MT6380
        tristate "MediaTek MT6380 PMIC"
        depends on MTK_PMIC_WRAP
@@ -906,6 +916,13 @@ config REGULATOR_SY8106A
        help
          This driver supports SY8106A single output regulator.
 
+config REGULATOR_SY8824X
+       tristate "Silergy SY8824C/SY8824E regulator"
+       depends on I2C && (OF || COMPILE_TEST)
+       select REGMAP_I2C
+       help
+         This driver supports SY8824C single output regulator.
+
 config REGULATOR_TPS51632
        tristate "TI TPS51632 Power Regulator"
        depends on I2C
index eef73b5..2210ba5 100644 (file)
@@ -79,6 +79,7 @@ obj-$(CONFIG_REGULATOR_MC13XXX_CORE) +=  mc13xxx-regulator-core.o
 obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
 obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
 obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
+obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o
 obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o
 obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o
 obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o
@@ -111,6 +112,7 @@ obj-$(CONFIG_REGULATOR_STM32_PWR) += stm32-pwr.o
 obj-$(CONFIG_REGULATOR_STPMIC1) += stpmic1_regulator.o
 obj-$(CONFIG_REGULATOR_STW481X_VMMC) += stw481x-vmmc.o
 obj-$(CONFIG_REGULATOR_SY8106A) += sy8106a-regulator.o
+obj-$(CONFIG_REGULATOR_SY8824X) += sy8824x.o
 obj-$(CONFIG_REGULATOR_TI_ABB) += ti-abb-regulator.o
 obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
 obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
index cf72d7c..0fa97f9 100644 (file)
 #include <linux/regulator/act8865.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/power_supply.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regmap.h>
+#include <dt-bindings/regulator/active-semi,8865-regulator.h>
 
 /*
  * ACT8600 Global Register Map.
  */
 #define        ACT8865_SYS_MODE        0x00
 #define        ACT8865_SYS_CTRL        0x01
+#define        ACT8865_SYS_UNLK_REGS   0x0b
 #define        ACT8865_DCDC1_VSET1     0x20
 #define        ACT8865_DCDC1_VSET2     0x21
 #define        ACT8865_DCDC1_CTRL      0x22
+#define        ACT8865_DCDC1_SUS       0x24
 #define        ACT8865_DCDC2_VSET1     0x30
 #define        ACT8865_DCDC2_VSET2     0x31
 #define        ACT8865_DCDC2_CTRL      0x32
+#define        ACT8865_DCDC2_SUS       0x34
 #define        ACT8865_DCDC3_VSET1     0x40
 #define        ACT8865_DCDC3_VSET2     0x41
 #define        ACT8865_DCDC3_CTRL      0x42
+#define        ACT8865_DCDC3_SUS       0x44
 #define        ACT8865_LDO1_VSET       0x50
 #define        ACT8865_LDO1_CTRL       0x51
+#define        ACT8865_LDO1_SUS        0x52
 #define        ACT8865_LDO2_VSET       0x54
 #define        ACT8865_LDO2_CTRL       0x55
+#define        ACT8865_LDO2_SUS        0x56
 #define        ACT8865_LDO3_VSET       0x60
 #define        ACT8865_LDO3_CTRL       0x61
+#define        ACT8865_LDO3_SUS        0x62
 #define        ACT8865_LDO4_VSET       0x64
 #define        ACT8865_LDO4_CTRL       0x65
+#define        ACT8865_LDO4_SUS        0x66
 #define        ACT8865_MSTROFF         0x20
 
 /*
  * Field Definitions.
  */
 #define        ACT8865_ENA             0x80    /* ON - [7] */
+#define        ACT8865_DIS             0x40    /* DIS - [6] */
+
 #define        ACT8865_VSEL_MASK       0x3F    /* VSET - [5:0] */
 
 
 #define ACT8600_LDO10_ENA              0x40    /* ON - [6] */
 #define ACT8600_SUDCDC_VSEL_MASK       0xFF    /* SUDCDC VSET - [7:0] */
 
+#define ACT8600_APCH_CHG_ACIN          BIT(7)
+#define ACT8600_APCH_CHG_USB           BIT(6)
+#define ACT8600_APCH_CSTATE0           BIT(5)
+#define ACT8600_APCH_CSTATE1           BIT(4)
+
 /*
  * ACT8865 voltage number
  */
@@ -217,6 +234,171 @@ static const struct regulator_linear_range act8600_sudcdc_voltage_ranges[] = {
        REGULATOR_LINEAR_RANGE(41400000, 248, 255, 0),
 };
 
+static int act8865_set_suspend_state(struct regulator_dev *rdev, bool enable)
+{
+       struct regmap *regmap = rdev->regmap;
+       int id = rdev->desc->id, reg, val;
+
+       switch (id) {
+       case ACT8865_ID_DCDC1:
+               reg = ACT8865_DCDC1_SUS;
+               val = 0xa8;
+               break;
+       case ACT8865_ID_DCDC2:
+               reg = ACT8865_DCDC2_SUS;
+               val = 0xa8;
+               break;
+       case ACT8865_ID_DCDC3:
+               reg = ACT8865_DCDC3_SUS;
+               val = 0xa8;
+               break;
+       case ACT8865_ID_LDO1:
+               reg = ACT8865_LDO1_SUS;
+               val = 0xe8;
+               break;
+       case ACT8865_ID_LDO2:
+               reg = ACT8865_LDO2_SUS;
+               val = 0xe8;
+               break;
+       case ACT8865_ID_LDO3:
+               reg = ACT8865_LDO3_SUS;
+               val = 0xe8;
+               break;
+       case ACT8865_ID_LDO4:
+               reg = ACT8865_LDO4_SUS;
+               val = 0xe8;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (enable)
+               val |= BIT(4);
+
+       /*
+        * Ask the PMIC to enable/disable this output when entering hibernate
+        * mode.
+        */
+       return regmap_write(regmap, reg, val);
+}
+
+static int act8865_set_suspend_enable(struct regulator_dev *rdev)
+{
+       return act8865_set_suspend_state(rdev, true);
+}
+
+static int act8865_set_suspend_disable(struct regulator_dev *rdev)
+{
+       return act8865_set_suspend_state(rdev, false);
+}
+
+static unsigned int act8865_of_map_mode(unsigned int mode)
+{
+       switch (mode) {
+       case ACT8865_REGULATOR_MODE_FIXED:
+               return REGULATOR_MODE_FAST;
+       case ACT8865_REGULATOR_MODE_NORMAL:
+               return REGULATOR_MODE_NORMAL;
+       case ACT8865_REGULATOR_MODE_LOWPOWER:
+               return REGULATOR_MODE_STANDBY;
+       default:
+               return REGULATOR_MODE_INVALID;
+       }
+}
+
+static int act8865_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+       struct regmap *regmap = rdev->regmap;
+       int id = rdev_get_id(rdev);
+       int reg, val = 0;
+
+       switch (id) {
+       case ACT8865_ID_DCDC1:
+               reg = ACT8865_DCDC1_CTRL;
+               break;
+       case ACT8865_ID_DCDC2:
+               reg = ACT8865_DCDC2_CTRL;
+               break;
+       case ACT8865_ID_DCDC3:
+               reg = ACT8865_DCDC3_CTRL;
+               break;
+       case ACT8865_ID_LDO1:
+               reg = ACT8865_LDO1_CTRL;
+               break;
+       case ACT8865_ID_LDO2:
+               reg = ACT8865_LDO2_CTRL;
+               break;
+       case ACT8865_ID_LDO3:
+               reg = ACT8865_LDO3_CTRL;
+               break;
+       case ACT8865_ID_LDO4:
+               reg = ACT8865_LDO4_CTRL;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (mode) {
+       case REGULATOR_MODE_FAST:
+       case REGULATOR_MODE_NORMAL:
+               if (id <= ACT8865_ID_DCDC3)
+                       val = BIT(5);
+               break;
+       case REGULATOR_MODE_STANDBY:
+               if (id > ACT8865_ID_DCDC3)
+                       val = BIT(5);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return regmap_update_bits(regmap, reg, BIT(5), val);
+}
+
+static unsigned int act8865_get_mode(struct regulator_dev *rdev)
+{
+       struct regmap *regmap = rdev->regmap;
+       int id = rdev_get_id(rdev);
+       int reg, ret, val = 0;
+
+       switch (id) {
+       case ACT8865_ID_DCDC1:
+               reg = ACT8865_DCDC1_CTRL;
+               break;
+       case ACT8865_ID_DCDC2:
+               reg = ACT8865_DCDC2_CTRL;
+               break;
+       case ACT8865_ID_DCDC3:
+               reg = ACT8865_DCDC3_CTRL;
+               break;
+       case ACT8865_ID_LDO1:
+               reg = ACT8865_LDO1_CTRL;
+               break;
+       case ACT8865_ID_LDO2:
+               reg = ACT8865_LDO2_CTRL;
+               break;
+       case ACT8865_ID_LDO3:
+               reg = ACT8865_LDO3_CTRL;
+               break;
+       case ACT8865_ID_LDO4:
+               reg = ACT8865_LDO4_CTRL;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ret = regmap_read(regmap, reg, &val);
+       if (ret)
+               return ret;
+
+       if (id <= ACT8865_ID_DCDC3 && (val & BIT(5)))
+               return REGULATOR_MODE_FAST;
+       else if (id > ACT8865_ID_DCDC3 && !(val & BIT(5)))
+               return REGULATOR_MODE_NORMAL;
+       else
+               return REGULATOR_MODE_STANDBY;
+}
+
 static const struct regulator_ops act8865_ops = {
        .list_voltage           = regulator_list_voltage_linear_range,
        .map_voltage            = regulator_map_voltage_linear_range,
@@ -224,24 +406,44 @@ static const struct regulator_ops act8865_ops = {
        .set_voltage_sel        = regulator_set_voltage_sel_regmap,
        .enable                 = regulator_enable_regmap,
        .disable                = regulator_disable_regmap,
+       .set_mode               = act8865_set_mode,
+       .get_mode               = act8865_get_mode,
        .is_enabled             = regulator_is_enabled_regmap,
+       .set_suspend_enable     = act8865_set_suspend_enable,
+       .set_suspend_disable    = act8865_set_suspend_disable,
 };
 
 static const struct regulator_ops act8865_ldo_ops = {
+       .list_voltage           = regulator_list_voltage_linear_range,
+       .map_voltage            = regulator_map_voltage_linear_range,
+       .get_voltage_sel        = regulator_get_voltage_sel_regmap,
+       .set_voltage_sel        = regulator_set_voltage_sel_regmap,
+       .enable                 = regulator_enable_regmap,
+       .disable                = regulator_disable_regmap,
+       .set_mode               = act8865_set_mode,
+       .get_mode               = act8865_get_mode,
+       .is_enabled             = regulator_is_enabled_regmap,
+       .set_suspend_enable     = act8865_set_suspend_enable,
+       .set_suspend_disable    = act8865_set_suspend_disable,
+       .set_pull_down          = regulator_set_pull_down_regmap,
+};
+
+static const struct regulator_ops act8865_fixed_ldo_ops = {
        .enable                 = regulator_enable_regmap,
        .disable                = regulator_disable_regmap,
        .is_enabled             = regulator_is_enabled_regmap,
 };
 
-#define ACT88xx_REG(_name, _family, _id, _vsel_reg, _supply)           \
+#define ACT88xx_REG_(_name, _family, _id, _vsel_reg, _supply, _ops)    \
        [_family##_ID_##_id] = {                                        \
                .name                   = _name,                        \
                .of_match               = of_match_ptr(_name),          \
+               .of_map_mode            = act8865_of_map_mode,          \
                .regulators_node        = of_match_ptr("regulators"),   \
                .supply_name            = _supply,                      \
                .id                     = _family##_ID_##_id,           \
                .type                   = REGULATOR_VOLTAGE,            \
-               .ops                    = &act8865_ops,                 \
+               .ops                    = _ops,                         \
                .n_voltages             = ACT8865_VOLTAGE_NUM,          \
                .linear_ranges          = act8865_voltage_ranges,       \
                .n_linear_ranges        = ARRAY_SIZE(act8865_voltage_ranges), \
@@ -249,9 +451,17 @@ static const struct regulator_ops act8865_ldo_ops = {
                .vsel_mask              = ACT8865_VSEL_MASK,            \
                .enable_reg             = _family##_##_id##_CTRL,       \
                .enable_mask            = ACT8865_ENA,                  \
+               .pull_down_reg          = _family##_##_id##_CTRL,       \
+               .pull_down_mask         = ACT8865_DIS,                  \
                .owner                  = THIS_MODULE,                  \
        }
 
+#define ACT88xx_REG(_name, _family, _id, _vsel_reg, _supply) \
+       ACT88xx_REG_(_name, _family, _id, _vsel_reg, _supply, &act8865_ops)
+
+#define ACT88xx_LDO(_name, _family, _id, _vsel_reg, _supply) \
+       ACT88xx_REG_(_name, _family, _id, _vsel_reg, _supply, &act8865_ldo_ops)
+
 static const struct regulator_desc act8600_regulators[] = {
        ACT88xx_REG("DCDC1", ACT8600, DCDC1, VSET, "vp1"),
        ACT88xx_REG("DCDC2", ACT8600, DCDC2, VSET, "vp2"),
@@ -281,7 +491,7 @@ static const struct regulator_desc act8600_regulators[] = {
                .of_match = of_match_ptr("LDO_REG9"),
                .regulators_node = of_match_ptr("regulators"),
                .id = ACT8600_ID_LDO9,
-               .ops = &act8865_ldo_ops,
+               .ops = &act8865_fixed_ldo_ops,
                .type = REGULATOR_VOLTAGE,
                .n_voltages = 1,
                .fixed_uV = 3300000,
@@ -294,7 +504,7 @@ static const struct regulator_desc act8600_regulators[] = {
                .of_match = of_match_ptr("LDO_REG10"),
                .regulators_node = of_match_ptr("regulators"),
                .id = ACT8600_ID_LDO10,
-               .ops = &act8865_ldo_ops,
+               .ops = &act8865_fixed_ldo_ops,
                .type = REGULATOR_VOLTAGE,
                .n_voltages = 1,
                .fixed_uV = 1200000,
@@ -323,20 +533,20 @@ static const struct regulator_desc act8865_regulators[] = {
        ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET1, "vp1"),
        ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET1, "vp2"),
        ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET1, "vp3"),
-       ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET, "inl45"),
-       ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET, "inl45"),
-       ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET, "inl67"),
-       ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET, "inl67"),
+       ACT88xx_LDO("LDO_REG1", ACT8865, LDO1, VSET, "inl45"),
+       ACT88xx_LDO("LDO_REG2", ACT8865, LDO2, VSET, "inl45"),
+       ACT88xx_LDO("LDO_REG3", ACT8865, LDO3, VSET, "inl67"),
+       ACT88xx_LDO("LDO_REG4", ACT8865, LDO4, VSET, "inl67"),
 };
 
 static const struct regulator_desc act8865_alt_regulators[] = {
        ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET2, "vp1"),
        ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET2, "vp2"),
        ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET2, "vp3"),
-       ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET, "inl45"),
-       ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET, "inl45"),
-       ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET, "inl67"),
-       ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET, "inl67"),
+       ACT88xx_LDO("LDO_REG1", ACT8865, LDO1, VSET, "inl45"),
+       ACT88xx_LDO("LDO_REG2", ACT8865, LDO2, VSET, "inl45"),
+       ACT88xx_LDO("LDO_REG3", ACT8865, LDO3, VSET, "inl67"),
+       ACT88xx_LDO("LDO_REG4", ACT8865, LDO4, VSET, "inl67"),
 };
 
 #ifdef CONFIG_OF
@@ -372,6 +582,75 @@ static void act8865_power_off(void)
        while (1);
 }
 
+static int act8600_charger_get_status(struct regmap *map)
+{
+       unsigned int val;
+       int ret;
+       u8 state0, state1;
+
+       ret = regmap_read(map, ACT8600_APCH_STAT, &val);
+       if (ret < 0)
+               return ret;
+
+       state0 = val & ACT8600_APCH_CSTATE0;
+       state1 = val & ACT8600_APCH_CSTATE1;
+
+       if (state0 && !state1)
+               return POWER_SUPPLY_STATUS_CHARGING;
+       if (!state0 && state1)
+               return POWER_SUPPLY_STATUS_NOT_CHARGING;
+       if (!state0 && !state1)
+               return POWER_SUPPLY_STATUS_DISCHARGING;
+
+       return POWER_SUPPLY_STATUS_UNKNOWN;
+}
+
+static int act8600_charger_get_property(struct power_supply *psy,
+               enum power_supply_property psp, union power_supply_propval *val)
+{
+       struct regmap *map = power_supply_get_drvdata(psy);
+       int ret;
+
+       switch (psp) {
+       case POWER_SUPPLY_PROP_STATUS:
+               ret = act8600_charger_get_status(map);
+               if (ret < 0)
+                       return ret;
+
+               val->intval = ret;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static enum power_supply_property act8600_charger_properties[] = {
+       POWER_SUPPLY_PROP_STATUS,
+};
+
+static const struct power_supply_desc act8600_charger_desc = {
+       .name = "act8600-charger",
+       .type = POWER_SUPPLY_TYPE_BATTERY,
+       .properties = act8600_charger_properties,
+       .num_properties = ARRAY_SIZE(act8600_charger_properties),
+       .get_property = act8600_charger_get_property,
+};
+
+static int act8600_charger_probe(struct device *dev, struct regmap *regmap)
+{
+       struct power_supply *charger;
+       struct power_supply_config cfg = {
+               .drv_data = regmap,
+               .of_node = dev->of_node,
+       };
+
+       charger = devm_power_supply_register(dev, &act8600_charger_desc, &cfg);
+
+       return PTR_ERR_OR_ZERO(charger);
+}
+
 static int act8865_pmic_probe(struct i2c_client *client,
                              const struct i2c_device_id *i2c_id)
 {
@@ -483,9 +762,20 @@ static int act8865_pmic_probe(struct i2c_client *client,
                }
        }
 
+       if (type == ACT8600) {
+               ret = act8600_charger_probe(dev, act8865->regmap);
+               if (ret < 0) {
+                       if (ret != -EPROBE_DEFER)
+                               dev_err(dev, "Failed to probe charger");
+                       return ret;
+               }
+       }
+
        i2c_set_clientdata(client, act8865);
 
-       return 0;
+       /* Unlock expert registers for ACT8865. */
+       return type != ACT8865 ? 0 : regmap_write(act8865->regmap,
+                                                 ACT8865_SYS_UNLK_REGS, 0xef);
 }
 
 static const struct i2c_device_id act8865_ids[] = {
index 5842849..d2f804d 100644 (file)
@@ -169,16 +169,16 @@ static int act8945a_set_mode(struct regulator_dev *rdev, unsigned int mode)
                reg = ACT8945A_DCDC3_CTRL;
                break;
        case ACT8945A_ID_LDO1:
-               reg = ACT8945A_LDO1_SUS;
+               reg = ACT8945A_LDO1_CTRL;
                break;
        case ACT8945A_ID_LDO2:
-               reg = ACT8945A_LDO2_SUS;
+               reg = ACT8945A_LDO2_CTRL;
                break;
        case ACT8945A_ID_LDO3:
-               reg = ACT8945A_LDO3_SUS;
+               reg = ACT8945A_LDO3_CTRL;
                break;
        case ACT8945A_ID_LDO4:
-               reg = ACT8945A_LDO4_SUS;
+               reg = ACT8945A_LDO4_CTRL;
                break;
        default:
                return -EINVAL;
index e0c0cf4..afe9447 100644 (file)
@@ -381,12 +381,16 @@ static struct device_node *of_get_child_regulator(struct device_node *parent,
                if (!regnode) {
                        regnode = of_get_child_regulator(child, prop_name);
                        if (regnode)
-                               return regnode;
+                               goto err_node_put;
                } else {
-                       return regnode;
+                       goto err_node_put;
                }
        }
        return NULL;
+
+err_node_put:
+       of_node_put(child);
+       return regnode;
 }
 
 /**
@@ -564,13 +568,15 @@ static ssize_t regulator_uV_show(struct device *dev,
                                struct device_attribute *attr, char *buf)
 {
        struct regulator_dev *rdev = dev_get_drvdata(dev);
-       ssize_t ret;
+       int uV;
 
        regulator_lock(rdev);
-       ret = sprintf(buf, "%d\n", regulator_get_voltage_rdev(rdev));
+       uV = regulator_get_voltage_rdev(rdev);
        regulator_unlock(rdev);
 
-       return ret;
+       if (uV < 0)
+               return uV;
+       return sprintf(buf, "%d\n", uV);
 }
 static DEVICE_ATTR(microvolts, 0444, regulator_uV_show, NULL);
 
@@ -5640,7 +5646,7 @@ static int __init regulator_init(void)
 /* init early to allow our consumers to complete system booting */
 core_initcall(regulator_init);
 
-static int __init regulator_late_cleanup(struct device *dev, void *data)
+static int regulator_late_cleanup(struct device *dev, void *data)
 {
        struct regulator_dev *rdev = dev_to_rdev(dev);
        const struct regulator_ops *ops = rdev->desc->ops;
@@ -5689,18 +5695,9 @@ unlock:
        return 0;
 }
 
-static int __init regulator_init_complete(void)
+static void regulator_init_complete_work_function(struct work_struct *work)
 {
        /*
-        * Since DT doesn't provide an idiomatic mechanism for
-        * enabling full constraints and since it's much more natural
-        * with DT to provide them just assume that a DT enabled
-        * system has full constraints.
-        */
-       if (of_have_populated_dt())
-               has_full_constraints = true;
-
-       /*
         * Regulators may had failed to resolve their input supplies
         * when were registered, either because the input supply was
         * not registered yet or because its parent device was not
@@ -5717,6 +5714,35 @@ static int __init regulator_init_complete(void)
         */
        class_for_each_device(&regulator_class, NULL, NULL,
                              regulator_late_cleanup);
+}
+
+static DECLARE_DELAYED_WORK(regulator_init_complete_work,
+                           regulator_init_complete_work_function);
+
+static int __init regulator_init_complete(void)
+{
+       /*
+        * Since DT doesn't provide an idiomatic mechanism for
+        * enabling full constraints and since it's much more natural
+        * with DT to provide them just assume that a DT enabled
+        * system has full constraints.
+        */
+       if (of_have_populated_dt())
+               has_full_constraints = true;
+
+       /*
+        * We punt completion for an arbitrary amount of time since
+        * systems like distros will load many drivers from userspace
+        * so consumers might not always be ready yet, this is
+        * particularly an issue with laptops where this might bounce
+        * the display off then on.  Ideally we'd get a notification
+        * from userspace when this happens but we don't so just wait
+        * a bit and hope we waited long enough.  It'd be better if
+        * we'd only do this on systems that need it, and a kernel
+        * command line option might be useful.
+        */
+       schedule_delayed_work(&regulator_init_complete_work,
+                             msecs_to_jiffies(30000));
 
        return 0;
 }
index 2ffc646..56f3f72 100644 (file)
@@ -1032,10 +1032,8 @@ static int da9062_regulator_probe(struct platform_device *pdev)
 
        /* LDOs overcurrent event support */
        irq = platform_get_irq_byname(pdev, "LDO_LIM");
-       if (irq < 0) {
-               dev_err(&pdev->dev, "Failed to get IRQ.\n");
+       if (irq < 0)
                return irq;
-       }
        regulators->irq_ldo_lim = irq;
 
        ret = devm_request_threaded_irq(&pdev->dev, irq,
index 02f8163..28b1b20 100644 (file)
@@ -863,10 +863,8 @@ static int da9063_regulator_probe(struct platform_device *pdev)
 
        /* LDOs overcurrent event support */
        irq = platform_get_irq_byname(pdev, "LDO_LIM");
-       if (irq < 0) {
-               dev_err(&pdev->dev, "Failed to get IRQ.\n");
+       if (irq < 0)
                return irq;
-       }
 
        ret = devm_request_threaded_irq(&pdev->dev, irq,
                                NULL, da9063_ldo_lim_event,
index 0309823..bf80748 100644 (file)
@@ -285,7 +285,7 @@ static struct da9211_pdata *da9211_parse_regulators_dt(
                pdata->reg_node[n] = da9211_matches[i].of_node;
                pdata->gpiod_ren[n] = devm_gpiod_get_from_of_node(dev,
                                  da9211_matches[i].of_node,
-                                 "enable",
+                                 "enable-gpios",
                                  0,
                                  GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE,
                                  "da9211-enable");
index 999547d..d90a6fd 100644 (file)
 #include <linux/gpio/consumer.h>
 #include <linux/slab.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/regulator/of_regulator.h>
 #include <linux/regulator/machine.h>
+#include <linux/clk.h>
+
 
 struct fixed_voltage_data {
        struct regulator_desc desc;
        struct regulator_dev *dev;
+
+       struct clk *enable_clock;
+       unsigned int clk_enable_counter;
 };
 
+struct fixed_dev_type {
+       bool has_enable_clock;
+};
+
+static const struct fixed_dev_type fixed_voltage_data = {
+       .has_enable_clock = false,
+};
+
+static const struct fixed_dev_type fixed_clkenable_data = {
+       .has_enable_clock = true,
+};
+
+static int reg_clock_enable(struct regulator_dev *rdev)
+{
+       struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
+       int ret = 0;
+
+       ret = clk_prepare_enable(priv->enable_clock);
+       if (ret)
+               return ret;
+
+       priv->clk_enable_counter++;
+
+       return ret;
+}
+
+static int reg_clock_disable(struct regulator_dev *rdev)
+{
+       struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
+
+       clk_disable_unprepare(priv->enable_clock);
+       priv->clk_enable_counter--;
+
+       return 0;
+}
+
+static int reg_clock_is_enabled(struct regulator_dev *rdev)
+{
+       struct fixed_voltage_data *priv = rdev_get_drvdata(rdev);
+
+       return priv->clk_enable_counter > 0;
+}
+
 
 /**
  * of_get_fixed_voltage_config - extract fixed_voltage_config structure info
@@ -84,10 +133,19 @@ of_get_fixed_voltage_config(struct device *dev,
 static struct regulator_ops fixed_voltage_ops = {
 };
 
+static struct regulator_ops fixed_voltage_clkenabled_ops = {
+       .enable = reg_clock_enable,
+       .disable = reg_clock_disable,
+       .is_enabled = reg_clock_is_enabled,
+};
+
 static int reg_fixed_voltage_probe(struct platform_device *pdev)
 {
+       struct device *dev = &pdev->dev;
        struct fixed_voltage_config *config;
        struct fixed_voltage_data *drvdata;
+       const struct fixed_dev_type *drvtype =
+               of_match_device(dev->driver->of_match_table, dev)->data;
        struct regulator_config cfg = { };
        enum gpiod_flags gflags;
        int ret;
@@ -118,7 +176,18 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
        }
        drvdata->desc.type = REGULATOR_VOLTAGE;
        drvdata->desc.owner = THIS_MODULE;
-       drvdata->desc.ops = &fixed_voltage_ops;
+
+       if (drvtype->has_enable_clock) {
+               drvdata->desc.ops = &fixed_voltage_clkenabled_ops;
+
+               drvdata->enable_clock = devm_clk_get(dev, NULL);
+               if (IS_ERR(drvdata->enable_clock)) {
+                       dev_err(dev, "Cant get enable-clock from devicetree\n");
+                       return -ENOENT;
+               }
+       } else {
+               drvdata->desc.ops = &fixed_voltage_ops;
+       }
 
        drvdata->desc.enable_time = config->startup_delay;
 
@@ -191,8 +260,16 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev)
 
 #if defined(CONFIG_OF)
 static const struct of_device_id fixed_of_match[] = {
-       { .compatible = "regulator-fixed", },
-       {},
+       {
+               .compatible = "regulator-fixed",
+               .data = &fixed_voltage_data,
+       },
+       {
+               .compatible = "regulator-fixed-clock",
+               .data = &fixed_clkenable_data,
+       },
+       {
+       },
 };
 MODULE_DEVICE_TABLE(of, fixed_of_match);
 #endif
index 4986cc5..ca3dc3f 100644 (file)
@@ -860,3 +860,24 @@ int regulator_get_current_limit_regmap(struct regulator_dev *rdev)
        return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(regulator_get_current_limit_regmap);
+
+/**
+ * regulator_bulk_set_supply_names - initialize the 'supply' fields in an array
+ *                                   of regulator_bulk_data structs
+ *
+ * @consumers: array of regulator_bulk_data entries to initialize
+ * @supply_names: array of supply name strings
+ * @num_supplies: number of supply names to initialize
+ *
+ * Note: the 'consumers' array must be the size of 'num_supplies'.
+ */
+void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
+                                    const char *const *supply_names,
+                                    unsigned int num_supplies)
+{
+       unsigned int i;
+
+       for (i = 0; i < num_supplies; i++)
+               consumers[i].supply = supply_names[i];
+}
+EXPORT_SYMBOL_GPL(regulator_bulk_set_supply_names);
index 5647e2f..4b9f618 100644 (file)
 
 /* LM3632 */
 #define LM3632_BOOST_VSEL_MAX          0x26
-#define LM3632_LDO_VSEL_MAX            0x29
+#define LM3632_LDO_VSEL_MAX            0x28
 #define LM3632_VBOOST_MIN              4500000
 #define LM3632_VLDO_MIN                        4000000
 
 /* LM36274 */
 #define LM36274_BOOST_VSEL_MAX         0x3f
-#define LM36274_LDO_VSEL_MAX           0x34
+#define LM36274_LDO_VSEL_MAX           0x32
 #define LM36274_VOLTAGE_MIN            4000000
 
 /* Common */
@@ -226,7 +226,7 @@ static const struct regulator_desc lm363x_regulator_desc[] = {
                .of_match       = "vboost",
                .id             = LM36274_BOOST,
                .ops            = &lm363x_boost_voltage_table_ops,
-               .n_voltages     = LM36274_BOOST_VSEL_MAX,
+               .n_voltages     = LM36274_BOOST_VSEL_MAX + 1,
                .min_uV         = LM36274_VOLTAGE_MIN,
                .uV_step        = LM363X_STEP_50mV,
                .type           = REGULATOR_VOLTAGE,
@@ -239,7 +239,7 @@ static const struct regulator_desc lm363x_regulator_desc[] = {
                .of_match       = "vpos",
                .id             = LM36274_LDO_POS,
                .ops            = &lm363x_regulator_voltage_table_ops,
-               .n_voltages     = LM36274_LDO_VSEL_MAX,
+               .n_voltages     = LM36274_LDO_VSEL_MAX + 1,
                .min_uV         = LM36274_VOLTAGE_MIN,
                .uV_step        = LM363X_STEP_50mV,
                .type           = REGULATOR_VOLTAGE,
@@ -254,7 +254,7 @@ static const struct regulator_desc lm363x_regulator_desc[] = {
                .of_match       = "vneg",
                .id             = LM36274_LDO_NEG,
                .ops            = &lm363x_regulator_voltage_table_ops,
-               .n_voltages     = LM36274_LDO_VSEL_MAX,
+               .n_voltages     = LM36274_LDO_VSEL_MAX + 1,
                .min_uV         = LM36274_VOLTAGE_MIN,
                .uV_step        = LM363X_STEP_50mV,
                .type           = REGULATOR_VOLTAGE,
index 0c440c5..4ae12ac 100644 (file)
@@ -65,7 +65,6 @@ static int lp87565_buck_set_ramp_delay(struct regulator_dev *rdev,
                                       int ramp_delay)
 {
        int id = rdev_get_id(rdev);
-       struct lp87565 *lp87565 = rdev_get_drvdata(rdev);
        unsigned int reg;
        int ret;
 
@@ -86,11 +85,11 @@ static int lp87565_buck_set_ramp_delay(struct regulator_dev *rdev,
        else
                reg = 0;
 
-       ret = regmap_update_bits(lp87565->regmap, regulators[id].ctrl2_reg,
+       ret = regmap_update_bits(rdev->regmap, regulators[id].ctrl2_reg,
                                 LP87565_BUCK_CTRL_2_SLEW_RATE,
                                 reg << __ffs(LP87565_BUCK_CTRL_2_SLEW_RATE));
        if (ret) {
-               dev_err(lp87565->dev, "SLEW RATE write failed: %d\n", ret);
+               dev_err(&rdev->dev, "SLEW RATE write failed: %d\n", ret);
                return ret;
        }
 
index 1b00f36..00e9bb9 100644 (file)
@@ -464,7 +464,7 @@ static int lp8788_config_ldo_enable_mode(struct platform_device *pdev,
 {
        struct lp8788 *lp = ldo->lp;
        enum lp8788_ext_ldo_en_id enable_id;
-       u8 en_mask[] = {
+       static const u8 en_mask[] = {
                [EN_ALDO1]   = LP8788_EN_SEL_ALDO1_M,
                [EN_ALDO234] = LP8788_EN_SEL_ALDO234_M,
                [EN_ALDO5]   = LP8788_EN_SEL_ALDO5_M,
index 8020eb5..c8e579e 100644 (file)
@@ -257,7 +257,7 @@ static int max77686_of_parse_cb(struct device_node *np,
        case MAX77686_BUCK9:
        case MAX77686_LDO20 ... MAX77686_LDO22:
                config->ena_gpiod = gpiod_get_from_of_node(np,
-                               "maxim,ena",
+                               "maxim,ena-gpios",
                                0,
                                GPIOD_OUT_HIGH | GPIOD_FLAGS_BIT_NONEXCLUSIVE,
                                "max77686-regulator");
index 4bca544..347043a 100644 (file)
@@ -485,7 +485,6 @@ static int max8660_probe(struct i2c_client *client,
                rdev = devm_regulator_register(&client->dev,
                                                  &max8660_reg[id], &config);
                if (IS_ERR(rdev)) {
-                       ret = PTR_ERR(rdev);
                        dev_err(&client->dev, "failed to register %s\n",
                                max8660_reg[id].name);
                        return PTR_ERR(rdev);
diff --git a/drivers/regulator/mt6358-regulator.c b/drivers/regulator/mt6358-regulator.c
new file mode 100644 (file)
index 0000000..ba42682
--- /dev/null
@@ -0,0 +1,549 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2019 MediaTek Inc.
+
+#include <linux/mfd/mt6358/registers.h>
+#include <linux/mfd/mt6397/core.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/mt6358-regulator.h>
+#include <linux/regulator/of_regulator.h>
+
+#define MT6358_BUCK_MODE_AUTO  0
+#define MT6358_BUCK_MODE_FORCE_PWM     1
+
+/*
+ * MT6358 regulators' information
+ *
+ * @desc: standard fields of regulator description.
+ * @qi: Mask for query enable signal status of regulators
+ */
+struct mt6358_regulator_info {
+       struct regulator_desc desc;
+       u32 status_reg;
+       u32 qi;
+       const u32 *index_table;
+       unsigned int n_table;
+       u32 vsel_shift;
+       u32 da_vsel_reg;
+       u32 da_vsel_mask;
+       u32 da_vsel_shift;
+       u32 modeset_reg;
+       u32 modeset_mask;
+       u32 modeset_shift;
+};
+
+#define MT6358_BUCK(match, vreg, min, max, step,               \
+       volt_ranges, vosel_mask, _da_vsel_reg, _da_vsel_mask,   \
+       _da_vsel_shift, _modeset_reg, _modeset_shift)           \
+[MT6358_ID_##vreg] = { \
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+               .ops = &mt6358_volt_range_ops,  \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6358_ID_##vreg,         \
+               .owner = THIS_MODULE,           \
+               .n_voltages = ((max) - (min)) / (step) + 1,     \
+               .linear_ranges = volt_ranges,           \
+               .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
+               .vsel_reg = MT6358_BUCK_##vreg##_ELR0,  \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = MT6358_BUCK_##vreg##_CON0,        \
+               .enable_mask = BIT(0),  \
+               .of_map_mode = mt6358_map_mode, \
+       },      \
+       .status_reg = MT6358_BUCK_##vreg##_DBG1,        \
+       .qi = BIT(0),   \
+       .da_vsel_reg = _da_vsel_reg,    \
+       .da_vsel_mask = _da_vsel_mask,  \
+       .da_vsel_shift = _da_vsel_shift,        \
+       .modeset_reg = _modeset_reg,    \
+       .modeset_mask = BIT(_modeset_shift),    \
+       .modeset_shift = _modeset_shift \
+}
+
+#define MT6358_LDO(match, vreg, ldo_volt_table,        \
+       ldo_index_table, enreg, enbit, vosel,   \
+       vosel_mask, vosel_shift)        \
+[MT6358_ID_##vreg] = { \
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+               .ops = &mt6358_volt_table_ops,  \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6358_ID_##vreg, \
+               .owner = THIS_MODULE,   \
+               .n_voltages = ARRAY_SIZE(ldo_volt_table),       \
+               .volt_table = ldo_volt_table,   \
+               .vsel_reg = vosel,      \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = enreg,    \
+               .enable_mask = BIT(enbit),      \
+       },      \
+       .status_reg = MT6358_LDO_##vreg##_CON1, \
+       .qi = BIT(15),  \
+       .index_table = ldo_index_table, \
+       .n_table = ARRAY_SIZE(ldo_index_table), \
+       .vsel_shift = vosel_shift,      \
+}
+
+#define MT6358_LDO1(match, vreg, min, max, step,       \
+       volt_ranges, _da_vsel_reg, _da_vsel_mask,       \
+       _da_vsel_shift, vosel, vosel_mask)      \
+[MT6358_ID_##vreg] = { \
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+               .ops = &mt6358_volt_range_ops,  \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6358_ID_##vreg, \
+               .owner = THIS_MODULE,   \
+               .n_voltages = ((max) - (min)) / (step) + 1,     \
+               .linear_ranges = volt_ranges,   \
+               .n_linear_ranges = ARRAY_SIZE(volt_ranges),     \
+               .vsel_reg = vosel,      \
+               .vsel_mask = vosel_mask,        \
+               .enable_reg = MT6358_LDO_##vreg##_CON0, \
+               .enable_mask = BIT(0),  \
+       },      \
+       .da_vsel_reg = _da_vsel_reg,    \
+       .da_vsel_mask = _da_vsel_mask,  \
+       .da_vsel_shift = _da_vsel_shift,        \
+       .status_reg = MT6358_LDO_##vreg##_DBG1, \
+       .qi = BIT(0),   \
+}
+
+#define MT6358_REG_FIXED(match, vreg,  \
+       enreg, enbit, volt)     \
+[MT6358_ID_##vreg] = { \
+       .desc = {       \
+               .name = #vreg,  \
+               .of_match = of_match_ptr(match),        \
+               .ops = &mt6358_volt_fixed_ops,  \
+               .type = REGULATOR_VOLTAGE,      \
+               .id = MT6358_ID_##vreg, \
+               .owner = THIS_MODULE,   \
+               .n_voltages = 1,        \
+               .enable_reg = enreg,    \
+               .enable_mask = BIT(enbit),      \
+               .min_uV = volt, \
+       },      \
+       .status_reg = MT6358_LDO_##vreg##_CON1, \
+       .qi = BIT(15),                                                  \
+}
+
+static const struct regulator_linear_range buck_volt_range1[] = {
+       REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 6250),
+};
+
+static const struct regulator_linear_range buck_volt_range2[] = {
+       REGULATOR_LINEAR_RANGE(500000, 0, 0x7f, 12500),
+};
+
+static const struct regulator_linear_range buck_volt_range3[] = {
+       REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000),
+};
+
+static const struct regulator_linear_range buck_volt_range4[] = {
+       REGULATOR_LINEAR_RANGE(1000000, 0, 0x7f, 12500),
+};
+
+static const u32 vdram2_voltages[] = {
+       600000, 1800000,
+};
+
+static const u32 vsim_voltages[] = {
+       1700000, 1800000, 2700000, 3000000, 3100000,
+};
+
+static const u32 vibr_voltages[] = {
+       1200000, 1300000, 1500000, 1800000,
+       2000000, 2800000, 3000000, 3300000,
+};
+
+static const u32 vusb_voltages[] = {
+       3000000, 3100000,
+};
+
+static const u32 vcamd_voltages[] = {
+       900000, 1000000, 1100000, 1200000,
+       1300000, 1500000, 1800000,
+};
+
+static const u32 vefuse_voltages[] = {
+       1700000, 1800000, 1900000,
+};
+
+static const u32 vmch_vemc_voltages[] = {
+       2900000, 3000000, 3300000,
+};
+
+static const u32 vcama_voltages[] = {
+       1800000, 2500000, 2700000,
+       2800000, 2900000, 3000000,
+};
+
+static const u32 vcn33_bt_wifi_voltages[] = {
+       3300000, 3400000, 3500000,
+};
+
+static const u32 vmc_voltages[] = {
+       1800000, 2900000, 3000000, 3300000,
+};
+
+static const u32 vldo28_voltages[] = {
+       2800000, 3000000,
+};
+
+static const u32 vdram2_idx[] = {
+       0, 12,
+};
+
+static const u32 vsim_idx[] = {
+       3, 4, 8, 11, 12,
+};
+
+static const u32 vibr_idx[] = {
+       0, 1, 2, 4, 5, 9, 11, 13,
+};
+
+static const u32 vusb_idx[] = {
+       3, 4,
+};
+
+static const u32 vcamd_idx[] = {
+       3, 4, 5, 6, 7, 9, 12,
+};
+
+static const u32 vefuse_idx[] = {
+       11, 12, 13,
+};
+
+static const u32 vmch_vemc_idx[] = {
+       2, 3, 5,
+};
+
+static const u32 vcama_idx[] = {
+       0, 7, 9, 10, 11, 12,
+};
+
+static const u32 vcn33_bt_wifi_idx[] = {
+       1, 2, 3,
+};
+
+static const u32 vmc_idx[] = {
+       4, 10, 11, 13,
+};
+
+static const u32 vldo28_idx[] = {
+       1, 3,
+};
+
+static unsigned int mt6358_map_mode(unsigned int mode)
+{
+       return mode == MT6358_BUCK_MODE_AUTO ?
+               REGULATOR_MODE_NORMAL : REGULATOR_MODE_FAST;
+}
+
+static int mt6358_set_voltage_sel(struct regulator_dev *rdev,
+                                 unsigned int selector)
+{
+       int idx, ret;
+       const u32 *pvol;
+       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+
+       pvol = info->index_table;
+
+       idx = pvol[selector];
+       ret = regmap_update_bits(rdev->regmap, info->desc.vsel_reg,
+                                info->desc.vsel_mask,
+                                idx << info->vsel_shift);
+
+       return ret;
+}
+
+static int mt6358_get_voltage_sel(struct regulator_dev *rdev)
+{
+       int idx, ret;
+       u32 selector;
+       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+       const u32 *pvol;
+
+       ret = regmap_read(rdev->regmap, info->desc.vsel_reg, &selector);
+       if (ret != 0) {
+               dev_info(&rdev->dev,
+                        "Failed to get mt6358 %s vsel reg: %d\n",
+                        info->desc.name, ret);
+               return ret;
+       }
+
+       selector = (selector & info->desc.vsel_mask) >> info->vsel_shift;
+       pvol = info->index_table;
+       for (idx = 0; idx < info->desc.n_voltages; idx++) {
+               if (pvol[idx] == selector)
+                       return idx;
+       }
+
+       return -EINVAL;
+}
+
+static int mt6358_get_buck_voltage_sel(struct regulator_dev *rdev)
+{
+       int ret, regval;
+       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+
+       ret = regmap_read(rdev->regmap, info->da_vsel_reg, &regval);
+       if (ret != 0) {
+               dev_err(&rdev->dev,
+                       "Failed to get mt6358 Buck %s vsel reg: %d\n",
+                       info->desc.name, ret);
+               return ret;
+       }
+
+       ret = (regval >> info->da_vsel_shift) & info->da_vsel_mask;
+
+       return ret;
+}
+
+static int mt6358_get_status(struct regulator_dev *rdev)
+{
+       int ret;
+       u32 regval;
+       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+
+       ret = regmap_read(rdev->regmap, info->status_reg, &regval);
+       if (ret != 0) {
+               dev_info(&rdev->dev, "Failed to get enable reg: %d\n", ret);
+               return ret;
+       }
+
+       return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF;
+}
+
+static int mt6358_regulator_set_mode(struct regulator_dev *rdev,
+                                    unsigned int mode)
+{
+       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+       int val;
+
+       switch (mode) {
+       case REGULATOR_MODE_FAST:
+               val = MT6358_BUCK_MODE_FORCE_PWM;
+               break;
+       case REGULATOR_MODE_NORMAL:
+               val = MT6358_BUCK_MODE_AUTO;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       dev_dbg(&rdev->dev, "mt6358 buck set_mode %#x, %#x, %#x, %#x\n",
+               info->modeset_reg, info->modeset_mask,
+               info->modeset_shift, val);
+
+       val <<= info->modeset_shift;
+
+       return regmap_update_bits(rdev->regmap, info->modeset_reg,
+                                 info->modeset_mask, val);
+}
+
+static unsigned int mt6358_regulator_get_mode(struct regulator_dev *rdev)
+{
+       struct mt6358_regulator_info *info = rdev_get_drvdata(rdev);
+       int ret, regval;
+
+       ret = regmap_read(rdev->regmap, info->modeset_reg, &regval);
+       if (ret != 0) {
+               dev_err(&rdev->dev,
+                       "Failed to get mt6358 buck mode: %d\n", ret);
+               return ret;
+       }
+
+       switch ((regval & info->modeset_mask) >> info->modeset_shift) {
+       case MT6358_BUCK_MODE_AUTO:
+               return REGULATOR_MODE_NORMAL;
+       case MT6358_BUCK_MODE_FORCE_PWM:
+               return REGULATOR_MODE_FAST;
+       default:
+               return -EINVAL;
+       }
+}
+
+static const struct regulator_ops mt6358_volt_range_ops = {
+       .list_voltage = regulator_list_voltage_linear_range,
+       .map_voltage = regulator_map_voltage_linear_range,
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+       .get_voltage_sel = mt6358_get_buck_voltage_sel,
+       .set_voltage_time_sel = regulator_set_voltage_time_sel,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .get_status = mt6358_get_status,
+       .set_mode = mt6358_regulator_set_mode,
+       .get_mode = mt6358_regulator_get_mode,
+};
+
+static const struct regulator_ops mt6358_volt_table_ops = {
+       .list_voltage = regulator_list_voltage_table,
+       .map_voltage = regulator_map_voltage_iterate,
+       .set_voltage_sel = mt6358_set_voltage_sel,
+       .get_voltage_sel = mt6358_get_voltage_sel,
+       .set_voltage_time_sel = regulator_set_voltage_time_sel,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .get_status = mt6358_get_status,
+};
+
+static const struct regulator_ops mt6358_volt_fixed_ops = {
+       .list_voltage = regulator_list_voltage_linear,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .get_status = mt6358_get_status,
+};
+
+/* The array is indexed by id(MT6358_ID_XXX) */
+static struct mt6358_regulator_info mt6358_regulators[] = {
+       MT6358_BUCK("buck_vdram1", VDRAM1, 500000, 2087500, 12500,
+                   buck_volt_range2, 0x7f, MT6358_BUCK_VDRAM1_DBG0, 0x7f,
+                   0, MT6358_VDRAM1_ANA_CON0, 8),
+       MT6358_BUCK("buck_vcore", VCORE, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VCORE_DBG0, 0x7f,
+                   0, MT6358_VCORE_VGPU_ANA_CON0, 1),
+       MT6358_BUCK("buck_vpa", VPA, 500000, 3650000, 50000,
+                   buck_volt_range3, 0x3f, MT6358_BUCK_VPA_DBG0, 0x3f, 0,
+                   MT6358_VPA_ANA_CON0, 3),
+       MT6358_BUCK("buck_vproc11", VPROC11, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VPROC11_DBG0, 0x7f,
+                   0, MT6358_VPROC_ANA_CON0, 1),
+       MT6358_BUCK("buck_vproc12", VPROC12, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VPROC12_DBG0, 0x7f,
+                   0, MT6358_VPROC_ANA_CON0, 2),
+       MT6358_BUCK("buck_vgpu", VGPU, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VGPU_ELR0, 0x7f, 0,
+                   MT6358_VCORE_VGPU_ANA_CON0, 2),
+       MT6358_BUCK("buck_vs2", VS2, 500000, 2087500, 12500,
+                   buck_volt_range2, 0x7f, MT6358_BUCK_VS2_DBG0, 0x7f, 0,
+                   MT6358_VS2_ANA_CON0, 8),
+       MT6358_BUCK("buck_vmodem", VMODEM, 500000, 1293750, 6250,
+                   buck_volt_range1, 0x7f, MT6358_BUCK_VMODEM_DBG0, 0x7f,
+                   0, MT6358_VMODEM_ANA_CON0, 8),
+       MT6358_BUCK("buck_vs1", VS1, 1000000, 2587500, 12500,
+                   buck_volt_range4, 0x7f, MT6358_BUCK_VS1_DBG0, 0x7f, 0,
+                   MT6358_VS1_ANA_CON0, 8),
+       MT6358_REG_FIXED("ldo_vrf12", VRF12,
+                        MT6358_LDO_VRF12_CON0, 0, 1200000),
+       MT6358_REG_FIXED("ldo_vio18", VIO18,
+                        MT6358_LDO_VIO18_CON0, 0, 1800000),
+       MT6358_REG_FIXED("ldo_vcamio", VCAMIO,
+                        MT6358_LDO_VCAMIO_CON0, 0, 1800000),
+       MT6358_REG_FIXED("ldo_vcn18", VCN18, MT6358_LDO_VCN18_CON0, 0, 1800000),
+       MT6358_REG_FIXED("ldo_vfe28", VFE28, MT6358_LDO_VFE28_CON0, 0, 2800000),
+       MT6358_REG_FIXED("ldo_vcn28", VCN28, MT6358_LDO_VCN28_CON0, 0, 2800000),
+       MT6358_REG_FIXED("ldo_vxo22", VXO22, MT6358_LDO_VXO22_CON0, 0, 2200000),
+       MT6358_REG_FIXED("ldo_vaux18", VAUX18,
+                        MT6358_LDO_VAUX18_CON0, 0, 1800000),
+       MT6358_REG_FIXED("ldo_vbif28", VBIF28,
+                        MT6358_LDO_VBIF28_CON0, 0, 2800000),
+       MT6358_REG_FIXED("ldo_vio28", VIO28, MT6358_LDO_VIO28_CON0, 0, 2800000),
+       MT6358_REG_FIXED("ldo_va12", VA12, MT6358_LDO_VA12_CON0, 0, 1200000),
+       MT6358_REG_FIXED("ldo_vrf18", VRF18, MT6358_LDO_VRF18_CON0, 0, 1800000),
+       MT6358_REG_FIXED("ldo_vaud28", VAUD28,
+                        MT6358_LDO_VAUD28_CON0, 0, 2800000),
+       MT6358_LDO("ldo_vdram2", VDRAM2, vdram2_voltages, vdram2_idx,
+                  MT6358_LDO_VDRAM2_CON0, 0, MT6358_LDO_VDRAM2_ELR0, 0x10, 0),
+       MT6358_LDO("ldo_vsim1", VSIM1, vsim_voltages, vsim_idx,
+                  MT6358_LDO_VSIM1_CON0, 0, MT6358_VSIM1_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vibr", VIBR, vibr_voltages, vibr_idx,
+                  MT6358_LDO_VIBR_CON0, 0, MT6358_VIBR_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vusb", VUSB, vusb_voltages, vusb_idx,
+                  MT6358_LDO_VUSB_CON0_0, 0, MT6358_VUSB_ANA_CON0, 0x700, 8),
+       MT6358_LDO("ldo_vcamd", VCAMD, vcamd_voltages, vcamd_idx,
+                  MT6358_LDO_VCAMD_CON0, 0, MT6358_VCAMD_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vefuse", VEFUSE, vefuse_voltages, vefuse_idx,
+                  MT6358_LDO_VEFUSE_CON0, 0, MT6358_VEFUSE_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vmch", VMCH, vmch_vemc_voltages, vmch_vemc_idx,
+                  MT6358_LDO_VMCH_CON0, 0, MT6358_VMCH_ANA_CON0, 0x700, 8),
+       MT6358_LDO("ldo_vcama1", VCAMA1, vcama_voltages, vcama_idx,
+                  MT6358_LDO_VCAMA1_CON0, 0, MT6358_VCAMA1_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vemc", VEMC, vmch_vemc_voltages, vmch_vemc_idx,
+                  MT6358_LDO_VEMC_CON0, 0, MT6358_VEMC_ANA_CON0, 0x700, 8),
+       MT6358_LDO("ldo_vcn33_bt", VCN33_BT, vcn33_bt_wifi_voltages,
+                  vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_0,
+                  0, MT6358_VCN33_ANA_CON0, 0x300, 8),
+       MT6358_LDO("ldo_vcn33_wifi", VCN33_WIFI, vcn33_bt_wifi_voltages,
+                  vcn33_bt_wifi_idx, MT6358_LDO_VCN33_CON0_1,
+                  0, MT6358_VCN33_ANA_CON0, 0x300, 8),
+       MT6358_LDO("ldo_vcama2", VCAMA2, vcama_voltages, vcama_idx,
+                  MT6358_LDO_VCAMA2_CON0, 0, MT6358_VCAMA2_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vmc", VMC, vmc_voltages, vmc_idx,
+                  MT6358_LDO_VMC_CON0, 0, MT6358_VMC_ANA_CON0, 0xf00, 8),
+       MT6358_LDO("ldo_vldo28", VLDO28, vldo28_voltages, vldo28_idx,
+                  MT6358_LDO_VLDO28_CON0_0, 0,
+                  MT6358_VLDO28_ANA_CON0, 0x300, 8),
+       MT6358_LDO("ldo_vsim2", VSIM2, vsim_voltages, vsim_idx,
+                  MT6358_LDO_VSIM2_CON0, 0, MT6358_VSIM2_ANA_CON0, 0xf00, 8),
+       MT6358_LDO1("ldo_vsram_proc11", VSRAM_PROC11, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_PROC11_DBG0, 0x7f, 8,
+                   MT6358_LDO_VSRAM_CON0, 0x7f),
+       MT6358_LDO1("ldo_vsram_others", VSRAM_OTHERS, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_OTHERS_DBG0, 0x7f, 8,
+                   MT6358_LDO_VSRAM_CON2, 0x7f),
+       MT6358_LDO1("ldo_vsram_gpu", VSRAM_GPU, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_GPU_DBG0, 0x7f, 8,
+                   MT6358_LDO_VSRAM_CON3, 0x7f),
+       MT6358_LDO1("ldo_vsram_proc12", VSRAM_PROC12, 500000, 1293750, 6250,
+                   buck_volt_range1, MT6358_LDO_VSRAM_PROC12_DBG0, 0x7f, 8,
+                   MT6358_LDO_VSRAM_CON1, 0x7f),
+};
+
+static int mt6358_regulator_probe(struct platform_device *pdev)
+{
+       struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent);
+       struct regulator_config config = {};
+       struct regulator_dev *rdev;
+       int i;
+
+       for (i = 0; i < MT6358_MAX_REGULATOR; i++) {
+               config.dev = &pdev->dev;
+               config.driver_data = &mt6358_regulators[i];
+               config.regmap = mt6397->regmap;
+
+               rdev = devm_regulator_register(&pdev->dev,
+                                              &mt6358_regulators[i].desc,
+                                              &config);
+               if (IS_ERR(rdev)) {
+                       dev_err(&pdev->dev, "failed to register %s\n",
+                               mt6358_regulators[i].desc.name);
+                       return PTR_ERR(rdev);
+               }
+       }
+
+       return 0;
+}
+
+static const struct platform_device_id mt6358_platform_ids[] = {
+       {"mt6358-regulator", 0},
+       { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(platform, mt6358_platform_ids);
+
+static struct platform_driver mt6358_regulator_driver = {
+       .driver = {
+               .name = "mt6358-regulator",
+       },
+       .probe = mt6358_regulator_probe,
+       .id_table = mt6358_platform_ids,
+};
+
+module_platform_driver(mt6358_regulator_driver);
+
+MODULE_AUTHOR("Hsin-Hsiung Wang <hsin-hsiung.wang@mediatek.com>");
+MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6358 PMIC");
+MODULE_LICENSE("GPL");
index b2c2d01..db6c085 100644 (file)
@@ -50,6 +50,20 @@ enum rpmh_regulator_type {
 #define PMIC4_BOB_MODE_AUTO                    2
 #define PMIC4_BOB_MODE_PWM                     3
 
+#define PMIC5_LDO_MODE_RETENTION               3
+#define PMIC5_LDO_MODE_LPM                     4
+#define PMIC5_LDO_MODE_HPM                     7
+
+#define PMIC5_SMPS_MODE_RETENTION              3
+#define PMIC5_SMPS_MODE_PFM                    4
+#define PMIC5_SMPS_MODE_AUTO                   6
+#define PMIC5_SMPS_MODE_PWM                    7
+
+#define PMIC5_BOB_MODE_PASS                    2
+#define PMIC5_BOB_MODE_PFM                     4
+#define PMIC5_BOB_MODE_AUTO                    6
+#define PMIC5_BOB_MODE_PWM                     7
+
 /**
  * struct rpmh_vreg_hw_data - RPMh regulator hardware configurations
  * @regulator_type:            RPMh accelerator type used to manage this
@@ -488,6 +502,14 @@ static const int pmic_mode_map_pmic4_ldo[REGULATOR_MODE_STANDBY + 1] = {
        [REGULATOR_MODE_FAST]    = -EINVAL,
 };
 
+static const int pmic_mode_map_pmic5_ldo[REGULATOR_MODE_STANDBY + 1] = {
+       [REGULATOR_MODE_INVALID] = -EINVAL,
+       [REGULATOR_MODE_STANDBY] = PMIC5_LDO_MODE_RETENTION,
+       [REGULATOR_MODE_IDLE]    = PMIC5_LDO_MODE_LPM,
+       [REGULATOR_MODE_NORMAL]  = PMIC5_LDO_MODE_HPM,
+       [REGULATOR_MODE_FAST]    = -EINVAL,
+};
+
 static unsigned int rpmh_regulator_pmic4_ldo_of_map_mode(unsigned int rpmh_mode)
 {
        unsigned int mode;
@@ -518,6 +540,14 @@ static const int pmic_mode_map_pmic4_smps[REGULATOR_MODE_STANDBY + 1] = {
        [REGULATOR_MODE_FAST]    = PMIC4_SMPS_MODE_PWM,
 };
 
+static const int pmic_mode_map_pmic5_smps[REGULATOR_MODE_STANDBY + 1] = {
+       [REGULATOR_MODE_INVALID] = -EINVAL,
+       [REGULATOR_MODE_STANDBY] = PMIC5_SMPS_MODE_RETENTION,
+       [REGULATOR_MODE_IDLE]    = PMIC5_SMPS_MODE_PFM,
+       [REGULATOR_MODE_NORMAL]  = PMIC5_SMPS_MODE_AUTO,
+       [REGULATOR_MODE_FAST]    = PMIC5_SMPS_MODE_PWM,
+};
+
 static unsigned int
 rpmh_regulator_pmic4_smps_of_map_mode(unsigned int rpmh_mode)
 {
@@ -552,6 +582,14 @@ static const int pmic_mode_map_pmic4_bob[REGULATOR_MODE_STANDBY + 1] = {
        [REGULATOR_MODE_FAST]    = PMIC4_BOB_MODE_PWM,
 };
 
+static const int pmic_mode_map_pmic5_bob[REGULATOR_MODE_STANDBY + 1] = {
+       [REGULATOR_MODE_INVALID] = -EINVAL,
+       [REGULATOR_MODE_STANDBY] = -EINVAL,
+       [REGULATOR_MODE_IDLE]    = PMIC5_BOB_MODE_PFM,
+       [REGULATOR_MODE_NORMAL]  = PMIC5_BOB_MODE_AUTO,
+       [REGULATOR_MODE_FAST]    = PMIC5_BOB_MODE_PWM,
+};
+
 static unsigned int rpmh_regulator_pmic4_bob_of_map_mode(unsigned int rpmh_mode)
 {
        unsigned int mode;
@@ -637,6 +675,72 @@ static const struct rpmh_vreg_hw_data pmic4_lvs = {
        /* LVS hardware does not support voltage or mode configuration. */
 };
 
+static const struct rpmh_vreg_hw_data pmic5_pldo = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_drms_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(1504000, 0, 255, 8000),
+       .n_voltages = 256,
+       .hpm_min_load_uA = 10000,
+       .pmic_mode_map = pmic_mode_map_pmic5_ldo,
+       .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic5_pldo_lv = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_drms_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(1504000, 0, 62, 8000),
+       .n_voltages = 63,
+       .hpm_min_load_uA = 10000,
+       .pmic_mode_map = pmic_mode_map_pmic5_ldo,
+       .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic5_nldo = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_drms_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 123, 8000),
+       .n_voltages = 124,
+       .hpm_min_load_uA = 30000,
+       .pmic_mode_map = pmic_mode_map_pmic5_ldo,
+       .of_map_mode = rpmh_regulator_pmic4_ldo_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic5_hfsmps510 = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(320000, 0, 215, 8000),
+       .n_voltages = 216,
+       .pmic_mode_map = pmic_mode_map_pmic5_smps,
+       .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic5_ftsmps510 = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(300000, 0, 263, 4000),
+       .n_voltages = 264,
+       .pmic_mode_map = pmic_mode_map_pmic5_smps,
+       .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic5_hfsmps515 = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(2800000, 0, 4, 1600),
+       .n_voltages = 5,
+       .pmic_mode_map = pmic_mode_map_pmic5_smps,
+       .of_map_mode = rpmh_regulator_pmic4_smps_of_map_mode,
+};
+
+static const struct rpmh_vreg_hw_data pmic5_bob = {
+       .regulator_type = VRM,
+       .ops = &rpmh_regulator_vrm_bypass_ops,
+       .voltage_range = REGULATOR_LINEAR_RANGE(300000, 0, 135, 32000),
+       .n_voltages = 136,
+       .pmic_mode_map = pmic_mode_map_pmic5_bob,
+       .of_map_mode = rpmh_regulator_pmic4_bob_of_map_mode,
+};
+
 #define RPMH_VREG(_name, _resource_name, _hw_data, _supply_name) \
 { \
        .name           = _name, \
@@ -705,6 +809,75 @@ static const struct rpmh_vreg_init_data pm8005_vreg_data[] = {
        {},
 };
 
+static const struct rpmh_vreg_init_data pm8150_vreg_data[] = {
+       RPMH_VREG("smps1",  "smp%s1",  &pmic5_ftsmps510, "vdd-s1"),
+       RPMH_VREG("smps2",  "smp%s2",  &pmic5_ftsmps510, "vdd-s2"),
+       RPMH_VREG("smps3",  "smp%s3",  &pmic5_ftsmps510, "vdd-s3"),
+       RPMH_VREG("smps4",  "smp%s4",  &pmic5_hfsmps510,   "vdd-s4"),
+       RPMH_VREG("smps5",  "smp%s5",  &pmic5_hfsmps510,   "vdd-s5"),
+       RPMH_VREG("smps6",  "smp%s6",  &pmic5_ftsmps510, "vdd-s6"),
+       RPMH_VREG("smps7",  "smp%s7",  &pmic5_ftsmps510, "vdd-s7"),
+       RPMH_VREG("smps8",  "smp%s8",  &pmic5_ftsmps510, "vdd-s8"),
+       RPMH_VREG("smps9",  "smp%s9",  &pmic5_ftsmps510, "vdd-s9"),
+       RPMH_VREG("smps10", "smp%s10", &pmic5_ftsmps510, "vdd-s10"),
+       RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_nldo,      "vdd-l1-l8-l11"),
+       RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_pldo,      "vdd-l2-l10"),
+       RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l3-l4-l5-l18"),
+       RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_nldo,      "vdd-l3-l4-l5-l18"),
+       RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_nldo,      "vdd-l3-l4-l5-l18"),
+       RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_nldo,      "vdd-l6-l9"),
+       RPMH_VREG("ldo7",   "ldo%s7",  &pmic5_pldo,      "vdd-l7-l12-l14-l15"),
+       RPMH_VREG("ldo8",   "ldo%s8",  &pmic5_nldo,      "vdd-l1-l8-l11"),
+       RPMH_VREG("ldo9",   "ldo%s9",  &pmic5_nldo,      "vdd-l6-l9"),
+       RPMH_VREG("ldo10",  "ldo%s10", &pmic5_pldo,      "vdd-l2-l10"),
+       RPMH_VREG("ldo11",  "ldo%s11", &pmic5_nldo,      "vdd-l1-l8-l11"),
+       RPMH_VREG("ldo12",  "ldo%s12", &pmic5_pldo_lv,   "vdd-l7-l12-l14-l15"),
+       RPMH_VREG("ldo13",  "ldo%s13", &pmic5_pldo,      "vdd-l13-l6-l17"),
+       RPMH_VREG("ldo14",  "ldo%s14", &pmic5_pldo_lv,   "vdd-l7-l12-l14-l15"),
+       RPMH_VREG("ldo15",  "ldo%s15", &pmic5_pldo_lv,   "vdd-l7-l12-l14-l15"),
+       RPMH_VREG("ldo16",  "ldo%s16", &pmic5_pldo,      "vdd-l13-l6-l17"),
+       RPMH_VREG("ldo17",  "ldo%s17", &pmic5_pldo,      "vdd-l13-l6-l17"),
+       RPMH_VREG("ldo18",  "ldo%s18", &pmic5_nldo,      "vdd-l3-l4-l5-l18"),
+       {},
+};
+
+static const struct rpmh_vreg_init_data pm8150l_vreg_data[] = {
+       RPMH_VREG("smps1",  "smp%s1",  &pmic5_ftsmps510, "vdd-s1"),
+       RPMH_VREG("smps2",  "smp%s2",  &pmic5_ftsmps510, "vdd-s2"),
+       RPMH_VREG("smps3",  "smp%s3",  &pmic5_ftsmps510, "vdd-s3"),
+       RPMH_VREG("smps4",  "smp%s4",  &pmic5_ftsmps510, "vdd-s4"),
+       RPMH_VREG("smps5",  "smp%s5",  &pmic5_ftsmps510, "vdd-s5"),
+       RPMH_VREG("smps6",  "smp%s6",  &pmic5_ftsmps510, "vdd-s6"),
+       RPMH_VREG("smps7",  "smp%s7",  &pmic5_ftsmps510, "vdd-s7"),
+       RPMH_VREG("smps8",  "smp%s8",  &pmic5_hfsmps510, "vdd-s8"),
+       RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_pldo_lv,   "vdd-l1-l8"),
+       RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_nldo,      "vdd-l2-l3"),
+       RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l2-l3"),
+       RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_pldo,      "vdd-l4-l5-l6"),
+       RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_pldo,      "vdd-l4-l5-l6"),
+       RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_pldo,      "vdd-l4-l5-l6"),
+       RPMH_VREG("ldo7",   "ldo%s7",  &pmic5_pldo,      "vdd-l7-l11"),
+       RPMH_VREG("ldo8",   "ldo%s8",  &pmic5_pldo_lv,   "vdd-l1-l8-l11"),
+       RPMH_VREG("ldo9",   "ldo%s9",  &pmic5_pldo,      "vdd-l9-l10"),
+       RPMH_VREG("ldo10",  "ldo%s10", &pmic5_pldo,      "vdd-l9-l10"),
+       RPMH_VREG("ldo11",  "ldo%s11", &pmic5_pldo,      "vdd-l7-l11"),
+       RPMH_VREG("bob",    "bob%s1",  &pmic5_bob,       "vdd-bob"),
+       {},
+};
+
+static const struct rpmh_vreg_init_data pm8009_vreg_data[] = {
+       RPMH_VREG("smps1",  "smp%s1",  &pmic5_hfsmps510, "vdd-s1"),
+       RPMH_VREG("smps2",  "smp%s2",  &pmic5_hfsmps515, "vdd-s2"),
+       RPMH_VREG("ldo1",   "ldo%s1",  &pmic5_nldo,      "vdd-l1"),
+       RPMH_VREG("ldo2",   "ldo%s2",  &pmic5_nldo,      "vdd-l2"),
+       RPMH_VREG("ldo3",   "ldo%s3",  &pmic5_nldo,      "vdd-l3"),
+       RPMH_VREG("ldo4",   "ldo%s4",  &pmic5_nldo,      "vdd-l4"),
+       RPMH_VREG("ldo5",   "ldo%s5",  &pmic5_pldo,      "vdd-l5-l6"),
+       RPMH_VREG("ldo6",   "ldo%s6",  &pmic5_pldo,      "vdd-l5-l6"),
+       RPMH_VREG("ldo7",   "ldo%s6",  &pmic5_pldo_lv,   "vdd-l7"),
+       {},
+};
+
 static int rpmh_regulator_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -744,6 +917,22 @@ static int rpmh_regulator_probe(struct platform_device *pdev)
 
 static const struct of_device_id rpmh_regulator_match_table[] = {
        {
+               .compatible = "qcom,pm8005-rpmh-regulators",
+               .data = pm8005_vreg_data,
+       },
+       {
+               .compatible = "qcom,pm8009-rpmh-regulators",
+               .data = pm8009_vreg_data,
+       },
+       {
+               .compatible = "qcom,pm8150-rpmh-regulators",
+               .data = pm8150_vreg_data,
+       },
+       {
+               .compatible = "qcom,pm8150l-rpmh-regulators",
+               .data = pm8150l_vreg_data,
+       },
+       {
                .compatible = "qcom,pm8998-rpmh-regulators",
                .data = pm8998_vreg_data,
        },
@@ -751,10 +940,6 @@ static const struct of_device_id rpmh_regulator_match_table[] = {
                .compatible = "qcom,pmi8998-rpmh-regulators",
                .data = pmi8998_vreg_data,
        },
-       {
-               .compatible = "qcom,pm8005-rpmh-regulators",
-               .data = pm8005_vreg_data,
-       },
        {}
 };
 MODULE_DEVICE_TABLE(of, rpmh_regulator_match_table);
index e7af0c5..61bd5ef 100644 (file)
@@ -606,7 +606,7 @@ static unsigned int rk8xx_regulator_of_map_mode(unsigned int mode)
        case 2:
                return REGULATOR_MODE_NORMAL;
        default:
-               return -EINVAL;
+               return REGULATOR_MODE_INVALID;
        }
 }
 
index 054baaa..5bc0088 100644 (file)
@@ -1226,7 +1226,7 @@ common_reg:
                        goto out;
                }
 
-               if (s2mps11->ext_control_gpiod[i]) {
+               if (config.ena_gpiod) {
                        ret = s2mps14_pmic_enable_ext_control(s2mps11,
                                        regulator);
                        if (ret < 0) {
index 04b7329..a0565da 100644 (file)
@@ -205,7 +205,7 @@ static int slg51000_of_parse_cb(struct device_node *np,
        ena_gpiod = devm_gpiod_get_from_of_node(chip->dev, np,
                                                "enable-gpios", 0,
                                                gflags, "gpio-en-ldo");
-       if (ena_gpiod) {
+       if (!IS_ERR(ena_gpiod)) {
                config->ena_gpiod = ena_gpiod;
                devm_gpiod_unhinge(chip->dev, config->ena_gpiod);
        }
@@ -447,18 +447,19 @@ static int slg51000_i2c_probe(struct i2c_client *client,
 {
        struct device *dev = &client->dev;
        struct slg51000 *chip;
-       struct gpio_desc *cs_gpiod = NULL;
+       struct gpio_desc *cs_gpiod;
        int error, ret;
 
        chip = devm_kzalloc(dev, sizeof(struct slg51000), GFP_KERNEL);
        if (!chip)
                return -ENOMEM;
 
-       cs_gpiod = devm_gpiod_get_from_of_node(dev, dev->of_node,
-                                              "dlg,cs-gpios", 0,
-                                              GPIOD_OUT_HIGH
-                                              | GPIOD_FLAGS_BIT_NONEXCLUSIVE,
-                                              "slg51000-cs");
+       cs_gpiod = devm_gpiod_get_optional(dev, "dlg,cs",
+                                          GPIOD_OUT_HIGH |
+                                               GPIOD_FLAGS_BIT_NONEXCLUSIVE);
+       if (IS_ERR(cs_gpiod))
+               return PTR_ERR(cs_gpiod);
+
        if (cs_gpiod) {
                dev_info(dev, "Found chip selector property\n");
                chip->cs_gpiod = cs_gpiod;
index 2a89766..03f162f 100644 (file)
@@ -20,7 +20,6 @@
 #define STM32MP1_SYSCFG_EN_BOOSTER_MASK        BIT(8)
 
 static const struct regulator_ops stm32h7_booster_ops = {
-       .list_voltage   = regulator_list_voltage_linear,
        .enable         = regulator_enable_regmap,
        .disable        = regulator_disable_regmap,
        .is_enabled     = regulator_is_enabled_regmap,
@@ -31,7 +30,6 @@ static const struct regulator_desc stm32h7_booster_desc = {
        .supply_name = "vdda",
        .n_voltages = 1,
        .type = REGULATOR_VOLTAGE,
-       .min_uV = 3300000,
        .fixed_uV = 3300000,
        .ramp_delay = 66000, /* up to 50us to stabilize */
        .ops = &stm32h7_booster_ops,
@@ -53,7 +51,6 @@ static int stm32mp1_booster_disable(struct regulator_dev *rdev)
 }
 
 static const struct regulator_ops stm32mp1_booster_ops = {
-       .list_voltage   = regulator_list_voltage_linear,
        .enable         = stm32mp1_booster_enable,
        .disable        = stm32mp1_booster_disable,
        .is_enabled     = regulator_is_enabled_regmap,
@@ -64,7 +61,6 @@ static const struct regulator_desc stm32mp1_booster_desc = {
        .supply_name = "vdda",
        .n_voltages = 1,
        .type = REGULATOR_VOLTAGE,
-       .min_uV = 3300000,
        .fixed_uV = 3300000,
        .ramp_delay = 66000,
        .ops = &stm32mp1_booster_ops,
diff --git a/drivers/regulator/sy8824x.c b/drivers/regulator/sy8824x.c
new file mode 100644 (file)
index 0000000..92adb4f
--- /dev/null
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// SY8824C/SY8824E regulator driver
+//
+// Copyright (C) 2019 Synaptics Incorporated
+//
+// Author: Jisheng Zhang <jszhang@kernel.org>
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/of_regulator.h>
+
+#define SY8824C_BUCK_EN                (1 << 7)
+#define SY8824C_MODE           (1 << 6)
+
+struct sy8824_config {
+       /* registers */
+       unsigned int vol_reg;
+       unsigned int mode_reg;
+       unsigned int enable_reg;
+       /* Voltage range and step(linear) */
+       unsigned int vsel_min;
+       unsigned int vsel_step;
+       unsigned int vsel_count;
+};
+
+struct sy8824_device_info {
+       struct device *dev;
+       struct regulator_desc desc;
+       struct regulator_init_data *regulator;
+       const struct sy8824_config *cfg;
+};
+
+static int sy8824_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+       struct sy8824_device_info *di = rdev_get_drvdata(rdev);
+       const struct sy8824_config *cfg = di->cfg;
+
+       switch (mode) {
+       case REGULATOR_MODE_FAST:
+               regmap_update_bits(rdev->regmap, cfg->mode_reg,
+                                  SY8824C_MODE, SY8824C_MODE);
+               break;
+       case REGULATOR_MODE_NORMAL:
+               regmap_update_bits(rdev->regmap, cfg->mode_reg,
+                                  SY8824C_MODE, 0);
+               break;
+       default:
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static unsigned int sy8824_get_mode(struct regulator_dev *rdev)
+{
+       struct sy8824_device_info *di = rdev_get_drvdata(rdev);
+       const struct sy8824_config *cfg = di->cfg;
+       u32 val;
+       int ret = 0;
+
+       ret = regmap_read(rdev->regmap, cfg->mode_reg, &val);
+       if (ret < 0)
+               return ret;
+       if (val & SY8824C_MODE)
+               return REGULATOR_MODE_FAST;
+       else
+               return REGULATOR_MODE_NORMAL;
+}
+
+static const struct regulator_ops sy8824_regulator_ops = {
+       .set_voltage_sel = regulator_set_voltage_sel_regmap,
+       .get_voltage_sel = regulator_get_voltage_sel_regmap,
+       .set_voltage_time_sel = regulator_set_voltage_time_sel,
+       .map_voltage = regulator_map_voltage_linear,
+       .list_voltage = regulator_list_voltage_linear,
+       .enable = regulator_enable_regmap,
+       .disable = regulator_disable_regmap,
+       .is_enabled = regulator_is_enabled_regmap,
+       .set_mode = sy8824_set_mode,
+       .get_mode = sy8824_get_mode,
+};
+
+static int sy8824_regulator_register(struct sy8824_device_info *di,
+                       struct regulator_config *config)
+{
+       struct regulator_desc *rdesc = &di->desc;
+       const struct sy8824_config *cfg = di->cfg;
+       struct regulator_dev *rdev;
+
+       rdesc->name = "sy8824-reg";
+       rdesc->supply_name = "vin";
+       rdesc->ops = &sy8824_regulator_ops;
+       rdesc->type = REGULATOR_VOLTAGE;
+       rdesc->n_voltages = cfg->vsel_count;
+       rdesc->enable_reg = cfg->enable_reg;
+       rdesc->enable_mask = SY8824C_BUCK_EN;
+       rdesc->min_uV = cfg->vsel_min;
+       rdesc->uV_step = cfg->vsel_step;
+       rdesc->vsel_reg = cfg->vol_reg;
+       rdesc->vsel_mask = cfg->vsel_count - 1;
+       rdesc->owner = THIS_MODULE;
+
+       rdev = devm_regulator_register(di->dev, &di->desc, config);
+       return PTR_ERR_OR_ZERO(rdev);
+}
+
+static const struct regmap_config sy8824_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+};
+
+static int sy8824_i2c_probe(struct i2c_client *client,
+                           const struct i2c_device_id *id)
+{
+       struct device *dev = &client->dev;
+       struct device_node *np = dev->of_node;
+       struct sy8824_device_info *di;
+       struct regulator_config config = { };
+       struct regmap *regmap;
+       int ret;
+
+       di = devm_kzalloc(dev, sizeof(struct sy8824_device_info), GFP_KERNEL);
+       if (!di)
+               return -ENOMEM;
+
+       di->regulator = of_get_regulator_init_data(dev, np, &di->desc);
+       if (!di->regulator) {
+               dev_err(dev, "Platform data not found!\n");
+               return -EINVAL;
+       }
+
+       di->dev = dev;
+       di->cfg = of_device_get_match_data(dev);
+
+       regmap = devm_regmap_init_i2c(client, &sy8824_regmap_config);
+       if (IS_ERR(regmap)) {
+               dev_err(dev, "Failed to allocate regmap!\n");
+               return PTR_ERR(regmap);
+       }
+       i2c_set_clientdata(client, di);
+
+       config.dev = di->dev;
+       config.init_data = di->regulator;
+       config.regmap = regmap;
+       config.driver_data = di;
+       config.of_node = np;
+
+       ret = sy8824_regulator_register(di, &config);
+       if (ret < 0)
+               dev_err(dev, "Failed to register regulator!\n");
+       return ret;
+}
+
+static const struct sy8824_config sy8824c_cfg = {
+       .vol_reg = 0x00,
+       .mode_reg = 0x00,
+       .enable_reg = 0x00,
+       .vsel_min = 762500,
+       .vsel_step = 12500,
+       .vsel_count = 64,
+};
+
+static const struct sy8824_config sy8824e_cfg = {
+       .vol_reg = 0x00,
+       .mode_reg = 0x00,
+       .enable_reg = 0x00,
+       .vsel_min = 700000,
+       .vsel_step = 12500,
+       .vsel_count = 64,
+};
+
+static const struct sy8824_config sy20276_cfg = {
+       .vol_reg = 0x00,
+       .mode_reg = 0x01,
+       .enable_reg = 0x01,
+       .vsel_min = 600000,
+       .vsel_step = 10000,
+       .vsel_count = 128,
+};
+
+static const struct sy8824_config sy20278_cfg = {
+       .vol_reg = 0x00,
+       .mode_reg = 0x01,
+       .enable_reg = 0x01,
+       .vsel_min = 762500,
+       .vsel_step = 12500,
+       .vsel_count = 64,
+};
+
+static const struct of_device_id sy8824_dt_ids[] = {
+       {
+               .compatible = "silergy,sy8824c",
+               .data = &sy8824c_cfg
+       },
+       {
+               .compatible = "silergy,sy8824e",
+               .data = &sy8824e_cfg
+       },
+       {
+               .compatible = "silergy,sy20276",
+               .data = &sy20276_cfg
+       },
+       {
+               .compatible = "silergy,sy20278",
+               .data = &sy20278_cfg
+       },
+       { }
+};
+MODULE_DEVICE_TABLE(of, sy8824_dt_ids);
+
+static const struct i2c_device_id sy8824_id[] = {
+       { "sy8824", },
+       { },
+};
+MODULE_DEVICE_TABLE(i2c, sy8824_id);
+
+static struct i2c_driver sy8824_regulator_driver = {
+       .driver = {
+               .name = "sy8824-regulator",
+               .of_match_table = of_match_ptr(sy8824_dt_ids),
+       },
+       .probe = sy8824_i2c_probe,
+       .id_table = sy8824_id,
+};
+module_i2c_driver(sy8824_regulator_driver);
+
+MODULE_AUTHOR("Jisheng Zhang <jszhang@kernel.org>");
+MODULE_DESCRIPTION("SY8824C/SY8824E regulator driver");
+MODULE_LICENSE("GPL v2");
index 6e22f5e..e302bd0 100644 (file)
@@ -138,7 +138,7 @@ static int tps65132_of_parse_cb(struct device_node *np,
 
        rpdata->en_gpiod = devm_fwnode_get_index_gpiod_from_child(tps->dev,
                                        "enable", 0, &np->fwnode, 0, "enable");
-       if (IS_ERR(rpdata->en_gpiod)) {
+       if (IS_ERR_OR_NULL(rpdata->en_gpiod)) {
                ret = PTR_ERR(rpdata->en_gpiod);
 
                /* Ignore the error other than probe defer */
@@ -150,7 +150,7 @@ static int tps65132_of_parse_cb(struct device_node *np,
        rpdata->act_dis_gpiod = devm_fwnode_get_index_gpiod_from_child(
                                        tps->dev, "active-discharge", 0,
                                        &np->fwnode, 0, "active-discharge");
-       if (IS_ERR(rpdata->act_dis_gpiod)) {
+       if (IS_ERR_OR_NULL(rpdata->act_dis_gpiod)) {
                ret = PTR_ERR(rpdata->act_dis_gpiod);
 
                /* Ignore the error other than probe defer */
index 6fa15b2..866b4dd 100644 (file)
@@ -359,6 +359,17 @@ static const u16 VINTANA2_VSEL_table[] = {
        2500, 2750,
 };
 
+/* 600mV to 1450mV in 12.5 mV steps */
+static const struct regulator_linear_range VDD1_ranges[] = {
+       REGULATOR_LINEAR_RANGE(600000, 0, 68, 12500)
+};
+
+/* 600mV to 1450mV in 12.5 mV steps, everything above = 1500mV */
+static const struct regulator_linear_range VDD2_ranges[] = {
+       REGULATOR_LINEAR_RANGE(600000, 0, 68, 12500),
+       REGULATOR_LINEAR_RANGE(1500000, 69, 69, 12500)
+};
+
 static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
 {
        struct twlreg_info      *info = rdev_get_drvdata(rdev);
@@ -427,6 +438,8 @@ static int twl4030smps_get_voltage(struct regulator_dev *rdev)
 }
 
 static const struct regulator_ops twl4030smps_ops = {
+       .list_voltage   = regulator_list_voltage_linear_range,
+
        .set_voltage    = twl4030smps_set_voltage,
        .get_voltage    = twl4030smps_get_voltage,
 };
@@ -466,7 +479,8 @@ static const struct twlreg_info TWL4030_INFO_##label = { \
                }, \
        }
 
-#define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf) \
+#define TWL4030_ADJUSTABLE_SMPS(label, offset, num, turnon_delay, remap_conf, \
+               n_volt) \
 static const struct twlreg_info TWL4030_INFO_##label = { \
        .base = offset, \
        .id = num, \
@@ -479,6 +493,9 @@ static const struct twlreg_info TWL4030_INFO_##label = { \
                .owner = THIS_MODULE, \
                .enable_time = turnon_delay, \
                .of_map_mode = twl4030reg_map_mode, \
+               .n_voltages = n_volt, \
+               .n_linear_ranges = ARRAY_SIZE(label ## _ranges), \
+               .linear_ranges = label ## _ranges, \
                }, \
        }
 
@@ -518,8 +535,8 @@ TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9, 100, 0x00);
 TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10, 100, 0x08);
 TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12, 100, 0x08);
 TWL4030_ADJUSTABLE_LDO(VIO, 0x4b, 14, 1000, 0x08);
-TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08);
-TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08);
+TWL4030_ADJUSTABLE_SMPS(VDD1, 0x55, 15, 1000, 0x08, 68);
+TWL4030_ADJUSTABLE_SMPS(VDD2, 0x63, 16, 1000, 0x08, 69);
 /* VUSBCP is managed *only* by the USB subchip */
 TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08);
 TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08);
index 5fe208b..b8100c3 100644 (file)
@@ -57,6 +57,9 @@ struct twlreg_info {
 #define VREG_BC_PROC           3
 #define VREG_BC_CLK_RST                4
 
+/* TWL6030 LDO register values for VREG_VOLTAGE */
+#define TWL6030_VREG_VOLTAGE_WR_S   BIT(7)
+
 /* TWL6030 LDO register values for CFG_STATE */
 #define TWL6030_CFG_STATE_OFF  0x00
 #define TWL6030_CFG_STATE_ON   0x01
@@ -68,9 +71,10 @@ struct twlreg_info {
 #define TWL6030_CFG_STATE_APP(v)       (((v) & TWL6030_CFG_STATE_APP_MASK) >>\
                                                TWL6030_CFG_STATE_APP_SHIFT)
 
-/* Flags for SMPS Voltage reading */
+/* Flags for SMPS Voltage reading and LDO reading*/
 #define SMPS_OFFSET_EN         BIT(0)
 #define SMPS_EXTENDED_EN       BIT(1)
+#define TWL_6030_WARM_RESET    BIT(3)
 
 /* twl6032 SMPS EPROM values */
 #define TWL6030_SMPS_OFFSET            0xB0
@@ -250,6 +254,9 @@ twl6030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector)
 {
        struct twlreg_info      *info = rdev_get_drvdata(rdev);
 
+       if (info->flags & TWL_6030_WARM_RESET)
+               selector |= TWL6030_VREG_VOLTAGE_WR_S;
+
        return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE,
                            selector);
 }
@@ -259,6 +266,9 @@ static int twl6030ldo_get_voltage_sel(struct regulator_dev *rdev)
        struct twlreg_info      *info = rdev_get_drvdata(rdev);
        int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE);
 
+       if (info->flags & TWL_6030_WARM_RESET)
+               vsel &= ~TWL6030_VREG_VOLTAGE_WR_S;
+
        return vsel;
 }
 
@@ -665,14 +675,14 @@ static int twlreg_probe(struct platform_device *pdev)
        struct regulation_constraints   *c;
        struct regulator_dev            *rdev;
        struct regulator_config         config = { };
+       struct device_node              *np = pdev->dev.of_node;
 
        template = of_device_get_match_data(&pdev->dev);
        if (!template)
                return -ENODEV;
 
        id = template->desc.id;
-       initdata = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
-                                               &template->desc);
+       initdata = of_get_regulator_init_data(&pdev->dev, np, &template->desc);
        if (!initdata)
                return -EINVAL;
 
@@ -710,10 +720,13 @@ static int twlreg_probe(struct platform_device *pdev)
                break;
        }
 
+       if (of_get_property(np, "ti,retain-on-reset", NULL))
+               info->flags |= TWL_6030_WARM_RESET;
+
        config.dev = &pdev->dev;
        config.init_data = initdata;
        config.driver_data = info;
-       config.of_node = pdev->dev.of_node;
+       config.of_node = np;
 
        rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
        if (IS_ERR(rdev)) {
index 9026d5a..2311924 100644 (file)
@@ -186,6 +186,10 @@ static const struct of_device_id uniphier_regulator_match[] = {
                .data = &uniphier_pro4_usb3_data,
        },
        {
+               .compatible = "socionext,uniphier-pro5-usb3-regulator",
+               .data = &uniphier_pro4_usb3_data,
+       },
+       {
                .compatible = "socionext,uniphier-pxs2-usb3-regulator",
                .data = &uniphier_pxs2_usb3_data,
        },
index 21efb7d..7b07281 100644 (file)
@@ -116,9 +116,20 @@ config RESET_QCOM_PDC
          to control reset signals provided by PDC for Modem, Compute,
          Display, GPU, Debug, AOP, Sensors, Audio, SP and APPS.
 
+config RESET_SCMI
+       tristate "Reset driver controlled via ARM SCMI interface"
+       depends on ARM_SCMI_PROTOCOL || COMPILE_TEST
+       default ARM_SCMI_PROTOCOL
+       help
+         This driver provides support for reset signal/domains that are
+         controlled by firmware that implements the SCMI interface.
+
+         This driver uses SCMI Message Protocol to interact with the
+         firmware controlling all the reset signals.
+
 config RESET_SIMPLE
        bool "Simple Reset Controller Driver" if COMPILE_TEST
-       default ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARCH_ASPEED || ARCH_BITMAIN
+       default ARCH_STM32 || ARCH_STRATIX10 || ARCH_SUNXI || ARCH_ZX || ARCH_ASPEED || ARCH_BITMAIN || ARC
        help
          This enables a simple reset controller driver for reset lines that
          that can be asserted and deasserted by toggling bits in a contiguous,
index 61456b8..cf60ce5 100644 (file)
@@ -18,6 +18,7 @@ obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
 obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
 obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
 obj-$(CONFIG_RESET_QCOM_PDC) += reset-qcom-pdc.o
+obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
 obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
 obj-$(CONFIG_RESET_STM32MP157) += reset-stm32mp1.o
 obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
index 3ecd770..1443a55 100644 (file)
@@ -169,9 +169,9 @@ static const struct imx7_src_signal imx8mq_src_signals[IMX8MQ_RESET_NUM] = {
        [IMX8MQ_RESET_OTG2_PHY_RESET]           = { SRC_USBOPHY2_RCR, BIT(0) },
        [IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N]    = { SRC_MIPIPHY_RCR, BIT(1) },
        [IMX8MQ_RESET_MIPI_DSI_RESET_N]         = { SRC_MIPIPHY_RCR, BIT(2) },
-       [IMX8MQ_RESET_MIPI_DIS_DPI_RESET_N]     = { SRC_MIPIPHY_RCR, BIT(3) },
-       [IMX8MQ_RESET_MIPI_DIS_ESC_RESET_N]     = { SRC_MIPIPHY_RCR, BIT(4) },
-       [IMX8MQ_RESET_MIPI_DIS_PCLK_RESET_N]    = { SRC_MIPIPHY_RCR, BIT(5) },
+       [IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N]     = { SRC_MIPIPHY_RCR, BIT(3) },
+       [IMX8MQ_RESET_MIPI_DSI_ESC_RESET_N]     = { SRC_MIPIPHY_RCR, BIT(4) },
+       [IMX8MQ_RESET_MIPI_DSI_PCLK_RESET_N]    = { SRC_MIPIPHY_RCR, BIT(5) },
        [IMX8MQ_RESET_PCIEPHY]                  = { SRC_PCIEPHY_RCR,
                                                    BIT(2) | BIT(1) },
        [IMX8MQ_RESET_PCIEPHY_PERST]            = { SRC_PCIEPHY_RCR, BIT(3) },
@@ -220,9 +220,9 @@ static int imx8mq_reset_set(struct reset_controller_dev *rcdev,
 
        case IMX8MQ_RESET_PCIE_CTRL_APPS_EN:
        case IMX8MQ_RESET_PCIE2_CTRL_APPS_EN:   /* fallthrough */
-       case IMX8MQ_RESET_MIPI_DIS_PCLK_RESET_N:        /* fallthrough */
-       case IMX8MQ_RESET_MIPI_DIS_ESC_RESET_N: /* fallthrough */
-       case IMX8MQ_RESET_MIPI_DIS_DPI_RESET_N: /* fallthrough */
+       case IMX8MQ_RESET_MIPI_DSI_PCLK_RESET_N:        /* fallthrough */
+       case IMX8MQ_RESET_MIPI_DSI_ESC_RESET_N: /* fallthrough */
+       case IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N: /* fallthrough */
        case IMX8MQ_RESET_MIPI_DSI_RESET_N:     /* fallthrough */
        case IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N:        /* fallthrough */
                value = assert ? 0 : bit;
index 5242e06..7d05d76 100644 (file)
@@ -1,58 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
  * Amlogic Meson Reset Controller driver
  *
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
- * Copyright (c) 2016 BayLibre, SAS.
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- * The full GNU General Public License is included in this distribution
- * in the file called COPYING.
- *
- * BSD LICENSE
- *
  * Copyright (c) 2016 BayLibre, SAS.
  * Author: Neil Armstrong <narmstrong@baylibre.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 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.
  */
 #include <linux/err.h>
 #include <linux/init.h>
diff --git a/drivers/reset/reset-scmi.c b/drivers/reset/reset-scmi.c
new file mode 100644 (file)
index 0000000..c6d3c84
--- /dev/null
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * ARM System Control and Management Interface (ARM SCMI) reset driver
+ *
+ * Copyright (C) 2019 ARM Ltd.
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/device.h>
+#include <linux/reset-controller.h>
+#include <linux/scmi_protocol.h>
+
+/**
+ * struct scmi_reset_data - reset controller information structure
+ * @rcdev: reset controller entity
+ * @handle: ARM SCMI handle used for communication with system controller
+ */
+struct scmi_reset_data {
+       struct reset_controller_dev rcdev;
+       const struct scmi_handle *handle;
+};
+
+#define to_scmi_reset_data(p)  container_of((p), struct scmi_reset_data, rcdev)
+#define to_scmi_handle(p)      (to_scmi_reset_data(p)->handle)
+
+/**
+ * scmi_reset_assert() - assert device reset
+ * @rcdev: reset controller entity
+ * @id: ID of the reset to be asserted
+ *
+ * This function implements the reset driver op to assert a device's reset
+ * using the ARM SCMI protocol.
+ *
+ * Return: 0 for successful request, else a corresponding error value
+ */
+static int
+scmi_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       const struct scmi_handle *handle = to_scmi_handle(rcdev);
+
+       return handle->reset_ops->assert(handle, id);
+}
+
+/**
+ * scmi_reset_deassert() - deassert device reset
+ * @rcdev: reset controller entity
+ * @id: ID of the reset to be deasserted
+ *
+ * This function implements the reset driver op to deassert a device's reset
+ * using the ARM SCMI protocol.
+ *
+ * Return: 0 for successful request, else a corresponding error value
+ */
+static int
+scmi_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       const struct scmi_handle *handle = to_scmi_handle(rcdev);
+
+       return handle->reset_ops->deassert(handle, id);
+}
+
+/**
+ * scmi_reset_reset() - reset the device
+ * @rcdev: reset controller entity
+ * @id: ID of the reset signal to be reset(assert + deassert)
+ *
+ * This function implements the reset driver op to trigger a device's
+ * reset signal using the ARM SCMI protocol.
+ *
+ * Return: 0 for successful request, else a corresponding error value
+ */
+static int
+scmi_reset_reset(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       const struct scmi_handle *handle = to_scmi_handle(rcdev);
+
+       return handle->reset_ops->reset(handle, id);
+}
+
+static const struct reset_control_ops scmi_reset_ops = {
+       .assert         = scmi_reset_assert,
+       .deassert       = scmi_reset_deassert,
+       .reset          = scmi_reset_reset,
+};
+
+static int scmi_reset_probe(struct scmi_device *sdev)
+{
+       struct scmi_reset_data *data;
+       struct device *dev = &sdev->dev;
+       struct device_node *np = dev->of_node;
+       const struct scmi_handle *handle = sdev->handle;
+
+       if (!handle || !handle->reset_ops)
+               return -ENODEV;
+
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       data->rcdev.ops = &scmi_reset_ops;
+       data->rcdev.owner = THIS_MODULE;
+       data->rcdev.of_node = np;
+       data->rcdev.nr_resets = handle->reset_ops->num_domains_get(handle);
+
+       return devm_reset_controller_register(dev, &data->rcdev);
+}
+
+static const struct scmi_device_id scmi_id_table[] = {
+       { SCMI_PROTOCOL_RESET },
+       { },
+};
+MODULE_DEVICE_TABLE(scmi, scmi_id_table);
+
+static struct scmi_driver scmi_reset_driver = {
+       .name = "scmi-reset",
+       .probe = scmi_reset_probe,
+       .id_table = scmi_id_table,
+};
+module_scmi_driver(scmi_reset_driver);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_DESCRIPTION("ARM SCMI reset controller driver");
+MODULE_LICENSE("GPL v2");
index 1154f7b..067e7e7 100644 (file)
@@ -127,6 +127,9 @@ static const struct of_device_id reset_simple_dt_ids[] = {
        { .compatible = "aspeed,ast2500-lpc-reset" },
        { .compatible = "bitmain,bm1880-reset",
                .data = &reset_simple_active_low },
+       { .compatible = "snps,dw-high-reset" },
+       { .compatible = "snps,dw-low-reset",
+               .data = &reset_simple_active_low },
        { /* sentinel */ },
 };
 
index 9c3310c..6502b14 100644 (file)
@@ -4374,6 +4374,10 @@ static int qeth_snmp_command(struct qeth_card *card, char __user *udata)
            get_user(req_len, &ureq->hdr.req_len))
                return -EFAULT;
 
+       /* Sanitize user input, to avoid overflows in iob size calculation: */
+       if (req_len > QETH_BUFSIZE)
+               return -EINVAL;
+
        iob = qeth_get_adapter_cmd(card, IPA_SETADP_SET_SNMP_CONTROL, req_len);
        if (!iob)
                return -ENOMEM;
index 8d8c495..d655586 100644 (file)
@@ -5715,7 +5715,7 @@ LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2,
  *      0    = Set nr_hw_queues by the number of CPUs or HW queues.
  *      1,128 = Manually specify the maximum nr_hw_queue value to be set,
  *
- * Value range is [0,128]. Default value is 8.
+ * Value range is [0,256]. Default value is 8.
  */
 LPFC_ATTR_R(fcp_mq_threshold, LPFC_FCP_MQ_THRESHOLD_DEF,
            LPFC_FCP_MQ_THRESHOLD_MIN, LPFC_FCP_MQ_THRESHOLD_MAX,
index 329f7aa..a81ef02 100644 (file)
@@ -46,7 +46,7 @@
 
 /* FCP MQ queue count limiting */
 #define LPFC_FCP_MQ_THRESHOLD_MIN      0
-#define LPFC_FCP_MQ_THRESHOLD_MAX      128
+#define LPFC_FCP_MQ_THRESHOLD_MAX      256
 #define LPFC_FCP_MQ_THRESHOLD_DEF      8
 
 /* Common buffer size to accomidate SCSI and NVME IO buffers */
index e5760c4..832af42 100644 (file)
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_tcq.h>
 
-#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
-#include <asm/sn/io.h>
-#endif
-
 
 /*
  * Compile time Options:
 
 #define NVRAM_DELAY()                  udelay(500)     /* 2 microseconds */
 
-#if defined(__ia64__) && !defined(ia64_platform_is)
-#define ia64_platform_is(foo)          (!strcmp(x, platform_name))
-#endif
-
-
 #define IS_ISP1040(ha) (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1020)
 #define IS_ISP1x40(ha) (ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1020 || \
                        ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP1240)
@@ -1427,15 +1418,6 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha)
        ha->flags.reset_active = 0;
        ha->flags.abort_isp_active = 0;
 
-#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
-       if (ia64_platform_is("sn2")) {
-               printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA "
-                      "dual channel lockup workaround\n", ha->host_no);
-               ha->flags.use_pci_vchannel = 1;
-               driver_setup.no_nvram = 1;
-       }
-#endif
-
        /* TODO: implement support for the 1040 nvram format */
        if (IS_ISP1040(ha))
                driver_setup.no_nvram = 1;
@@ -2251,13 +2233,6 @@ qla1280_nvram_config(struct scsi_qla_host *ha)
        mb[1] = nv->firmware_feature.f.enable_fast_posting;
        mb[1] |= nv->firmware_feature.f.report_lvd_bus_transition << 1;
        mb[1] |= nv->firmware_feature.f.disable_synchronous_backoff << 5;
-#if defined(CONFIG_IA64_GENERIC) || defined (CONFIG_IA64_SGI_SN2)
-       if (ia64_platform_is("sn2")) {
-               printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA "
-                      "workaround\n", ha->host_no);
-               mb[1] |= nv->firmware_feature.f.unused_9 << 9; /* XXX */
-       }
-#endif
        status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb);
 
        /* Retry count and delay. */
@@ -2888,12 +2863,6 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
                                break;
 
                        dma_handle = sg_dma_address(s);
-#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
-                       if (ha->flags.use_pci_vchannel)
-                               sn_pci_set_vchan(ha->pdev,
-                                                (unsigned long *)&dma_handle,
-                                                SCSI_BUS_32(cmd));
-#endif
                        *dword_ptr++ =
                                cpu_to_le32(lower_32_bits(dma_handle));
                        *dword_ptr++ =
@@ -2950,12 +2919,6 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
                                if (cnt == 5)
                                        break;
                                dma_handle = sg_dma_address(s);
-#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
-                               if (ha->flags.use_pci_vchannel)
-                                       sn_pci_set_vchan(ha->pdev,
-                                                        (unsigned long *)&dma_handle,
-                                                        SCSI_BUS_32(cmd));
-#endif
                                *dword_ptr++ =
                                        cpu_to_le32(lower_32_bits(dma_handle));
                                *dword_ptr++ =
index b496206..a1a8aef 100644 (file)
@@ -1055,9 +1055,6 @@ struct scsi_qla_host {
                uint32_t reset_active:1;                /* 3 */
                uint32_t abort_isp_active:1;            /* 4 */
                uint32_t disable_risc_code_load:1;      /* 5 */
-#ifdef __ia64__
-               uint32_t use_pci_vchannel:1;
-#endif
        } flags;
 
        struct nvram nvram;
index da83034..d4c3bae 100644 (file)
@@ -4575,20 +4575,6 @@ qla2x00_nvram_config(scsi_qla_host_t *vha)
                rval = 1;
        }
 
-#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
-       /*
-        * The SN2 does not provide BIOS emulation which means you can't change
-        * potentially bogus BIOS settings. Force the use of default settings
-        * for link rate and frame size.  Hope that the rest of the settings
-        * are valid.
-        */
-       if (ia64_platform_is("sn2")) {
-               nv->frame_payload_size = 2048;
-               if (IS_QLA23XX(ha))
-                       nv->special_options[1] = BIT_7;
-       }
-#endif
-
        /* Reset Initialization control block */
        memset(icb, 0, ha->init_cb_size);
 
diff --git a/drivers/sn/Kconfig b/drivers/sn/Kconfig
deleted file mode 100644 (file)
index a6c443d..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Miscellaneous SN-specific devices
-#
-
-menu "SN Devices"
-       depends on SGI_SN
-
-config SGI_IOC3
-       tristate "SGI IOC3 Base IO support"
-       default m
-       ---help---
-       This option enables basic support for the SGI IOC3-based Base IO
-       controller card.  This option does not enable any specific
-       functions on such a card, but provides necessary infrastructure
-       for other drivers to utilize.
-
-       If you have an SGI Altix with an IOC3-based
-       I/O controller or a PCI IOC3 serial card say Y.
-       Otherwise say N.
-
-endmenu
diff --git a/drivers/sn/Makefile b/drivers/sn/Makefile
deleted file mode 100644 (file)
index f0e809a..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Makefile for the Altix device drivers.
-#
-#
-
-obj-$(CONFIG_SGI_IOC3) += ioc3.o
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c
deleted file mode 100644 (file)
index 358025a..0000000
+++ /dev/null
@@ -1,844 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * SGI IOC3 master driver and IRQ demuxer
- *
- * Copyright (c) 2005 Stanislaw Skowronek <skylark@linux-mips.org>
- * Heavily based on similar work by:
- *   Brent Casavant <bcasavan@sgi.com> - IOC4 master driver
- *   Pat Gefre <pfg@sgi.com> - IOC3 serial port IRQ demuxer
- */
-
-#include <linux/errno.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <linux/ioc3.h>
-#include <linux/rwsem.h>
-#include <linux/slab.h>
-
-#define IOC3_PCI_SIZE 0x100000
-
-static LIST_HEAD(ioc3_devices);
-static int ioc3_counter;
-static DECLARE_RWSEM(ioc3_devices_rwsem);
-
-static struct ioc3_submodule *ioc3_submodules[IOC3_MAX_SUBMODULES];
-static struct ioc3_submodule *ioc3_ethernet;
-static DEFINE_RWLOCK(ioc3_submodules_lock);
-
-/* NIC probing code */
-
-#define GPCR_MLAN_EN    0x00200000      /* enable MCR to pin 8 */
-
-static inline unsigned mcr_pack(unsigned pulse, unsigned sample)
-{
-       return (pulse << 10) | (sample << 2);
-}
-
-static int nic_wait(struct ioc3_driver_data *idd)
-{
-       unsigned mcr;
-
-        do {
-                mcr = readl(&idd->vma->mcr);
-        } while (!(mcr & 2));
-
-        return mcr & 1;
-}
-
-static int nic_reset(struct ioc3_driver_data *idd)
-{
-        int presence;
-       unsigned long flags;
-
-       local_irq_save(flags);
-       writel(mcr_pack(500, 65), &idd->vma->mcr);
-       presence = nic_wait(idd);
-       local_irq_restore(flags);
-
-       udelay(500);
-
-        return presence;
-}
-
-static int nic_read_bit(struct ioc3_driver_data *idd)
-{
-       int result;
-       unsigned long flags;
-
-       local_irq_save(flags);
-       writel(mcr_pack(6, 13), &idd->vma->mcr);
-       result = nic_wait(idd);
-       local_irq_restore(flags);
-
-       udelay(500);
-
-       return result;
-}
-
-static void nic_write_bit(struct ioc3_driver_data *idd, int bit)
-{
-       if (bit)
-               writel(mcr_pack(6, 110), &idd->vma->mcr);
-       else
-               writel(mcr_pack(80, 30), &idd->vma->mcr);
-
-       nic_wait(idd);
-}
-
-static unsigned nic_read_byte(struct ioc3_driver_data *idd)
-{
-       unsigned result = 0;
-       int i;
-
-       for (i = 0; i < 8; i++)
-               result = (result >> 1) | (nic_read_bit(idd) << 7);
-
-       return result;
-}
-
-static void nic_write_byte(struct ioc3_driver_data *idd, int byte)
-{
-       int i, bit;
-
-       for (i = 8; i; i--) {
-               bit = byte & 1;
-               byte >>= 1;
-
-               nic_write_bit(idd, bit);
-       }
-}
-
-static unsigned long
-nic_find(struct ioc3_driver_data *idd, int *last, unsigned long addr)
-{
-       int a, b, index, disc;
-
-       nic_reset(idd);
-
-       /* Search ROM.  */
-       nic_write_byte(idd, 0xF0);
-
-       /* Algorithm from ``Book of iButton Standards''.  */
-       for (index = 0, disc = 0; index < 64; index++) {
-               a = nic_read_bit(idd);
-               b = nic_read_bit(idd);
-
-               if (a && b) {
-                       printk(KERN_WARNING "IOC3 NIC search failed.\n");
-                       *last = 0;
-                       return 0;
-               }
-
-               if (!a && !b) {
-                       if (index == *last) {
-                               addr |= 1UL << index;
-                       } else if (index > *last) {
-                               addr &= ~(1UL << index);
-                               disc = index;
-                       } else if ((addr & (1UL << index)) == 0)
-                               disc = index;
-                       nic_write_bit(idd, (addr>>index)&1);
-                       continue;
-               } else {
-                       if (a)
-                               addr |= 1UL << index;
-                       else
-                               addr &= ~(1UL << index);
-                       nic_write_bit(idd, a);
-                       continue;
-               }
-       }
-       *last = disc;
-       return addr;
-}
-
-static void nic_addr(struct ioc3_driver_data *idd, unsigned long addr)
-{
-       int index;
-
-       nic_reset(idd);
-       nic_write_byte(idd, 0xF0);
-       for (index = 0; index < 64; index++) {
-               nic_read_bit(idd);
-               nic_read_bit(idd);
-               nic_write_bit(idd, (addr>>index)&1);
-       }
-}
-
-static void crc16_byte(unsigned int *crc, unsigned char db)
-{
-       int i;
-
-       for(i=0;i<8;i++) {
-               *crc <<= 1;
-               if((db^(*crc>>16)) & 1)
-                       *crc ^= 0x8005;
-               db >>= 1;
-       }
-       *crc &= 0xFFFF;
-}
-
-static unsigned int crc16_area(unsigned char *dbs, int size, unsigned int crc)
-{
-       while(size--)
-               crc16_byte(&crc, *(dbs++));
-       return crc;
-}
-
-static void crc8_byte(unsigned int *crc, unsigned char db)
-{
-       int i,f;
-
-       for(i=0;i<8;i++) {
-               f = (*crc ^ db) & 1;
-               *crc >>= 1;
-               db >>= 1;
-               if(f)
-                       *crc ^= 0x8c;
-       }
-       *crc &= 0xff;
-}
-
-static unsigned int crc8_addr(unsigned long addr)
-{
-       int i;
-       unsigned int crc = 0x00;
-
-       for(i=0;i<8;i++)
-               crc8_byte(&crc, addr>>(i<<3));
-       return crc;
-}
-
-static void
-read_redir_page(struct ioc3_driver_data *idd, unsigned long addr, int page,
-                       unsigned char *redir, unsigned char *data)
-{
-       int loops = 16, i;
-
-       while(redir[page] != 0xFF) {
-               page = redir[page]^0xFF;
-               loops--;
-               if(loops<0) {
-                       printk(KERN_ERR "IOC3: NIC circular redirection\n");
-                       return;
-               }
-       }
-       loops = 3;
-       while(loops>0) {
-               nic_addr(idd, addr);
-               nic_write_byte(idd, 0xF0);
-               nic_write_byte(idd, (page << 5) & 0xE0);
-               nic_write_byte(idd, (page >> 3) & 0x1F);
-               for(i=0;i<0x20;i++)
-                       data[i] = nic_read_byte(idd);
-               if(crc16_area(data, 0x20, 0x0000) == 0x800d)
-                       return;
-               loops--;
-       }
-       printk(KERN_ERR "IOC3: CRC error in data page\n");
-       for(i=0;i<0x20;i++)
-               data[i] = 0x00;
-}
-
-static void
-read_redir_map(struct ioc3_driver_data *idd, unsigned long addr,
-                                        unsigned char *redir)
-{
-       int i,j,loops = 3,crc_ok;
-       unsigned int crc;
-
-       while(loops>0) {
-               crc_ok = 1;
-               nic_addr(idd, addr);
-               nic_write_byte(idd, 0xAA);
-               nic_write_byte(idd, 0x00);
-               nic_write_byte(idd, 0x01);
-               for(i=0;i<64;i+=8) {
-                       for(j=0;j<8;j++)
-                               redir[i+j] = nic_read_byte(idd);
-                       crc = crc16_area(redir+i, 8, (i==0)?0x8707:0x0000);
-                       crc16_byte(&crc, nic_read_byte(idd));
-                       crc16_byte(&crc, nic_read_byte(idd));
-                       if(crc != 0x800d)
-                               crc_ok = 0;
-               }
-               if(crc_ok)
-                       return;
-               loops--;
-       }
-       printk(KERN_ERR "IOC3: CRC error in redirection page\n");
-       for(i=0;i<64;i++)
-               redir[i] = 0xFF;
-}
-
-static void read_nic(struct ioc3_driver_data *idd, unsigned long addr)
-{
-       unsigned char redir[64];
-       unsigned char data[64],part[32];
-       int i,j;
-
-       /* read redirections */
-       read_redir_map(idd, addr, redir);
-       /* read data pages */
-       read_redir_page(idd, addr, 0, redir, data);
-       read_redir_page(idd, addr, 1, redir, data+32);
-       /* assemble the part # */
-       j=0;
-       for(i=0;i<19;i++)
-               if(data[i+11] != ' ')
-                       part[j++] = data[i+11];
-       for(i=0;i<6;i++)
-               if(data[i+32] != ' ')
-                       part[j++] = data[i+32];
-       part[j] = 0;
-       /* skip Octane power supplies */
-       if(!strncmp(part, "060-0035-", 9))
-               return;
-       if(!strncmp(part, "060-0038-", 9))
-               return;
-       strcpy(idd->nic_part, part);
-       /* assemble the serial # */
-       j=0;
-       for(i=0;i<10;i++)
-               if(data[i+1] != ' ')
-                       idd->nic_serial[j++] = data[i+1];
-       idd->nic_serial[j] = 0;
-}
-
-static void read_mac(struct ioc3_driver_data *idd, unsigned long addr)
-{
-       int i, loops = 3;
-       unsigned char data[13];
-
-       while(loops>0) {
-               nic_addr(idd, addr);
-               nic_write_byte(idd, 0xF0);
-               nic_write_byte(idd, 0x00);
-               nic_write_byte(idd, 0x00);
-               nic_read_byte(idd);
-               for(i=0;i<13;i++)
-                       data[i] = nic_read_byte(idd);
-               if(crc16_area(data, 13, 0x0000) == 0x800d) {
-                       for(i=10;i>4;i--)
-                               idd->nic_mac[10-i] = data[i];
-                       return;
-               }
-               loops--;
-       }
-       printk(KERN_ERR "IOC3: CRC error in MAC address\n");
-       for(i=0;i<6;i++)
-               idd->nic_mac[i] = 0x00;
-}
-
-static void probe_nic(struct ioc3_driver_data *idd)
-{
-        int save = 0, loops = 3;
-        unsigned long first, addr;
-
-        writel(GPCR_MLAN_EN, &idd->vma->gpcr_s);
-
-        while(loops>0) {
-                idd->nic_part[0] = 0;
-                idd->nic_serial[0] = 0;
-                addr = first = nic_find(idd, &save, 0);
-                if(!first)
-                        return;
-                while(1) {
-                        if(crc8_addr(addr))
-                                break;
-                        else {
-                                switch(addr & 0xFF) {
-                                case 0x0B:
-                                        read_nic(idd, addr);
-                                        break;
-                                case 0x09:
-                                case 0x89:
-                                case 0x91:
-                                        read_mac(idd, addr);
-                                        break;
-                                }
-                        }
-                        addr = nic_find(idd, &save, addr);
-                        if(addr == first)
-                                return;
-                }
-                loops--;
-        }
-        printk(KERN_ERR "IOC3: CRC error in NIC address\n");
-}
-
-/* Interrupts */
-
-static void write_ireg(struct ioc3_driver_data *idd, uint32_t val, int which)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&idd->ir_lock, flags);
-       switch (which) {
-       case IOC3_W_IES:
-               writel(val, &idd->vma->sio_ies);
-               break;
-       case IOC3_W_IEC:
-               writel(val, &idd->vma->sio_iec);
-               break;
-       }
-       spin_unlock_irqrestore(&idd->ir_lock, flags);
-}
-static inline uint32_t get_pending_intrs(struct ioc3_driver_data *idd)
-{
-       unsigned long flag;
-       uint32_t intrs = 0;
-
-       spin_lock_irqsave(&idd->ir_lock, flag);
-       intrs = readl(&idd->vma->sio_ir);
-       intrs &= readl(&idd->vma->sio_ies);
-       spin_unlock_irqrestore(&idd->ir_lock, flag);
-       return intrs;
-}
-
-static irqreturn_t ioc3_intr_io(int irq, void *arg)
-{
-       unsigned long flags;
-       struct ioc3_driver_data *idd = arg;
-       int handled = 1, id;
-       unsigned int pending;
-
-       read_lock_irqsave(&ioc3_submodules_lock, flags);
-
-       if(idd->dual_irq && readb(&idd->vma->eisr)) {
-               /* send Ethernet IRQ to the driver */
-               if(ioc3_ethernet && idd->active[ioc3_ethernet->id] &&
-                                               ioc3_ethernet->intr) {
-                       handled = handled && !ioc3_ethernet->intr(ioc3_ethernet,
-                                                       idd, 0);
-               }
-       }
-       pending = get_pending_intrs(idd);       /* look at the IO IRQs */
-
-       for(id=0;id<IOC3_MAX_SUBMODULES;id++) {
-               if(idd->active[id] && ioc3_submodules[id]
-                               && (pending & ioc3_submodules[id]->irq_mask)
-                               && ioc3_submodules[id]->intr) {
-                       write_ireg(idd, ioc3_submodules[id]->irq_mask,
-                                                       IOC3_W_IEC);
-                       if(!ioc3_submodules[id]->intr(ioc3_submodules[id],
-                                  idd, pending & ioc3_submodules[id]->irq_mask))
-                               pending &= ~ioc3_submodules[id]->irq_mask;
-                       if (ioc3_submodules[id]->reset_mask)
-                               write_ireg(idd, ioc3_submodules[id]->irq_mask,
-                                                       IOC3_W_IES);
-               }
-       }
-       read_unlock_irqrestore(&ioc3_submodules_lock, flags);
-       if(pending) {
-               printk(KERN_WARNING
-                 "IOC3: Pending IRQs 0x%08x discarded and disabled\n",pending);
-               write_ireg(idd, pending, IOC3_W_IEC);
-               handled = 1;
-       }
-       return handled?IRQ_HANDLED:IRQ_NONE;
-}
-
-static irqreturn_t ioc3_intr_eth(int irq, void *arg)
-{
-       unsigned long flags;
-       struct ioc3_driver_data *idd = (struct ioc3_driver_data *)arg;
-       int handled = 1;
-
-       if(!idd->dual_irq)
-               return IRQ_NONE;
-       read_lock_irqsave(&ioc3_submodules_lock, flags);
-       if(ioc3_ethernet && idd->active[ioc3_ethernet->id]
-                               && ioc3_ethernet->intr)
-               handled = handled && !ioc3_ethernet->intr(ioc3_ethernet, idd, 0);
-       read_unlock_irqrestore(&ioc3_submodules_lock, flags);
-       return handled?IRQ_HANDLED:IRQ_NONE;
-}
-
-void ioc3_enable(struct ioc3_submodule *is,
-                               struct ioc3_driver_data *idd, unsigned int irqs)
-{
-       write_ireg(idd, irqs & is->irq_mask, IOC3_W_IES);
-}
-
-void ioc3_ack(struct ioc3_submodule *is, struct ioc3_driver_data *idd,
-                               unsigned int irqs)
-{
-       writel(irqs & is->irq_mask, &idd->vma->sio_ir);
-}
-
-void ioc3_disable(struct ioc3_submodule *is,
-                               struct ioc3_driver_data *idd, unsigned int irqs)
-{
-       write_ireg(idd, irqs & is->irq_mask, IOC3_W_IEC);
-}
-
-void ioc3_gpcr_set(struct ioc3_driver_data *idd, unsigned int val)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&idd->gpio_lock, flags);
-       writel(val, &idd->vma->gpcr_s);
-       spin_unlock_irqrestore(&idd->gpio_lock, flags);
-}
-
-/* Keep it simple, stupid! */
-static int find_slot(void **tab, int max)
-{
-       int i;
-       for(i=0;i<max;i++)
-               if(!(tab[i]))
-                       return i;
-       return -1;
-}
-
-/* Register an IOC3 submodule */
-int ioc3_register_submodule(struct ioc3_submodule *is)
-{
-       struct ioc3_driver_data *idd;
-       int alloc_id;
-       unsigned long flags;
-
-       write_lock_irqsave(&ioc3_submodules_lock, flags);
-       alloc_id = find_slot((void **)ioc3_submodules, IOC3_MAX_SUBMODULES);
-       if(alloc_id != -1) {
-               ioc3_submodules[alloc_id] = is;
-               if(is->ethernet) {
-                       if(ioc3_ethernet==NULL)
-                               ioc3_ethernet=is;
-                       else
-                               printk(KERN_WARNING
-                                 "IOC3 Ethernet module already registered!\n");
-               }
-       }
-       write_unlock_irqrestore(&ioc3_submodules_lock, flags);
-
-       if(alloc_id == -1) {
-               printk(KERN_WARNING "Increase IOC3_MAX_SUBMODULES!\n");
-               return -ENOMEM;
-       }
-
-       is->id=alloc_id;
-
-       /* Initialize submodule for each IOC3 */
-       if (!is->probe)
-               return 0;
-
-       down_read(&ioc3_devices_rwsem);
-       list_for_each_entry(idd, &ioc3_devices, list) {
-               /* set to 1 for IRQs in probe */
-               idd->active[alloc_id] = 1;
-               idd->active[alloc_id] = !is->probe(is, idd);
-       }
-       up_read(&ioc3_devices_rwsem);
-
-       return 0;
-}
-
-/* Unregister an IOC3 submodule */
-void ioc3_unregister_submodule(struct ioc3_submodule *is)
-{
-       struct ioc3_driver_data *idd;
-       unsigned long flags;
-
-       write_lock_irqsave(&ioc3_submodules_lock, flags);
-       if(ioc3_submodules[is->id]==is)
-               ioc3_submodules[is->id]=NULL;
-       else
-               printk(KERN_WARNING
-                       "IOC3 submodule %s has wrong ID.\n",is->name);
-       if(ioc3_ethernet==is)
-               ioc3_ethernet = NULL;
-       write_unlock_irqrestore(&ioc3_submodules_lock, flags);
-
-       /* Remove submodule for each IOC3 */
-       down_read(&ioc3_devices_rwsem);
-       list_for_each_entry(idd, &ioc3_devices, list)
-               if(idd->active[is->id]) {
-                       if(is->remove)
-                               if(is->remove(is, idd))
-                                       printk(KERN_WARNING
-                                              "%s: IOC3 submodule %s remove failed "
-                                              "for pci_dev %s.\n",
-                                              __func__, module_name(is->owner),
-                                              pci_name(idd->pdev));
-                       idd->active[is->id] = 0;
-                       if(is->irq_mask)
-                               write_ireg(idd, is->irq_mask, IOC3_W_IEC);
-               }
-       up_read(&ioc3_devices_rwsem);
-}
-
-/*********************
- * Device management *
- *********************/
-
-static char *ioc3_class_names[] = { "unknown", "IP27 BaseIO", "IP30 system",
-                       "MENET 1/2/3", "MENET 4", "CADduo", "Altix Serial" };
-
-static int ioc3_class(struct ioc3_driver_data *idd)
-{
-       int res = IOC3_CLASS_NONE;
-       /* NIC-based logic */
-       if(!strncmp(idd->nic_part, "030-0891-", 9))
-               res = IOC3_CLASS_BASE_IP30;
-       if(!strncmp(idd->nic_part, "030-1155-", 9))
-               res = IOC3_CLASS_CADDUO;
-       if(!strncmp(idd->nic_part, "030-1657-", 9))
-               res = IOC3_CLASS_SERIAL;
-       if(!strncmp(idd->nic_part, "030-1664-", 9))
-               res = IOC3_CLASS_SERIAL;
-       /* total random heuristics */
-#ifdef CONFIG_SGI_IP27
-       if(!idd->nic_part[0])
-               res = IOC3_CLASS_BASE_IP27;
-#endif
-       /* print educational message */
-       printk(KERN_INFO "IOC3 part: [%s], serial: [%s] => class %s\n",
-                       idd->nic_part, idd->nic_serial, ioc3_class_names[res]);
-       return res;
-}
-/* Adds a new instance of an IOC3 card */
-static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
-{
-       struct ioc3_driver_data *idd;
-       uint32_t pcmd;
-       int ret, id;
-
-       /* Enable IOC3 and take ownership of it */
-       if ((ret = pci_enable_device(pdev))) {
-               printk(KERN_WARNING
-                      "%s: Failed to enable IOC3 device for pci_dev %s.\n",
-                      __func__, pci_name(pdev));
-               goto out;
-       }
-       pci_set_master(pdev);
-
-#ifdef USE_64BIT_DMA
-        ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
-        if (!ret) {
-                ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
-                if (ret < 0) {
-                        printk(KERN_WARNING "%s: Unable to obtain 64 bit DMA "
-                               "for consistent allocations\n",
-                               __func__);
-                }
-       }
-#endif
-
-       /* Set up per-IOC3 data */
-       idd = kzalloc(sizeof(struct ioc3_driver_data), GFP_KERNEL);
-       if (!idd) {
-               printk(KERN_WARNING
-                      "%s: Failed to allocate IOC3 data for pci_dev %s.\n",
-                      __func__, pci_name(pdev));
-               ret = -ENODEV;
-               goto out_idd;
-       }
-       spin_lock_init(&idd->ir_lock);
-       spin_lock_init(&idd->gpio_lock);
-       idd->pdev = pdev;
-
-       /* Map all IOC3 registers.  These are shared between subdevices
-        * so the main IOC3 module manages them.
-        */
-       idd->pma = pci_resource_start(pdev, 0);
-       if (!idd->pma) {
-               printk(KERN_WARNING
-                      "%s: Unable to find IOC3 resource "
-                      "for pci_dev %s.\n",
-                      __func__, pci_name(pdev));
-               ret = -ENODEV;
-               goto out_pci;
-       }
-       if (!request_mem_region(idd->pma, IOC3_PCI_SIZE, "ioc3")) {
-               printk(KERN_WARNING
-                      "%s: Unable to request IOC3 region "
-                      "for pci_dev %s.\n",
-                      __func__, pci_name(pdev));
-               ret = -ENODEV;
-               goto out_pci;
-       }
-       idd->vma = ioremap(idd->pma, IOC3_PCI_SIZE);
-       if (!idd->vma) {
-               printk(KERN_WARNING
-                      "%s: Unable to remap IOC3 region "
-                      "for pci_dev %s.\n",
-                      __func__, pci_name(pdev));
-               ret = -ENODEV;
-               goto out_misc_region;
-       }
-
-       /* Track PCI-device specific data */
-       pci_set_drvdata(pdev, idd);
-       down_write(&ioc3_devices_rwsem);
-       list_add_tail(&idd->list, &ioc3_devices);
-       idd->id = ioc3_counter++;
-       up_write(&ioc3_devices_rwsem);
-
-       idd->gpdr_shadow = readl(&idd->vma->gpdr);
-
-       /* Read IOC3 NIC contents */
-       probe_nic(idd);
-
-       /* Detect IOC3 class */
-       idd->class = ioc3_class(idd);
-
-       /* Initialize IOC3 */
-       pci_read_config_dword(pdev, PCI_COMMAND, &pcmd);
-       pci_write_config_dword(pdev, PCI_COMMAND,
-                               pcmd | PCI_COMMAND_MEMORY |
-                               PCI_COMMAND_PARITY | PCI_COMMAND_SERR |
-                               PCI_SCR_DROP_MODE_EN);
-
-       write_ireg(idd, ~0, IOC3_W_IEC);
-       writel(~0, &idd->vma->sio_ir);
-
-       /* Set up IRQs */
-       if(idd->class == IOC3_CLASS_BASE_IP30
-                               || idd->class == IOC3_CLASS_BASE_IP27) {
-               writel(0, &idd->vma->eier);
-               writel(~0, &idd->vma->eisr);
-
-               idd->dual_irq = 1;
-               if (!request_irq(pdev->irq, ioc3_intr_eth, IRQF_SHARED,
-                                "ioc3-eth", (void *)idd)) {
-                       idd->irq_eth = pdev->irq;
-               } else {
-                       printk(KERN_WARNING
-                              "%s : request_irq fails for IRQ 0x%x\n ",
-                              __func__, pdev->irq);
-               }
-               if (!request_irq(pdev->irq+2, ioc3_intr_io, IRQF_SHARED,
-                                "ioc3-io", (void *)idd)) {
-                       idd->irq_io = pdev->irq+2;
-               } else {
-                       printk(KERN_WARNING
-                              "%s : request_irq fails for IRQ 0x%x\n ",
-                              __func__, pdev->irq+2);
-               }
-       } else {
-               if (!request_irq(pdev->irq, ioc3_intr_io, IRQF_SHARED,
-                                "ioc3", (void *)idd)) {
-                       idd->irq_io = pdev->irq;
-               } else {
-                       printk(KERN_WARNING
-                              "%s : request_irq fails for IRQ 0x%x\n ",
-                              __func__, pdev->irq);
-               }
-       }
-
-       /* Add this IOC3 to all submodules */
-       for(id=0;id<IOC3_MAX_SUBMODULES;id++)
-               if(ioc3_submodules[id] && ioc3_submodules[id]->probe) {
-                       idd->active[id] = 1;
-                       idd->active[id] = !ioc3_submodules[id]->probe
-                                               (ioc3_submodules[id], idd);
-               }
-
-       printk(KERN_INFO "IOC3 Master Driver loaded for %s\n", pci_name(pdev));
-
-       return 0;
-
-out_misc_region:
-       release_mem_region(idd->pma, IOC3_PCI_SIZE);
-out_pci:
-       kfree(idd);
-out_idd:
-       pci_disable_device(pdev);
-out:
-       return ret;
-}
-
-/* Removes a particular instance of an IOC3 card. */
-static void ioc3_remove(struct pci_dev *pdev)
-{
-       int id;
-       struct ioc3_driver_data *idd;
-
-       idd = pci_get_drvdata(pdev);
-
-       /* Remove this IOC3 from all submodules */
-       for(id=0;id<IOC3_MAX_SUBMODULES;id++)
-               if(idd->active[id]) {
-                       if(ioc3_submodules[id] && ioc3_submodules[id]->remove)
-                               if(ioc3_submodules[id]->remove(ioc3_submodules[id],
-                                                               idd))
-                                       printk(KERN_WARNING
-                                              "%s: IOC3 submodule 0x%s remove failed "
-                                              "for pci_dev %s.\n",
-                                               __func__,
-                                               module_name(ioc3_submodules[id]->owner),
-                                               pci_name(pdev));
-                       idd->active[id] = 0;
-               }
-
-       /* Clear and disable all IRQs */
-       write_ireg(idd, ~0, IOC3_W_IEC);
-       writel(~0, &idd->vma->sio_ir);
-
-       /* Release resources */
-       free_irq(idd->irq_io, (void *)idd);
-       if(idd->dual_irq)
-               free_irq(idd->irq_eth, (void *)idd);
-       iounmap(idd->vma);
-       release_mem_region(idd->pma, IOC3_PCI_SIZE);
-
-       /* Disable IOC3 and relinquish */
-       pci_disable_device(pdev);
-
-       /* Remove and free driver data */
-       down_write(&ioc3_devices_rwsem);
-       list_del(&idd->list);
-       up_write(&ioc3_devices_rwsem);
-       kfree(idd);
-}
-
-static struct pci_device_id ioc3_id_table[] = {
-       {PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, PCI_ANY_ID, PCI_ANY_ID},
-       {0}
-};
-
-static struct pci_driver ioc3_driver = {
-       .name = "IOC3",
-       .id_table = ioc3_id_table,
-       .probe = ioc3_probe,
-       .remove = ioc3_remove,
-};
-
-MODULE_DEVICE_TABLE(pci, ioc3_id_table);
-
-/*********************
- * Module management *
- *********************/
-
-/* Module load */
-static int __init ioc3_init(void)
-{
-       if (ia64_platform_is("sn2"))
-               return pci_register_driver(&ioc3_driver);
-       return -ENODEV;
-}
-
-/* Module unload */
-static void __exit ioc3_exit(void)
-{
-       pci_unregister_driver(&ioc3_driver);
-}
-
-module_init(ioc3_init);
-module_exit(ioc3_exit);
-
-MODULE_AUTHOR("Stanislaw Skowronek <skylark@linux-mips.org>");
-MODULE_DESCRIPTION("PCI driver for SGI IOC3");
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL_GPL(ioc3_register_submodule);
-EXPORT_SYMBOL_GPL(ioc3_unregister_submodule);
-EXPORT_SYMBOL_GPL(ioc3_ack);
-EXPORT_SYMBOL_GPL(ioc3_gpcr_set);
-EXPORT_SYMBOL_GPL(ioc3_disable);
-EXPORT_SYMBOL_GPL(ioc3_enable);
index 23bfb8e..bc2c912 100644 (file)
@@ -37,6 +37,17 @@ config MESON_GX_PM_DOMAINS
          Say yes to expose Amlogic Meson GX Power Domains as
          Generic Power Domains.
 
+config MESON_EE_PM_DOMAINS
+       bool "Amlogic Meson Everything-Else Power Domains driver"
+       depends on ARCH_MESON || COMPILE_TEST
+       depends on PM && OF
+       default ARCH_MESON
+       select PM_GENERIC_DOMAINS
+       select PM_GENERIC_DOMAINS_OF
+       help
+         Say yes to expose Amlogic Meson Everything-Else Power Domains as
+         Generic Power Domains.
+
 config MESON_MX_SOCINFO
        bool "Amlogic Meson MX SoC Information driver"
        depends on ARCH_MESON || COMPILE_TEST
index f2e4ed1..de79d04 100644 (file)
@@ -4,3 +4,4 @@ obj-$(CONFIG_MESON_CLK_MEASURE) += meson-clk-measure.o
 obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o
 obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-gx-pwrc-vpu.o
 obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o
+obj-$(CONFIG_MESON_EE_PM_DOMAINS) += meson-ee-pwrc.o
index 19d4cbc..0fa47d7 100644 (file)
@@ -11,6 +11,8 @@
 #include <linux/debugfs.h>
 #include <linux/regmap.h>
 
+static DEFINE_MUTEX(measure_lock);
+
 #define MSR_CLK_DUTY           0x0
 #define MSR_CLK_REG0           0x4
 #define MSR_CLK_REG1           0x8
@@ -322,6 +324,8 @@ static struct meson_msr_id clk_msr_g12a[CLK_MSR_MAX] = {
        CLK_MSR_ID(84, "co_tx"),
        CLK_MSR_ID(89, "hdmi_todig"),
        CLK_MSR_ID(90, "hdmitx_sys"),
+       CLK_MSR_ID(91, "sys_cpub_div16"),
+       CLK_MSR_ID(92, "sys_pll_cpub_div16"),
        CLK_MSR_ID(94, "eth_phy_rx"),
        CLK_MSR_ID(95, "eth_phy_pll"),
        CLK_MSR_ID(96, "vpu_b"),
@@ -353,6 +357,136 @@ static struct meson_msr_id clk_msr_g12a[CLK_MSR_MAX] = {
        CLK_MSR_ID(122, "audio_pdm_dclk"),
 };
 
+static struct meson_msr_id clk_msr_sm1[CLK_MSR_MAX] = {
+       CLK_MSR_ID(0, "ring_osc_out_ee_0"),
+       CLK_MSR_ID(1, "ring_osc_out_ee_1"),
+       CLK_MSR_ID(2, "ring_osc_out_ee_2"),
+       CLK_MSR_ID(3, "ring_osc_out_ee_3"),
+       CLK_MSR_ID(4, "gp0_pll"),
+       CLK_MSR_ID(5, "gp1_pll"),
+       CLK_MSR_ID(6, "enci"),
+       CLK_MSR_ID(7, "clk81"),
+       CLK_MSR_ID(8, "encp"),
+       CLK_MSR_ID(9, "encl"),
+       CLK_MSR_ID(10, "vdac"),
+       CLK_MSR_ID(11, "eth_tx"),
+       CLK_MSR_ID(12, "hifi_pll"),
+       CLK_MSR_ID(13, "mod_tcon"),
+       CLK_MSR_ID(14, "fec_0"),
+       CLK_MSR_ID(15, "fec_1"),
+       CLK_MSR_ID(16, "fec_2"),
+       CLK_MSR_ID(17, "sys_pll_div16"),
+       CLK_MSR_ID(18, "sys_cpu_div16"),
+       CLK_MSR_ID(19, "lcd_an_ph2"),
+       CLK_MSR_ID(20, "rtc_osc_out"),
+       CLK_MSR_ID(21, "lcd_an_ph3"),
+       CLK_MSR_ID(22, "eth_phy_ref"),
+       CLK_MSR_ID(23, "mpll_50m"),
+       CLK_MSR_ID(24, "eth_125m"),
+       CLK_MSR_ID(25, "eth_rmii"),
+       CLK_MSR_ID(26, "sc_int"),
+       CLK_MSR_ID(27, "in_mac"),
+       CLK_MSR_ID(28, "sar_adc"),
+       CLK_MSR_ID(29, "pcie_inp"),
+       CLK_MSR_ID(30, "pcie_inn"),
+       CLK_MSR_ID(31, "mpll_test_out"),
+       CLK_MSR_ID(32, "vdec"),
+       CLK_MSR_ID(34, "eth_mpll_50m"),
+       CLK_MSR_ID(35, "mali"),
+       CLK_MSR_ID(36, "hdmi_tx_pixel"),
+       CLK_MSR_ID(37, "cdac"),
+       CLK_MSR_ID(38, "vdin_meas"),
+       CLK_MSR_ID(39, "bt656"),
+       CLK_MSR_ID(40, "arm_ring_osc_out_4"),
+       CLK_MSR_ID(41, "eth_rx_or_rmii"),
+       CLK_MSR_ID(42, "mp0_out"),
+       CLK_MSR_ID(43, "fclk_div5"),
+       CLK_MSR_ID(44, "pwm_b"),
+       CLK_MSR_ID(45, "pwm_a"),
+       CLK_MSR_ID(46, "vpu"),
+       CLK_MSR_ID(47, "ddr_dpll_pt"),
+       CLK_MSR_ID(48, "mp1_out"),
+       CLK_MSR_ID(49, "mp2_out"),
+       CLK_MSR_ID(50, "mp3_out"),
+       CLK_MSR_ID(51, "sd_emmc_c"),
+       CLK_MSR_ID(52, "sd_emmc_b"),
+       CLK_MSR_ID(53, "sd_emmc_a"),
+       CLK_MSR_ID(54, "vpu_clkc"),
+       CLK_MSR_ID(55, "vid_pll_div_out"),
+       CLK_MSR_ID(56, "wave420l_a"),
+       CLK_MSR_ID(57, "wave420l_c"),
+       CLK_MSR_ID(58, "wave420l_b"),
+       CLK_MSR_ID(59, "hcodec"),
+       CLK_MSR_ID(60, "arm_ring_osc_out_5"),
+       CLK_MSR_ID(61, "gpio_msr"),
+       CLK_MSR_ID(62, "hevcb"),
+       CLK_MSR_ID(63, "dsi_meas"),
+       CLK_MSR_ID(64, "spicc_1"),
+       CLK_MSR_ID(65, "spicc_0"),
+       CLK_MSR_ID(66, "vid_lock"),
+       CLK_MSR_ID(67, "dsi_phy"),
+       CLK_MSR_ID(68, "hdcp22_esm"),
+       CLK_MSR_ID(69, "hdcp22_skp"),
+       CLK_MSR_ID(70, "pwm_f"),
+       CLK_MSR_ID(71, "pwm_e"),
+       CLK_MSR_ID(72, "pwm_d"),
+       CLK_MSR_ID(73, "pwm_c"),
+       CLK_MSR_ID(74, "arm_ring_osc_out_6"),
+       CLK_MSR_ID(75, "hevcf"),
+       CLK_MSR_ID(76, "arm_ring_osc_out_7"),
+       CLK_MSR_ID(77, "rng_ring_osc_0"),
+       CLK_MSR_ID(78, "rng_ring_osc_1"),
+       CLK_MSR_ID(79, "rng_ring_osc_2"),
+       CLK_MSR_ID(80, "rng_ring_osc_3"),
+       CLK_MSR_ID(81, "vapb"),
+       CLK_MSR_ID(82, "ge2d"),
+       CLK_MSR_ID(83, "co_rx"),
+       CLK_MSR_ID(84, "co_tx"),
+       CLK_MSR_ID(85, "arm_ring_osc_out_8"),
+       CLK_MSR_ID(86, "arm_ring_osc_out_9"),
+       CLK_MSR_ID(87, "mipi_dsi_phy"),
+       CLK_MSR_ID(88, "cis2_adapt"),
+       CLK_MSR_ID(89, "hdmi_todig"),
+       CLK_MSR_ID(90, "hdmitx_sys"),
+       CLK_MSR_ID(91, "nna_core"),
+       CLK_MSR_ID(92, "nna_axi"),
+       CLK_MSR_ID(93, "vad"),
+       CLK_MSR_ID(94, "eth_phy_rx"),
+       CLK_MSR_ID(95, "eth_phy_pll"),
+       CLK_MSR_ID(96, "vpu_b"),
+       CLK_MSR_ID(97, "cpu_b_tmp"),
+       CLK_MSR_ID(98, "ts"),
+       CLK_MSR_ID(99, "arm_ring_osc_out_10"),
+       CLK_MSR_ID(100, "arm_ring_osc_out_11"),
+       CLK_MSR_ID(101, "arm_ring_osc_out_12"),
+       CLK_MSR_ID(102, "arm_ring_osc_out_13"),
+       CLK_MSR_ID(103, "arm_ring_osc_out_14"),
+       CLK_MSR_ID(104, "arm_ring_osc_out_15"),
+       CLK_MSR_ID(105, "arm_ring_osc_out_16"),
+       CLK_MSR_ID(106, "ephy_test"),
+       CLK_MSR_ID(107, "au_dac_g128x"),
+       CLK_MSR_ID(108, "audio_locker_out"),
+       CLK_MSR_ID(109, "audio_locker_in"),
+       CLK_MSR_ID(110, "audio_tdmout_c_sclk"),
+       CLK_MSR_ID(111, "audio_tdmout_b_sclk"),
+       CLK_MSR_ID(112, "audio_tdmout_a_sclk"),
+       CLK_MSR_ID(113, "audio_tdmin_lb_sclk"),
+       CLK_MSR_ID(114, "audio_tdmin_c_sclk"),
+       CLK_MSR_ID(115, "audio_tdmin_b_sclk"),
+       CLK_MSR_ID(116, "audio_tdmin_a_sclk"),
+       CLK_MSR_ID(117, "audio_resample"),
+       CLK_MSR_ID(118, "audio_pdm_sys"),
+       CLK_MSR_ID(119, "audio_spdifout_b"),
+       CLK_MSR_ID(120, "audio_spdifout"),
+       CLK_MSR_ID(121, "audio_spdifin"),
+       CLK_MSR_ID(122, "audio_pdm_dclk"),
+       CLK_MSR_ID(123, "audio_resampled"),
+       CLK_MSR_ID(124, "earcrx_pll"),
+       CLK_MSR_ID(125, "earcrx_pll_test"),
+       CLK_MSR_ID(126, "csi_phy0"),
+       CLK_MSR_ID(127, "csi2_data"),
+};
+
 static int meson_measure_id(struct meson_msr_id *clk_msr_id,
                               unsigned int duration)
 {
@@ -360,6 +494,10 @@ static int meson_measure_id(struct meson_msr_id *clk_msr_id,
        unsigned int val;
        int ret;
 
+       ret = mutex_lock_interruptible(&measure_lock);
+       if (ret)
+               return ret;
+
        regmap_write(priv->regmap, MSR_CLK_REG0, 0);
 
        /* Set measurement duration */
@@ -377,8 +515,10 @@ static int meson_measure_id(struct meson_msr_id *clk_msr_id,
 
        ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0,
                                       val, !(val & MSR_BUSY), 10, 10000);
-       if (ret)
+       if (ret) {
+               mutex_unlock(&measure_lock);
                return ret;
+       }
 
        /* Disable */
        regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0);
@@ -386,6 +526,8 @@ static int meson_measure_id(struct meson_msr_id *clk_msr_id,
        /* Get the value in multiple of gate time counts */
        regmap_read(priv->regmap, MSR_CLK_REG2, &val);
 
+       mutex_unlock(&measure_lock);
+
        if (val >= MSR_VAL_MASK)
                return -EINVAL;
 
@@ -533,6 +675,10 @@ static const struct of_device_id meson_msr_match_table[] = {
                .compatible = "amlogic,meson-g12a-clk-measure",
                .data = (void *)clk_msr_g12a,
        },
+       {
+               .compatible = "amlogic,meson-sm1-clk-measure",
+               .data = (void *)clk_msr_sm1,
+       },
        { /* sentinel */ }
 };
 
diff --git a/drivers/soc/amlogic/meson-ee-pwrc.c b/drivers/soc/amlogic/meson-ee-pwrc.c
new file mode 100644 (file)
index 0000000..5823f5b
--- /dev/null
@@ -0,0 +1,492 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/bitfield.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_device.h>
+#include <linux/reset-controller.h>
+#include <linux/reset.h>
+#include <linux/clk.h>
+#include <dt-bindings/power/meson-g12a-power.h>
+#include <dt-bindings/power/meson-sm1-power.h>
+
+/* AO Offsets */
+
+#define AO_RTI_GEN_PWR_SLEEP0          (0x3a << 2)
+#define AO_RTI_GEN_PWR_ISO0            (0x3b << 2)
+
+/* HHI Offsets */
+
+#define HHI_MEM_PD_REG0                        (0x40 << 2)
+#define HHI_VPU_MEM_PD_REG0            (0x41 << 2)
+#define HHI_VPU_MEM_PD_REG1            (0x42 << 2)
+#define HHI_VPU_MEM_PD_REG3            (0x43 << 2)
+#define HHI_VPU_MEM_PD_REG4            (0x44 << 2)
+#define HHI_AUDIO_MEM_PD_REG0          (0x45 << 2)
+#define HHI_NANOQ_MEM_PD_REG0          (0x46 << 2)
+#define HHI_NANOQ_MEM_PD_REG1          (0x47 << 2)
+#define HHI_VPU_MEM_PD_REG2            (0x4d << 2)
+
+struct meson_ee_pwrc;
+struct meson_ee_pwrc_domain;
+
+struct meson_ee_pwrc_mem_domain {
+       unsigned int reg;
+       unsigned int mask;
+};
+
+struct meson_ee_pwrc_top_domain {
+       unsigned int sleep_reg;
+       unsigned int sleep_mask;
+       unsigned int iso_reg;
+       unsigned int iso_mask;
+};
+
+struct meson_ee_pwrc_domain_desc {
+       char *name;
+       unsigned int reset_names_count;
+       unsigned int clk_names_count;
+       struct meson_ee_pwrc_top_domain *top_pd;
+       unsigned int mem_pd_count;
+       struct meson_ee_pwrc_mem_domain *mem_pd;
+       bool (*get_power)(struct meson_ee_pwrc_domain *pwrc_domain);
+};
+
+struct meson_ee_pwrc_domain_data {
+       unsigned int count;
+       struct meson_ee_pwrc_domain_desc *domains;
+};
+
+/* TOP Power Domains */
+
+static struct meson_ee_pwrc_top_domain g12a_pwrc_vpu = {
+       .sleep_reg = AO_RTI_GEN_PWR_SLEEP0,
+       .sleep_mask = BIT(8),
+       .iso_reg = AO_RTI_GEN_PWR_SLEEP0,
+       .iso_mask = BIT(9),
+};
+
+#define SM1_EE_PD(__bit)                                       \
+       {                                                       \
+               .sleep_reg = AO_RTI_GEN_PWR_SLEEP0,             \
+               .sleep_mask = BIT(__bit),                       \
+               .iso_reg = AO_RTI_GEN_PWR_ISO0,                 \
+               .iso_mask = BIT(__bit),                         \
+       }
+
+static struct meson_ee_pwrc_top_domain sm1_pwrc_vpu = SM1_EE_PD(8);
+static struct meson_ee_pwrc_top_domain sm1_pwrc_nna = SM1_EE_PD(16);
+static struct meson_ee_pwrc_top_domain sm1_pwrc_usb = SM1_EE_PD(17);
+static struct meson_ee_pwrc_top_domain sm1_pwrc_pci = SM1_EE_PD(18);
+static struct meson_ee_pwrc_top_domain sm1_pwrc_ge2d = SM1_EE_PD(19);
+
+/* Memory PD Domains */
+
+#define VPU_MEMPD(__reg)                                       \
+       { __reg, GENMASK(1, 0) },                               \
+       { __reg, GENMASK(3, 2) },                               \
+       { __reg, GENMASK(5, 4) },                               \
+       { __reg, GENMASK(7, 6) },                               \
+       { __reg, GENMASK(9, 8) },                               \
+       { __reg, GENMASK(11, 10) },                             \
+       { __reg, GENMASK(13, 12) },                             \
+       { __reg, GENMASK(15, 14) },                             \
+       { __reg, GENMASK(17, 16) },                             \
+       { __reg, GENMASK(19, 18) },                             \
+       { __reg, GENMASK(21, 20) },                             \
+       { __reg, GENMASK(23, 22) },                             \
+       { __reg, GENMASK(25, 24) },                             \
+       { __reg, GENMASK(27, 26) },                             \
+       { __reg, GENMASK(29, 28) },                             \
+       { __reg, GENMASK(31, 30) }
+
+#define VPU_HHI_MEMPD(__reg)                                   \
+       { __reg, BIT(8) },                                      \
+       { __reg, BIT(9) },                                      \
+       { __reg, BIT(10) },                                     \
+       { __reg, BIT(11) },                                     \
+       { __reg, BIT(12) },                                     \
+       { __reg, BIT(13) },                                     \
+       { __reg, BIT(14) },                                     \
+       { __reg, BIT(15) }
+
+static struct meson_ee_pwrc_mem_domain g12a_pwrc_mem_vpu[] = {
+       VPU_MEMPD(HHI_VPU_MEM_PD_REG0),
+       VPU_MEMPD(HHI_VPU_MEM_PD_REG1),
+       VPU_MEMPD(HHI_VPU_MEM_PD_REG2),
+       VPU_HHI_MEMPD(HHI_MEM_PD_REG0),
+};
+
+static struct meson_ee_pwrc_mem_domain g12a_pwrc_mem_eth[] = {
+       { HHI_MEM_PD_REG0, GENMASK(3, 2) },
+};
+
+static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_vpu[] = {
+       VPU_MEMPD(HHI_VPU_MEM_PD_REG0),
+       VPU_MEMPD(HHI_VPU_MEM_PD_REG1),
+       VPU_MEMPD(HHI_VPU_MEM_PD_REG2),
+       VPU_MEMPD(HHI_VPU_MEM_PD_REG3),
+       { HHI_VPU_MEM_PD_REG4, GENMASK(1, 0) },
+       { HHI_VPU_MEM_PD_REG4, GENMASK(3, 2) },
+       { HHI_VPU_MEM_PD_REG4, GENMASK(5, 4) },
+       { HHI_VPU_MEM_PD_REG4, GENMASK(7, 6) },
+       VPU_HHI_MEMPD(HHI_MEM_PD_REG0),
+};
+
+static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_nna[] = {
+       { HHI_NANOQ_MEM_PD_REG0, 0xff },
+       { HHI_NANOQ_MEM_PD_REG1, 0xff },
+};
+
+static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_usb[] = {
+       { HHI_MEM_PD_REG0, GENMASK(31, 30) },
+};
+
+static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_pcie[] = {
+       { HHI_MEM_PD_REG0, GENMASK(29, 26) },
+};
+
+static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_ge2d[] = {
+       { HHI_MEM_PD_REG0, GENMASK(25, 18) },
+};
+
+static struct meson_ee_pwrc_mem_domain sm1_pwrc_mem_audio[] = {
+       { HHI_MEM_PD_REG0, GENMASK(5, 4) },
+       { HHI_AUDIO_MEM_PD_REG0, GENMASK(1, 0) },
+       { HHI_AUDIO_MEM_PD_REG0, GENMASK(3, 2) },
+       { HHI_AUDIO_MEM_PD_REG0, GENMASK(5, 4) },
+       { HHI_AUDIO_MEM_PD_REG0, GENMASK(7, 6) },
+       { HHI_AUDIO_MEM_PD_REG0, GENMASK(13, 12) },
+       { HHI_AUDIO_MEM_PD_REG0, GENMASK(15, 14) },
+       { HHI_AUDIO_MEM_PD_REG0, GENMASK(17, 16) },
+       { HHI_AUDIO_MEM_PD_REG0, GENMASK(19, 18) },
+       { HHI_AUDIO_MEM_PD_REG0, GENMASK(21, 20) },
+       { HHI_AUDIO_MEM_PD_REG0, GENMASK(23, 22) },
+       { HHI_AUDIO_MEM_PD_REG0, GENMASK(25, 24) },
+       { HHI_AUDIO_MEM_PD_REG0, GENMASK(27, 26) },
+};
+
+#define VPU_PD(__name, __top_pd, __mem, __get_power, __resets, __clks) \
+       {                                                               \
+               .name = __name,                                         \
+               .reset_names_count = __resets,                          \
+               .clk_names_count = __clks,                              \
+               .top_pd = __top_pd,                                     \
+               .mem_pd_count = ARRAY_SIZE(__mem),                      \
+               .mem_pd = __mem,                                        \
+               .get_power = __get_power,                               \
+       }
+
+#define TOP_PD(__name, __top_pd, __mem, __get_power)                   \
+       {                                                               \
+               .name = __name,                                         \
+               .top_pd = __top_pd,                                     \
+               .mem_pd_count = ARRAY_SIZE(__mem),                      \
+               .mem_pd = __mem,                                        \
+               .get_power = __get_power,                               \
+       }
+
+#define MEM_PD(__name, __mem)                                          \
+       TOP_PD(__name, NULL, __mem, NULL)
+
+static bool pwrc_ee_get_power(struct meson_ee_pwrc_domain *pwrc_domain);
+
+static struct meson_ee_pwrc_domain_desc g12a_pwrc_domains[] = {
+       [PWRC_G12A_VPU_ID]  = VPU_PD("VPU", &g12a_pwrc_vpu, g12a_pwrc_mem_vpu,
+                                    pwrc_ee_get_power, 11, 2),
+       [PWRC_G12A_ETH_ID] = MEM_PD("ETH", g12a_pwrc_mem_eth),
+};
+
+static struct meson_ee_pwrc_domain_desc sm1_pwrc_domains[] = {
+       [PWRC_SM1_VPU_ID]  = VPU_PD("VPU", &sm1_pwrc_vpu, sm1_pwrc_mem_vpu,
+                                   pwrc_ee_get_power, 11, 2),
+       [PWRC_SM1_NNA_ID]  = TOP_PD("NNA", &sm1_pwrc_nna, sm1_pwrc_mem_nna,
+                                   pwrc_ee_get_power),
+       [PWRC_SM1_USB_ID]  = TOP_PD("USB", &sm1_pwrc_usb, sm1_pwrc_mem_usb,
+                                   pwrc_ee_get_power),
+       [PWRC_SM1_PCIE_ID] = TOP_PD("PCI", &sm1_pwrc_pci, sm1_pwrc_mem_pcie,
+                                   pwrc_ee_get_power),
+       [PWRC_SM1_GE2D_ID] = TOP_PD("GE2D", &sm1_pwrc_ge2d, sm1_pwrc_mem_ge2d,
+                                   pwrc_ee_get_power),
+       [PWRC_SM1_AUDIO_ID] = MEM_PD("AUDIO", sm1_pwrc_mem_audio),
+       [PWRC_SM1_ETH_ID] = MEM_PD("ETH", g12a_pwrc_mem_eth),
+};
+
+struct meson_ee_pwrc_domain {
+       struct generic_pm_domain base;
+       bool enabled;
+       struct meson_ee_pwrc *pwrc;
+       struct meson_ee_pwrc_domain_desc desc;
+       struct clk_bulk_data *clks;
+       int num_clks;
+       struct reset_control *rstc;
+       int num_rstc;
+};
+
+struct meson_ee_pwrc {
+       struct regmap *regmap_ao;
+       struct regmap *regmap_hhi;
+       struct meson_ee_pwrc_domain *domains;
+       struct genpd_onecell_data xlate;
+};
+
+static bool pwrc_ee_get_power(struct meson_ee_pwrc_domain *pwrc_domain)
+{
+       u32 reg;
+
+       regmap_read(pwrc_domain->pwrc->regmap_ao,
+                   pwrc_domain->desc.top_pd->sleep_reg, &reg);
+
+       return (reg & pwrc_domain->desc.top_pd->sleep_mask);
+}
+
+static int meson_ee_pwrc_off(struct generic_pm_domain *domain)
+{
+       struct meson_ee_pwrc_domain *pwrc_domain =
+               container_of(domain, struct meson_ee_pwrc_domain, base);
+       int i;
+
+       if (pwrc_domain->desc.top_pd)
+               regmap_update_bits(pwrc_domain->pwrc->regmap_ao,
+                                  pwrc_domain->desc.top_pd->sleep_reg,
+                                  pwrc_domain->desc.top_pd->sleep_mask,
+                                  pwrc_domain->desc.top_pd->sleep_mask);
+       udelay(20);
+
+       for (i = 0 ; i < pwrc_domain->desc.mem_pd_count ; ++i)
+               regmap_update_bits(pwrc_domain->pwrc->regmap_hhi,
+                                  pwrc_domain->desc.mem_pd[i].reg,
+                                  pwrc_domain->desc.mem_pd[i].mask,
+                                  pwrc_domain->desc.mem_pd[i].mask);
+
+       udelay(20);
+
+       if (pwrc_domain->desc.top_pd)
+               regmap_update_bits(pwrc_domain->pwrc->regmap_ao,
+                                  pwrc_domain->desc.top_pd->iso_reg,
+                                  pwrc_domain->desc.top_pd->iso_mask,
+                                  pwrc_domain->desc.top_pd->iso_mask);
+
+       if (pwrc_domain->num_clks) {
+               msleep(20);
+               clk_bulk_disable_unprepare(pwrc_domain->num_clks,
+                                          pwrc_domain->clks);
+       }
+
+       return 0;
+}
+
+static int meson_ee_pwrc_on(struct generic_pm_domain *domain)
+{
+       struct meson_ee_pwrc_domain *pwrc_domain =
+               container_of(domain, struct meson_ee_pwrc_domain, base);
+       int i, ret;
+
+       if (pwrc_domain->desc.top_pd)
+               regmap_update_bits(pwrc_domain->pwrc->regmap_ao,
+                                  pwrc_domain->desc.top_pd->sleep_reg,
+                                  pwrc_domain->desc.top_pd->sleep_mask, 0);
+       udelay(20);
+
+       for (i = 0 ; i < pwrc_domain->desc.mem_pd_count ; ++i)
+               regmap_update_bits(pwrc_domain->pwrc->regmap_hhi,
+                                  pwrc_domain->desc.mem_pd[i].reg,
+                                  pwrc_domain->desc.mem_pd[i].mask, 0);
+
+       udelay(20);
+
+       ret = reset_control_assert(pwrc_domain->rstc);
+       if (ret)
+               return ret;
+
+       if (pwrc_domain->desc.top_pd)
+               regmap_update_bits(pwrc_domain->pwrc->regmap_ao,
+                                  pwrc_domain->desc.top_pd->iso_reg,
+                                  pwrc_domain->desc.top_pd->iso_mask, 0);
+
+       ret = reset_control_deassert(pwrc_domain->rstc);
+       if (ret)
+               return ret;
+
+       return clk_bulk_prepare_enable(pwrc_domain->num_clks,
+                                      pwrc_domain->clks);
+}
+
+static int meson_ee_pwrc_init_domain(struct platform_device *pdev,
+                                    struct meson_ee_pwrc *pwrc,
+                                    struct meson_ee_pwrc_domain *dom)
+{
+       dom->pwrc = pwrc;
+       dom->num_rstc = dom->desc.reset_names_count;
+       dom->num_clks = dom->desc.clk_names_count;
+
+       if (dom->num_rstc) {
+               int count = reset_control_get_count(&pdev->dev);
+
+               if (count != dom->num_rstc)
+                       dev_warn(&pdev->dev, "Invalid resets count %d for domain %s\n",
+                                count, dom->desc.name);
+
+               dom->rstc = devm_reset_control_array_get(&pdev->dev, false,
+                                                        false);
+               if (IS_ERR(dom->rstc))
+                       return PTR_ERR(dom->rstc);
+       }
+
+       if (dom->num_clks) {
+               int ret = devm_clk_bulk_get_all(&pdev->dev, &dom->clks);
+               if (ret < 0)
+                       return ret;
+
+               if (dom->num_clks != ret) {
+                       dev_warn(&pdev->dev, "Invalid clocks count %d for domain %s\n",
+                                ret, dom->desc.name);
+                       dom->num_clks = ret;
+               }
+       }
+
+       dom->base.name = dom->desc.name;
+       dom->base.power_on = meson_ee_pwrc_on;
+       dom->base.power_off = meson_ee_pwrc_off;
+
+       /*
+         * TOFIX: This is a special case for the VPU power domain, which can
+        * be enabled previously by the bootloader. In this case the VPU
+         * pipeline may be functional but no driver maybe never attach
+         * to this power domain, and if the domain is disabled it could
+         * cause system errors. This is why the pm_domain_always_on_gov
+         * is used here.
+         * For the same reason, the clocks should be enabled in case
+         * we need to power the domain off, otherwise the internal clocks
+         * prepare/enable counters won't be in sync.
+         */
+       if (dom->num_clks && dom->desc.get_power && !dom->desc.get_power(dom)) {
+               int ret = clk_bulk_prepare_enable(dom->num_clks, dom->clks);
+               if (ret)
+                       return ret;
+
+               pm_genpd_init(&dom->base, &pm_domain_always_on_gov, false);
+       } else
+               pm_genpd_init(&dom->base, NULL,
+                             (dom->desc.get_power ?
+                              dom->desc.get_power(dom) : true));
+
+       return 0;
+}
+
+static int meson_ee_pwrc_probe(struct platform_device *pdev)
+{
+       const struct meson_ee_pwrc_domain_data *match;
+       struct regmap *regmap_ao, *regmap_hhi;
+       struct meson_ee_pwrc *pwrc;
+       int i, ret;
+
+       match = of_device_get_match_data(&pdev->dev);
+       if (!match) {
+               dev_err(&pdev->dev, "failed to get match data\n");
+               return -ENODEV;
+       }
+
+       pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL);
+       if (!pwrc)
+               return -ENOMEM;
+
+       pwrc->xlate.domains = devm_kcalloc(&pdev->dev, match->count,
+                                          sizeof(*pwrc->xlate.domains),
+                                          GFP_KERNEL);
+       if (!pwrc->xlate.domains)
+               return -ENOMEM;
+
+       pwrc->domains = devm_kcalloc(&pdev->dev, match->count,
+                                    sizeof(*pwrc->domains), GFP_KERNEL);
+       if (!pwrc->domains)
+               return -ENOMEM;
+
+       pwrc->xlate.num_domains = match->count;
+
+       regmap_hhi = syscon_node_to_regmap(of_get_parent(pdev->dev.of_node));
+       if (IS_ERR(regmap_hhi)) {
+               dev_err(&pdev->dev, "failed to get HHI regmap\n");
+               return PTR_ERR(regmap_hhi);
+       }
+
+       regmap_ao = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
+                                                   "amlogic,ao-sysctrl");
+       if (IS_ERR(regmap_ao)) {
+               dev_err(&pdev->dev, "failed to get AO regmap\n");
+               return PTR_ERR(regmap_ao);
+       }
+
+       pwrc->regmap_ao = regmap_ao;
+       pwrc->regmap_hhi = regmap_hhi;
+
+       platform_set_drvdata(pdev, pwrc);
+
+       for (i = 0 ; i < match->count ; ++i) {
+               struct meson_ee_pwrc_domain *dom = &pwrc->domains[i];
+
+               memcpy(&dom->desc, &match->domains[i], sizeof(dom->desc));
+
+               ret = meson_ee_pwrc_init_domain(pdev, pwrc, dom);
+               if (ret)
+                       return ret;
+
+               pwrc->xlate.domains[i] = &dom->base;
+       }
+
+       of_genpd_add_provider_onecell(pdev->dev.of_node, &pwrc->xlate);
+
+       return 0;
+}
+
+static void meson_ee_pwrc_shutdown(struct platform_device *pdev)
+{
+       struct meson_ee_pwrc *pwrc = platform_get_drvdata(pdev);
+       int i;
+
+       for (i = 0 ; i < pwrc->xlate.num_domains ; ++i) {
+               struct meson_ee_pwrc_domain *dom = &pwrc->domains[i];
+
+               if (dom->desc.get_power && !dom->desc.get_power(dom))
+                       meson_ee_pwrc_off(&dom->base);
+       }
+}
+
+static struct meson_ee_pwrc_domain_data meson_ee_g12a_pwrc_data = {
+       .count = ARRAY_SIZE(g12a_pwrc_domains),
+       .domains = g12a_pwrc_domains,
+};
+
+static struct meson_ee_pwrc_domain_data meson_ee_sm1_pwrc_data = {
+       .count = ARRAY_SIZE(sm1_pwrc_domains),
+       .domains = sm1_pwrc_domains,
+};
+
+static const struct of_device_id meson_ee_pwrc_match_table[] = {
+       {
+               .compatible = "amlogic,meson-g12a-pwrc",
+               .data = &meson_ee_g12a_pwrc_data,
+       },
+       {
+               .compatible = "amlogic,meson-sm1-pwrc",
+               .data = &meson_ee_sm1_pwrc_data,
+       },
+       { /* sentinel */ }
+};
+
+static struct platform_driver meson_ee_pwrc_driver = {
+       .probe = meson_ee_pwrc_probe,
+       .shutdown = meson_ee_pwrc_shutdown,
+       .driver = {
+               .name           = "meson_ee_pwrc",
+               .of_match_table = meson_ee_pwrc_match_table,
+       },
+};
+builtin_platform_driver(meson_ee_pwrc_driver);
index bca3495..6d0d04f 100644 (file)
@@ -39,6 +39,7 @@ static const struct meson_gx_soc_id {
        { "TXHD", 0x27 },
        { "G12A", 0x28 },
        { "G12B", 0x29 },
+       { "SM1", 0x2b },
 };
 
 static const struct meson_gx_package_id {
@@ -65,6 +66,8 @@ static const struct meson_gx_package_id {
        { "S905D2", 0x28, 0x10, 0xf0 },
        { "S905X2", 0x28, 0x40, 0xf0 },
        { "S922X", 0x29, 0x40, 0xf0 },
+       { "A311D", 0x29, 0x10, 0xf0 },
+       { "S905X3", 0x2b, 0x5, 0xf },
 };
 
 static inline unsigned int socinfo_to_major(u32 socinfo)
@@ -138,8 +141,10 @@ static int __init meson_gx_socinfo_init(void)
        }
 
        /* check if chip-id is available */
-       if (!of_property_read_bool(np, "amlogic,has-chip-id"))
+       if (!of_property_read_bool(np, "amlogic,has-chip-id")) {
+               of_node_put(np);
                return -ENODEV;
+       }
 
        /* node should be a syscon */
        regmap = syscon_node_to_regmap(np);
index 9168d8d..27243f7 100644 (file)
@@ -73,7 +73,7 @@ static u64 get_mc_fw_base_address(void)
 
        mcfbaregs = ioremap(mc_base_addr.start, resource_size(&mc_base_addr));
        if (!mcfbaregs) {
-               pr_err("could not map MC Firmaware Base registers\n");
+               pr_err("could not map MC Firmware Base registers\n");
                return 0;
        }
 
index b9539ef..518a8e0 100644 (file)
@@ -305,8 +305,6 @@ void dpaa2_io_service_deregister(struct dpaa2_io *service,
        list_del(&ctx->node);
        spin_unlock_irqrestore(&d->lock_notifications, irqflags);
 
-       if (dev)
-               device_link_remove(dev, d->dev);
 }
 EXPORT_SYMBOL_GPL(dpaa2_io_service_deregister);
 
index 1ef8068..34810f9 100644 (file)
@@ -102,6 +102,11 @@ static const struct fsl_soc_die_attr fsl_soc_die[] = {
          .svr          = 0x87360000,
          .mask         = 0xff3f0000,
        },
+       /* Die: LS1028A, SoC: LS1028A */
+       { .die          = "LS1028A",
+         .svr          = 0x870b0000,
+         .mask         = 0xff3f0000,
+       },
        { },
 };
 
@@ -224,6 +229,7 @@ static const struct of_device_id fsl_guts_of_match[] = {
        { .compatible = "fsl,ls1012a-dcfg", },
        { .compatible = "fsl,ls1046a-dcfg", },
        { .compatible = "fsl,lx2160a-dcfg", },
+       { .compatible = "fsl,ls1028a-dcfg", },
        {}
 };
 MODULE_DEVICE_TABLE(of, fsl_guts_of_match);
index f84ab59..f4fb527 100644 (file)
@@ -635,30 +635,31 @@ int bman_p_irqsource_add(struct bman_portal *p, u32 bits)
        return 0;
 }
 
-static int bm_shutdown_pool(u32 bpid)
+int bm_shutdown_pool(u32 bpid)
 {
+       int err = 0;
        struct bm_mc_command *bm_cmd;
        union bm_mc_result *bm_res;
 
+
+       struct bman_portal *p = get_affine_portal();
        while (1) {
-               struct bman_portal *p = get_affine_portal();
                /* Acquire buffers until empty */
                bm_cmd = bm_mc_start(&p->p);
                bm_cmd->bpid = bpid;
                bm_mc_commit(&p->p, BM_MCC_VERB_CMD_ACQUIRE | 1);
                if (!bm_mc_result_timeout(&p->p, &bm_res)) {
-                       put_affine_portal();
                        pr_crit("BMan Acquire Command timedout\n");
-                       return -ETIMEDOUT;
+                       err = -ETIMEDOUT;
+                       goto done;
                }
                if (!(bm_res->verb & BM_MCR_VERB_ACQUIRE_BUFCOUNT)) {
-                       put_affine_portal();
                        /* Pool is empty */
-                       return 0;
+                       goto done;
                }
-               put_affine_portal();
        }
-
+done:
+       put_affine_portal();
        return 0;
 }
 
index 7c3cc96..cb24a08 100644 (file)
@@ -97,17 +97,40 @@ static void bm_get_version(u16 *id, u8 *major, u8 *minor)
 /* signal transactions for FBPRs with higher priority */
 #define FBPR_AR_RPRIO_HI BIT(30)
 
-static void bm_set_memory(u64 ba, u32 size)
+/* Track if probe has occurred and if cleanup is required */
+static int __bman_probed;
+static int __bman_requires_cleanup;
+
+
+static int bm_set_memory(u64 ba, u32 size)
 {
+       u32 bar, bare;
        u32 exp = ilog2(size);
        /* choke if size isn't within range */
        DPAA_ASSERT(size >= 4096 && size <= 1024*1024*1024 &&
                   is_power_of_2(size));
        /* choke if '[e]ba' has lower-alignment than 'size' */
        DPAA_ASSERT(!(ba & (size - 1)));
+
+       /* Check to see if BMan has already been initialized */
+       bar = bm_ccsr_in(REG_FBPR_BAR);
+       if (bar) {
+               /* Maker sure ba == what was programmed) */
+               bare = bm_ccsr_in(REG_FBPR_BARE);
+               if (bare != upper_32_bits(ba) || bar != lower_32_bits(ba)) {
+                       pr_err("Attempted to reinitialize BMan with different BAR, got 0x%llx read BARE=0x%x BAR=0x%x\n",
+                              ba, bare, bar);
+                       return -ENOMEM;
+               }
+               pr_info("BMan BAR already configured\n");
+               __bman_requires_cleanup = 1;
+               return 1;
+       }
+
        bm_ccsr_out(REG_FBPR_BARE, upper_32_bits(ba));
        bm_ccsr_out(REG_FBPR_BAR, lower_32_bits(ba));
        bm_ccsr_out(REG_FBPR_AR, exp - 1);
+       return 0;
 }
 
 /*
@@ -120,7 +143,6 @@ static void bm_set_memory(u64 ba, u32 size)
  */
 static dma_addr_t fbpr_a;
 static size_t fbpr_sz;
-static int __bman_probed;
 
 static int bman_fbpr(struct reserved_mem *rmem)
 {
@@ -173,6 +195,16 @@ int bman_is_probed(void)
 }
 EXPORT_SYMBOL_GPL(bman_is_probed);
 
+int bman_requires_cleanup(void)
+{
+       return __bman_requires_cleanup;
+}
+
+void bman_done_cleanup(void)
+{
+       __bman_requires_cleanup = 0;
+}
+
 static int fsl_bman_probe(struct platform_device *pdev)
 {
        int ret, err_irq;
index cf4f10d..923c440 100644 (file)
@@ -100,7 +100,7 @@ static int bman_portal_probe(struct platform_device *pdev)
        struct device_node *node = dev->of_node;
        struct bm_portal_config *pcfg;
        struct resource *addr_phys[2];
-       int irq, cpu, err;
+       int irq, cpu, err, i;
 
        err = bman_is_probed();
        if (!err)
@@ -135,10 +135,8 @@ static int bman_portal_probe(struct platform_device *pdev)
        pcfg->cpu = -1;
 
        irq = platform_get_irq(pdev, 0);
-       if (irq <= 0) {
-               dev_err(dev, "Can't get %pOF IRQ'\n", node);
+       if (irq <= 0)
                goto err_ioremap1;
-       }
        pcfg->irq = irq;
 
        pcfg->addr_virt_ce = memremap(addr_phys[0]->start,
@@ -178,6 +176,22 @@ static int bman_portal_probe(struct platform_device *pdev)
        if (!cpu_online(cpu))
                bman_offline_cpu(cpu);
 
+       if (__bman_portals_probed == 1 && bman_requires_cleanup()) {
+               /*
+                * BMan wasn't reset prior to boot (Kexec for example)
+                * Empty all the buffer pools so they are in reset state
+                */
+               for (i = 0; i < BM_POOL_MAX; i++) {
+                       err =  bm_shutdown_pool(i);
+                       if (err) {
+                               dev_err(dev, "Failed to shutdown bpool %d\n",
+                                       i);
+                               goto err_portal_init;
+                       }
+               }
+               bman_done_cleanup();
+       }
+
        return 0;
 
 err_portal_init:
index 751ce90..aa3981e 100644 (file)
@@ -76,3 +76,8 @@ int bman_p_irqsource_add(struct bman_portal *p, u32 bits);
 
 const struct bm_portal_config *
 bman_get_bm_portal_config(const struct bman_portal *portal);
+
+int bman_requires_cleanup(void);
+void bman_done_cleanup(void);
+
+int bm_shutdown_pool(u32 bpid);
index e6d48dc..9dd8bb5 100644 (file)
 int qbman_init_private_mem(struct device *dev, int idx, dma_addr_t *addr,
                                size_t *size)
 {
-       int ret;
        struct device_node *mem_node;
-       u64 size64;
+       struct reserved_mem *rmem;
+       struct property *prop;
+       int len, err;
+       __be32 *res_array;
 
-       ret = of_reserved_mem_device_init_by_idx(dev, dev->of_node, idx);
-       if (ret) {
-               dev_err(dev,
-                       "of_reserved_mem_device_init_by_idx(%d) failed 0x%x\n",
-                       idx, ret);
-               return -ENODEV;
-       }
-       mem_node = of_parse_phandle(dev->of_node, "memory-region", 0);
-       if (mem_node) {
-               ret = of_property_read_u64(mem_node, "size", &size64);
-               if (ret) {
-                       dev_err(dev, "of_address_to_resource fails 0x%x\n",
-                               ret);
-                       return -ENODEV;
-               }
-               *size = size64;
-       } else {
+       mem_node = of_parse_phandle(dev->of_node, "memory-region", idx);
+       if (!mem_node) {
                dev_err(dev, "No memory-region found for index %d\n", idx);
                return -ENODEV;
        }
 
-       if (!dma_alloc_coherent(dev, *size, addr, 0)) {
-               dev_err(dev, "DMA Alloc memory failed\n");
+       rmem = of_reserved_mem_lookup(mem_node);
+       if (!rmem) {
+               dev_err(dev, "of_reserved_mem_lookup() returned NULL\n");
                return -ENODEV;
        }
+       *addr = rmem->base;
+       *size = rmem->size;
 
        /*
-        * Disassociate the reserved memory area from the device
-        * because a device can only have one DMA memory area. This
-        * should be fine since the memory is allocated and initialized
-        * and only ever accessed by the QBMan device from now on
+        * Check if the reg property exists - if not insert the node
+        * so upon kexec() the same memory region address will be preserved.
+        * This is needed because QBMan HW does not allow the base address/
+        * size to be modified once set.
         */
-       of_reserved_mem_device_release(dev);
+       prop = of_find_property(mem_node, "reg", &len);
+       if (!prop) {
+               prop = devm_kzalloc(dev, sizeof(*prop), GFP_KERNEL);
+               if (!prop)
+                       return -ENOMEM;
+               prop->value = res_array = devm_kzalloc(dev, sizeof(__be32) * 4,
+                                                      GFP_KERNEL);
+               if (!prop->value)
+                       return -ENOMEM;
+               res_array[0] = cpu_to_be32(upper_32_bits(*addr));
+               res_array[1] = cpu_to_be32(lower_32_bits(*addr));
+               res_array[2] = cpu_to_be32(upper_32_bits(*size));
+               res_array[3] = cpu_to_be32(lower_32_bits(*size));
+               prop->length = sizeof(__be32) * 4;
+               prop->name = devm_kstrdup(dev, "reg", GFP_KERNEL);
+               if (!prop->name)
+                       return -ENOMEM;
+               err = of_add_property(mem_node, prop);
+               if (err)
+                       return err;
+       }
+
        return 0;
 }
index 636f83f..bf68d86 100644 (file)
@@ -1018,6 +1018,20 @@ static inline void put_affine_portal(void)
        put_cpu_var(qman_affine_portal);
 }
 
+
+static inline struct qman_portal *get_portal_for_channel(u16 channel)
+{
+       int i;
+
+       for (i = 0; i < num_possible_cpus(); i++) {
+               if (affine_portals[i] &&
+                   affine_portals[i]->config->channel == channel)
+                       return affine_portals[i];
+       }
+
+       return NULL;
+}
+
 static struct workqueue_struct *qm_portal_wq;
 
 int qman_dqrr_set_ithresh(struct qman_portal *portal, u8 ithresh)
@@ -1070,6 +1084,20 @@ int qman_wq_alloc(void)
        return 0;
 }
 
+
+void qman_enable_irqs(void)
+{
+       int i;
+
+       for (i = 0; i < num_possible_cpus(); i++) {
+               if (affine_portals[i]) {
+                       qm_out(&affine_portals[i]->p, QM_REG_ISR, 0xffffffff);
+                       qm_out(&affine_portals[i]->p, QM_REG_IIR, 0);
+               }
+
+       }
+}
+
 /*
  * This is what everything can wait on, even if it migrates to a different cpu
  * to the one whose affine portal it is waiting on.
@@ -1164,6 +1192,7 @@ static int drain_mr_fqrni(struct qm_portal *p)
 {
        const union qm_mr_entry *msg;
 loop:
+       qm_mr_pvb_update(p);
        msg = qm_mr_current(p);
        if (!msg) {
                /*
@@ -1180,7 +1209,8 @@ loop:
                 * entries well before the ring has been fully consumed, so
                 * we're being *really* paranoid here.
                 */
-               msleep(1);
+               mdelay(1);
+               qm_mr_pvb_update(p);
                msg = qm_mr_current(p);
                if (!msg)
                        return 0;
@@ -1267,8 +1297,8 @@ static int qman_create_portal(struct qman_portal *portal,
        qm_out(p, QM_REG_ISDR, isdr);
        portal->irq_sources = 0;
        qm_out(p, QM_REG_IER, 0);
-       qm_out(p, QM_REG_ISR, 0xffffffff);
        snprintf(portal->irqname, MAX_IRQNAME, IRQNAME, c->cpu);
+       qm_out(p, QM_REG_IIR, 1);
        if (request_irq(c->irq, portal_isr, 0, portal->irqname, portal)) {
                dev_err(c->dev, "request_irq() failed\n");
                goto fail_irq;
@@ -1288,7 +1318,7 @@ static int qman_create_portal(struct qman_portal *portal,
        isdr &= ~(QM_PIRQ_DQRI | QM_PIRQ_MRI);
        qm_out(p, QM_REG_ISDR, isdr);
        if (qm_dqrr_current(p)) {
-               dev_err(c->dev, "DQRR unclean\n");
+               dev_dbg(c->dev, "DQRR unclean\n");
                qm_dqrr_cdc_consume_n(p, 0xffff);
        }
        if (qm_mr_current(p) && drain_mr_fqrni(p)) {
@@ -1301,8 +1331,10 @@ static int qman_create_portal(struct qman_portal *portal,
        }
        /* Success */
        portal->config = c;
+       qm_out(p, QM_REG_ISR, 0xffffffff);
        qm_out(p, QM_REG_ISDR, 0);
-       qm_out(p, QM_REG_IIR, 0);
+       if (!qman_requires_cleanup())
+               qm_out(p, QM_REG_IIR, 0);
        /* Write a sane SDQCR */
        qm_dqrr_sdqcr_set(p, portal->sdqcr);
        return 0;
@@ -2581,9 +2613,9 @@ static int _qm_dqrr_consume_and_match(struct qm_portal *p, u32 fqid, int s,
 #define qm_dqrr_drain_nomatch(p) \
        _qm_dqrr_consume_and_match(p, 0, 0, false)
 
-static int qman_shutdown_fq(u32 fqid)
+int qman_shutdown_fq(u32 fqid)
 {
-       struct qman_portal *p;
+       struct qman_portal *p, *channel_portal;
        struct device *dev;
        union qm_mc_command *mcc;
        union qm_mc_result *mcr;
@@ -2623,17 +2655,28 @@ static int qman_shutdown_fq(u32 fqid)
        channel = qm_fqd_get_chan(&mcr->queryfq.fqd);
        wq = qm_fqd_get_wq(&mcr->queryfq.fqd);
 
+       if (channel < qm_channel_pool1) {
+               channel_portal = get_portal_for_channel(channel);
+               if (channel_portal == NULL) {
+                       dev_err(dev, "Can't find portal for dedicated channel 0x%x\n",
+                               channel);
+                       ret = -EIO;
+                       goto out;
+               }
+       } else
+               channel_portal = p;
+
        switch (state) {
        case QM_MCR_NP_STATE_TEN_SCHED:
        case QM_MCR_NP_STATE_TRU_SCHED:
        case QM_MCR_NP_STATE_ACTIVE:
        case QM_MCR_NP_STATE_PARKED:
                orl_empty = 0;
-               mcc = qm_mc_start(&p->p);
+               mcc = qm_mc_start(&channel_portal->p);
                qm_fqid_set(&mcc->fq, fqid);
-               qm_mc_commit(&p->p, QM_MCC_VERB_ALTER_RETIRE);
-               if (!qm_mc_result_timeout(&p->p, &mcr)) {
-                       dev_err(dev, "QUERYFQ_NP timeout\n");
+               qm_mc_commit(&channel_portal->p, QM_MCC_VERB_ALTER_RETIRE);
+               if (!qm_mc_result_timeout(&channel_portal->p, &mcr)) {
+                       dev_err(dev, "ALTER_RETIRE timeout\n");
                        ret = -ETIMEDOUT;
                        goto out;
                }
@@ -2641,6 +2684,9 @@ static int qman_shutdown_fq(u32 fqid)
                            QM_MCR_VERB_ALTER_RETIRE);
                res = mcr->result; /* Make a copy as we reuse MCR below */
 
+               if (res == QM_MCR_RESULT_OK)
+                       drain_mr_fqrni(&channel_portal->p);
+
                if (res == QM_MCR_RESULT_PENDING) {
                        /*
                         * Need to wait for the FQRN in the message ring, which
@@ -2670,21 +2716,25 @@ static int qman_shutdown_fq(u32 fqid)
                        }
                        /* Set the sdqcr to drain this channel */
                        if (channel < qm_channel_pool1)
-                               qm_dqrr_sdqcr_set(&p->p,
+                               qm_dqrr_sdqcr_set(&channel_portal->p,
                                                  QM_SDQCR_TYPE_ACTIVE |
                                                  QM_SDQCR_CHANNELS_DEDICATED);
                        else
-                               qm_dqrr_sdqcr_set(&p->p,
+                               qm_dqrr_sdqcr_set(&channel_portal->p,
                                                  QM_SDQCR_TYPE_ACTIVE |
                                                  QM_SDQCR_CHANNELS_POOL_CONV
                                                  (channel));
                        do {
                                /* Keep draining DQRR while checking the MR*/
-                               qm_dqrr_drain_nomatch(&p->p);
+                               qm_dqrr_drain_nomatch(&channel_portal->p);
                                /* Process message ring too */
-                               found_fqrn = qm_mr_drain(&p->p, FQRN);
+                               found_fqrn = qm_mr_drain(&channel_portal->p,
+                                                        FQRN);
                                cpu_relax();
                        } while (!found_fqrn);
+                       /* Restore SDQCR */
+                       qm_dqrr_sdqcr_set(&channel_portal->p,
+                                         channel_portal->sdqcr);
 
                }
                if (res != QM_MCR_RESULT_OK &&
@@ -2715,9 +2765,8 @@ static int qman_shutdown_fq(u32 fqid)
                                 * Wait for a dequeue and process the dequeues,
                                 * making sure to empty the ring completely
                                 */
-                       } while (qm_dqrr_drain_wait(&p->p, fqid, FQ_EMPTY));
+                       } while (!qm_dqrr_drain_wait(&p->p, fqid, FQ_EMPTY));
                }
-               qm_dqrr_sdqcr_set(&p->p, 0);
 
                while (!orl_empty) {
                        /* Wait for the ORL to have been completely drained */
@@ -2754,7 +2803,7 @@ static int qman_shutdown_fq(u32 fqid)
 
                DPAA_ASSERT((mcr->verb & QM_MCR_VERB_MASK) ==
                            QM_MCR_VERB_ALTER_OOS);
-               if (mcr->result) {
+               if (mcr->result != QM_MCR_RESULT_OK) {
                        dev_err(dev, "OOS fail: FQ 0x%x (0x%x)\n",
                                fqid, mcr->result);
                        ret = -EIO;
index a6bb430..157659f 100644 (file)
@@ -274,6 +274,7 @@ static u32 __iomem *qm_ccsr_start;
 /* A SDQCR mask comprising all the available/visible pool channels */
 static u32 qm_pools_sdqcr;
 static int __qman_probed;
+static int  __qman_requires_cleanup;
 
 static inline u32 qm_ccsr_in(u32 offset)
 {
@@ -340,19 +341,55 @@ static void qm_get_version(u16 *id, u8 *major, u8 *minor)
 }
 
 #define PFDR_AR_EN             BIT(31)
-static void qm_set_memory(enum qm_memory memory, u64 ba, u32 size)
+static int qm_set_memory(enum qm_memory memory, u64 ba, u32 size)
 {
+       void *ptr;
        u32 offset = (memory == qm_memory_fqd) ? REG_FQD_BARE : REG_PFDR_BARE;
        u32 exp = ilog2(size);
+       u32 bar, bare;
 
        /* choke if size isn't within range */
        DPAA_ASSERT((size >= 4096) && (size <= 1024*1024*1024) &&
                    is_power_of_2(size));
        /* choke if 'ba' has lower-alignment than 'size' */
        DPAA_ASSERT(!(ba & (size - 1)));
+
+       /* Check to see if QMan has already been initialized */
+       bar = qm_ccsr_in(offset + REG_offset_BAR);
+       if (bar) {
+               /* Maker sure ba == what was programmed) */
+               bare = qm_ccsr_in(offset);
+               if (bare != upper_32_bits(ba) || bar != lower_32_bits(ba)) {
+                       pr_err("Attempted to reinitialize QMan with different BAR, got 0x%llx read BARE=0x%x BAR=0x%x\n",
+                              ba, bare, bar);
+                       return -ENOMEM;
+               }
+               __qman_requires_cleanup = 1;
+               /* Return 1 to indicate memory was previously programmed */
+               return 1;
+       }
+       /* Need to temporarily map the area to make sure it is zeroed */
+       ptr = memremap(ba, size, MEMREMAP_WB);
+       if (!ptr) {
+               pr_crit("memremap() of QMan private memory failed\n");
+               return -ENOMEM;
+       }
+       memset(ptr, 0, size);
+
+#ifdef CONFIG_PPC
+       /*
+        * PPC doesn't appear to flush the cache on memunmap() but the
+        * cache must be flushed since QMan does non coherent accesses
+        * to this memory
+        */
+       flush_dcache_range((unsigned long) ptr, (unsigned long) ptr+size);
+#endif
+       memunmap(ptr);
+
        qm_ccsr_out(offset, upper_32_bits(ba));
        qm_ccsr_out(offset + REG_offset_BAR, lower_32_bits(ba));
        qm_ccsr_out(offset + REG_offset_AR, PFDR_AR_EN | (exp - 1));
+       return 0;
 }
 
 static void qm_set_pfdr_threshold(u32 th, u8 k)
@@ -455,7 +492,7 @@ RESERVEDMEM_OF_DECLARE(qman_pfdr, "fsl,qman-pfdr", qman_pfdr);
 
 #endif
 
-static unsigned int qm_get_fqid_maxcnt(void)
+unsigned int qm_get_fqid_maxcnt(void)
 {
        return fqd_sz / 64;
 }
@@ -571,12 +608,19 @@ static int qman_init_ccsr(struct device *dev)
        int i, err;
 
        /* FQD memory */
-       qm_set_memory(qm_memory_fqd, fqd_a, fqd_sz);
+       err = qm_set_memory(qm_memory_fqd, fqd_a, fqd_sz);
+       if (err < 0)
+               return err;
        /* PFDR memory */
-       qm_set_memory(qm_memory_pfdr, pfdr_a, pfdr_sz);
-       err = qm_init_pfdr(dev, 8, pfdr_sz / 64 - 8);
-       if (err)
+       err = qm_set_memory(qm_memory_pfdr, pfdr_a, pfdr_sz);
+       if (err < 0)
                return err;
+       /* Only initialize PFDRs if the QMan was not initialized before */
+       if (err == 0) {
+               err = qm_init_pfdr(dev, 8, pfdr_sz / 64 - 8);
+               if (err)
+                       return err;
+       }
        /* thresholds */
        qm_set_pfdr_threshold(512, 64);
        qm_set_sfdr_threshold(128);
@@ -693,6 +737,18 @@ int qman_is_probed(void)
 }
 EXPORT_SYMBOL_GPL(qman_is_probed);
 
+int qman_requires_cleanup(void)
+{
+       return __qman_requires_cleanup;
+}
+
+void qman_done_cleanup(void)
+{
+       qman_enable_irqs();
+       __qman_requires_cleanup = 0;
+}
+
+
 static int fsl_qman_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
index e2186b6..5685b67 100644 (file)
@@ -233,7 +233,7 @@ static int qman_portal_probe(struct platform_device *pdev)
        struct device_node *node = dev->of_node;
        struct qm_portal_config *pcfg;
        struct resource *addr_phys[2];
-       int irq, cpu, err;
+       int irq, cpu, err, i;
        u32 val;
 
        err = qman_is_probed();
@@ -275,10 +275,8 @@ static int qman_portal_probe(struct platform_device *pdev)
        pcfg->channel = val;
        pcfg->cpu = -1;
        irq = platform_get_irq(pdev, 0);
-       if (irq <= 0) {
-               dev_err(dev, "Can't get %pOF IRQ\n", node);
+       if (irq <= 0)
                goto err_ioremap1;
-       }
        pcfg->irq = irq;
 
        pcfg->addr_virt_ce = memremap(addr_phys[0]->start,
@@ -325,6 +323,22 @@ static int qman_portal_probe(struct platform_device *pdev)
        if (!cpu_online(cpu))
                qman_offline_cpu(cpu);
 
+       if (__qman_portals_probed == 1 && qman_requires_cleanup()) {
+               /*
+                * QMan wasn't reset prior to boot (Kexec for example)
+                * Empty all the frame queues so they are in reset state
+                */
+               for (i = 0; i < qm_get_fqid_maxcnt(); i++) {
+                       err =  qman_shutdown_fq(i);
+                       if (err) {
+                               dev_err(dev, "Failed to shutdown frame queue %d\n",
+                                       i);
+                               goto err_portal_init;
+                       }
+               }
+               qman_done_cleanup();
+       }
+
        return 0;
 
 err_portal_init:
index 0451571..fd1cf54 100644 (file)
@@ -272,3 +272,11 @@ extern struct qman_portal *affine_portals[NR_CPUS];
 extern struct qman_portal *qman_dma_portal;
 const struct qm_portal_config *qman_get_qm_portal_config(
                                                struct qman_portal *portal);
+
+unsigned int qm_get_fqid_maxcnt(void);
+
+int qman_shutdown_fq(u32 fqid);
+
+int qman_requires_cleanup(void);
+void qman_done_cleanup(void);
+void qman_enable_irqs(void);
index c9519e6..417df7e 100644 (file)
@@ -10,6 +10,7 @@
  * General Purpose functions for the global management of the
  * QUICC Engine (QE).
  */
+#include <linux/bitmap.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -39,29 +40,32 @@ static DEFINE_SPINLOCK(qe_lock);
 DEFINE_SPINLOCK(cmxgcr_lock);
 EXPORT_SYMBOL(cmxgcr_lock);
 
-/* QE snum state */
-enum qe_snum_state {
-       QE_SNUM_STATE_USED,
-       QE_SNUM_STATE_FREE
-};
-
-/* QE snum */
-struct qe_snum {
-       u8 num;
-       enum qe_snum_state state;
-};
-
 /* We allocate this here because it is used almost exclusively for
  * the communication processor devices.
  */
 struct qe_immap __iomem *qe_immr;
 EXPORT_SYMBOL(qe_immr);
 
-static struct qe_snum snums[QE_NUM_OF_SNUM];   /* Dynamically allocated SNUMs */
+static u8 snums[QE_NUM_OF_SNUM];       /* Dynamically allocated SNUMs */
+static DECLARE_BITMAP(snum_state, QE_NUM_OF_SNUM);
 static unsigned int qe_num_of_snum;
 
 static phys_addr_t qebase = -1;
 
+static struct device_node *qe_get_device_node(void)
+{
+       struct device_node *qe;
+
+       /*
+        * Newer device trees have an "fsl,qe" compatible property for the QE
+        * node, but we still need to support older device trees.
+        */
+       qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
+       if (qe)
+               return qe;
+       return of_find_node_by_type(NULL, "qe");
+}
+
 static phys_addr_t get_qe_base(void)
 {
        struct device_node *qe;
@@ -71,12 +75,9 @@ static phys_addr_t get_qe_base(void)
        if (qebase != -1)
                return qebase;
 
-       qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
-       if (!qe) {
-               qe = of_find_node_by_type(NULL, "qe");
-               if (!qe)
-                       return qebase;
-       }
+       qe = qe_get_device_node();
+       if (!qe)
+               return qebase;
 
        ret = of_address_to_resource(qe, 0, &res);
        if (!ret)
@@ -170,12 +171,9 @@ unsigned int qe_get_brg_clk(void)
        if (brg_clk)
                return brg_clk;
 
-       qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
-       if (!qe) {
-               qe = of_find_node_by_type(NULL, "qe");
-               if (!qe)
-                       return brg_clk;
-       }
+       qe = qe_get_device_node();
+       if (!qe)
+               return brg_clk;
 
        prop = of_get_property(qe, "brg-frequency", &size);
        if (prop && size == sizeof(*prop))
@@ -281,7 +279,6 @@ EXPORT_SYMBOL(qe_clock_source);
  */
 static void qe_snums_init(void)
 {
-       int i;
        static const u8 snum_init_76[] = {
                0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
                0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
@@ -302,19 +299,39 @@ static void qe_snums_init(void)
                0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
                0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
        };
-       static const u8 *snum_init;
+       struct device_node *qe;
+       const u8 *snum_init;
+       int i;
 
-       qe_num_of_snum = qe_get_num_of_snums();
+       bitmap_zero(snum_state, QE_NUM_OF_SNUM);
+       qe_num_of_snum = 28; /* The default number of snum for threads is 28 */
+       qe = qe_get_device_node();
+       if (qe) {
+               i = of_property_read_variable_u8_array(qe, "fsl,qe-snums",
+                                                      snums, 1, QE_NUM_OF_SNUM);
+               if (i > 0) {
+                       of_node_put(qe);
+                       qe_num_of_snum = i;
+                       return;
+               }
+               /*
+                * Fall back to legacy binding of using the value of
+                * fsl,qe-num-snums to choose one of the static arrays
+                * above.
+                */
+               of_property_read_u32(qe, "fsl,qe-num-snums", &qe_num_of_snum);
+               of_node_put(qe);
+       }
 
-       if (qe_num_of_snum == 76)
+       if (qe_num_of_snum == 76) {
                snum_init = snum_init_76;
-       else
+       } else if (qe_num_of_snum == 28 || qe_num_of_snum == 46) {
                snum_init = snum_init_46;
-
-       for (i = 0; i < qe_num_of_snum; i++) {
-               snums[i].num = snum_init[i];
-               snums[i].state = QE_SNUM_STATE_FREE;
+       } else {
+               pr_err("QE: unsupported value of fsl,qe-num-snums: %u\n", qe_num_of_snum);
+               return;
        }
+       memcpy(snums, snum_init, qe_num_of_snum);
 }
 
 int qe_get_snum(void)
@@ -324,12 +341,10 @@ int qe_get_snum(void)
        int i;
 
        spin_lock_irqsave(&qe_lock, flags);
-       for (i = 0; i < qe_num_of_snum; i++) {
-               if (snums[i].state == QE_SNUM_STATE_FREE) {
-                       snums[i].state = QE_SNUM_STATE_USED;
-                       snum = snums[i].num;
-                       break;
-               }
+       i = find_first_zero_bit(snum_state, qe_num_of_snum);
+       if (i < qe_num_of_snum) {
+               set_bit(i, snum_state);
+               snum = snums[i];
        }
        spin_unlock_irqrestore(&qe_lock, flags);
 
@@ -339,14 +354,10 @@ EXPORT_SYMBOL(qe_get_snum);
 
 void qe_put_snum(u8 snum)
 {
-       int i;
+       const u8 *p = memchr(snums, snum, qe_num_of_snum);
 
-       for (i = 0; i < qe_num_of_snum; i++) {
-               if (snums[i].num == snum) {
-                       snums[i].state = QE_SNUM_STATE_FREE;
-                       break;
-               }
-       }
+       if (p)
+               clear_bit(p - snums, snum_state);
 }
 EXPORT_SYMBOL(qe_put_snum);
 
@@ -572,16 +583,9 @@ struct qe_firmware_info *qe_get_firmware_info(void)
 
        initialized = 1;
 
-       /*
-        * Newer device trees have an "fsl,qe" compatible property for the QE
-        * node, but we still need to support older device trees.
-       */
-       qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
-       if (!qe) {
-               qe = of_find_node_by_type(NULL, "qe");
-               if (!qe)
-                       return NULL;
-       }
+       qe = qe_get_device_node();
+       if (!qe)
+               return NULL;
 
        /* Find the 'firmware' child node */
        fw = of_get_child_by_name(qe, "firmware");
@@ -627,16 +631,9 @@ unsigned int qe_get_num_of_risc(void)
        unsigned int num_of_risc = 0;
        const u32 *prop;
 
-       qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
-       if (!qe) {
-               /* Older devices trees did not have an "fsl,qe"
-                * compatible property, so we need to look for
-                * the QE node by name.
-                */
-               qe = of_find_node_by_type(NULL, "qe");
-               if (!qe)
-                       return num_of_risc;
-       }
+       qe = qe_get_device_node();
+       if (!qe)
+               return num_of_risc;
 
        prop = of_get_property(qe, "fsl,qe-num-riscs", &size);
        if (prop && size == sizeof(*prop))
@@ -650,37 +647,7 @@ EXPORT_SYMBOL(qe_get_num_of_risc);
 
 unsigned int qe_get_num_of_snums(void)
 {
-       struct device_node *qe;
-       int size;
-       unsigned int num_of_snums;
-       const u32 *prop;
-
-       num_of_snums = 28; /* The default number of snum for threads is 28 */
-       qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
-       if (!qe) {
-               /* Older devices trees did not have an "fsl,qe"
-                * compatible property, so we need to look for
-                * the QE node by name.
-                */
-               qe = of_find_node_by_type(NULL, "qe");
-               if (!qe)
-                       return num_of_snums;
-       }
-
-       prop = of_get_property(qe, "fsl,qe-num-snums", &size);
-       if (prop && size == sizeof(*prop)) {
-               num_of_snums = *prop;
-               if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) {
-                       /* No QE ever has fewer than 28 SNUMs */
-                       pr_err("QE: number of snum is invalid\n");
-                       of_node_put(qe);
-                       return -EINVAL;
-               }
-       }
-
-       of_node_put(qe);
-
-       return num_of_snums;
+       return qe_num_of_snum;
 }
 EXPORT_SYMBOL(qe_get_num_of_snums);
 
index 31b8d00..b0dffb0 100644 (file)
@@ -198,7 +198,7 @@ static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
                err = regulator_disable(domain->regulator);
                if (err)
                        dev_err(domain->dev,
-                               "failed to disable regulator: %d\n", ret);
+                               "failed to disable regulator: %d\n", err);
                /* Preserve earlier error code */
                ret = ret ?: err;
        }
index 676f612..50831eb 100644 (file)
@@ -27,6 +27,40 @@ struct imx_sc_msg_misc_get_soc_id {
        } data;
 } __packed;
 
+struct imx_sc_msg_misc_get_soc_uid {
+       struct imx_sc_rpc_msg hdr;
+       u32 uid_low;
+       u32 uid_high;
+} __packed;
+
+static ssize_t soc_uid_show(struct device *dev,
+                           struct device_attribute *attr, char *buf)
+{
+       struct imx_sc_msg_misc_get_soc_uid msg;
+       struct imx_sc_rpc_msg *hdr = &msg.hdr;
+       u64 soc_uid;
+       int ret;
+
+       hdr->ver = IMX_SC_RPC_VERSION;
+       hdr->svc = IMX_SC_RPC_SVC_MISC;
+       hdr->func = IMX_SC_MISC_FUNC_UNIQUE_ID;
+       hdr->size = 1;
+
+       ret = imx_scu_call_rpc(soc_ipc_handle, &msg, false);
+       if (ret) {
+               pr_err("%s: get soc uid failed, ret %d\n", __func__, ret);
+               return ret;
+       }
+
+       soc_uid = msg.uid_high;
+       soc_uid <<= 32;
+       soc_uid |= msg.uid_low;
+
+       return sprintf(buf, "%016llX\n", soc_uid);
+}
+
+static DEVICE_ATTR_RO(soc_uid);
+
 static int imx_scu_soc_id(void)
 {
        struct imx_sc_msg_misc_get_soc_id msg;
@@ -102,6 +136,11 @@ static int imx_scu_soc_probe(struct platform_device *pdev)
                goto free_revision;
        }
 
+       ret = device_create_file(soc_device_to_device(soc_dev),
+                                &dev_attr_soc_uid);
+       if (ret)
+               goto free_revision;
+
        return 0;
 
 free_revision:
index f924ae8..b983157 100644 (file)
@@ -16,6 +16,9 @@
 #define IMX8MQ_SW_INFO_B1              0x40
 #define IMX8MQ_SW_MAGIC_B1             0xff0055aa
 
+#define OCOTP_UID_LOW                  0x410
+#define OCOTP_UID_HIGH                 0x420
+
 /* Same as ANADIG_DIGPROG_IMX7D */
 #define ANADIG_DIGPROG_IMX8MM  0x800
 
@@ -24,6 +27,16 @@ struct imx8_soc_data {
        u32 (*soc_revision)(void);
 };
 
+static u64 soc_uid;
+
+static ssize_t soc_uid_show(struct device *dev,
+                           struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%016llX\n", soc_uid);
+}
+
+static DEVICE_ATTR_RO(soc_uid);
+
 static u32 __init imx8mq_soc_revision(void)
 {
        struct device_node *np;
@@ -42,6 +55,10 @@ static u32 __init imx8mq_soc_revision(void)
        if (magic == IMX8MQ_SW_MAGIC_B1)
                rev = REV_B1;
 
+       soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH);
+       soc_uid <<= 32;
+       soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW);
+
        iounmap(ocotp_base);
 
 out:
@@ -49,6 +66,26 @@ out:
        return rev;
 }
 
+static void __init imx8mm_soc_uid(void)
+{
+       void __iomem *ocotp_base;
+       struct device_node *np;
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-ocotp");
+       if (!np)
+               return;
+
+       ocotp_base = of_iomap(np, 0);
+       WARN_ON(!ocotp_base);
+
+       soc_uid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH);
+       soc_uid <<= 32;
+       soc_uid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW);
+
+       iounmap(ocotp_base);
+       of_node_put(np);
+}
+
 static u32 __init imx8mm_soc_revision(void)
 {
        struct device_node *np;
@@ -66,6 +103,9 @@ static u32 __init imx8mm_soc_revision(void)
 
        iounmap(anatop_base);
        of_node_put(np);
+
+       imx8mm_soc_uid();
+
        return rev;
 }
 
@@ -140,6 +180,11 @@ static int __init imx8_soc_init(void)
                goto free_rev;
        }
 
+       ret = device_create_file(soc_device_to_device(soc_dev),
+                                &dev_attr_soc_uid);
+       if (ret)
+               goto free_rev;
+
        if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
                platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
 
index de2e62c..e3eb19b 100644 (file)
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
+if ARCH_IXP4XX || COMPILE_TEST
+
 menu "IXP4xx SoC drivers"
 
 config IXP4XX_QMGR
@@ -15,3 +17,5 @@ config IXP4XX_NPE
          and is automatically selected by Ethernet and HSS drivers.
 
 endmenu
+
+endif
index ff9fef5..7aa0517 100644 (file)
@@ -136,7 +136,7 @@ static int cmdq_pkt_append_command(struct cmdq_pkt *pkt, enum cmdq_code code,
        return 0;
 }
 
-int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset)
+int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value)
 {
        u32 arg_a = (offset & CMDQ_ARG_A_WRITE_MASK) |
                    (subsys << CMDQ_SUBSYS_SHIFT);
@@ -145,8 +145,8 @@ int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset)
 }
 EXPORT_SYMBOL(cmdq_pkt_write);
 
-int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
-                       u32 subsys, u32 offset, u32 mask)
+int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
+                       u16 offset, u32 value, u32 mask)
 {
        u32 offset_mask = offset;
        int err = 0;
@@ -161,7 +161,7 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
 }
 EXPORT_SYMBOL(cmdq_pkt_write_mask);
 
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event)
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event)
 {
        u32 arg_b;
 
@@ -181,7 +181,7 @@ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event)
 }
 EXPORT_SYMBOL(cmdq_pkt_wfe);
 
-int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u32 event)
+int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event)
 {
        if (event >= CMDQ_MAX_EVENT)
                return -EINVAL;
index a6d1bfb..661e47a 100644 (file)
@@ -175,6 +175,14 @@ config QCOM_SMSM
          Say yes here to support the Qualcomm Shared Memory State Machine.
          The state machine is represented by bits in shared memory.
 
+config QCOM_SOCINFO
+       tristate "Qualcomm socinfo driver"
+       depends on QCOM_SMEM
+       select SOC_BUS
+       help
+        Say yes here to support the Qualcomm socinfo driver, providing
+        information about the SoC to user space.
+
 config QCOM_WCNSS_CTRL
        tristate "Qualcomm WCNSS control driver"
        depends on ARCH_QCOM || COMPILE_TEST
index eeb088b..1627887 100644 (file)
@@ -18,6 +18,7 @@ obj-$(CONFIG_QCOM_SMEM) +=    smem.o
 obj-$(CONFIG_QCOM_SMEM_STATE) += smem_state.o
 obj-$(CONFIG_QCOM_SMP2P)       += smp2p.o
 obj-$(CONFIG_QCOM_SMSM)        += smsm.o
+obj-$(CONFIG_QCOM_SOCINFO)     += socinfo.o
 obj-$(CONFIG_QCOM_WCNSS_CTRL) += wcnss_ctrl.o
 obj-$(CONFIG_QCOM_APR) += apr.o
 obj-$(CONFIG_QCOM_LLCC) += llcc-slice.o
index d5cf953..7d622ea 100644 (file)
@@ -630,6 +630,9 @@ int geni_se_tx_dma_prep(struct geni_se *se, void *buf, size_t len,
        struct geni_wrapper *wrapper = se->wrapper;
        u32 val;
 
+       if (!wrapper)
+               return -EINVAL;
+
        *iova = dma_map_single(wrapper->dev, buf, len, DMA_TO_DEVICE);
        if (dma_mapping_error(wrapper->dev, *iova))
                return -EIO;
@@ -663,6 +666,9 @@ int geni_se_rx_dma_prep(struct geni_se *se, void *buf, size_t len,
        struct geni_wrapper *wrapper = se->wrapper;
        u32 val;
 
+       if (!wrapper)
+               return -EINVAL;
+
        *iova = dma_map_single(wrapper->dev, buf, len, DMA_FROM_DEVICE);
        if (dma_mapping_error(wrapper->dev, *iova))
                return -EIO;
index 5f88519..33a27e6 100644 (file)
@@ -10,6 +10,8 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
+#include <linux/thermal.h>
+#include <linux/slab.h>
 
 #define QMP_DESC_MAGIC                 0x0
 #define QMP_DESC_VERSION               0x4
 /* 64 bytes is enough to store the requests and provides padding to 4 bytes */
 #define QMP_MSG_LEN                    64
 
+#define QMP_NUM_COOLING_RESOURCES      2
+
+static bool qmp_cdev_init_state = 1;
+
+struct qmp_cooling_device {
+       struct thermal_cooling_device *cdev;
+       struct qmp *qmp;
+       char *name;
+       bool state;
+};
+
 /**
  * struct qmp - driver state for QMP implementation
  * @msgram: iomem referencing the message RAM used for communication
@@ -69,6 +82,7 @@ struct qmp {
 
        struct clk_hw qdss_clk;
        struct genpd_onecell_data pd_data;
+       struct qmp_cooling_device *cooling_devs;
 };
 
 struct qmp_pd {
@@ -385,6 +399,118 @@ static void qmp_pd_remove(struct qmp *qmp)
                pm_genpd_remove(data->domains[i]);
 }
 
+static int qmp_cdev_get_max_state(struct thermal_cooling_device *cdev,
+                                 unsigned long *state)
+{
+       *state = qmp_cdev_init_state;
+       return 0;
+}
+
+static int qmp_cdev_get_cur_state(struct thermal_cooling_device *cdev,
+                                 unsigned long *state)
+{
+       struct qmp_cooling_device *qmp_cdev = cdev->devdata;
+
+       *state = qmp_cdev->state;
+       return 0;
+}
+
+static int qmp_cdev_set_cur_state(struct thermal_cooling_device *cdev,
+                                 unsigned long state)
+{
+       struct qmp_cooling_device *qmp_cdev = cdev->devdata;
+       char buf[QMP_MSG_LEN] = {};
+       bool cdev_state;
+       int ret;
+
+       /* Normalize state */
+       cdev_state = !!state;
+
+       if (qmp_cdev->state == state)
+               return 0;
+
+       snprintf(buf, sizeof(buf),
+                "{class: volt_flr, event:zero_temp, res:%s, value:%s}",
+                       qmp_cdev->name,
+                       cdev_state ? "off" : "on");
+
+       ret = qmp_send(qmp_cdev->qmp, buf, sizeof(buf));
+
+       if (!ret)
+               qmp_cdev->state = cdev_state;
+
+       return ret;
+}
+
+static struct thermal_cooling_device_ops qmp_cooling_device_ops = {
+       .get_max_state = qmp_cdev_get_max_state,
+       .get_cur_state = qmp_cdev_get_cur_state,
+       .set_cur_state = qmp_cdev_set_cur_state,
+};
+
+static int qmp_cooling_device_add(struct qmp *qmp,
+                                 struct qmp_cooling_device *qmp_cdev,
+                                 struct device_node *node)
+{
+       char *cdev_name = (char *)node->name;
+
+       qmp_cdev->qmp = qmp;
+       qmp_cdev->state = qmp_cdev_init_state;
+       qmp_cdev->name = cdev_name;
+       qmp_cdev->cdev = devm_thermal_of_cooling_device_register
+                               (qmp->dev, node,
+                               cdev_name,
+                               qmp_cdev, &qmp_cooling_device_ops);
+
+       if (IS_ERR(qmp_cdev->cdev))
+               dev_err(qmp->dev, "unable to register %s cooling device\n",
+                       cdev_name);
+
+       return PTR_ERR_OR_ZERO(qmp_cdev->cdev);
+}
+
+static int qmp_cooling_devices_register(struct qmp *qmp)
+{
+       struct device_node *np, *child;
+       int count = QMP_NUM_COOLING_RESOURCES;
+       int ret;
+
+       np = qmp->dev->of_node;
+
+       qmp->cooling_devs = devm_kcalloc(qmp->dev, count,
+                                        sizeof(*qmp->cooling_devs),
+                                        GFP_KERNEL);
+
+       if (!qmp->cooling_devs)
+               return -ENOMEM;
+
+       for_each_available_child_of_node(np, child) {
+               if (!of_find_property(child, "#cooling-cells", NULL))
+                       continue;
+               ret = qmp_cooling_device_add(qmp, &qmp->cooling_devs[count++],
+                                            child);
+               if (ret)
+                       goto unroll;
+       }
+
+       return 0;
+
+unroll:
+       while (--count >= 0)
+               thermal_cooling_device_unregister
+                       (qmp->cooling_devs[count].cdev);
+
+       return ret;
+}
+
+static void qmp_cooling_devices_remove(struct qmp *qmp)
+{
+       int i;
+
+       for (i = 0; i < QMP_NUM_COOLING_RESOURCES; i++)
+               thermal_cooling_device_unregister(qmp->cooling_devs[i].cdev);
+}
+
 static int qmp_probe(struct platform_device *pdev)
 {
        struct resource *res;
@@ -433,6 +559,10 @@ static int qmp_probe(struct platform_device *pdev)
        if (ret)
                goto err_remove_qdss_clk;
 
+       ret = qmp_cooling_devices_register(qmp);
+       if (ret)
+               dev_err(&pdev->dev, "failed to register aoss cooling devices\n");
+
        platform_set_drvdata(pdev, qmp);
 
        return 0;
@@ -453,6 +583,7 @@ static int qmp_remove(struct platform_device *pdev)
 
        qmp_qdss_clk_remove(qmp);
        qmp_pd_remove(qmp);
+       qmp_cooling_devices_remove(qmp);
 
        qmp_close(qmp);
        mbox_free_channel(qmp->mbox_chan);
@@ -461,7 +592,9 @@ static int qmp_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id qmp_dt_match[] = {
+       { .compatible = "qcom,sc7180-aoss-qmp", },
        { .compatible = "qcom,sdm845-aoss-qmp", },
+       { .compatible = "qcom,sm8150-aoss-qmp", },
        {}
 };
 MODULE_DEVICE_TABLE(of, qmp_dt_match);
index f27c00d..28c19bc 100644 (file)
@@ -84,7 +84,7 @@
 #define SMEM_GLOBAL_HOST       0xfffe
 
 /* Max number of processors/hosts in a system */
-#define SMEM_HOST_COUNT                10
+#define SMEM_HOST_COUNT                11
 
 /**
   * struct smem_proc_comm - proc_comm communication struct (legacy)
@@ -268,6 +268,7 @@ struct qcom_smem {
        struct smem_partition_header *partitions[SMEM_HOST_COUNT];
        size_t cacheline[SMEM_HOST_COUNT];
        u32 item_count;
+       struct platform_device *socinfo;
 
        unsigned num_regions;
        struct smem_region regions[];
@@ -963,11 +964,19 @@ static int qcom_smem_probe(struct platform_device *pdev)
 
        __smem = smem;
 
+       smem->socinfo = platform_device_register_data(&pdev->dev, "qcom-socinfo",
+                                                     PLATFORM_DEVID_NONE, NULL,
+                                                     0);
+       if (IS_ERR(smem->socinfo))
+               dev_dbg(&pdev->dev, "failed to register socinfo device\n");
+
        return 0;
 }
 
 static int qcom_smem_remove(struct platform_device *pdev)
 {
+       platform_device_unregister(__smem->socinfo);
+
        hwspin_lock_free(__smem->hwlock);
        __smem = NULL;
 
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c
new file mode 100644 (file)
index 0000000..a39ea50
--- /dev/null
@@ -0,0 +1,476 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, Linaro Ltd.
+ */
+
+#include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+#include <linux/slab.h>
+#include <linux/soc/qcom/smem.h>
+#include <linux/string.h>
+#include <linux/sys_soc.h>
+#include <linux/types.h>
+
+/*
+ * SoC version type with major number in the upper 16 bits and minor
+ * number in the lower 16 bits.
+ */
+#define SOCINFO_MAJOR(ver) (((ver) >> 16) & 0xffff)
+#define SOCINFO_MINOR(ver) ((ver) & 0xffff)
+#define SOCINFO_VERSION(maj, min)  ((((maj) & 0xffff) << 16)|((min) & 0xffff))
+
+#define SMEM_SOCINFO_BUILD_ID_LENGTH           32
+
+/*
+ * SMEM item id, used to acquire handles to respective
+ * SMEM region.
+ */
+#define SMEM_HW_SW_BUILD_ID            137
+
+#ifdef CONFIG_DEBUG_FS
+#define SMEM_IMAGE_VERSION_BLOCKS_COUNT        32
+#define SMEM_IMAGE_VERSION_SIZE                4096
+#define SMEM_IMAGE_VERSION_NAME_SIZE           75
+#define SMEM_IMAGE_VERSION_VARIANT_SIZE        20
+#define SMEM_IMAGE_VERSION_OEM_SIZE            32
+
+/*
+ * SMEM Image table indices
+ */
+#define SMEM_IMAGE_TABLE_BOOT_INDEX     0
+#define SMEM_IMAGE_TABLE_TZ_INDEX       1
+#define SMEM_IMAGE_TABLE_RPM_INDEX      3
+#define SMEM_IMAGE_TABLE_APPS_INDEX     10
+#define SMEM_IMAGE_TABLE_MPSS_INDEX     11
+#define SMEM_IMAGE_TABLE_ADSP_INDEX     12
+#define SMEM_IMAGE_TABLE_CNSS_INDEX     13
+#define SMEM_IMAGE_TABLE_VIDEO_INDEX    14
+#define SMEM_IMAGE_VERSION_TABLE       469
+
+/*
+ * SMEM Image table names
+ */
+static const char *const socinfo_image_names[] = {
+       [SMEM_IMAGE_TABLE_ADSP_INDEX] = "adsp",
+       [SMEM_IMAGE_TABLE_APPS_INDEX] = "apps",
+       [SMEM_IMAGE_TABLE_BOOT_INDEX] = "boot",
+       [SMEM_IMAGE_TABLE_CNSS_INDEX] = "cnss",
+       [SMEM_IMAGE_TABLE_MPSS_INDEX] = "mpss",
+       [SMEM_IMAGE_TABLE_RPM_INDEX] = "rpm",
+       [SMEM_IMAGE_TABLE_TZ_INDEX] = "tz",
+       [SMEM_IMAGE_TABLE_VIDEO_INDEX] = "video",
+};
+
+static const char *const pmic_models[] = {
+       [0]  = "Unknown PMIC model",
+       [9]  = "PM8994",
+       [11] = "PM8916",
+       [13] = "PM8058",
+       [14] = "PM8028",
+       [15] = "PM8901",
+       [16] = "PM8027",
+       [17] = "ISL9519",
+       [18] = "PM8921",
+       [19] = "PM8018",
+       [20] = "PM8015",
+       [21] = "PM8014",
+       [22] = "PM8821",
+       [23] = "PM8038",
+       [24] = "PM8922",
+       [25] = "PM8917",
+};
+#endif /* CONFIG_DEBUG_FS */
+
+/* Socinfo SMEM item structure */
+struct socinfo {
+       __le32 fmt;
+       __le32 id;
+       __le32 ver;
+       char build_id[SMEM_SOCINFO_BUILD_ID_LENGTH];
+       /* Version 2 */
+       __le32 raw_id;
+       __le32 raw_ver;
+       /* Version 3 */
+       __le32 hw_plat;
+       /* Version 4 */
+       __le32 plat_ver;
+       /* Version 5 */
+       __le32 accessory_chip;
+       /* Version 6 */
+       __le32 hw_plat_subtype;
+       /* Version 7 */
+       __le32 pmic_model;
+       __le32 pmic_die_rev;
+       /* Version 8 */
+       __le32 pmic_model_1;
+       __le32 pmic_die_rev_1;
+       __le32 pmic_model_2;
+       __le32 pmic_die_rev_2;
+       /* Version 9 */
+       __le32 foundry_id;
+       /* Version 10 */
+       __le32 serial_num;
+       /* Version 11 */
+       __le32 num_pmics;
+       __le32 pmic_array_offset;
+       /* Version 12 */
+       __le32 chip_family;
+       __le32 raw_device_family;
+       __le32 raw_device_num;
+};
+
+#ifdef CONFIG_DEBUG_FS
+struct socinfo_params {
+       u32 raw_device_family;
+       u32 hw_plat_subtype;
+       u32 accessory_chip;
+       u32 raw_device_num;
+       u32 chip_family;
+       u32 foundry_id;
+       u32 plat_ver;
+       u32 raw_ver;
+       u32 hw_plat;
+       u32 fmt;
+};
+
+struct smem_image_version {
+       char name[SMEM_IMAGE_VERSION_NAME_SIZE];
+       char variant[SMEM_IMAGE_VERSION_VARIANT_SIZE];
+       char pad;
+       char oem[SMEM_IMAGE_VERSION_OEM_SIZE];
+};
+#endif /* CONFIG_DEBUG_FS */
+
+struct qcom_socinfo {
+       struct soc_device *soc_dev;
+       struct soc_device_attribute attr;
+#ifdef CONFIG_DEBUG_FS
+       struct dentry *dbg_root;
+       struct socinfo_params info;
+#endif /* CONFIG_DEBUG_FS */
+};
+
+struct soc_id {
+       unsigned int id;
+       const char *name;
+};
+
+static const struct soc_id soc_id[] = {
+       { 87, "MSM8960" },
+       { 109, "APQ8064" },
+       { 122, "MSM8660A" },
+       { 123, "MSM8260A" },
+       { 124, "APQ8060A" },
+       { 126, "MSM8974" },
+       { 130, "MPQ8064" },
+       { 138, "MSM8960AB" },
+       { 139, "APQ8060AB" },
+       { 140, "MSM8260AB" },
+       { 141, "MSM8660AB" },
+       { 178, "APQ8084" },
+       { 184, "APQ8074" },
+       { 185, "MSM8274" },
+       { 186, "MSM8674" },
+       { 194, "MSM8974PRO" },
+       { 206, "MSM8916" },
+       { 208, "APQ8074-AA" },
+       { 209, "APQ8074-AB" },
+       { 210, "APQ8074PRO" },
+       { 211, "MSM8274-AA" },
+       { 212, "MSM8274-AB" },
+       { 213, "MSM8274PRO" },
+       { 214, "MSM8674-AA" },
+       { 215, "MSM8674-AB" },
+       { 216, "MSM8674PRO" },
+       { 217, "MSM8974-AA" },
+       { 218, "MSM8974-AB" },
+       { 246, "MSM8996" },
+       { 247, "APQ8016" },
+       { 248, "MSM8216" },
+       { 249, "MSM8116" },
+       { 250, "MSM8616" },
+       { 291, "APQ8096" },
+       { 305, "MSM8996SG" },
+       { 310, "MSM8996AU" },
+       { 311, "APQ8096AU" },
+       { 312, "APQ8096SG" },
+};
+
+static const char *socinfo_machine(struct device *dev, unsigned int id)
+{
+       int idx;
+
+       for (idx = 0; idx < ARRAY_SIZE(soc_id); idx++) {
+               if (soc_id[idx].id == id)
+                       return soc_id[idx].name;
+       }
+
+       return NULL;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#define QCOM_OPEN(name, _func)                                         \
+static int qcom_open_##name(struct inode *inode, struct file *file)    \
+{                                                                      \
+       return single_open(file, _func, inode->i_private);              \
+}                                                                      \
+                                                                       \
+static const struct file_operations qcom_ ##name## _ops = {            \
+       .open = qcom_open_##name,                                       \
+       .read = seq_read,                                               \
+       .llseek = seq_lseek,                                            \
+       .release = single_release,                                      \
+}
+
+#define DEBUGFS_ADD(info, name)                                                \
+       debugfs_create_file(__stringify(name), 0400,                    \
+                           qcom_socinfo->dbg_root,                     \
+                           info, &qcom_ ##name## _ops)
+
+
+static int qcom_show_build_id(struct seq_file *seq, void *p)
+{
+       struct socinfo *socinfo = seq->private;
+
+       seq_printf(seq, "%s\n", socinfo->build_id);
+
+       return 0;
+}
+
+static int qcom_show_pmic_model(struct seq_file *seq, void *p)
+{
+       struct socinfo *socinfo = seq->private;
+       int model = SOCINFO_MINOR(le32_to_cpu(socinfo->pmic_model));
+
+       if (model < 0)
+               return -EINVAL;
+
+       seq_printf(seq, "%s\n", pmic_models[model]);
+
+       return 0;
+}
+
+static int qcom_show_pmic_die_revision(struct seq_file *seq, void *p)
+{
+       struct socinfo *socinfo = seq->private;
+
+       seq_printf(seq, "%u.%u\n",
+                  SOCINFO_MAJOR(le32_to_cpu(socinfo->pmic_die_rev)),
+                  SOCINFO_MINOR(le32_to_cpu(socinfo->pmic_die_rev)));
+
+       return 0;
+}
+
+QCOM_OPEN(build_id, qcom_show_build_id);
+QCOM_OPEN(pmic_model, qcom_show_pmic_model);
+QCOM_OPEN(pmic_die_rev, qcom_show_pmic_die_revision);
+
+#define DEFINE_IMAGE_OPS(type)                                 \
+static int show_image_##type(struct seq_file *seq, void *p)              \
+{                                                                \
+       struct smem_image_version *image_version = seq->private;  \
+       seq_puts(seq, image_version->type);                       \
+       seq_puts(seq, "\n");                                      \
+       return 0;                                                 \
+}                                                                \
+static int open_image_##type(struct inode *inode, struct file *file)     \
+{                                                                        \
+       return single_open(file, show_image_##type, inode->i_private); \
+}                                                                        \
+                                                                         \
+static const struct file_operations qcom_image_##type##_ops = {          \
+       .open = open_image_##type,                                        \
+       .read = seq_read,                                                 \
+       .llseek = seq_lseek,                                              \
+       .release = single_release,                                        \
+}
+
+DEFINE_IMAGE_OPS(name);
+DEFINE_IMAGE_OPS(variant);
+DEFINE_IMAGE_OPS(oem);
+
+static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo,
+                                struct socinfo *info)
+{
+       struct smem_image_version *versions;
+       struct dentry *dentry;
+       size_t size;
+       int i;
+
+       qcom_socinfo->dbg_root = debugfs_create_dir("qcom_socinfo", NULL);
+
+       qcom_socinfo->info.fmt = __le32_to_cpu(info->fmt);
+
+       switch (qcom_socinfo->info.fmt) {
+       case SOCINFO_VERSION(0, 12):
+               qcom_socinfo->info.chip_family =
+                       __le32_to_cpu(info->chip_family);
+               qcom_socinfo->info.raw_device_family =
+                       __le32_to_cpu(info->raw_device_family);
+               qcom_socinfo->info.raw_device_num =
+                       __le32_to_cpu(info->raw_device_num);
+
+               debugfs_create_x32("chip_family", 0400, qcom_socinfo->dbg_root,
+                                  &qcom_socinfo->info.chip_family);
+               debugfs_create_x32("raw_device_family", 0400,
+                                  qcom_socinfo->dbg_root,
+                                  &qcom_socinfo->info.raw_device_family);
+               debugfs_create_x32("raw_device_number", 0400,
+                                  qcom_socinfo->dbg_root,
+                                  &qcom_socinfo->info.raw_device_num);
+               /* Fall through */
+       case SOCINFO_VERSION(0, 11):
+       case SOCINFO_VERSION(0, 10):
+       case SOCINFO_VERSION(0, 9):
+               qcom_socinfo->info.foundry_id = __le32_to_cpu(info->foundry_id);
+
+               debugfs_create_u32("foundry_id", 0400, qcom_socinfo->dbg_root,
+                                  &qcom_socinfo->info.foundry_id);
+               /* Fall through */
+       case SOCINFO_VERSION(0, 8):
+       case SOCINFO_VERSION(0, 7):
+               DEBUGFS_ADD(info, pmic_model);
+               DEBUGFS_ADD(info, pmic_die_rev);
+               /* Fall through */
+       case SOCINFO_VERSION(0, 6):
+               qcom_socinfo->info.hw_plat_subtype =
+                       __le32_to_cpu(info->hw_plat_subtype);
+
+               debugfs_create_u32("hardware_platform_subtype", 0400,
+                                  qcom_socinfo->dbg_root,
+                                  &qcom_socinfo->info.hw_plat_subtype);
+               /* Fall through */
+       case SOCINFO_VERSION(0, 5):
+               qcom_socinfo->info.accessory_chip =
+                       __le32_to_cpu(info->accessory_chip);
+
+               debugfs_create_u32("accessory_chip", 0400,
+                                  qcom_socinfo->dbg_root,
+                                  &qcom_socinfo->info.accessory_chip);
+               /* Fall through */
+       case SOCINFO_VERSION(0, 4):
+               qcom_socinfo->info.plat_ver = __le32_to_cpu(info->plat_ver);
+
+               debugfs_create_u32("platform_version", 0400,
+                                  qcom_socinfo->dbg_root,
+                                  &qcom_socinfo->info.plat_ver);
+               /* Fall through */
+       case SOCINFO_VERSION(0, 3):
+               qcom_socinfo->info.hw_plat = __le32_to_cpu(info->hw_plat);
+
+               debugfs_create_u32("hardware_platform", 0400,
+                                  qcom_socinfo->dbg_root,
+                                  &qcom_socinfo->info.hw_plat);
+               /* Fall through */
+       case SOCINFO_VERSION(0, 2):
+               qcom_socinfo->info.raw_ver  = __le32_to_cpu(info->raw_ver);
+
+               debugfs_create_u32("raw_version", 0400, qcom_socinfo->dbg_root,
+                                  &qcom_socinfo->info.raw_ver);
+               /* Fall through */
+       case SOCINFO_VERSION(0, 1):
+               DEBUGFS_ADD(info, build_id);
+               break;
+       }
+
+       versions = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_IMAGE_VERSION_TABLE,
+                                &size);
+
+       for (i = 0; i < ARRAY_SIZE(socinfo_image_names); i++) {
+               if (!socinfo_image_names[i])
+                       continue;
+
+               dentry = debugfs_create_dir(socinfo_image_names[i],
+                                           qcom_socinfo->dbg_root);
+               debugfs_create_file("name", 0400, dentry, &versions[i],
+                                   &qcom_image_name_ops);
+               debugfs_create_file("variant", 0400, dentry, &versions[i],
+                                   &qcom_image_variant_ops);
+               debugfs_create_file("oem", 0400, dentry, &versions[i],
+                                   &qcom_image_oem_ops);
+       }
+}
+
+static void socinfo_debugfs_exit(struct qcom_socinfo *qcom_socinfo)
+{
+       debugfs_remove_recursive(qcom_socinfo->dbg_root);
+}
+#else
+static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo,
+                                struct socinfo *info)
+{
+}
+static void socinfo_debugfs_exit(struct qcom_socinfo *qcom_socinfo) {  }
+#endif /* CONFIG_DEBUG_FS */
+
+static int qcom_socinfo_probe(struct platform_device *pdev)
+{
+       struct qcom_socinfo *qs;
+       struct socinfo *info;
+       size_t item_size;
+
+       info = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_HW_SW_BUILD_ID,
+                             &item_size);
+       if (IS_ERR(info)) {
+               dev_err(&pdev->dev, "Couldn't find socinfo\n");
+               return PTR_ERR(info);
+       }
+
+       qs = devm_kzalloc(&pdev->dev, sizeof(*qs), GFP_KERNEL);
+       if (!qs)
+               return -ENOMEM;
+
+       qs->attr.family = "Snapdragon";
+       qs->attr.machine = socinfo_machine(&pdev->dev,
+                                          le32_to_cpu(info->id));
+       qs->attr.revision = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%u.%u",
+                                          SOCINFO_MAJOR(le32_to_cpu(info->ver)),
+                                          SOCINFO_MINOR(le32_to_cpu(info->ver)));
+       if (offsetof(struct socinfo, serial_num) <= item_size)
+               qs->attr.serial_number = devm_kasprintf(&pdev->dev, GFP_KERNEL,
+                                                       "%u",
+                                                       le32_to_cpu(info->serial_num));
+
+       qs->soc_dev = soc_device_register(&qs->attr);
+       if (IS_ERR(qs->soc_dev))
+               return PTR_ERR(qs->soc_dev);
+
+       socinfo_debugfs_init(qs, info);
+
+       /* Feed the soc specific unique data into entropy pool */
+       add_device_randomness(info, item_size);
+
+       platform_set_drvdata(pdev, qs->soc_dev);
+
+       return 0;
+}
+
+static int qcom_socinfo_remove(struct platform_device *pdev)
+{
+       struct qcom_socinfo *qs = platform_get_drvdata(pdev);
+
+       soc_device_unregister(qs->soc_dev);
+
+       socinfo_debugfs_exit(qs);
+
+       return 0;
+}
+
+static struct platform_driver qcom_socinfo_driver = {
+       .probe = qcom_socinfo_probe,
+       .remove = qcom_socinfo_remove,
+       .driver  = {
+               .name = "qcom-socinfo",
+       },
+};
+
+module_platform_driver(qcom_socinfo_driver);
+
+MODULE_DESCRIPTION("Qualcomm SoCinfo driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:qcom-socinfo");
index 2bbf49e..3c5e017 100644 (file)
@@ -55,6 +55,7 @@ config ARCH_EMEV2
 
 config ARCH_R7S72100
        bool "RZ/A1H (R7S72100)"
+       select ARM_ERRATA_754322
        select PM
        select PM_GENERIC_DOMAINS
        select RENESAS_OSTM
@@ -72,12 +73,14 @@ config ARCH_R8A73A4
        bool "R-Mobile APE6 (R8A73A40)"
        select ARCH_RMOBILE
        select ARM_ERRATA_798181 if SMP
+       select ARM_ERRATA_814220
        select HAVE_ARM_ARCH_TIMER
        select RENESAS_IRQC
 
 config ARCH_R8A7740
        bool "R-Mobile A1 (R8A77400)"
        select ARCH_RMOBILE
+       select ARM_ERRATA_754322
        select RENESAS_INTC_IRQPIN
 
 config ARCH_R8A7743
@@ -95,20 +98,24 @@ config ARCH_R8A7744
 config ARCH_R8A7745
        bool "RZ/G1E (R8A77450)"
        select ARCH_RCAR_GEN2
+       select ARM_ERRATA_814220
        select SYSC_R8A7745
 
 config ARCH_R8A77470
        bool "RZ/G1C (R8A77470)"
        select ARCH_RCAR_GEN2
+       select ARM_ERRATA_814220
        select SYSC_R8A77470
 
 config ARCH_R8A7778
        bool "R-Car M1A (R8A77781)"
        select ARCH_RCAR_GEN1
+       select ARM_ERRATA_754322
 
 config ARCH_R8A7779
        bool "R-Car H1 (R8A77790)"
        select ARCH_RCAR_GEN1
+       select ARM_ERRATA_754322
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select SYSC_R8A7779
@@ -117,6 +124,7 @@ config ARCH_R8A7790
        bool "R-Car H2 (R8A77900)"
        select ARCH_RCAR_GEN2
        select ARM_ERRATA_798181 if SMP
+       select ARM_ERRATA_814220
        select I2C
        select SYSC_R8A7790
 
@@ -143,15 +151,18 @@ config ARCH_R8A7793
 config ARCH_R8A7794
        bool "R-Car E2 (R8A77940)"
        select ARCH_RCAR_GEN2
+       select ARM_ERRATA_814220
        select SYSC_R8A7794
 
 config ARCH_R9A06G032
        bool "RZ/N1D (R9A06G032)"
        select ARCH_RZN1
+       select ARM_ERRATA_814220
 
 config ARCH_SH73A0
        bool "SH-Mobile AG5 (R8A73A00)"
        select ARCH_RMOBILE
+       select ARM_ERRATA_754322
        select HAVE_ARM_SCU if SMP
        select HAVE_ARM_TWD if SMP
        select RENESAS_INTC_IRQPIN
index 0c80fab..59b5e6b 100644 (file)
@@ -170,7 +170,7 @@ struct rcar_sysc_pd {
        struct generic_pm_domain genpd;
        struct rcar_sysc_ch ch;
        unsigned int flags;
-       char name[0];
+       char name[];
 };
 
 static inline struct rcar_sysc_pd *to_rcar_pd(struct generic_pm_domain *d)
@@ -200,7 +200,6 @@ static int __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
 {
        struct generic_pm_domain *genpd = &pd->genpd;
        const char *name = pd->genpd.name;
-       struct dev_power_governor *gov = &simple_qos_governor;
        int error;
 
        if (pd->flags & PD_CPU) {
@@ -254,7 +253,7 @@ static int __init rcar_sysc_pd_setup(struct rcar_sysc_pd *pd)
        rcar_sysc_power(&pd->ch, true);
 
 finalize:
-       error = pm_genpd_init(genpd, gov, false);
+       error = pm_genpd_init(genpd, &simple_qos_governor, false);
        if (error)
                pr_err("Failed to init PM domain %s: %d\n", name, error);
 
@@ -346,7 +345,7 @@ static int __init rcar_sysc_pd_init(void)
        if (info->init) {
                error = info->init();
                if (error)
-                       return error;
+                       goto out_put;
        }
 
        has_cpg_mstp = of_find_compatible_node(NULL, NULL,
index 421ae1c..54b616a 100644 (file)
@@ -48,12 +48,8 @@ struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d)
 static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
 {
        struct rmobile_pm_domain *rmobile_pd = to_rmobile_pd(genpd);
-       unsigned int mask;
+       unsigned int mask = BIT(rmobile_pd->bit_shift);
 
-       if (rmobile_pd->bit_shift == ~0)
-               return -EBUSY;
-
-       mask = BIT(rmobile_pd->bit_shift);
        if (rmobile_pd->suspend) {
                int ret = rmobile_pd->suspend();
 
@@ -80,14 +76,10 @@ static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
 
 static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd)
 {
-       unsigned int mask;
+       unsigned int mask = BIT(rmobile_pd->bit_shift);
        unsigned int retry_count;
        int ret = 0;
 
-       if (rmobile_pd->bit_shift == ~0)
-               return 0;
-
-       mask = BIT(rmobile_pd->bit_shift);
        if (__raw_readl(rmobile_pd->base + PSTR) & mask)
                return ret;
 
@@ -122,11 +114,15 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
        struct dev_power_governor *gov = rmobile_pd->gov;
 
        genpd->flags |= GENPD_FLAG_PM_CLK | GENPD_FLAG_ACTIVE_WAKEUP;
-       genpd->power_off                = rmobile_pd_power_down;
-       genpd->power_on                 = rmobile_pd_power_up;
-       genpd->attach_dev               = cpg_mstp_attach_dev;
-       genpd->detach_dev               = cpg_mstp_detach_dev;
-       __rmobile_pd_power_up(rmobile_pd);
+       genpd->attach_dev = cpg_mstp_attach_dev;
+       genpd->detach_dev = cpg_mstp_detach_dev;
+
+       if (!(genpd->flags & GENPD_FLAG_ALWAYS_ON)) {
+               genpd->power_off = rmobile_pd_power_down;
+               genpd->power_on = rmobile_pd_power_up;
+               __rmobile_pd_power_up(rmobile_pd);
+       }
+
        pm_genpd_init(genpd, gov ? : &simple_qos_governor, false);
 }
 
@@ -270,6 +266,11 @@ static void __init rmobile_setup_pm_domain(struct device_node *np,
                break;
 
        case PD_NORMAL:
+               if (pd->bit_shift == ~0) {
+                       /* Top-level always-on domain */
+                       pr_debug("PM domain %s is always-on domain\n", name);
+                       pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
+               }
                break;
        }
 
index 2186285..33ad0de 100644 (file)
@@ -7,6 +7,12 @@ menuconfig SOC_SAMSUNG
 
 if SOC_SAMSUNG
 
+config EXYNOS_CHIPID
+       bool "Exynos Chipid controller driver" if COMPILE_TEST
+       depends on ARCH_EXYNOS || COMPILE_TEST
+       select MFD_SYSCON
+       select SOC_BUS
+
 config EXYNOS_PMU
        bool "Exynos PMU controller driver" if COMPILE_TEST
        depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
index 29f294b..3b6a879 100644 (file)
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_EXYNOS_CHIPID)    += exynos-chipid.o
 obj-$(CONFIG_EXYNOS_PMU)       += exynos-pmu.o
 
 obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)   += exynos3250-pmu.o exynos4-pmu.o \
diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c
new file mode 100644 (file)
index 0000000..c55a47c
--- /dev/null
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
+ *           http://www.samsung.com/
+ *
+ * EXYNOS - CHIP ID support
+ * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
+ * Author: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
+ */
+
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include <linux/soc/samsung/exynos-chipid.h>
+#include <linux/sys_soc.h>
+
+static const struct exynos_soc_id {
+       const char *name;
+       unsigned int id;
+} soc_ids[] = {
+       { "EXYNOS3250", 0xE3472000 },
+       { "EXYNOS4210", 0x43200000 },   /* EVT0 revision */
+       { "EXYNOS4210", 0x43210000 },
+       { "EXYNOS4212", 0x43220000 },
+       { "EXYNOS4412", 0xE4412000 },
+       { "EXYNOS5250", 0x43520000 },
+       { "EXYNOS5260", 0xE5260000 },
+       { "EXYNOS5410", 0xE5410000 },
+       { "EXYNOS5420", 0xE5420000 },
+       { "EXYNOS5440", 0xE5440000 },
+       { "EXYNOS5800", 0xE5422000 },
+       { "EXYNOS7420", 0xE7420000 },
+       { "EXYNOS5433", 0xE5433000 },
+};
+
+static const char * __init product_id_to_soc_id(unsigned int product_id)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
+               if ((product_id & EXYNOS_MASK) == soc_ids[i].id)
+                       return soc_ids[i].name;
+       return NULL;
+}
+
+int __init exynos_chipid_early_init(void)
+{
+       struct soc_device_attribute *soc_dev_attr;
+       struct soc_device *soc_dev;
+       struct device_node *root;
+       struct regmap *regmap;
+       u32 product_id;
+       u32 revision;
+       int ret;
+
+       regmap = syscon_regmap_lookup_by_compatible("samsung,exynos4210-chipid");
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       ret = regmap_read(regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
+       if (ret < 0)
+               return ret;
+
+       revision = product_id & EXYNOS_REV_MASK;
+
+       soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
+       if (!soc_dev_attr)
+               return -ENOMEM;
+
+       soc_dev_attr->family = "Samsung Exynos";
+
+       root = of_find_node_by_path("/");
+       of_property_read_string(root, "model", &soc_dev_attr->machine);
+       of_node_put(root);
+
+       soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
+       soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
+       if (!soc_dev_attr->soc_id) {
+               pr_err("Unknown SoC\n");
+               ret = -ENODEV;
+               goto err;
+       }
+
+       /* please note that the actual registration will be deferred */
+       soc_dev = soc_device_register(soc_dev_attr);
+       if (IS_ERR(soc_dev)) {
+               ret = PTR_ERR(soc_dev);
+               goto err;
+       }
+
+       /* it is too early to use dev_info() here (soc_dev is NULL) */
+       pr_info("soc soc0: Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
+               soc_dev_attr->soc_id, product_id, revision);
+
+       return 0;
+
+err:
+       kfree(soc_dev_attr->revision);
+       kfree(soc_dev_attr);
+       return ret;
+}
+
+early_initcall(exynos_chipid_early_init);
index bb77c22..ccc6d53 100644 (file)
@@ -141,7 +141,7 @@ static int __init am43xx_map_gic(void)
 }
 
 #ifdef CONFIG_SUSPEND
-struct wkup_m3_wakeup_src rtc_wake_src(void)
+static struct wkup_m3_wakeup_src rtc_wake_src(void)
 {
        u32 i;
 
@@ -157,7 +157,7 @@ struct wkup_m3_wakeup_src rtc_wake_src(void)
        return rtc_ext_wakeup;
 }
 
-int am33xx_rtc_only_idle(unsigned long wfi_flags)
+static int am33xx_rtc_only_idle(unsigned long wfi_flags)
 {
        omap_rtc_power_off_program(&omap_rtc->dev);
        am33xx_do_wfi_sram(wfi_flags);
@@ -252,7 +252,7 @@ static int am33xx_pm_begin(suspend_state_t state)
        if (state == PM_SUSPEND_MEM && pm_ops->check_off_mode_enable()) {
                nvmem = devm_nvmem_device_get(&omap_rtc->dev,
                                              "omap_rtc_scratch0");
-               if (nvmem)
+               if (!IS_ERR(nvmem))
                        nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4, 4,
                                           (void *)&rtc_magic_val);
                rtc_only_idle = 1;
@@ -278,9 +278,12 @@ static void am33xx_pm_end(void)
        struct nvmem_device *nvmem;
 
        nvmem = devm_nvmem_device_get(&omap_rtc->dev, "omap_rtc_scratch0");
+       if (IS_ERR(nvmem))
+               return;
+
        m3_ipc->ops->finish_low_power(m3_ipc);
        if (rtc_only_idle) {
-               if (retrigger_irq)
+               if (retrigger_irq) {
                        /*
                         * 32 bits of Interrupt Set-Pending correspond to 32
                         * 32 interrupts. Compute the bit offset of the
@@ -291,8 +294,10 @@ static void am33xx_pm_end(void)
                        writel_relaxed(1 << (retrigger_irq & 31),
                                       gic_dist_base + GIC_INT_SET_PENDING_BASE
                                       + retrigger_irq / 32 * 4);
-                       nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4, 4,
-                                          (void *)&val);
+               }
+
+               nvmem_device_write(nvmem, RTC_SCRATCH_MAGIC_REG * 4, 4,
+                                  (void *)&val);
        }
 
        rtc_only_idle = 0;
@@ -415,7 +420,7 @@ static int am33xx_pm_rtc_setup(void)
 
                nvmem = devm_nvmem_device_get(&omap_rtc->dev,
                                              "omap_rtc_scratch0");
-               if (nvmem) {
+               if (!IS_ERR(nvmem)) {
                        nvmem_device_read(nvmem, RTC_SCRATCH_MAGIC_REG * 4,
                                          4, (void *)&rtc_magic_val);
                        if ((rtc_magic_val & 0xffff) != RTC_REG_BOOT_MAGIC)
index 97817dd..8c2a2f2 100644 (file)
 #include <linux/pm_domain.h>
 #include <linux/slab.h>
 #include <linux/soc/ti/ti_sci_protocol.h>
+#include <dt-bindings/soc/ti,sci_pm_domain.h>
 
 /**
  * struct ti_sci_genpd_dev_data: holds data needed for every device attached
  *                              to this genpd
  * @idx: index of the device that identifies it with the system
  *      control processor.
+ * @exclusive: Permissions for exclusive request or shared request of the
+ *            device.
  */
 struct ti_sci_genpd_dev_data {
        int idx;
+       u8 exclusive;
 };
 
 /**
@@ -55,6 +59,14 @@ static int ti_sci_dev_id(struct device *dev)
        return sci_dev_data->idx;
 }
 
+static u8 is_ti_sci_dev_exclusive(struct device *dev)
+{
+       struct generic_pm_domain_data *genpd_data = dev_gpd_data(dev);
+       struct ti_sci_genpd_dev_data *sci_dev_data = genpd_data->data;
+
+       return sci_dev_data->exclusive;
+}
+
 /**
  * ti_sci_dev_to_sci_handle(): get pointer to ti_sci_handle
  * @dev: pointer to device associated with this genpd
@@ -79,7 +91,10 @@ static int ti_sci_dev_start(struct device *dev)
        const struct ti_sci_handle *ti_sci = ti_sci_dev_to_sci_handle(dev);
        int idx = ti_sci_dev_id(dev);
 
-       return ti_sci->ops.dev_ops.get_device(ti_sci, idx);
+       if (is_ti_sci_dev_exclusive(dev))
+               return ti_sci->ops.dev_ops.get_device_exclusive(ti_sci, idx);
+       else
+               return ti_sci->ops.dev_ops.get_device(ti_sci, idx);
 }
 
 /**
@@ -110,7 +125,7 @@ static int ti_sci_pd_attach_dev(struct generic_pm_domain *domain,
        if (ret < 0)
                return ret;
 
-       if (pd_args.args_count != 1)
+       if (pd_args.args_count != 1 && pd_args.args_count != 2)
                return -EINVAL;
 
        idx = pd_args.args[0];
@@ -128,6 +143,10 @@ static int ti_sci_pd_attach_dev(struct generic_pm_domain *domain,
                return -ENOMEM;
 
        sci_dev_data->idx = idx;
+       /* Enable the exclusive permissions by default */
+       sci_dev_data->exclusive = TI_SCI_PD_EXCLUSIVE;
+       if (pd_args.args_count == 2)
+               sci_dev_data->exclusive = pd_args.args[1] & 0x1;
 
        genpd_data = dev_gpd_data(dev);
        genpd_data->data = sci_dev_data;
index ea5fd2e..d64feeb 100644 (file)
@@ -203,10 +203,13 @@ static int __init ux500_soc_device_init(void)
        ux500_setup_id();
 
        soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
-       if (!soc_dev_attr)
+       if (!soc_dev_attr) {
+               of_node_put(backupram);
                return -ENOMEM;
+       }
 
        soc_info_populate(soc_dev_attr, backupram);
+       of_node_put(backupram);
 
        soc_dev = soc_device_register(soc_dev_attr);
        if (IS_ERR(soc_dev)) {
index 3a1d8f1..0f0fdb5 100644 (file)
@@ -433,6 +433,16 @@ config SPI_MT7621
        help
          This selects a driver for the MediaTek MT7621 SPI Controller.
 
+config SPI_NPCM_FIU
+       tristate "Nuvoton NPCM FLASH Interface Unit"
+       depends on ARCH_NPCM || COMPILE_TEST
+       depends on OF && HAS_IOMEM
+       help
+         This enables support for the Flash Interface Unit SPI controller
+         in master mode.
+         This driver does not support generic SPI. The implementation only
+         supports spi-mem interface.
+
 config SPI_NPCM_PSPI
        tristate "Nuvoton NPCM PSPI Controller"
        depends on ARCH_NPCM || COMPILE_TEST
@@ -440,13 +450,6 @@ config SPI_NPCM_PSPI
          This driver provides support for Nuvoton NPCM BMC
          Peripheral SPI controller in master mode.
 
-config SPI_NUC900
-       tristate "Nuvoton NUC900 series SPI"
-       depends on ARCH_W90X900
-       select SPI_BITBANG
-       help
-         SPI driver for Nuvoton NUC900 series ARM SoCs
-
 config SPI_LANTIQ_SSC
        tristate "Lantiq SSC SPI controller"
        depends on LANTIQ || COMPILE_TEST
index 63dcab5..bb49c9e 100644 (file)
@@ -63,8 +63,8 @@ obj-$(CONFIG_SPI_MT65XX)                += spi-mt65xx.o
 obj-$(CONFIG_SPI_MT7621)               += spi-mt7621.o
 obj-$(CONFIG_SPI_MXIC)                 += spi-mxic.o
 obj-$(CONFIG_SPI_MXS)                  += spi-mxs.o
+obj-$(CONFIG_SPI_NPCM_FIU)             += spi-npcm-fiu.o
 obj-$(CONFIG_SPI_NPCM_PSPI)            += spi-npcm-pspi.o
-obj-$(CONFIG_SPI_NUC900)               += spi-nuc900.o
 obj-$(CONFIG_SPI_NXP_FLEXSPI)          += spi-nxp-fspi.o
 obj-$(CONFIG_SPI_OC_TINY)              += spi-oc-tiny.o
 spi-octeon-objs                                := spi-cavium.o spi-cavium-octeon.o
index 6a7d7b5..fd8007e 100644 (file)
@@ -526,7 +526,6 @@ static int atmel_qspi_probe(struct platform_device *pdev)
        /* Request the IRQ */
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
-               dev_err(&pdev->dev, "missing IRQ\n");
                err = irq;
                goto disable_qspick;
        }
index ea160f1..41d71ba 100644 (file)
@@ -170,7 +170,6 @@ static int altera_spi_probe(struct platform_device *pdev)
 {
        struct altera_spi *hw;
        struct spi_master *master;
-       struct resource *res;
        int err = -ENODEV;
 
        master = spi_alloc_master(&pdev->dev, sizeof(struct altera_spi));
@@ -189,8 +188,7 @@ static int altera_spi_probe(struct platform_device *pdev)
        hw = spi_master_get_devdata(master);
 
        /* find and map our resources */
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       hw->base = devm_ioremap_resource(&pdev->dev, res);
+       hw->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(hw->base)) {
                err = PTR_ERR(hw->base);
                goto exit;
index 0328883..e450ee1 100644 (file)
@@ -817,7 +817,6 @@ static int a3700_spi_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct device_node *of_node = dev->of_node;
-       struct resource *res;
        struct spi_master *master;
        struct a3700_spi *spi;
        u32 num_cs = 0;
@@ -855,8 +854,7 @@ static int a3700_spi_probe(struct platform_device *pdev)
 
        spi->master = master;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       spi->base = devm_ioremap_resource(dev, res);
+       spi->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(spi->base)) {
                ret = PTR_ERR(spi->base);
                goto error;
@@ -864,7 +862,6 @@ static int a3700_spi_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
-               dev_err(dev, "could not get irq: %d\n", irq);
                ret = -ENXIO;
                goto error;
        }
index 032a615..eb9a243 100644 (file)
@@ -139,7 +139,6 @@ static int ath79_spi_probe(struct platform_device *pdev)
        struct spi_master *master;
        struct ath79_spi *sp;
        struct ath79_spi_platform_data *pdata;
-       struct resource *r;
        unsigned long rate;
        int ret;
 
@@ -169,8 +168,7 @@ static int ath79_spi_probe(struct platform_device *pdev)
        sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
        sp->bitbang.flags = SPI_CS_HIGH;
 
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       sp->base = devm_ioremap_resource(&pdev->dev, r);
+       sp->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(sp->base)) {
                ret = PTR_ERR(sp->base);
                goto err_put_master;
index f00b367..acf318e 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/pinctrl/consumer.h>
 #include <linux/pm_runtime.h>
+#include <trace/events/spi.h>
 
 /* SPI register offsets */
 #define SPI_CR                                 0x0000
@@ -1409,9 +1410,13 @@ static int atmel_spi_transfer_one_message(struct spi_master *master,
        msg->actual_length = 0;
 
        list_for_each_entry(xfer, &msg->transfers, transfer_list) {
+               trace_spi_transfer_start(msg, xfer);
+
                ret = atmel_spi_one_transfer(master, msg, xfer);
                if (ret)
                        goto msg_done;
+
+               trace_spi_transfer_stop(msg, xfer);
        }
 
        if (as->use_pdc)
index 3b1833e..74842f6 100644 (file)
@@ -460,7 +460,6 @@ static int spi_engine_probe(struct platform_device *pdev)
        struct spi_engine *spi_engine;
        struct spi_master *master;
        unsigned int version;
-       struct resource *res;
        int irq;
        int ret;
 
@@ -480,8 +479,7 @@ static int spi_engine_probe(struct platform_device *pdev)
 
        spin_lock_init(&spi_engine->lock);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       spi_engine->base = devm_ioremap_resource(&pdev->dev, res);
+       spi_engine->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(spi_engine->base)) {
                ret = PTR_ERR(spi_engine->base);
                goto err_put_master;
index 902bdbf..7a35318 100644 (file)
@@ -343,7 +343,7 @@ static int bcm_qspi_bspi_set_flex_mode(struct bcm_qspi *qspi,
 {
        int bpc = 0, bpp = 0;
        u8 command = op->cmd.opcode;
-       int width  = op->cmd.buswidth ? op->cmd.buswidth : SPI_NBITS_SINGLE;
+       int width = op->data.buswidth ? op->data.buswidth : SPI_NBITS_SINGLE;
        int addrlen = op->addr.nbytes;
        int flex_mode = 1;
 
@@ -897,6 +897,7 @@ static int bcm_qspi_transfer_one(struct spi_master *master,
 
                read_from_hw(qspi, slots);
        }
+       bcm_qspi_enable_bspi(qspi);
 
        return 0;
 }
@@ -981,7 +982,7 @@ static int bcm_qspi_exec_mem_op(struct spi_mem *mem,
        if (mspi_read)
                return bcm_qspi_mspi_exec_mem_op(spi, op);
 
-       ret = bcm_qspi_bspi_set_mode(qspi, op, -1);
+       ret = bcm_qspi_bspi_set_mode(qspi, op, 0);
 
        if (!ret)
                ret = bcm_qspi_bspi_exec_mem_op(spi, op);
index 840b1b8..b4070c0 100644 (file)
@@ -25,7 +25,9 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
-#include <linux/of_gpio.h>
+#include <linux/gpio/consumer.h>
+#include <linux/gpio/machine.h> /* FIXME: using chip internals */
+#include <linux/gpio/driver.h> /* FIXME: using chip internals */
 #include <linux/of_irq.h>
 #include <linux/spi/spi.h>
 
@@ -66,6 +68,7 @@
 #define BCM2835_SPI_FIFO_SIZE          64
 #define BCM2835_SPI_FIFO_SIZE_3_4      48
 #define BCM2835_SPI_DMA_MIN_LENGTH     96
+#define BCM2835_SPI_NUM_CS             3   /* raise as necessary */
 #define BCM2835_SPI_MODE_BITS  (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
                                | SPI_NO_CS | SPI_3WIRE)
 
@@ -92,7 +95,8 @@ MODULE_PARM_DESC(polling_limit_us,
  * @rx_prologue: bytes received without DMA if first RX sglist entry's
  *     length is not a multiple of 4 (to overcome hardware limitation)
  * @tx_spillover: whether @tx_prologue spills over to second TX sglist entry
- * @dma_pending: whether a DMA transfer is in progress
+ * @prepare_cs: precalculated CS register value for ->prepare_message()
+ *     (uses slave-specific clock polarity and phase settings)
  * @debugfs_dir: the debugfs directory - neede to remove debugfs when
  *      unloading the module
  * @count_transfer_polling: count of how often polling mode is used
@@ -102,6 +106,19 @@ MODULE_PARM_DESC(polling_limit_us,
  *      These are counted as well in @count_transfer_polling and
  *      @count_transfer_irq
  * @count_transfer_dma: count how often dma mode is used
+ * @chip_select: SPI slave currently selected
+ *     (used by bcm2835_spi_dma_tx_done() to write @clear_rx_cs)
+ * @tx_dma_active: whether a TX DMA descriptor is in progress
+ * @rx_dma_active: whether a RX DMA descriptor is in progress
+ *     (used by bcm2835_spi_dma_tx_done() to handle a race)
+ * @fill_tx_desc: preallocated TX DMA descriptor used for RX-only transfers
+ *     (cyclically copies from zero page to TX FIFO)
+ * @fill_tx_addr: bus address of zero page
+ * @clear_rx_desc: preallocated RX DMA descriptor used for TX-only transfers
+ *     (cyclically clears RX FIFO by writing @clear_rx_cs to CS register)
+ * @clear_rx_addr: bus address of @clear_rx_cs
+ * @clear_rx_cs: precalculated CS register value to clear RX FIFO
+ *     (uses slave-specific clock polarity and phase settings)
  */
 struct bcm2835_spi {
        void __iomem *regs;
@@ -115,13 +132,22 @@ struct bcm2835_spi {
        int tx_prologue;
        int rx_prologue;
        unsigned int tx_spillover;
-       unsigned int dma_pending;
+       u32 prepare_cs[BCM2835_SPI_NUM_CS];
 
        struct dentry *debugfs_dir;
        u64 count_transfer_polling;
        u64 count_transfer_irq;
        u64 count_transfer_irq_after_polling;
        u64 count_transfer_dma;
+
+       u8 chip_select;
+       unsigned int tx_dma_active;
+       unsigned int rx_dma_active;
+       struct dma_async_tx_descriptor *fill_tx_desc;
+       dma_addr_t fill_tx_addr;
+       struct dma_async_tx_descriptor *clear_rx_desc[BCM2835_SPI_NUM_CS];
+       dma_addr_t clear_rx_addr;
+       u32 clear_rx_cs[BCM2835_SPI_NUM_CS] ____cacheline_aligned;
 };
 
 #if defined(CONFIG_DEBUG_FS)
@@ -319,6 +345,13 @@ static void bcm2835_spi_reset_hw(struct spi_controller *ctlr)
                BCM2835_SPI_CS_INTD |
                BCM2835_SPI_CS_DMAEN |
                BCM2835_SPI_CS_TA);
+       /*
+        * Transmission sometimes breaks unless the DONE bit is written at the
+        * end of every transfer.  The spec says it's a RO bit.  Either the
+        * spec is wrong and the bit is actually of type RW1C, or it's a
+        * hardware erratum.
+        */
+       cs |= BCM2835_SPI_CS_DONE;
        /* and reset RX/TX FIFOS */
        cs |= BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX;
 
@@ -448,14 +481,14 @@ static void bcm2835_spi_transfer_prologue(struct spi_controller *ctlr,
        bs->rx_prologue  = 0;
        bs->tx_spillover = false;
 
-       if (!sg_is_last(&tfr->tx_sg.sgl[0]))
+       if (bs->tx_buf && !sg_is_last(&tfr->tx_sg.sgl[0]))
                bs->tx_prologue = sg_dma_len(&tfr->tx_sg.sgl[0]) & 3;
 
-       if (!sg_is_last(&tfr->rx_sg.sgl[0])) {
+       if (bs->rx_buf && !sg_is_last(&tfr->rx_sg.sgl[0])) {
                bs->rx_prologue = sg_dma_len(&tfr->rx_sg.sgl[0]) & 3;
 
                if (bs->rx_prologue > bs->tx_prologue) {
-                       if (sg_is_last(&tfr->tx_sg.sgl[0])) {
+                       if (!bs->tx_buf || sg_is_last(&tfr->tx_sg.sgl[0])) {
                                bs->tx_prologue  = bs->rx_prologue;
                        } else {
                                bs->tx_prologue += 4;
@@ -477,7 +510,9 @@ static void bcm2835_spi_transfer_prologue(struct spi_controller *ctlr,
                bcm2835_wr_fifo_count(bs, bs->rx_prologue);
                bcm2835_wait_tx_fifo_empty(bs);
                bcm2835_rd_fifo_count(bs, bs->rx_prologue);
-               bcm2835_spi_reset_hw(ctlr);
+               bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_CLEAR_RX
+                                                 | BCM2835_SPI_CS_CLEAR_TX
+                                                 | BCM2835_SPI_CS_DONE);
 
                dma_sync_single_for_device(ctlr->dma_rx->device->dev,
                                           sg_dma_address(&tfr->rx_sg.sgl[0]),
@@ -487,6 +522,9 @@ static void bcm2835_spi_transfer_prologue(struct spi_controller *ctlr,
                sg_dma_len(&tfr->rx_sg.sgl[0])     -= bs->rx_prologue;
        }
 
+       if (!bs->tx_buf)
+               return;
+
        /*
         * Write remaining TX prologue.  Adjust first entry in TX sglist.
         * Also adjust second entry if prologue spills over to it.
@@ -498,7 +536,8 @@ static void bcm2835_spi_transfer_prologue(struct spi_controller *ctlr,
                                                  | BCM2835_SPI_CS_DMAEN);
                bcm2835_wr_fifo_count(bs, tx_remaining);
                bcm2835_wait_tx_fifo_empty(bs);
-               bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_CLEAR_TX);
+               bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_CLEAR_TX
+                                                 | BCM2835_SPI_CS_DONE);
        }
 
        if (likely(!bs->tx_spillover)) {
@@ -531,6 +570,9 @@ static void bcm2835_spi_undo_prologue(struct bcm2835_spi *bs)
                sg_dma_len(&tfr->rx_sg.sgl[0])     += bs->rx_prologue;
        }
 
+       if (!bs->tx_buf)
+               goto out;
+
        if (likely(!bs->tx_spillover)) {
                sg_dma_address(&tfr->tx_sg.sgl[0]) -= bs->tx_prologue;
                sg_dma_len(&tfr->tx_sg.sgl[0])     += bs->tx_prologue;
@@ -539,32 +581,85 @@ static void bcm2835_spi_undo_prologue(struct bcm2835_spi *bs)
                sg_dma_address(&tfr->tx_sg.sgl[1]) -= 4;
                sg_dma_len(&tfr->tx_sg.sgl[1])     += 4;
        }
+out:
+       bs->tx_prologue = 0;
 }
 
-static void bcm2835_spi_dma_done(void *data)
+/**
+ * bcm2835_spi_dma_rx_done() - callback for DMA RX channel
+ * @data: SPI master controller
+ *
+ * Used for bidirectional and RX-only transfers.
+ */
+static void bcm2835_spi_dma_rx_done(void *data)
 {
        struct spi_controller *ctlr = data;
        struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
 
-       /* reset fifo and HW */
-       bcm2835_spi_reset_hw(ctlr);
-
-       /* and terminate tx-dma as we do not have an irq for it
+       /* terminate tx-dma as we do not have an irq for it
         * because when the rx dma will terminate and this callback
         * is called the tx-dma must have finished - can't get to this
         * situation otherwise...
         */
-       if (cmpxchg(&bs->dma_pending, true, false)) {
-               dmaengine_terminate_async(ctlr->dma_tx);
-               bcm2835_spi_undo_prologue(bs);
-       }
+       dmaengine_terminate_async(ctlr->dma_tx);
+       bs->tx_dma_active = false;
+       bs->rx_dma_active = false;
+       bcm2835_spi_undo_prologue(bs);
+
+       /* reset fifo and HW */
+       bcm2835_spi_reset_hw(ctlr);
 
        /* and mark as completed */;
        complete(&ctlr->xfer_completion);
 }
 
+/**
+ * bcm2835_spi_dma_tx_done() - callback for DMA TX channel
+ * @data: SPI master controller
+ *
+ * Used for TX-only transfers.
+ */
+static void bcm2835_spi_dma_tx_done(void *data)
+{
+       struct spi_controller *ctlr = data;
+       struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
+
+       /* busy-wait for TX FIFO to empty */
+       while (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE))
+               bcm2835_wr(bs, BCM2835_SPI_CS,
+                          bs->clear_rx_cs[bs->chip_select]);
+
+       bs->tx_dma_active = false;
+       smp_wmb();
+
+       /*
+        * In case of a very short transfer, RX DMA may not have been
+        * issued yet.  The onus is then on bcm2835_spi_transfer_one_dma()
+        * to terminate it immediately after issuing.
+        */
+       if (cmpxchg(&bs->rx_dma_active, true, false))
+               dmaengine_terminate_async(ctlr->dma_rx);
+
+       bcm2835_spi_undo_prologue(bs);
+       bcm2835_spi_reset_hw(ctlr);
+       complete(&ctlr->xfer_completion);
+}
+
+/**
+ * bcm2835_spi_prepare_sg() - prepare and submit DMA descriptor for sglist
+ * @ctlr: SPI master controller
+ * @spi: SPI slave
+ * @tfr: SPI transfer
+ * @bs: BCM2835 SPI controller
+ * @is_tx: whether to submit DMA descriptor for TX or RX sglist
+ *
+ * Prepare and submit a DMA descriptor for the TX or RX sglist of @tfr.
+ * Return 0 on success or a negative error number.
+ */
 static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
+                                 struct spi_device *spi,
                                  struct spi_transfer *tfr,
+                                 struct bcm2835_spi *bs,
                                  bool is_tx)
 {
        struct dma_chan *chan;
@@ -581,8 +676,7 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
                chan  = ctlr->dma_tx;
                nents = tfr->tx_sg.nents;
                sgl   = tfr->tx_sg.sgl;
-               flags = 0 /* no  tx interrupt */;
-
+               flags = tfr->rx_buf ? 0 : DMA_PREP_INTERRUPT;
        } else {
                dir   = DMA_DEV_TO_MEM;
                chan  = ctlr->dma_rx;
@@ -595,10 +689,17 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
        if (!desc)
                return -EINVAL;
 
-       /* set callback for rx */
+       /*
+        * Completion is signaled by the RX channel for bidirectional and
+        * RX-only transfers; else by the TX channel for TX-only transfers.
+        */
        if (!is_tx) {
-               desc->callback = bcm2835_spi_dma_done;
+               desc->callback = bcm2835_spi_dma_rx_done;
+               desc->callback_param = ctlr;
+       } else if (!tfr->rx_buf) {
+               desc->callback = bcm2835_spi_dma_tx_done;
                desc->callback_param = ctlr;
+               bs->chip_select = spi->chip_select;
        }
 
        /* submit it to DMA-engine */
@@ -607,12 +708,60 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
        return dma_submit_error(cookie);
 }
 
+/**
+ * bcm2835_spi_transfer_one_dma() - perform SPI transfer using DMA engine
+ * @ctlr: SPI master controller
+ * @spi: SPI slave
+ * @tfr: SPI transfer
+ * @cs: CS register
+ *
+ * For *bidirectional* transfers (both tx_buf and rx_buf are non-%NULL), set up
+ * the TX and RX DMA channel to copy between memory and FIFO register.
+ *
+ * For *TX-only* transfers (rx_buf is %NULL), copying the RX FIFO's contents to
+ * memory is pointless.  However not reading the RX FIFO isn't an option either
+ * because transmission is halted once it's full.  As a workaround, cyclically
+ * clear the RX FIFO by setting the CLEAR_RX bit in the CS register.
+ *
+ * The CS register value is precalculated in bcm2835_spi_setup().  Normally
+ * this is called only once, on slave registration.  A DMA descriptor to write
+ * this value is preallocated in bcm2835_dma_init().  All that's left to do
+ * when performing a TX-only transfer is to submit this descriptor to the RX
+ * DMA channel.  Latency is thereby minimized.  The descriptor does not
+ * generate any interrupts while running.  It must be terminated once the
+ * TX DMA channel is done.
+ *
+ * Clearing the RX FIFO is paced by the DREQ signal.  The signal is asserted
+ * when the RX FIFO becomes half full, i.e. 32 bytes.  (Tuneable with the DC
+ * register.)  Reading 32 bytes from the RX FIFO would normally require 8 bus
+ * accesses, whereas clearing it requires only 1 bus access.  So an 8-fold
+ * reduction in bus traffic and thus energy consumption is achieved.
+ *
+ * For *RX-only* transfers (tx_buf is %NULL), fill the TX FIFO by cyclically
+ * copying from the zero page.  The DMA descriptor to do this is preallocated
+ * in bcm2835_dma_init().  It must be terminated once the RX DMA channel is
+ * done and can then be reused.
+ *
+ * The BCM2835 DMA driver autodetects when a transaction copies from the zero
+ * page and utilizes the DMA controller's ability to synthesize zeroes instead
+ * of copying them from memory.  This reduces traffic on the memory bus.  The
+ * feature is not available on so-called "lite" channels, but normally TX DMA
+ * is backed by a full-featured channel.
+ *
+ * Zero-filling the TX FIFO is paced by the DREQ signal.  Unfortunately the
+ * BCM2835 SPI controller continues to assert DREQ even after the DLEN register
+ * has been counted down to zero (hardware erratum).  Thus, when the transfer
+ * has finished, the DMA engine zero-fills the TX FIFO until it is half full.
+ * (Tuneable with the DC register.)  So up to 9 gratuitous bus accesses are
+ * performed at the end of an RX-only transfer.
+ */
 static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr,
                                        struct spi_device *spi,
                                        struct spi_transfer *tfr,
                                        u32 cs)
 {
        struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
+       dma_cookie_t cookie;
        int ret;
 
        /* update usage statistics */
@@ -625,16 +774,15 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr,
        bcm2835_spi_transfer_prologue(ctlr, tfr, bs, cs);
 
        /* setup tx-DMA */
-       ret = bcm2835_spi_prepare_sg(ctlr, tfr, true);
+       if (bs->tx_buf) {
+               ret = bcm2835_spi_prepare_sg(ctlr, spi, tfr, bs, true);
+       } else {
+               cookie = dmaengine_submit(bs->fill_tx_desc);
+               ret = dma_submit_error(cookie);
+       }
        if (ret)
                goto err_reset_hw;
 
-       /* start TX early */
-       dma_async_issue_pending(ctlr->dma_tx);
-
-       /* mark as dma pending */
-       bs->dma_pending = 1;
-
        /* set the DMA length */
        bcm2835_wr(bs, BCM2835_SPI_DLEN, bs->tx_len);
 
@@ -642,20 +790,43 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr,
        bcm2835_wr(bs, BCM2835_SPI_CS,
                   cs | BCM2835_SPI_CS_TA | BCM2835_SPI_CS_DMAEN);
 
+       bs->tx_dma_active = true;
+       smp_wmb();
+
+       /* start TX early */
+       dma_async_issue_pending(ctlr->dma_tx);
+
        /* setup rx-DMA late - to run transfers while
         * mapping of the rx buffers still takes place
         * this saves 10us or more.
         */
-       ret = bcm2835_spi_prepare_sg(ctlr, tfr, false);
+       if (bs->rx_buf) {
+               ret = bcm2835_spi_prepare_sg(ctlr, spi, tfr, bs, false);
+       } else {
+               cookie = dmaengine_submit(bs->clear_rx_desc[spi->chip_select]);
+               ret = dma_submit_error(cookie);
+       }
        if (ret) {
                /* need to reset on errors */
                dmaengine_terminate_sync(ctlr->dma_tx);
-               bs->dma_pending = false;
+               bs->tx_dma_active = false;
                goto err_reset_hw;
        }
 
        /* start rx dma late */
        dma_async_issue_pending(ctlr->dma_rx);
+       bs->rx_dma_active = true;
+       smp_mb();
+
+       /*
+        * In case of a very short TX-only transfer, bcm2835_spi_dma_tx_done()
+        * may run before RX DMA is issued.  Terminate RX DMA if so.
+        */
+       if (!bs->rx_buf && !bs->tx_dma_active &&
+           cmpxchg(&bs->rx_dma_active, true, false)) {
+               dmaengine_terminate_async(ctlr->dma_rx);
+               bcm2835_spi_reset_hw(ctlr);
+       }
 
        /* wait for wakeup in framework */
        return 1;
@@ -678,26 +849,52 @@ static bool bcm2835_spi_can_dma(struct spi_controller *ctlr,
        return true;
 }
 
-static void bcm2835_dma_release(struct spi_controller *ctlr)
+static void bcm2835_dma_release(struct spi_controller *ctlr,
+                               struct bcm2835_spi *bs)
 {
+       int i;
+
        if (ctlr->dma_tx) {
                dmaengine_terminate_sync(ctlr->dma_tx);
+
+               if (bs->fill_tx_desc)
+                       dmaengine_desc_free(bs->fill_tx_desc);
+
+               if (bs->fill_tx_addr)
+                       dma_unmap_page_attrs(ctlr->dma_tx->device->dev,
+                                            bs->fill_tx_addr, sizeof(u32),
+                                            DMA_TO_DEVICE,
+                                            DMA_ATTR_SKIP_CPU_SYNC);
+
                dma_release_channel(ctlr->dma_tx);
                ctlr->dma_tx = NULL;
        }
+
        if (ctlr->dma_rx) {
                dmaengine_terminate_sync(ctlr->dma_rx);
+
+               for (i = 0; i < BCM2835_SPI_NUM_CS; i++)
+                       if (bs->clear_rx_desc[i])
+                               dmaengine_desc_free(bs->clear_rx_desc[i]);
+
+               if (bs->clear_rx_addr)
+                       dma_unmap_single(ctlr->dma_rx->device->dev,
+                                        bs->clear_rx_addr,
+                                        sizeof(bs->clear_rx_cs),
+                                        DMA_TO_DEVICE);
+
                dma_release_channel(ctlr->dma_rx);
                ctlr->dma_rx = NULL;
        }
 }
 
-static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev)
+static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev,
+                            struct bcm2835_spi *bs)
 {
        struct dma_slave_config slave_config;
        const __be32 *addr;
        dma_addr_t dma_reg_base;
-       int ret;
+       int ret, i;
 
        /* base address in dma-space */
        addr = of_get_address(ctlr->dev.of_node, 0, NULL, NULL);
@@ -719,7 +916,11 @@ static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev)
                goto err_release;
        }
 
-       /* configure DMAs */
+       /*
+        * The TX DMA channel either copies a transfer's TX buffer to the FIFO
+        * or, in case of an RX-only transfer, cyclically copies from the zero
+        * page to the FIFO using a preallocated, reusable descriptor.
+        */
        slave_config.dst_addr = (u32)(dma_reg_base + BCM2835_SPI_FIFO);
        slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 
@@ -727,17 +928,74 @@ static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev)
        if (ret)
                goto err_config;
 
+       bs->fill_tx_addr = dma_map_page_attrs(ctlr->dma_tx->device->dev,
+                                             ZERO_PAGE(0), 0, sizeof(u32),
+                                             DMA_TO_DEVICE,
+                                             DMA_ATTR_SKIP_CPU_SYNC);
+       if (dma_mapping_error(ctlr->dma_tx->device->dev, bs->fill_tx_addr)) {
+               dev_err(dev, "cannot map zero page - not using DMA mode\n");
+               bs->fill_tx_addr = 0;
+               goto err_release;
+       }
+
+       bs->fill_tx_desc = dmaengine_prep_dma_cyclic(ctlr->dma_tx,
+                                                    bs->fill_tx_addr,
+                                                    sizeof(u32), 0,
+                                                    DMA_MEM_TO_DEV, 0);
+       if (!bs->fill_tx_desc) {
+               dev_err(dev, "cannot prepare fill_tx_desc - not using DMA mode\n");
+               goto err_release;
+       }
+
+       ret = dmaengine_desc_set_reuse(bs->fill_tx_desc);
+       if (ret) {
+               dev_err(dev, "cannot reuse fill_tx_desc - not using DMA mode\n");
+               goto err_release;
+       }
+
+       /*
+        * The RX DMA channel is used bidirectionally:  It either reads the
+        * RX FIFO or, in case of a TX-only transfer, cyclically writes a
+        * precalculated value to the CS register to clear the RX FIFO.
+        */
        slave_config.src_addr = (u32)(dma_reg_base + BCM2835_SPI_FIFO);
        slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+       slave_config.dst_addr = (u32)(dma_reg_base + BCM2835_SPI_CS);
+       slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 
        ret = dmaengine_slave_config(ctlr->dma_rx, &slave_config);
        if (ret)
                goto err_config;
 
+       bs->clear_rx_addr = dma_map_single(ctlr->dma_rx->device->dev,
+                                          bs->clear_rx_cs,
+                                          sizeof(bs->clear_rx_cs),
+                                          DMA_TO_DEVICE);
+       if (dma_mapping_error(ctlr->dma_rx->device->dev, bs->clear_rx_addr)) {
+               dev_err(dev, "cannot map clear_rx_cs - not using DMA mode\n");
+               bs->clear_rx_addr = 0;
+               goto err_release;
+       }
+
+       for (i = 0; i < BCM2835_SPI_NUM_CS; i++) {
+               bs->clear_rx_desc[i] = dmaengine_prep_dma_cyclic(ctlr->dma_rx,
+                                          bs->clear_rx_addr + i * sizeof(u32),
+                                          sizeof(u32), 0,
+                                          DMA_MEM_TO_DEV, 0);
+               if (!bs->clear_rx_desc[i]) {
+                       dev_err(dev, "cannot prepare clear_rx_desc - not using DMA mode\n");
+                       goto err_release;
+               }
+
+               ret = dmaengine_desc_set_reuse(bs->clear_rx_desc[i]);
+               if (ret) {
+                       dev_err(dev, "cannot reuse clear_rx_desc - not using DMA mode\n");
+                       goto err_release;
+               }
+       }
+
        /* all went well, so set can_dma */
        ctlr->can_dma = bcm2835_spi_can_dma;
-       /* need to do TX AND RX DMA, so we need dummy buffers */
-       ctlr->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX;
 
        return;
 
@@ -745,7 +1003,7 @@ err_config:
        dev_err(dev, "issue configuring dma: %d - not using DMA mode\n",
                ret);
 err_release:
-       bcm2835_dma_release(ctlr);
+       bcm2835_dma_release(ctlr, bs);
 err:
        return;
 }
@@ -812,7 +1070,7 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr,
        struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
        unsigned long spi_hz, clk_hz, cdiv, spi_used_hz;
        unsigned long hz_per_byte, byte_limit;
-       u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
+       u32 cs = bs->prepare_cs[spi->chip_select];
 
        /* set clock */
        spi_hz = tfr->speed_hz;
@@ -834,18 +1092,8 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr,
        bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv);
 
        /* handle all the 3-wire mode */
-       if (spi->mode & SPI_3WIRE && tfr->rx_buf &&
-           tfr->rx_buf != ctlr->dummy_rx)
+       if (spi->mode & SPI_3WIRE && tfr->rx_buf)
                cs |= BCM2835_SPI_CS_REN;
-       else
-               cs &= ~BCM2835_SPI_CS_REN;
-
-       /*
-        * The driver always uses software-controlled GPIO Chip Select.
-        * Set the hardware-controlled native Chip Select to an invalid
-        * value to prevent it from interfering.
-        */
-       cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01;
 
        /* set transmit buffers and length */
        bs->tx_buf = tfr->tx_buf;
@@ -882,7 +1130,6 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr,
 {
        struct spi_device *spi = msg->spi;
        struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
-       u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
        int ret;
 
        if (ctlr->can_dma) {
@@ -897,14 +1144,11 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr,
                        return ret;
        }
 
-       cs &= ~(BCM2835_SPI_CS_CPOL | BCM2835_SPI_CS_CPHA);
-
-       if (spi->mode & SPI_CPOL)
-               cs |= BCM2835_SPI_CS_CPOL;
-       if (spi->mode & SPI_CPHA)
-               cs |= BCM2835_SPI_CS_CPHA;
-
-       bcm2835_wr(bs, BCM2835_SPI_CS, cs);
+       /*
+        * Set up clock polarity before spi_transfer_one_message() asserts
+        * chip select to avoid a gratuitous clock signal edge.
+        */
+       bcm2835_wr(bs, BCM2835_SPI_CS, bs->prepare_cs[spi->chip_select]);
 
        return 0;
 }
@@ -915,11 +1159,12 @@ static void bcm2835_spi_handle_err(struct spi_controller *ctlr,
        struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
 
        /* if an error occurred and we have an active dma, then terminate */
-       if (cmpxchg(&bs->dma_pending, true, false)) {
-               dmaengine_terminate_sync(ctlr->dma_tx);
-               dmaengine_terminate_sync(ctlr->dma_rx);
-               bcm2835_spi_undo_prologue(bs);
-       }
+       dmaengine_terminate_sync(ctlr->dma_tx);
+       bs->tx_dma_active = false;
+       dmaengine_terminate_sync(ctlr->dma_rx);
+       bs->rx_dma_active = false;
+       bcm2835_spi_undo_prologue(bs);
+
        /* and reset */
        bcm2835_spi_reset_hw(ctlr);
 }
@@ -931,14 +1176,50 @@ static int chip_match_name(struct gpio_chip *chip, void *data)
 
 static int bcm2835_spi_setup(struct spi_device *spi)
 {
-       int err;
+       struct spi_controller *ctlr = spi->controller;
+       struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
        struct gpio_chip *chip;
+       enum gpio_lookup_flags lflags;
+       u32 cs;
+
+       /*
+        * Precalculate SPI slave's CS register value for ->prepare_message():
+        * The driver always uses software-controlled GPIO chip select, hence
+        * set the hardware-controlled native chip select to an invalid value
+        * to prevent it from interfering.
+        */
+       cs = BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01;
+       if (spi->mode & SPI_CPOL)
+               cs |= BCM2835_SPI_CS_CPOL;
+       if (spi->mode & SPI_CPHA)
+               cs |= BCM2835_SPI_CS_CPHA;
+       bs->prepare_cs[spi->chip_select] = cs;
+
+       /*
+        * Precalculate SPI slave's CS register value to clear RX FIFO
+        * in case of a TX-only DMA transfer.
+        */
+       if (ctlr->dma_rx) {
+               bs->clear_rx_cs[spi->chip_select] = cs |
+                                                   BCM2835_SPI_CS_TA |
+                                                   BCM2835_SPI_CS_DMAEN |
+                                                   BCM2835_SPI_CS_CLEAR_RX;
+               dma_sync_single_for_device(ctlr->dma_rx->device->dev,
+                                          bs->clear_rx_addr,
+                                          sizeof(bs->clear_rx_cs),
+                                          DMA_TO_DEVICE);
+       }
+
        /*
         * sanity checking the native-chipselects
         */
        if (spi->mode & SPI_NO_CS)
                return 0;
-       if (gpio_is_valid(spi->cs_gpio))
+       /*
+        * The SPI core has successfully requested the CS GPIO line from the
+        * device tree, so we are done.
+        */
+       if (spi->cs_gpiod)
                return 0;
        if (spi->chip_select > 1) {
                /* error in the case of native CS requested with CS > 1
@@ -949,29 +1230,43 @@ static int bcm2835_spi_setup(struct spi_device *spi)
                        "setup: only two native chip-selects are supported\n");
                return -EINVAL;
        }
-       /* now translate native cs to GPIO */
+
+       /*
+        * Translate native CS to GPIO
+        *
+        * FIXME: poking around in the gpiolib internals like this is
+        * not very good practice. Find a way to locate the real problem
+        * and fix it. Why is the GPIO descriptor in spi->cs_gpiod
+        * sometimes not assigned correctly? Erroneous device trees?
+        */
 
        /* get the gpio chip for the base */
        chip = gpiochip_find("pinctrl-bcm2835", chip_match_name);
        if (!chip)
                return 0;
 
-       /* and calculate the real CS */
-       spi->cs_gpio = chip->base + 8 - spi->chip_select;
+       /*
+        * Retrieve the corresponding GPIO line used for CS.
+        * The inversion semantics will be handled by the GPIO core
+        * code, so we pass GPIOS_OUT_LOW for "unasserted" and
+        * the correct flag for inversion semantics. The SPI_CS_HIGH
+        * on spi->mode cannot be checked for polarity in this case
+        * as the flag use_gpio_descriptors enforces SPI_CS_HIGH.
+        */
+       if (of_property_read_bool(spi->dev.of_node, "spi-cs-high"))
+               lflags = GPIO_ACTIVE_HIGH;
+       else
+               lflags = GPIO_ACTIVE_LOW;
+       spi->cs_gpiod = gpiochip_request_own_desc(chip, 8 - spi->chip_select,
+                                                 DRV_NAME,
+                                                 lflags,
+                                                 GPIOD_OUT_LOW);
+       if (IS_ERR(spi->cs_gpiod))
+               return PTR_ERR(spi->cs_gpiod);
 
        /* and set up the "mode" and level */
-       dev_info(&spi->dev, "setting up native-CS%i as GPIO %i\n",
-                spi->chip_select, spi->cs_gpio);
-
-       /* set up GPIO as output and pull to the correct level */
-       err = gpio_direction_output(spi->cs_gpio,
-                                   (spi->mode & SPI_CS_HIGH) ? 0 : 1);
-       if (err) {
-               dev_err(&spi->dev,
-                       "could not set CS%i gpio %i as output: %i",
-                       spi->chip_select, spi->cs_gpio, err);
-               return err;
-       }
+       dev_info(&spi->dev, "setting up native-CS%i to use GPIO\n",
+                spi->chip_select);
 
        return 0;
 }
@@ -980,18 +1275,19 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
 {
        struct spi_controller *ctlr;
        struct bcm2835_spi *bs;
-       struct resource *res;
        int err;
 
-       ctlr = spi_alloc_master(&pdev->dev, sizeof(*bs));
+       ctlr = spi_alloc_master(&pdev->dev, ALIGN(sizeof(*bs),
+                                                 dma_get_cache_alignment()));
        if (!ctlr)
                return -ENOMEM;
 
        platform_set_drvdata(pdev, ctlr);
 
+       ctlr->use_gpio_descriptors = true;
        ctlr->mode_bits = BCM2835_SPI_MODE_BITS;
        ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
-       ctlr->num_chipselect = 3;
+       ctlr->num_chipselect = BCM2835_SPI_NUM_CS;
        ctlr->setup = bcm2835_spi_setup;
        ctlr->transfer_one = bcm2835_spi_transfer_one;
        ctlr->handle_err = bcm2835_spi_handle_err;
@@ -1000,8 +1296,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
 
        bs = spi_controller_get_devdata(ctlr);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       bs->regs = devm_ioremap_resource(&pdev->dev, res);
+       bs->regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(bs->regs)) {
                err = PTR_ERR(bs->regs);
                goto out_controller_put;
@@ -1016,14 +1311,13 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
 
        bs->irq = platform_get_irq(pdev, 0);
        if (bs->irq <= 0) {
-               dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq);
                err = bs->irq ? bs->irq : -ENODEV;
                goto out_controller_put;
        }
 
        clk_prepare_enable(bs->clk);
 
-       bcm2835_dma_init(ctlr, &pdev->dev);
+       bcm2835_dma_init(ctlr, &pdev->dev, bs);
 
        /* initialise the hardware with the default polarities */
        bcm2835_wr(bs, BCM2835_SPI_CS,
@@ -1067,7 +1361,7 @@ static int bcm2835_spi_remove(struct platform_device *pdev)
 
        clk_disable_unprepare(bs->clk);
 
-       bcm2835_dma_release(ctlr);
+       bcm2835_dma_release(ctlr, bs);
 
        return 0;
 }
index bb57035..a2162ff 100644 (file)
@@ -491,7 +491,6 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
 {
        struct spi_master *master;
        struct bcm2835aux_spi *bs;
-       struct resource *res;
        unsigned long clk_hz;
        int err;
 
@@ -524,8 +523,7 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
        bs = spi_master_get_devdata(master);
 
        /* the main area */
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       bs->regs = devm_ioremap_resource(&pdev->dev, res);
+       bs->regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(bs->regs)) {
                err = PTR_ERR(bs->regs);
                goto out_master_put;
@@ -540,7 +538,6 @@ static int bcm2835aux_spi_probe(struct platform_device *pdev)
 
        bs->irq = platform_get_irq(pdev, 0);
        if (bs->irq <= 0) {
-               dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq);
                err = bs->irq ? bs->irq : -ENODEV;
                goto out_master_put;
        }
index 9a06ffd..c6836a9 100644 (file)
@@ -330,7 +330,6 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
 {
        struct spi_master *master;
        struct bcm63xx_hsspi *bs;
-       struct resource *res_mem;
        void __iomem *regs;
        struct device *dev = &pdev->dev;
        struct clk *clk, *pll_clk = NULL;
@@ -338,13 +337,10 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
        u32 reg, rate, num_cs = HSSPI_SPI_MAX_CS;
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(dev, "no irq: %d\n", irq);
+       if (irq < 0)
                return irq;
-       }
 
-       res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       regs = devm_ioremap_resource(dev, res_mem);
+       regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(regs))
                return PTR_ERR(regs);
 
index df1c94a..fdd7eaa 100644 (file)
@@ -520,10 +520,8 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
        }
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(dev, "no irq: %d\n", irq);
+       if (irq < 0)
                return irq;
-       }
 
        clk = devm_clk_get(dev, "spi");
        if (IS_ERR(clk)) {
index 7c41e4e..c36587b 100644 (file)
@@ -474,7 +474,6 @@ static int cdns_spi_probe(struct platform_device *pdev)
        int ret = 0, irq;
        struct spi_master *master;
        struct cdns_spi *xspi;
-       struct resource *res;
        u32 num_cs;
 
        master = spi_alloc_master(&pdev->dev, sizeof(*xspi));
@@ -485,8 +484,7 @@ static int cdns_spi_probe(struct platform_device *pdev)
        master->dev.of_node = pdev->dev.of_node;
        platform_set_drvdata(pdev, master);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       xspi->regs = devm_ioremap_resource(&pdev->dev, res);
+       xspi->regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(xspi->regs)) {
                ret = PTR_ERR(xspi->regs);
                goto remove_master;
@@ -540,7 +538,6 @@ static int cdns_spi_probe(struct platform_device *pdev)
        irq = platform_get_irq(pdev, 0);
        if (irq <= 0) {
                ret = -ENXIO;
-               dev_err(&pdev->dev, "irq number is invalid\n");
                goto clk_dis_all;
        }
 
index ee4703e..1a2de6c 100644 (file)
@@ -18,7 +18,6 @@
 
 static int octeon_spi_probe(struct platform_device *pdev)
 {
-       struct resource *res_mem;
        void __iomem *reg_base;
        struct spi_master *master;
        struct octeon_spi *p;
@@ -30,8 +29,7 @@ static int octeon_spi_probe(struct platform_device *pdev)
        p = spi_master_get_devdata(master);
        platform_set_drvdata(pdev, master);
 
-       res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       reg_base = devm_ioremap_resource(&pdev->dev, res_mem);
+       reg_base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(reg_base)) {
                err = PTR_ERR(reg_base);
                goto fail;
index 4daba12..5e900f2 100644 (file)
@@ -91,7 +91,6 @@ static int spi_clps711x_probe(struct platform_device *pdev)
 {
        struct spi_clps711x_data *hw;
        struct spi_master *master;
-       struct resource *res;
        int irq, ret;
 
        irq = platform_get_irq(pdev, 0);
@@ -125,8 +124,7 @@ static int spi_clps711x_probe(struct platform_device *pdev)
                goto err_out;
        }
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       hw->syncio = devm_ioremap_resource(&pdev->dev, res);
+       hw->syncio = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(hw->syncio)) {
                ret = PTR_ERR(hw->syncio);
                goto err_out;
index 5ff48ab..f80e06c 100644 (file)
@@ -339,7 +339,6 @@ static int mcfqspi_probe(struct platform_device *pdev)
 {
        struct spi_master *master;
        struct mcfqspi *mcfqspi;
-       struct resource *res;
        struct mcfqspi_platform_data *pdata;
        int status;
 
@@ -362,8 +361,7 @@ static int mcfqspi_probe(struct platform_device *pdev)
 
        mcfqspi = spi_master_get_devdata(master);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       mcfqspi->iobase = devm_ioremap_resource(&pdev->dev, res);
+       mcfqspi->iobase = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(mcfqspi->iobase)) {
                status = PTR_ERR(mcfqspi->iobase);
                goto fail0;
index 18c0656..bd46fca 100644 (file)
@@ -79,14 +79,12 @@ static int dw_spi_mscc_init(struct platform_device *pdev,
                            const char *cpu_syscon, u32 if_si_owner_offset)
 {
        struct dw_spi_mscc *dwsmscc;
-       struct resource *res;
 
        dwsmscc = devm_kzalloc(&pdev->dev, sizeof(*dwsmscc), GFP_KERNEL);
        if (!dwsmscc)
                return -ENOMEM;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       dwsmscc->spi_mst = devm_ioremap_resource(&pdev->dev, res);
+       dwsmscc->spi_mst = devm_platform_ioremap_resource(pdev, 1);
        if (IS_ERR(dwsmscc->spi_mst)) {
                dev_err(&pdev->dev, "SPI_MST region map failed\n");
                return PTR_ERR(dwsmscc->spi_mst);
@@ -138,7 +136,6 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
                         struct dw_spi_mmio *dwsmmio);
        struct dw_spi_mmio *dwsmmio;
        struct dw_spi *dws;
-       struct resource *mem;
        int ret;
        int num_cs;
 
@@ -150,18 +147,15 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
        dws = &dwsmmio->dws;
 
        /* Get basic io resource and map it */
-       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       dws->regs = devm_ioremap_resource(&pdev->dev, mem);
+       dws->regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(dws->regs)) {
                dev_err(&pdev->dev, "SPI region map failed\n");
                return PTR_ERR(dws->regs);
        }
 
        dws->irq = platform_get_irq(pdev, 0);
-       if (dws->irq < 0) {
-               dev_err(&pdev->dev, "no irq resource?\n");
+       if (dws->irq < 0)
                return dws->irq; /* -ENXIO */
-       }
 
        dwsmmio->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(dwsmmio->clk))
@@ -172,8 +166,10 @@ static int dw_spi_mmio_probe(struct platform_device *pdev)
 
        /* Optional clock needed to access the registers */
        dwsmmio->pclk = devm_clk_get_optional(&pdev->dev, "pclk");
-       if (IS_ERR(dwsmmio->pclk))
-               return PTR_ERR(dwsmmio->pclk);
+       if (IS_ERR(dwsmmio->pclk)) {
+               ret = PTR_ERR(dwsmmio->pclk);
+               goto out_clk;
+       }
        ret = clk_prepare_enable(dwsmmio->pclk);
        if (ret)
                goto out_clk;
index 9651679..1406449 100644 (file)
@@ -19,6 +19,7 @@ struct spi_pci_desc {
        int     (*setup)(struct dw_spi *);
        u16     num_cs;
        u16     bus_num;
+       u32     max_freq;
 };
 
 static struct spi_pci_desc spi_pci_mid_desc_1 = {
@@ -33,6 +34,12 @@ static struct spi_pci_desc spi_pci_mid_desc_2 = {
        .bus_num = 1,
 };
 
+static struct spi_pci_desc spi_pci_ehl_desc = {
+       .num_cs = 1,
+       .bus_num = -1,
+       .max_freq = 100000000,
+};
+
 static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        struct dw_spi *dws;
@@ -65,6 +72,7 @@ static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (desc) {
                dws->num_cs = desc->num_cs;
                dws->bus_num = desc->bus_num;
+               dws->max_freq = desc->max_freq;
 
                if (desc->setup) {
                        ret = desc->setup(dws);
@@ -98,16 +106,14 @@ static void spi_pci_remove(struct pci_dev *pdev)
 #ifdef CONFIG_PM_SLEEP
 static int spi_suspend(struct device *dev)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct dw_spi *dws = pci_get_drvdata(pdev);
+       struct dw_spi *dws = dev_get_drvdata(dev);
 
        return dw_spi_suspend_host(dws);
 }
 
 static int spi_resume(struct device *dev)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
-       struct dw_spi *dws = pci_get_drvdata(pdev);
+       struct dw_spi *dws = dev_get_drvdata(dev);
 
        return dw_spi_resume_host(dws);
 }
@@ -125,8 +131,14 @@ static const struct pci_device_id pci_ids[] = {
        { PCI_VDEVICE(INTEL, 0x0800), (kernel_ulong_t)&spi_pci_mid_desc_1},
        /* Intel MID platform SPI controller 2 */
        { PCI_VDEVICE(INTEL, 0x0812), (kernel_ulong_t)&spi_pci_mid_desc_2},
+       /* Intel Elkhart Lake PSE SPI controllers */
+       { PCI_VDEVICE(INTEL, 0x4b84), (kernel_ulong_t)&spi_pci_ehl_desc},
+       { PCI_VDEVICE(INTEL, 0x4b85), (kernel_ulong_t)&spi_pci_ehl_desc},
+       { PCI_VDEVICE(INTEL, 0x4b86), (kernel_ulong_t)&spi_pci_ehl_desc},
+       { PCI_VDEVICE(INTEL, 0x4b87), (kernel_ulong_t)&spi_pci_ehl_desc},
        {},
 };
+MODULE_DEVICE_TABLE(pci, pci_ids);
 
 static struct pci_driver dw_spi_driver = {
        .name =         DRIVER_NAME,
index eb1f214..64d4c44 100644 (file)
@@ -400,10 +400,8 @@ static int efm32_spi_probe(struct platform_device *pdev)
        }
 
        ret = platform_get_irq(pdev, 0);
-       if (ret <= 0) {
-               dev_err(&pdev->dev, "failed to get rx irq (%d)\n", ret);
+       if (ret <= 0)
                goto err;
-       }
 
        ddata->rxirq = ret;
 
index 4034e3e..4e1ccd4 100644 (file)
@@ -656,10 +656,8 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
        }
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(&pdev->dev, "failed to get irq resources\n");
+       if (irq < 0)
                return -EBUSY;
-       }
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
index e967ac5..858f054 100644 (file)
@@ -305,12 +305,10 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
        }
 
        if (mspi->flags & SPI_CPM1) {
-               struct resource *res;
                void *pram;
 
-               res = platform_get_resource(to_platform_device(dev),
-                                           IORESOURCE_MEM, 1);
-               pram = devm_ioremap_resource(dev, res);
+               pram = devm_platform_ioremap_resource(to_platform_device(dev),
+                                                     1);
                if (IS_ERR(pram))
                        mspi->pram = NULL;
                else
index 53335cc..bec758e 100644 (file)
@@ -9,26 +9,16 @@
 #include <linux/delay.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
-#include <linux/err.h>
-#include <linux/errno.h>
 #include <linux/interrupt.h>
-#include <linux/io.h>
 #include <linux/kernel.h>
-#include <linux/math64.h>
 #include <linux/module.h>
-#include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/pinctrl/consumer.h>
-#include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
 #include <linux/regmap.h>
-#include <linux/sched.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi-fsl-dspi.h>
-#include <linux/spi/spi_bitbang.h>
-#include <linux/time.h>
 
-#define DRIVER_NAME "fsl-dspi"
+#define DRIVER_NAME                    "fsl-dspi"
 
 #ifdef CONFIG_M5441x
 #define DSPI_FIFO_SIZE                 16
 #endif
 #define DSPI_DMA_BUFSIZE               (DSPI_FIFO_SIZE * 1024)
 
-#define SPI_MCR                0x00
-#define SPI_MCR_MASTER         (1 << 31)
-#define SPI_MCR_PCSIS          (0x3F << 16)
-#define SPI_MCR_CLR_TXF        (1 << 11)
-#define SPI_MCR_CLR_RXF        (1 << 10)
-#define SPI_MCR_XSPI           (1 << 3)
-
-#define SPI_TCR                        0x08
-#define SPI_TCR_GET_TCNT(x)    (((x) & 0xffff0000) >> 16)
-
-#define SPI_CTAR(x)            (0x0c + (((x) & 0x3) * 4))
-#define SPI_CTAR_FMSZ(x)       (((x) & 0x0000000f) << 27)
-#define SPI_CTAR_CPOL(x)       ((x) << 26)
-#define SPI_CTAR_CPHA(x)       ((x) << 25)
-#define SPI_CTAR_LSBFE(x)      ((x) << 24)
-#define SPI_CTAR_PCSSCK(x)     (((x) & 0x00000003) << 22)
-#define SPI_CTAR_PASC(x)       (((x) & 0x00000003) << 20)
-#define SPI_CTAR_PDT(x)        (((x) & 0x00000003) << 18)
-#define SPI_CTAR_PBR(x)        (((x) & 0x00000003) << 16)
-#define SPI_CTAR_CSSCK(x)      (((x) & 0x0000000f) << 12)
-#define SPI_CTAR_ASC(x)        (((x) & 0x0000000f) << 8)
-#define SPI_CTAR_DT(x)         (((x) & 0x0000000f) << 4)
-#define SPI_CTAR_BR(x)         ((x) & 0x0000000f)
-#define SPI_CTAR_SCALE_BITS    0xf
-
-#define SPI_CTAR0_SLAVE        0x0c
-
-#define SPI_SR                 0x2c
-#define SPI_SR_EOQF            0x10000000
-#define SPI_SR_TCFQF           0x80000000
-#define SPI_SR_CLEAR           0x9aaf0000
-
-#define SPI_RSER_TFFFE         BIT(25)
-#define SPI_RSER_TFFFD         BIT(24)
-#define SPI_RSER_RFDFE         BIT(17)
-#define SPI_RSER_RFDFD         BIT(16)
-
-#define SPI_RSER               0x30
-#define SPI_RSER_EOQFE         0x10000000
-#define SPI_RSER_TCFQE         0x80000000
-
-#define SPI_PUSHR              0x34
-#define SPI_PUSHR_CMD_CONT     (1 << 15)
-#define SPI_PUSHR_CONT         (SPI_PUSHR_CMD_CONT << 16)
-#define SPI_PUSHR_CMD_CTAS(x)  (((x) & 0x0003) << 12)
-#define SPI_PUSHR_CTAS(x)      (SPI_PUSHR_CMD_CTAS(x) << 16)
-#define SPI_PUSHR_CMD_EOQ      (1 << 11)
-#define SPI_PUSHR_EOQ          (SPI_PUSHR_CMD_EOQ << 16)
-#define SPI_PUSHR_CMD_CTCNT    (1 << 10)
-#define SPI_PUSHR_CTCNT                (SPI_PUSHR_CMD_CTCNT << 16)
-#define SPI_PUSHR_CMD_PCS(x)   ((1 << x) & 0x003f)
-#define SPI_PUSHR_PCS(x)       (SPI_PUSHR_CMD_PCS(x) << 16)
-#define SPI_PUSHR_TXDATA(x)    ((x) & 0x0000ffff)
-
-#define SPI_PUSHR_SLAVE        0x34
-
-#define SPI_POPR               0x38
-#define SPI_POPR_RXDATA(x)     ((x) & 0x0000ffff)
-
-#define SPI_TXFR0              0x3c
-#define SPI_TXFR1              0x40
-#define SPI_TXFR2              0x44
-#define SPI_TXFR3              0x48
-#define SPI_RXFR0              0x7c
-#define SPI_RXFR1              0x80
-#define SPI_RXFR2              0x84
-#define SPI_RXFR3              0x88
-
-#define SPI_CTARE(x)           (0x11c + (((x) & 0x3) * 4))
-#define SPI_CTARE_FMSZE(x)     (((x) & 0x1) << 16)
-#define SPI_CTARE_DTCP(x)      ((x) & 0x7ff)
-
-#define SPI_SREX               0x13c
-
-#define SPI_FRAME_BITS(bits)   SPI_CTAR_FMSZ((bits) - 1)
-#define SPI_FRAME_BITS_MASK    SPI_CTAR_FMSZ(0xf)
-#define SPI_FRAME_BITS_16      SPI_CTAR_FMSZ(0xf)
-#define SPI_FRAME_BITS_8       SPI_CTAR_FMSZ(0x7)
-
-#define SPI_FRAME_EBITS(bits)  SPI_CTARE_FMSZE(((bits) - 1) >> 4)
-#define SPI_FRAME_EBITS_MASK   SPI_CTARE_FMSZE(1)
+#define SPI_MCR                                0x00
+#define SPI_MCR_MASTER                 BIT(31)
+#define SPI_MCR_PCSIS                  (0x3F << 16)
+#define SPI_MCR_CLR_TXF                        BIT(11)
+#define SPI_MCR_CLR_RXF                        BIT(10)
+#define SPI_MCR_XSPI                   BIT(3)
+
+#define SPI_TCR                                0x08
+#define SPI_TCR_GET_TCNT(x)            (((x) & GENMASK(31, 16)) >> 16)
+
+#define SPI_CTAR(x)                    (0x0c + (((x) & GENMASK(1, 0)) * 4))
+#define SPI_CTAR_FMSZ(x)               (((x) << 27) & GENMASK(30, 27))
+#define SPI_CTAR_CPOL                  BIT(26)
+#define SPI_CTAR_CPHA                  BIT(25)
+#define SPI_CTAR_LSBFE                 BIT(24)
+#define SPI_CTAR_PCSSCK(x)             (((x) << 22) & GENMASK(23, 22))
+#define SPI_CTAR_PASC(x)               (((x) << 20) & GENMASK(21, 20))
+#define SPI_CTAR_PDT(x)                        (((x) << 18) & GENMASK(19, 18))
+#define SPI_CTAR_PBR(x)                        (((x) << 16) & GENMASK(17, 16))
+#define SPI_CTAR_CSSCK(x)              (((x) << 12) & GENMASK(15, 12))
+#define SPI_CTAR_ASC(x)                        (((x) << 8) & GENMASK(11, 8))
+#define SPI_CTAR_DT(x)                 (((x) << 4) & GENMASK(7, 4))
+#define SPI_CTAR_BR(x)                 ((x) & GENMASK(3, 0))
+#define SPI_CTAR_SCALE_BITS            0xf
+
+#define SPI_CTAR0_SLAVE                        0x0c
+
+#define SPI_SR                         0x2c
+#define SPI_SR_TCFQF                   BIT(31)
+#define SPI_SR_EOQF                    BIT(28)
+#define SPI_SR_TFUF                    BIT(27)
+#define SPI_SR_TFFF                    BIT(25)
+#define SPI_SR_CMDTCF                  BIT(23)
+#define SPI_SR_SPEF                    BIT(21)
+#define SPI_SR_RFOF                    BIT(19)
+#define SPI_SR_TFIWF                   BIT(18)
+#define SPI_SR_RFDF                    BIT(17)
+#define SPI_SR_CMDFFF                  BIT(16)
+#define SPI_SR_CLEAR                   (SPI_SR_TCFQF | SPI_SR_EOQF | \
+                                       SPI_SR_TFUF | SPI_SR_TFFF | \
+                                       SPI_SR_CMDTCF | SPI_SR_SPEF | \
+                                       SPI_SR_RFOF | SPI_SR_TFIWF | \
+                                       SPI_SR_RFDF | SPI_SR_CMDFFF)
+
+#define SPI_RSER_TFFFE                 BIT(25)
+#define SPI_RSER_TFFFD                 BIT(24)
+#define SPI_RSER_RFDFE                 BIT(17)
+#define SPI_RSER_RFDFD                 BIT(16)
+
+#define SPI_RSER                       0x30
+#define SPI_RSER_TCFQE                 BIT(31)
+#define SPI_RSER_EOQFE                 BIT(28)
+
+#define SPI_PUSHR                      0x34
+#define SPI_PUSHR_CMD_CONT             BIT(15)
+#define SPI_PUSHR_CMD_CTAS(x)          (((x) << 12 & GENMASK(14, 12)))
+#define SPI_PUSHR_CMD_EOQ              BIT(11)
+#define SPI_PUSHR_CMD_CTCNT            BIT(10)
+#define SPI_PUSHR_CMD_PCS(x)           (BIT(x) & GENMASK(5, 0))
+
+#define SPI_PUSHR_SLAVE                        0x34
+
+#define SPI_POPR                       0x38
+
+#define SPI_TXFR0                      0x3c
+#define SPI_TXFR1                      0x40
+#define SPI_TXFR2                      0x44
+#define SPI_TXFR3                      0x48
+#define SPI_RXFR0                      0x7c
+#define SPI_RXFR1                      0x80
+#define SPI_RXFR2                      0x84
+#define SPI_RXFR3                      0x88
+
+#define SPI_CTARE(x)                   (0x11c + (((x) & GENMASK(1, 0)) * 4))
+#define SPI_CTARE_FMSZE(x)             (((x) & 0x1) << 16)
+#define SPI_CTARE_DTCP(x)              ((x) & 0x7ff)
+
+#define SPI_SREX                       0x13c
+
+#define SPI_FRAME_BITS(bits)           SPI_CTAR_FMSZ((bits) - 1)
+#define SPI_FRAME_EBITS(bits)          SPI_CTARE_FMSZE(((bits) - 1) >> 4)
 
 /* Register offsets for regmap_pushr */
-#define PUSHR_CMD              0x0
-#define PUSHR_TX               0x2
+#define PUSHR_CMD                      0x0
+#define PUSHR_TX                       0x2
 
-#define SPI_CS_INIT            0x01
-#define SPI_CS_ASSERT          0x02
-#define SPI_CS_DROP            0x04
-
-#define DMA_COMPLETION_TIMEOUT msecs_to_jiffies(3000)
+#define DMA_COMPLETION_TIMEOUT         msecs_to_jiffies(3000)
 
 struct chip_data {
-       u32 ctar_val;
-       u16 void_write_data;
+       u32                     ctar_val;
+       u16                     void_write_data;
 };
 
 enum dspi_trans_mode {
@@ -141,75 +127,75 @@ enum dspi_trans_mode {
 };
 
 struct fsl_dspi_devtype_data {
-       enum dspi_trans_mode trans_mode;
-       u8 max_clock_factor;
-       bool xspi_mode;
+       enum dspi_trans_mode    trans_mode;
+       u8                      max_clock_factor;
+       bool                    xspi_mode;
 };
 
 static const struct fsl_dspi_devtype_data vf610_data = {
-       .trans_mode = DSPI_DMA_MODE,
-       .max_clock_factor = 2,
+       .trans_mode             = DSPI_DMA_MODE,
+       .max_clock_factor       = 2,
 };
 
 static const struct fsl_dspi_devtype_data ls1021a_v1_data = {
-       .trans_mode = DSPI_TCFQ_MODE,
-       .max_clock_factor = 8,
-       .xspi_mode = true,
+       .trans_mode             = DSPI_TCFQ_MODE,
+       .max_clock_factor       = 8,
+       .xspi_mode              = true,
 };
 
 static const struct fsl_dspi_devtype_data ls2085a_data = {
-       .trans_mode = DSPI_TCFQ_MODE,
-       .max_clock_factor = 8,
+       .trans_mode             = DSPI_TCFQ_MODE,
+       .max_clock_factor       = 8,
 };
 
 static const struct fsl_dspi_devtype_data coldfire_data = {
-       .trans_mode = DSPI_EOQ_MODE,
-       .max_clock_factor = 8,
+       .trans_mode             = DSPI_EOQ_MODE,
+       .max_clock_factor       = 8,
 };
 
 struct fsl_dspi_dma {
        /* Length of transfer in words of DSPI_FIFO_SIZE */
-       u32 curr_xfer_len;
-
-       u32 *tx_dma_buf;
-       struct dma_chan *chan_tx;
-       dma_addr_t tx_dma_phys;
-       struct completion cmd_tx_complete;
-       struct dma_async_tx_descriptor *tx_desc;
-
-       u32 *rx_dma_buf;
-       struct dma_chan *chan_rx;
-       dma_addr_t rx_dma_phys;
-       struct completion cmd_rx_complete;
-       struct dma_async_tx_descriptor *rx_desc;
+       u32                                     curr_xfer_len;
+
+       u32                                     *tx_dma_buf;
+       struct dma_chan                         *chan_tx;
+       dma_addr_t                              tx_dma_phys;
+       struct completion                       cmd_tx_complete;
+       struct dma_async_tx_descriptor          *tx_desc;
+
+       u32                                     *rx_dma_buf;
+       struct dma_chan                         *chan_rx;
+       dma_addr_t                              rx_dma_phys;
+       struct completion                       cmd_rx_complete;
+       struct dma_async_tx_descriptor          *rx_desc;
 };
 
 struct fsl_dspi {
-       struct spi_master       *master;
-       struct platform_device  *pdev;
-
-       struct regmap           *regmap;
-       struct regmap           *regmap_pushr;
-       int                     irq;
-       struct clk              *clk;
-
-       struct spi_transfer     *cur_transfer;
-       struct spi_message      *cur_msg;
-       struct chip_data        *cur_chip;
-       size_t                  len;
-       const void              *tx;
-       void                    *rx;
-       void                    *rx_end;
-       u16                     void_write_data;
-       u16                     tx_cmd;
-       u8                      bits_per_word;
-       u8                      bytes_per_word;
-       const struct fsl_dspi_devtype_data *devtype_data;
-
-       wait_queue_head_t       waitq;
-       u32                     waitflags;
-
-       struct fsl_dspi_dma     *dma;
+       struct spi_controller                   *ctlr;
+       struct platform_device                  *pdev;
+
+       struct regmap                           *regmap;
+       struct regmap                           *regmap_pushr;
+       int                                     irq;
+       struct clk                              *clk;
+
+       struct spi_transfer                     *cur_transfer;
+       struct spi_message                      *cur_msg;
+       struct chip_data                        *cur_chip;
+       size_t                                  len;
+       const void                              *tx;
+       void                                    *rx;
+       void                                    *rx_end;
+       u16                                     void_write_data;
+       u16                                     tx_cmd;
+       u8                                      bits_per_word;
+       u8                                      bytes_per_word;
+       const struct fsl_dspi_devtype_data      *devtype_data;
+
+       wait_queue_head_t                       waitq;
+       u32                                     waitflags;
+
+       struct fsl_dspi_dma                     *dma;
 };
 
 static u32 dspi_pop_tx(struct fsl_dspi *dspi)
@@ -233,7 +219,7 @@ static u32 dspi_pop_tx_pushr(struct fsl_dspi *dspi)
 {
        u16 cmd = dspi->tx_cmd, data = dspi_pop_tx(dspi);
 
-       if (spi_controller_is_slave(dspi->master))
+       if (spi_controller_is_slave(dspi->ctlr))
                return data;
 
        if (dspi->len > 0)
@@ -246,7 +232,7 @@ static void dspi_push_rx(struct fsl_dspi *dspi, u32 rxdata)
        if (!dspi->rx)
                return;
 
-       /* Mask of undefined bits */
+       /* Mask off undefined bits */
        rxdata &= (1 << dspi->bits_per_word) - 1;
 
        if (dspi->bytes_per_word == 1)
@@ -282,8 +268,8 @@ static void dspi_rx_dma_callback(void *arg)
 
 static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 {
-       struct fsl_dspi_dma *dma = dspi->dma;
        struct device *dev = &dspi->pdev->dev;
+       struct fsl_dspi_dma *dma = dspi->dma;
        int time_left;
        int i;
 
@@ -332,13 +318,13 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
        dma_async_issue_pending(dma->chan_rx);
        dma_async_issue_pending(dma->chan_tx);
 
-       if (spi_controller_is_slave(dspi->master)) {
+       if (spi_controller_is_slave(dspi->ctlr)) {
                wait_for_completion_interruptible(&dspi->dma->cmd_rx_complete);
                return 0;
        }
 
        time_left = wait_for_completion_timeout(&dspi->dma->cmd_tx_complete,
-                                       DMA_COMPLETION_TIMEOUT);
+                                               DMA_COMPLETION_TIMEOUT);
        if (time_left == 0) {
                dev_err(dev, "DMA tx timeout\n");
                dmaengine_terminate_all(dma->chan_tx);
@@ -347,7 +333,7 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
        }
 
        time_left = wait_for_completion_timeout(&dspi->dma->cmd_rx_complete,
-                                       DMA_COMPLETION_TIMEOUT);
+                                               DMA_COMPLETION_TIMEOUT);
        if (time_left == 0) {
                dev_err(dev, "DMA rx timeout\n");
                dmaengine_terminate_all(dma->chan_tx);
@@ -360,9 +346,9 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
 
 static int dspi_dma_xfer(struct fsl_dspi *dspi)
 {
-       struct fsl_dspi_dma *dma = dspi->dma;
-       struct device *dev = &dspi->pdev->dev;
        struct spi_message *message = dspi->cur_msg;
+       struct device *dev = &dspi->pdev->dev;
+       struct fsl_dspi_dma *dma = dspi->dma;
        int curr_remaining_bytes;
        int bytes_per_buffer;
        int ret = 0;
@@ -397,9 +383,9 @@ exit:
 
 static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
 {
-       struct fsl_dspi_dma *dma;
-       struct dma_slave_config cfg;
        struct device *dev = &dspi->pdev->dev;
+       struct dma_slave_config cfg;
+       struct fsl_dspi_dma *dma;
        int ret;
 
        dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
@@ -421,14 +407,14 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr)
        }
 
        dma->tx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE,
-                                       &dma->tx_dma_phys, GFP_KERNEL);
+                                            &dma->tx_dma_phys, GFP_KERNEL);
        if (!dma->tx_dma_buf) {
                ret = -ENOMEM;
                goto err_tx_dma_buf;
        }
 
        dma->rx_dma_buf = dma_alloc_coherent(dev, DSPI_DMA_BUFSIZE,
-                                       &dma->rx_dma_phys, GFP_KERNEL);
+                                            &dma->rx_dma_phys, GFP_KERNEL);
        if (!dma->rx_dma_buf) {
                ret = -ENOMEM;
                goto err_rx_dma_buf;
@@ -485,30 +471,31 @@ static void dspi_release_dma(struct fsl_dspi *dspi)
        struct fsl_dspi_dma *dma = dspi->dma;
        struct device *dev = &dspi->pdev->dev;
 
-       if (dma) {
-               if (dma->chan_tx) {
-                       dma_unmap_single(dev, dma->tx_dma_phys,
-                                       DSPI_DMA_BUFSIZE, DMA_TO_DEVICE);
-                       dma_release_channel(dma->chan_tx);
-               }
+       if (!dma)
+               return;
 
-               if (dma->chan_rx) {
-                       dma_unmap_single(dev, dma->rx_dma_phys,
-                                       DSPI_DMA_BUFSIZE, DMA_FROM_DEVICE);
-                       dma_release_channel(dma->chan_rx);
-               }
+       if (dma->chan_tx) {
+               dma_unmap_single(dev, dma->tx_dma_phys,
+                                DSPI_DMA_BUFSIZE, DMA_TO_DEVICE);
+               dma_release_channel(dma->chan_tx);
+       }
+
+       if (dma->chan_rx) {
+               dma_unmap_single(dev, dma->rx_dma_phys,
+                                DSPI_DMA_BUFSIZE, DMA_FROM_DEVICE);
+               dma_release_channel(dma->chan_rx);
        }
 }
 
 static void hz_to_spi_baud(char *pbr, char *br, int speed_hz,
-               unsigned long clkrate)
+                          unsigned long clkrate)
 {
        /* Valid baud rate pre-scaler values */
        int pbr_tbl[4] = {2, 3, 5, 7};
        int brs[16] = { 2,      4,      6,      8,
-               16,     32,     64,     128,
-               256,    512,    1024,   2048,
-               4096,   8192,   16384,  32768 };
+                       16,     32,     64,     128,
+                       256,    512,    1024,   2048,
+                       4096,   8192,   16384,  32768 };
        int scale_needed, scale, minscale = INT_MAX;
        int i, j;
 
@@ -538,15 +525,15 @@ static void hz_to_spi_baud(char *pbr, char *br, int speed_hz,
 }
 
 static void ns_delay_scale(char *psc, char *sc, int delay_ns,
-               unsigned long clkrate)
+                          unsigned long clkrate)
 {
-       int pscale_tbl[4] = {1, 3, 5, 7};
        int scale_needed, scale, minscale = INT_MAX;
-       int i, j;
+       int pscale_tbl[4] = {1, 3, 5, 7};
        u32 remainder;
+       int i, j;
 
        scale_needed = div_u64_rem((u64)delay_ns * clkrate, NSEC_PER_SEC,
-                       &remainder);
+                                  &remainder);
        if (remainder)
                scale_needed++;
 
@@ -601,7 +588,7 @@ static void dspi_tcfq_write(struct fsl_dspi *dspi)
                 */
                u32 data = dspi_pop_tx(dspi);
 
-               if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE(1)) {
+               if (dspi->cur_chip->ctar_val & SPI_CTAR_LSBFE) {
                        /* LSB */
                        tx_fifo_write(dspi, data & 0xFFFF);
                        tx_fifo_write(dspi, data >> 16);
@@ -655,19 +642,90 @@ static void dspi_eoq_read(struct fsl_dspi *dspi)
 {
        int fifo_size = DSPI_FIFO_SIZE;
 
-       /* Read one FIFO entry at and push to rx buffer */
+       /* Read one FIFO entry and push to rx buffer */
        while ((dspi->rx < dspi->rx_end) && fifo_size--)
                dspi_push_rx(dspi, fifo_read(dspi));
 }
 
-static int dspi_transfer_one_message(struct spi_master *master,
-               struct spi_message *message)
+static int dspi_rxtx(struct fsl_dspi *dspi)
 {
-       struct fsl_dspi *dspi = spi_master_get_devdata(master);
+       struct spi_message *msg = dspi->cur_msg;
+       enum dspi_trans_mode trans_mode;
+       u16 spi_tcnt;
+       u32 spi_tcr;
+
+       /* Get transfer counter (in number of SPI transfers). It was
+        * reset to 0 when transfer(s) were started.
+        */
+       regmap_read(dspi->regmap, SPI_TCR, &spi_tcr);
+       spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr);
+       /* Update total number of bytes that were transferred */
+       msg->actual_length += spi_tcnt * dspi->bytes_per_word;
+
+       trans_mode = dspi->devtype_data->trans_mode;
+       if (trans_mode == DSPI_EOQ_MODE)
+               dspi_eoq_read(dspi);
+       else if (trans_mode == DSPI_TCFQ_MODE)
+               dspi_tcfq_read(dspi);
+
+       if (!dspi->len)
+               /* Success! */
+               return 0;
+
+       if (trans_mode == DSPI_EOQ_MODE)
+               dspi_eoq_write(dspi);
+       else if (trans_mode == DSPI_TCFQ_MODE)
+               dspi_tcfq_write(dspi);
+
+       return -EINPROGRESS;
+}
+
+static int dspi_poll(struct fsl_dspi *dspi)
+{
+       int tries = 1000;
+       u32 spi_sr;
+
+       do {
+               regmap_read(dspi->regmap, SPI_SR, &spi_sr);
+               regmap_write(dspi->regmap, SPI_SR, spi_sr);
+
+               if (spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF))
+                       break;
+       } while (--tries);
+
+       if (!tries)
+               return -ETIMEDOUT;
+
+       return dspi_rxtx(dspi);
+}
+
+static irqreturn_t dspi_interrupt(int irq, void *dev_id)
+{
+       struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id;
+       u32 spi_sr;
+
+       regmap_read(dspi->regmap, SPI_SR, &spi_sr);
+       regmap_write(dspi->regmap, SPI_SR, spi_sr);
+
+       if (!(spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF)))
+               return IRQ_NONE;
+
+       if (dspi_rxtx(dspi) == 0) {
+               dspi->waitflags = 1;
+               wake_up_interruptible(&dspi->waitq);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static int dspi_transfer_one_message(struct spi_controller *ctlr,
+                                    struct spi_message *message)
+{
+       struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr);
        struct spi_device *spi = message->spi;
+       enum dspi_trans_mode trans_mode;
        struct spi_transfer *transfer;
        int status = 0;
-       enum dspi_trans_mode trans_mode;
 
        message->actual_length = 0;
 
@@ -677,7 +735,7 @@ static int dspi_transfer_one_message(struct spi_master *master,
                dspi->cur_chip = spi_get_ctldata(spi);
                /* Prepare command word for CMD FIFO */
                dspi->tx_cmd = SPI_PUSHR_CMD_CTAS(0) |
-                       SPI_PUSHR_CMD_PCS(spi->chip_select);
+                              SPI_PUSHR_CMD_PCS(spi->chip_select);
                if (list_is_last(&dspi->cur_transfer->transfer_list,
                                 &dspi->cur_msg->transfers)) {
                        /* Leave PCS activated after last transfer when
@@ -718,8 +776,8 @@ static int dspi_transfer_one_message(struct spi_master *master,
                             SPI_FRAME_BITS(transfer->bits_per_word));
                if (dspi->devtype_data->xspi_mode)
                        regmap_write(dspi->regmap, SPI_CTARE(0),
-                                    SPI_FRAME_EBITS(transfer->bits_per_word)
-                                    SPI_CTARE_DTCP(1));
+                                    SPI_FRAME_EBITS(transfer->bits_per_word) |
+                                    SPI_CTARE_DTCP(1));
 
                trans_mode = dspi->devtype_data->trans_mode;
                switch (trans_mode) {
@@ -733,8 +791,8 @@ static int dspi_transfer_one_message(struct spi_master *master,
                        break;
                case DSPI_DMA_MODE:
                        regmap_write(dspi->regmap, SPI_RSER,
-                               SPI_RSER_TFFFE | SPI_RSER_TFFFD |
-                               SPI_RSER_RFDFE | SPI_RSER_RFDFD);
+                                    SPI_RSER_TFFFE | SPI_RSER_TFFFD |
+                                    SPI_RSER_RFDFE | SPI_RSER_RFDFD);
                        status = dspi_dma_xfer(dspi);
                        break;
                default:
@@ -744,13 +802,18 @@ static int dspi_transfer_one_message(struct spi_master *master,
                        goto out;
                }
 
-               if (trans_mode != DSPI_DMA_MODE) {
-                       if (wait_event_interruptible(dspi->waitq,
-                                               dspi->waitflags))
-                               dev_err(&dspi->pdev->dev,
-                                       "wait transfer complete fail!\n");
+               if (!dspi->irq) {
+                       do {
+                               status = dspi_poll(dspi);
+                       } while (status == -EINPROGRESS);
+               } else if (trans_mode != DSPI_DMA_MODE) {
+                       status = wait_event_interruptible(dspi->waitq,
+                                                         dspi->waitflags);
                        dspi->waitflags = 0;
                }
+               if (status)
+                       dev_err(&dspi->pdev->dev,
+                               "Waiting for transfer to complete failed!\n");
 
                if (transfer->delay_usecs)
                        udelay(transfer->delay_usecs);
@@ -758,19 +821,19 @@ static int dspi_transfer_one_message(struct spi_master *master,
 
 out:
        message->status = status;
-       spi_finalize_current_message(master);
+       spi_finalize_current_message(ctlr);
 
        return status;
 }
 
 static int dspi_setup(struct spi_device *spi)
 {
-       struct chip_data *chip;
-       struct fsl_dspi *dspi = spi_master_get_devdata(spi->master);
-       struct fsl_dspi_platform_data *pdata;
-       u32 cs_sck_delay = 0, sck_cs_delay = 0;
+       struct fsl_dspi *dspi = spi_controller_get_devdata(spi->controller);
        unsigned char br = 0, pbr = 0, pcssck = 0, cssck = 0;
+       u32 cs_sck_delay = 0, sck_cs_delay = 0;
+       struct fsl_dspi_platform_data *pdata;
        unsigned char pasc = 0, asc = 0;
+       struct chip_data *chip;
        unsigned long clkrate;
 
        /* Only alloc on first setup */
@@ -785,10 +848,10 @@ static int dspi_setup(struct spi_device *spi)
 
        if (!pdata) {
                of_property_read_u32(spi->dev.of_node, "fsl,spi-cs-sck-delay",
-                               &cs_sck_delay);
+                                    &cs_sck_delay);
 
                of_property_read_u32(spi->dev.of_node, "fsl,spi-sck-cs-delay",
-                               &sck_cs_delay);
+                                    &sck_cs_delay);
        } else {
                cs_sck_delay = pdata->cs_sck_delay;
                sck_cs_delay = pdata->sck_cs_delay;
@@ -805,18 +868,22 @@ static int dspi_setup(struct spi_device *spi)
        /* Set After SCK delay scale values */
        ns_delay_scale(&pasc, &asc, sck_cs_delay, clkrate);
 
-       chip->ctar_val = SPI_CTAR_CPOL(spi->mode & SPI_CPOL ? 1 : 0)
-               | SPI_CTAR_CPHA(spi->mode & SPI_CPHA ? 1 : 0);
-
-       if (!spi_controller_is_slave(dspi->master)) {
-               chip->ctar_val |= SPI_CTAR_LSBFE(spi->mode &
-                                                SPI_LSB_FIRST ? 1 : 0)
-                       | SPI_CTAR_PCSSCK(pcssck)
-                       | SPI_CTAR_CSSCK(cssck)
-                       | SPI_CTAR_PASC(pasc)
-                       | SPI_CTAR_ASC(asc)
-                       | SPI_CTAR_PBR(pbr)
-                       | SPI_CTAR_BR(br);
+       chip->ctar_val = 0;
+       if (spi->mode & SPI_CPOL)
+               chip->ctar_val |= SPI_CTAR_CPOL;
+       if (spi->mode & SPI_CPHA)
+               chip->ctar_val |= SPI_CTAR_CPHA;
+
+       if (!spi_controller_is_slave(dspi->ctlr)) {
+               chip->ctar_val |= SPI_CTAR_PCSSCK(pcssck) |
+                                 SPI_CTAR_CSSCK(cssck) |
+                                 SPI_CTAR_PASC(pasc) |
+                                 SPI_CTAR_ASC(asc) |
+                                 SPI_CTAR_PBR(pbr) |
+                                 SPI_CTAR_BR(br);
+
+               if (spi->mode & SPI_LSB_FIRST)
+                       chip->ctar_val |= SPI_CTAR_LSBFE;
        }
 
        spi_set_ctldata(spi, chip);
@@ -829,68 +896,11 @@ static void dspi_cleanup(struct spi_device *spi)
        struct chip_data *chip = spi_get_ctldata((struct spi_device *)spi);
 
        dev_dbg(&spi->dev, "spi_device %u.%u cleanup\n",
-                       spi->master->bus_num, spi->chip_select);
+               spi->controller->bus_num, spi->chip_select);
 
        kfree(chip);
 }
 
-static irqreturn_t dspi_interrupt(int irq, void *dev_id)
-{
-       struct fsl_dspi *dspi = (struct fsl_dspi *)dev_id;
-       struct spi_message *msg = dspi->cur_msg;
-       enum dspi_trans_mode trans_mode;
-       u32 spi_sr, spi_tcr;
-       u16 spi_tcnt;
-
-       regmap_read(dspi->regmap, SPI_SR, &spi_sr);
-       regmap_write(dspi->regmap, SPI_SR, spi_sr);
-
-
-       if (spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF)) {
-               /* Get transfer counter (in number of SPI transfers). It was
-                * reset to 0 when transfer(s) were started.
-                */
-               regmap_read(dspi->regmap, SPI_TCR, &spi_tcr);
-               spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr);
-               /* Update total number of bytes that were transferred */
-               msg->actual_length += spi_tcnt * dspi->bytes_per_word;
-
-               trans_mode = dspi->devtype_data->trans_mode;
-               switch (trans_mode) {
-               case DSPI_EOQ_MODE:
-                       dspi_eoq_read(dspi);
-                       break;
-               case DSPI_TCFQ_MODE:
-                       dspi_tcfq_read(dspi);
-                       break;
-               default:
-                       dev_err(&dspi->pdev->dev, "unsupported trans_mode %u\n",
-                               trans_mode);
-                               return IRQ_HANDLED;
-               }
-
-               if (!dspi->len) {
-                       dspi->waitflags = 1;
-                       wake_up_interruptible(&dspi->waitq);
-               } else {
-                       switch (trans_mode) {
-                       case DSPI_EOQ_MODE:
-                               dspi_eoq_write(dspi);
-                               break;
-                       case DSPI_TCFQ_MODE:
-                               dspi_tcfq_write(dspi);
-                               break;
-                       default:
-                               dev_err(&dspi->pdev->dev,
-                                       "unsupported trans_mode %u\n",
-                                       trans_mode);
-                       }
-               }
-       }
-
-       return IRQ_HANDLED;
-}
-
 static const struct of_device_id fsl_dspi_dt_ids[] = {
        { .compatible = "fsl,vf610-dspi", .data = &vf610_data, },
        { .compatible = "fsl,ls1021a-v1.0-dspi", .data = &ls1021a_v1_data, },
@@ -902,10 +912,10 @@ MODULE_DEVICE_TABLE(of, fsl_dspi_dt_ids);
 #ifdef CONFIG_PM_SLEEP
 static int dspi_suspend(struct device *dev)
 {
-       struct spi_master *master = dev_get_drvdata(dev);
-       struct fsl_dspi *dspi = spi_master_get_devdata(master);
+       struct spi_controller *ctlr = dev_get_drvdata(dev);
+       struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr);
 
-       spi_master_suspend(master);
+       spi_controller_suspend(ctlr);
        clk_disable_unprepare(dspi->clk);
 
        pinctrl_pm_select_sleep_state(dev);
@@ -915,8 +925,8 @@ static int dspi_suspend(struct device *dev)
 
 static int dspi_resume(struct device *dev)
 {
-       struct spi_master *master = dev_get_drvdata(dev);
-       struct fsl_dspi *dspi = spi_master_get_devdata(master);
+       struct spi_controller *ctlr = dev_get_drvdata(dev);
+       struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr);
        int ret;
 
        pinctrl_pm_select_default_state(dev);
@@ -924,7 +934,7 @@ static int dspi_resume(struct device *dev)
        ret = clk_prepare_enable(dspi->clk);
        if (ret)
                return ret;
-       spi_master_resume(master);
+       spi_controller_resume(ctlr);
 
        return 0;
 }
@@ -939,16 +949,16 @@ static const struct regmap_range dspi_volatile_ranges[] = {
 };
 
 static const struct regmap_access_table dspi_volatile_table = {
-       .yes_ranges     = dspi_volatile_ranges,
-       .n_yes_ranges   = ARRAY_SIZE(dspi_volatile_ranges),
+       .yes_ranges     = dspi_volatile_ranges,
+       .n_yes_ranges   = ARRAY_SIZE(dspi_volatile_ranges),
 };
 
 static const struct regmap_config dspi_regmap_config = {
-       .reg_bits = 32,
-       .val_bits = 32,
-       .reg_stride = 4,
-       .max_register = 0x88,
-       .volatile_table = &dspi_volatile_table,
+       .reg_bits       = 32,
+       .val_bits       = 32,
+       .reg_stride     = 4,
+       .max_register   = 0x88,
+       .volatile_table = &dspi_volatile_table,
 };
 
 static const struct regmap_range dspi_xspi_volatile_ranges[] = {
@@ -959,33 +969,34 @@ static const struct regmap_range dspi_xspi_volatile_ranges[] = {
 };
 
 static const struct regmap_access_table dspi_xspi_volatile_table = {
-       .yes_ranges     = dspi_xspi_volatile_ranges,
-       .n_yes_ranges   = ARRAY_SIZE(dspi_xspi_volatile_ranges),
+       .yes_ranges     = dspi_xspi_volatile_ranges,
+       .n_yes_ranges   = ARRAY_SIZE(dspi_xspi_volatile_ranges),
 };
 
 static const struct regmap_config dspi_xspi_regmap_config[] = {
        {
-               .reg_bits = 32,
-               .val_bits = 32,
-               .reg_stride = 4,
-               .max_register = 0x13c,
-               .volatile_table = &dspi_xspi_volatile_table,
+               .reg_bits       = 32,
+               .val_bits       = 32,
+               .reg_stride     = 4,
+               .max_register   = 0x13c,
+               .volatile_table = &dspi_xspi_volatile_table,
        },
        {
-               .name = "pushr",
-               .reg_bits = 16,
-               .val_bits = 16,
-               .reg_stride = 2,
-               .max_register = 0x2,
+               .name           = "pushr",
+               .reg_bits       = 16,
+               .val_bits       = 16,
+               .reg_stride     = 2,
+               .max_register   = 0x2,
        },
 };
 
 static void dspi_init(struct fsl_dspi *dspi)
 {
-       unsigned int mcr = SPI_MCR_PCSIS |
-               (dspi->devtype_data->xspi_mode ? SPI_MCR_XSPI : 0);
+       unsigned int mcr = SPI_MCR_PCSIS;
 
-       if (!spi_controller_is_slave(dspi->master))
+       if (dspi->devtype_data->xspi_mode)
+               mcr |= SPI_MCR_XSPI;
+       if (!spi_controller_is_slave(dspi->ctlr))
                mcr |= SPI_MCR_MASTER;
 
        regmap_write(dspi->regmap, SPI_MCR, mcr);
@@ -998,34 +1009,33 @@ static void dspi_init(struct fsl_dspi *dspi)
 static int dspi_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
-       struct spi_master *master;
+       const struct regmap_config *regmap_config;
+       struct fsl_dspi_platform_data *pdata;
+       struct spi_controller *ctlr;
+       int ret, cs_num, bus_num;
        struct fsl_dspi *dspi;
        struct resource *res;
-       const struct regmap_config *regmap_config;
        void __iomem *base;
-       struct fsl_dspi_platform_data *pdata;
-       int ret = 0, cs_num, bus_num;
 
-       master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi));
-       if (!master)
+       ctlr = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi));
+       if (!ctlr)
                return -ENOMEM;
 
-       dspi = spi_master_get_devdata(master);
+       dspi = spi_controller_get_devdata(ctlr);
        dspi->pdev = pdev;
-       dspi->master = master;
+       dspi->ctlr = ctlr;
 
-       master->transfer = NULL;
-       master->setup = dspi_setup;
-       master->transfer_one_message = dspi_transfer_one_message;
-       master->dev.of_node = pdev->dev.of_node;
+       ctlr->setup = dspi_setup;
+       ctlr->transfer_one_message = dspi_transfer_one_message;
+       ctlr->dev.of_node = pdev->dev.of_node;
 
-       master->cleanup = dspi_cleanup;
-       master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
+       ctlr->cleanup = dspi_cleanup;
+       ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
 
        pdata = dev_get_platdata(&pdev->dev);
        if (pdata) {
-               master->num_chipselect = pdata->cs_num;
-               master->bus_num = pdata->bus_num;
+               ctlr->num_chipselect = pdata->cs_num;
+               ctlr->bus_num = pdata->bus_num;
 
                dspi->devtype_data = &coldfire_data;
        } else {
@@ -1033,38 +1043,38 @@ static int dspi_probe(struct platform_device *pdev)
                ret = of_property_read_u32(np, "spi-num-chipselects", &cs_num);
                if (ret < 0) {
                        dev_err(&pdev->dev, "can't get spi-num-chipselects\n");
-                       goto out_master_put;
+                       goto out_ctlr_put;
                }
-               master->num_chipselect = cs_num;
+               ctlr->num_chipselect = cs_num;
 
                ret = of_property_read_u32(np, "bus-num", &bus_num);
                if (ret < 0) {
                        dev_err(&pdev->dev, "can't get bus-num\n");
-                       goto out_master_put;
+                       goto out_ctlr_put;
                }
-               master->bus_num = bus_num;
+               ctlr->bus_num = bus_num;
 
                if (of_property_read_bool(np, "spi-slave"))
-                       master->slave = true;
+                       ctlr->slave = true;
 
                dspi->devtype_data = of_device_get_match_data(&pdev->dev);
                if (!dspi->devtype_data) {
                        dev_err(&pdev->dev, "can't get devtype_data\n");
                        ret = -EFAULT;
-                       goto out_master_put;
+                       goto out_ctlr_put;
                }
        }
 
        if (dspi->devtype_data->xspi_mode)
-               master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
+               ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
        else
-               master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
+               ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(base)) {
                ret = PTR_ERR(base);
-               goto out_master_put;
+               goto out_ctlr_put;
        }
 
        if (dspi->devtype_data->xspi_mode)
@@ -1076,7 +1086,7 @@ static int dspi_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to init regmap: %ld\n",
                                PTR_ERR(dspi->regmap));
                ret = PTR_ERR(dspi->regmap);
-               goto out_master_put;
+               goto out_ctlr_put;
        }
 
        if (dspi->devtype_data->xspi_mode) {
@@ -1088,7 +1098,7 @@ static int dspi_probe(struct platform_device *pdev)
                                "failed to init pushr regmap: %ld\n",
                                PTR_ERR(dspi->regmap_pushr));
                        ret = PTR_ERR(dspi->regmap_pushr);
-                       goto out_master_put;
+                       goto out_ctlr_put;
                }
        }
 
@@ -1096,18 +1106,20 @@ static int dspi_probe(struct platform_device *pdev)
        if (IS_ERR(dspi->clk)) {
                ret = PTR_ERR(dspi->clk);
                dev_err(&pdev->dev, "unable to get clock\n");
-               goto out_master_put;
+               goto out_ctlr_put;
        }
        ret = clk_prepare_enable(dspi->clk);
        if (ret)
-               goto out_master_put;
+               goto out_ctlr_put;
 
        dspi_init(dspi);
+
        dspi->irq = platform_get_irq(pdev, 0);
-       if (dspi->irq < 0) {
-               dev_err(&pdev->dev, "can't get platform irq\n");
-               ret = dspi->irq;
-               goto out_clk_put;
+       if (dspi->irq <= 0) {
+               dev_info(&pdev->dev,
+                        "can't get platform irq, using poll mode\n");
+               dspi->irq = 0;
+               goto poll_mode;
        }
 
        ret = devm_request_irq(&pdev->dev, dspi->irq, dspi_interrupt,
@@ -1117,6 +1129,9 @@ static int dspi_probe(struct platform_device *pdev)
                goto out_clk_put;
        }
 
+       init_waitqueue_head(&dspi->waitq);
+
+poll_mode:
        if (dspi->devtype_data->trans_mode == DSPI_DMA_MODE) {
                ret = dspi_request_dma(dspi, res->start);
                if (ret < 0) {
@@ -1125,15 +1140,14 @@ static int dspi_probe(struct platform_device *pdev)
                }
        }
 
-       master->max_speed_hz =
+       ctlr->max_speed_hz =
                clk_get_rate(dspi->clk) / dspi->devtype_data->max_clock_factor;
 
-       init_waitqueue_head(&dspi->waitq);
-       platform_set_drvdata(pdev, master);
+       platform_set_drvdata(pdev, ctlr);
 
-       ret = spi_register_master(master);
+       ret = spi_register_controller(ctlr);
        if (ret != 0) {
-               dev_err(&pdev->dev, "Problem registering DSPI master\n");
+               dev_err(&pdev->dev, "Problem registering DSPI ctlr\n");
                goto out_clk_put;
        }
 
@@ -1141,32 +1155,32 @@ static int dspi_probe(struct platform_device *pdev)
 
 out_clk_put:
        clk_disable_unprepare(dspi->clk);
-out_master_put:
-       spi_master_put(master);
+out_ctlr_put:
+       spi_controller_put(ctlr);
 
        return ret;
 }
 
 static int dspi_remove(struct platform_device *pdev)
 {
-       struct spi_master *master = platform_get_drvdata(pdev);
-       struct fsl_dspi *dspi = spi_master_get_devdata(master);
+       struct spi_controller *ctlr = platform_get_drvdata(pdev);
+       struct fsl_dspi *dspi = spi_controller_get_devdata(ctlr);
 
        /* Disconnect from the SPI framework */
        dspi_release_dma(dspi);
        clk_disable_unprepare(dspi->clk);
-       spi_unregister_master(dspi->master);
+       spi_unregister_controller(dspi->ctlr);
 
        return 0;
 }
 
 static struct platform_driver fsl_dspi_driver = {
-       .driver.name    = DRIVER_NAME,
-       .driver.of_match_table = fsl_dspi_dt_ids,
-       .driver.owner   = THIS_MODULE,
-       .driver.pm = &dspi_pm,
-       .probe          = dspi_probe,
-       .remove         = dspi_remove,
+       .driver.name            = DRIVER_NAME,
+       .driver.of_match_table  = fsl_dspi_dt_ids,
+       .driver.owner           = THIS_MODULE,
+       .driver.pm              = &dspi_pm,
+       .probe                  = dspi_probe,
+       .remove                 = dspi_remove,
 };
 module_platform_driver(fsl_dspi_driver);
 
index 3576167..015a1ab 100644 (file)
@@ -91,9 +91,6 @@ static inline u32 mpc8xxx_spi_read_reg(__be32 __iomem *reg)
 
 struct mpc8xxx_spi_probe_info {
        struct fsl_spi_platform_data pdata;
-       int ngpios;
-       int *gpios;
-       bool *alow_flags;
        __be32 __iomem *immr_spi_cs;
 };
 
index 448c00e..c02e24c 100644 (file)
@@ -860,10 +860,8 @@ static int fsl_qspi_probe(struct platform_device *pdev)
 
        /* find the irq */
        ret = platform_get_irq(pdev, 0);
-       if (ret < 0) {
-               dev_err(dev, "failed to get the irq: %d\n", ret);
+       if (ret < 0)
                goto err_disable_clk;
-       }
 
        ret = devm_request_irq(dev, ret,
                        fsl_qspi_irq_handler, 0, pdev->name, q);
index 1d9b33a..4b80ace 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/fsl_devices.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/kernel.h>
@@ -28,7 +28,6 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
-#include <linux/of_gpio.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/spi/spi.h>
@@ -481,32 +480,6 @@ static int fsl_spi_setup(struct spi_device *spi)
                return retval;
        }
 
-       if (mpc8xxx_spi->type == TYPE_GRLIB) {
-               if (gpio_is_valid(spi->cs_gpio)) {
-                       int desel;
-
-                       retval = gpio_request(spi->cs_gpio,
-                                             dev_name(&spi->dev));
-                       if (retval)
-                               return retval;
-
-                       desel = !(spi->mode & SPI_CS_HIGH);
-                       retval = gpio_direction_output(spi->cs_gpio, desel);
-                       if (retval) {
-                               gpio_free(spi->cs_gpio);
-                               return retval;
-                       }
-               } else if (spi->cs_gpio != -ENOENT) {
-                       if (spi->cs_gpio < 0)
-                               return spi->cs_gpio;
-                       return -EINVAL;
-               }
-               /* When spi->cs_gpio == -ENOENT, a hole in the phandle list
-                * indicates to use native chipselect if present, or allow for
-                * an always selected chip
-                */
-       }
-
        /* Initialize chipselect - might be active for SPI_CS_HIGH mode */
        fsl_spi_chipselect(spi, BITBANG_CS_INACTIVE);
 
@@ -515,12 +488,8 @@ static int fsl_spi_setup(struct spi_device *spi)
 
 static void fsl_spi_cleanup(struct spi_device *spi)
 {
-       struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(spi->master);
        struct spi_mpc8xxx_cs *cs = spi_get_ctldata(spi);
 
-       if (mpc8xxx_spi->type == TYPE_GRLIB && gpio_is_valid(spi->cs_gpio))
-               gpio_free(spi->cs_gpio);
-
        kfree(cs);
        spi_set_ctldata(spi, NULL);
 }
@@ -586,8 +555,8 @@ static void fsl_spi_grlib_cs_control(struct spi_device *spi, bool on)
        u32 slvsel;
        u16 cs = spi->chip_select;
 
-       if (gpio_is_valid(spi->cs_gpio)) {
-               gpio_set_value(spi->cs_gpio, on);
+       if (spi->cs_gpiod) {
+               gpiod_set_value(spi->cs_gpiod, on);
        } else if (cs < mpc8xxx_spi->native_chipselects) {
                slvsel = mpc8xxx_spi_read_reg(&reg_base->slvsel);
                slvsel = on ? (slvsel | (1 << cs)) : (slvsel & ~(1 << cs));
@@ -718,139 +687,19 @@ err:
 
 static void fsl_spi_cs_control(struct spi_device *spi, bool on)
 {
-       struct device *dev = spi->dev.parent->parent;
-       struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
-       struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
-       u16 cs = spi->chip_select;
-
-       if (cs < pinfo->ngpios) {
-               int gpio = pinfo->gpios[cs];
-               bool alow = pinfo->alow_flags[cs];
-
-               gpio_set_value(gpio, on ^ alow);
+       if (spi->cs_gpiod) {
+               gpiod_set_value(spi->cs_gpiod, on);
        } else {
-               if (WARN_ON_ONCE(cs > pinfo->ngpios || !pinfo->immr_spi_cs))
+               struct device *dev = spi->dev.parent->parent;
+               struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
+               struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
+
+               if (WARN_ON_ONCE(!pinfo->immr_spi_cs))
                        return;
                iowrite32be(on ? SPI_BOOT_SEL_BIT : 0, pinfo->immr_spi_cs);
        }
 }
 
-static int of_fsl_spi_get_chipselects(struct device *dev)
-{
-       struct device_node *np = dev->of_node;
-       struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
-       struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
-       bool spisel_boot = IS_ENABLED(CONFIG_FSL_SOC) &&
-               of_property_read_bool(np, "fsl,spisel_boot");
-       int ngpios;
-       int i = 0;
-       int ret;
-
-       ngpios = of_gpio_count(np);
-       ngpios = max(ngpios, 0);
-       if (ngpios == 0 && !spisel_boot) {
-               /*
-                * SPI w/o chip-select line. One SPI device is still permitted
-                * though.
-                */
-               pdata->max_chipselect = 1;
-               return 0;
-       }
-
-       pinfo->ngpios = ngpios;
-       pinfo->gpios = kmalloc_array(ngpios, sizeof(*pinfo->gpios),
-                                    GFP_KERNEL);
-       if (!pinfo->gpios)
-               return -ENOMEM;
-       memset(pinfo->gpios, -1, ngpios * sizeof(*pinfo->gpios));
-
-       pinfo->alow_flags = kcalloc(ngpios, sizeof(*pinfo->alow_flags),
-                                   GFP_KERNEL);
-       if (!pinfo->alow_flags) {
-               ret = -ENOMEM;
-               goto err_alloc_flags;
-       }
-
-       for (; i < ngpios; i++) {
-               int gpio;
-               enum of_gpio_flags flags;
-
-               gpio = of_get_gpio_flags(np, i, &flags);
-               if (!gpio_is_valid(gpio)) {
-                       dev_err(dev, "invalid gpio #%d: %d\n", i, gpio);
-                       ret = gpio;
-                       goto err_loop;
-               }
-
-               ret = gpio_request(gpio, dev_name(dev));
-               if (ret) {
-                       dev_err(dev, "can't request gpio #%d: %d\n", i, ret);
-                       goto err_loop;
-               }
-
-               pinfo->gpios[i] = gpio;
-               pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW;
-
-               ret = gpio_direction_output(pinfo->gpios[i],
-                                           pinfo->alow_flags[i]);
-               if (ret) {
-                       dev_err(dev,
-                               "can't set output direction for gpio #%d: %d\n",
-                               i, ret);
-                       goto err_loop;
-               }
-       }
-
-#if IS_ENABLED(CONFIG_FSL_SOC)
-       if (spisel_boot) {
-               pinfo->immr_spi_cs = ioremap(get_immrbase() + IMMR_SPI_CS_OFFSET, 4);
-               if (!pinfo->immr_spi_cs) {
-                       ret = -ENOMEM;
-                       i = ngpios - 1;
-                       goto err_loop;
-               }
-       }
-#endif
-
-       pdata->max_chipselect = ngpios + spisel_boot;
-       pdata->cs_control = fsl_spi_cs_control;
-
-       return 0;
-
-err_loop:
-       while (i >= 0) {
-               if (gpio_is_valid(pinfo->gpios[i]))
-                       gpio_free(pinfo->gpios[i]);
-               i--;
-       }
-
-       kfree(pinfo->alow_flags);
-       pinfo->alow_flags = NULL;
-err_alloc_flags:
-       kfree(pinfo->gpios);
-       pinfo->gpios = NULL;
-       return ret;
-}
-
-static int of_fsl_spi_free_chipselects(struct device *dev)
-{
-       struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
-       struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
-       int i;
-
-       if (!pinfo->gpios)
-               return 0;
-
-       for (i = 0; i < pdata->max_chipselect; i++) {
-               if (gpio_is_valid(pinfo->gpios[i]))
-                       gpio_free(pinfo->gpios[i]);
-       }
-
-       kfree(pinfo->gpios);
-       kfree(pinfo->alow_flags);
-       return 0;
-}
-
 static int of_fsl_spi_probe(struct platform_device *ofdev)
 {
        struct device *dev = &ofdev->dev;
@@ -866,9 +715,21 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
 
        type = fsl_spi_get_type(&ofdev->dev);
        if (type == TYPE_FSL) {
-               ret = of_fsl_spi_get_chipselects(dev);
-               if (ret)
-                       goto err;
+               struct fsl_spi_platform_data *pdata = dev_get_platdata(dev);
+#if IS_ENABLED(CONFIG_FSL_SOC)
+               struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata);
+               bool spisel_boot = of_property_read_bool(np, "fsl,spisel_boot");
+
+               if (spisel_boot) {
+                       pinfo->immr_spi_cs = ioremap(get_immrbase() + IMMR_SPI_CS_OFFSET, 4);
+                       if (!pinfo->immr_spi_cs) {
+                               ret = -ENOMEM;
+                               goto err;
+                       }
+               }
+#endif
+
+               pdata->cs_control = fsl_spi_cs_control;
        }
 
        ret = of_address_to_resource(np, 0, &mem);
@@ -891,8 +752,6 @@ static int of_fsl_spi_probe(struct platform_device *ofdev)
 
 err:
        irq_dispose_mapping(irq);
-       if (type == TYPE_FSL)
-               of_fsl_spi_free_chipselects(dev);
        return ret;
 }
 
@@ -902,8 +761,6 @@ static int of_fsl_spi_remove(struct platform_device *ofdev)
        struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master);
 
        fsl_spi_cpm_free(mpc8xxx_spi);
-       if (mpc8xxx_spi->type == TYPE_FSL)
-               of_fsl_spi_free_chipselects(&ofdev->dev);
        return 0;
 }
 
index 5f0b0d5..6f3d64a 100644 (file)
@@ -534,18 +534,14 @@ static int spi_geni_probe(struct platform_device *pdev)
        int ret, irq;
        struct spi_master *spi;
        struct spi_geni_master *mas;
-       struct resource *res;
        void __iomem *base;
        struct clk *clk;
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(&pdev->dev, "Err getting IRQ %d\n", irq);
+       if (irq < 0)
                return irq;
-       }
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       base = devm_ioremap_resource(&pdev->dev, res);
+       base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(base))
                return PTR_ERR(base);
 
index 9eb8215..1d3e23e 100644 (file)
@@ -290,10 +290,7 @@ static int spi_gpio_request(struct device *dev, struct spi_gpio *spi_gpio)
                return PTR_ERR(spi_gpio->miso);
 
        spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW);
-       if (IS_ERR(spi_gpio->sck))
-               return PTR_ERR(spi_gpio->sck);
-
-       return 0;
+       return PTR_ERR_OR_ZERO(spi_gpio->sck);
 }
 
 #ifdef CONFIG_OF
index 8f01858..9dfe8b0 100644 (file)
@@ -819,22 +819,16 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
        }
 
        rx_irq = platform_get_irq_byname(pdev, LTQ_SPI_RX_IRQ_NAME);
-       if (rx_irq < 0) {
-               dev_err(dev, "failed to get %s\n", LTQ_SPI_RX_IRQ_NAME);
+       if (rx_irq < 0)
                return -ENXIO;
-       }
 
        tx_irq = platform_get_irq_byname(pdev, LTQ_SPI_TX_IRQ_NAME);
-       if (tx_irq < 0) {
-               dev_err(dev, "failed to get %s\n", LTQ_SPI_TX_IRQ_NAME);
+       if (tx_irq < 0)
                return -ENXIO;
-       }
 
        err_irq = platform_get_irq_byname(pdev, LTQ_SPI_ERR_IRQ_NAME);
-       if (err_irq < 0) {
-               dev_err(dev, "failed to get %s\n", LTQ_SPI_ERR_IRQ_NAME);
+       if (err_irq < 0)
                return -ENXIO;
-       }
 
        master = spi_alloc_master(dev, sizeof(struct lantiq_ssc_spi));
        if (!master)
index f50779f..2d43654 100644 (file)
@@ -185,7 +185,6 @@ spi_lp8841_rtc_probe(struct platform_device *pdev)
        int                             ret;
        struct spi_master               *master;
        struct spi_lp8841_rtc           *data;
-       void                            *iomem;
 
        master = spi_alloc_master(&pdev->dev, sizeof(*data));
        if (!master)
@@ -207,8 +206,7 @@ spi_lp8841_rtc_probe(struct platform_device *pdev)
 
        data = spi_master_get_devdata(master);
 
-       iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       data->iomem = devm_ioremap_resource(&pdev->dev, iomem);
+       data->iomem = devm_platform_ioremap_resource(pdev, 0);
        ret = PTR_ERR_OR_ZERO(data->iomem);
        if (ret) {
                dev_err(&pdev->dev, "failed to get IO address\n");
index 7fe4488..f3f1044 100644 (file)
@@ -503,7 +503,6 @@ static int meson_spicc_probe(struct platform_device *pdev)
 {
        struct spi_master *master;
        struct meson_spicc_device *spicc;
-       struct resource *res;
        int ret, irq, rate;
 
        master = spi_alloc_master(&pdev->dev, sizeof(*spicc));
@@ -517,8 +516,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
        spicc->pdev = pdev;
        platform_set_drvdata(pdev, spicc);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       spicc->base = devm_ioremap_resource(&pdev->dev, res);
+       spicc->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(spicc->base)) {
                dev_err(&pdev->dev, "io resource mapping failed\n");
                ret = PTR_ERR(spicc->base);
index f7fe9b1..c7b0399 100644 (file)
@@ -286,7 +286,6 @@ static int meson_spifc_probe(struct platform_device *pdev)
 {
        struct spi_master *master;
        struct meson_spifc *spifc;
-       struct resource *res;
        void __iomem *base;
        unsigned int rate;
        int ret = 0;
@@ -300,8 +299,7 @@ static int meson_spifc_probe(struct platform_device *pdev)
        spifc = spi_master_get_devdata(master);
        spifc->dev = &pdev->dev;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       base = devm_ioremap_resource(spifc->dev, res);
+       base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(base)) {
                ret = PTR_ERR(base);
                goto out_err;
index 45d8a70..6888a4d 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/platform_data/spi-mt65xx.h>
 #include <linux/pm_runtime.h>
 #include <linux/spi/spi.h>
+#include <linux/dma-mapping.h>
 
 #define SPI_CFG0_REG                      0x0000
 #define SPI_CFG1_REG                      0x0004
@@ -28,6 +29,8 @@
 #define SPI_STATUS0_REG                   0x001c
 #define SPI_PAD_SEL_REG                   0x0024
 #define SPI_CFG2_REG                      0x0028
+#define SPI_TX_SRC_REG_64                 0x002c
+#define SPI_RX_DST_REG_64                 0x0030
 
 #define SPI_CFG0_SCK_HIGH_OFFSET          0
 #define SPI_CFG0_SCK_LOW_OFFSET           8
 
 #define MTK_SPI_MAX_FIFO_SIZE 32U
 #define MTK_SPI_PACKET_SIZE 1024
+#define MTK_SPI_32BITS_MASK  (0xffffffff)
+
+#define DMA_ADDR_EXT_BITS (36)
+#define DMA_ADDR_DEF_BITS (32)
 
 struct mtk_spi_compatible {
        bool need_pad_sel;
@@ -80,6 +87,8 @@ struct mtk_spi_compatible {
        bool must_tx;
        /* some IC design adjust cfg register to enhance time accuracy */
        bool enhance_timing;
+       /* some IC support DMA addr extension */
+       bool dma_ext;
 };
 
 struct mtk_spi {
@@ -102,6 +111,13 @@ static const struct mtk_spi_compatible mt2712_compat = {
        .must_tx = true,
 };
 
+static const struct mtk_spi_compatible mt6765_compat = {
+       .need_pad_sel = true,
+       .must_tx = true,
+       .enhance_timing = true,
+       .dma_ext = true,
+};
+
 static const struct mtk_spi_compatible mt7622_compat = {
        .must_tx = true,
        .enhance_timing = true,
@@ -137,6 +153,9 @@ static const struct of_device_id mtk_spi_of_match[] = {
        { .compatible = "mediatek,mt6589-spi",
                .data = (void *)&mtk_common_compat,
        },
+       { .compatible = "mediatek,mt6765-spi",
+               .data = (void *)&mt6765_compat,
+       },
        { .compatible = "mediatek,mt7622-spi",
                .data = (void *)&mt7622_compat,
        },
@@ -371,10 +390,25 @@ static void mtk_spi_setup_dma_addr(struct spi_master *master,
 {
        struct mtk_spi *mdata = spi_master_get_devdata(master);
 
-       if (mdata->tx_sgl)
-               writel(xfer->tx_dma, mdata->base + SPI_TX_SRC_REG);
-       if (mdata->rx_sgl)
-               writel(xfer->rx_dma, mdata->base + SPI_RX_DST_REG);
+       if (mdata->tx_sgl) {
+               writel((u32)(xfer->tx_dma & MTK_SPI_32BITS_MASK),
+                      mdata->base + SPI_TX_SRC_REG);
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+               if (mdata->dev_comp->dma_ext)
+                       writel((u32)(xfer->tx_dma >> 32),
+                              mdata->base + SPI_TX_SRC_REG_64);
+#endif
+       }
+
+       if (mdata->rx_sgl) {
+               writel((u32)(xfer->rx_dma & MTK_SPI_32BITS_MASK),
+                      mdata->base + SPI_RX_DST_REG);
+#ifdef CONFIG_ARCH_DMA_ADDR_T_64BIT
+               if (mdata->dev_comp->dma_ext)
+                       writel((u32)(xfer->rx_dma >> 32),
+                              mdata->base + SPI_RX_DST_REG_64);
+#endif
+       }
 }
 
 static int mtk_spi_fifo_transfer(struct spi_master *master,
@@ -586,7 +620,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
        struct mtk_spi *mdata;
        const struct of_device_id *of_id;
        struct resource *res;
-       int i, irq, ret;
+       int i, irq, ret, addr_bits;
 
        master = spi_alloc_master(&pdev->dev, sizeof(*mdata));
        if (!master) {
@@ -664,7 +698,6 @@ static int mtk_spi_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
-               dev_err(&pdev->dev, "failed to get irq (%d)\n", irq);
                ret = irq;
                goto err_put_master;
        }
@@ -753,6 +786,15 @@ static int mtk_spi_probe(struct platform_device *pdev)
                }
        }
 
+       if (mdata->dev_comp->dma_ext)
+               addr_bits = DMA_ADDR_EXT_BITS;
+       else
+               addr_bits = DMA_ADDR_DEF_BITS;
+       ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(addr_bits));
+       if (ret)
+               dev_notice(&pdev->dev, "SPI dma_set_mask(%d) failed, ret:%d\n",
+                          addr_bits, ret);
+
        return 0;
 
 err_disable_runtime_pm:
index ff85982..2c3b7a2 100644 (file)
@@ -327,7 +327,6 @@ static int mt7621_spi_probe(struct platform_device *pdev)
        struct spi_controller *master;
        struct mt7621_spi *rs;
        void __iomem *base;
-       struct resource *r;
        int status = 0;
        struct clk *clk;
        int ret;
@@ -336,8 +335,7 @@ static int mt7621_spi_probe(struct platform_device *pdev)
        if (!match)
                return -EINVAL;
 
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       base = devm_ioremap_resource(&pdev->dev, r);
+       base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(base))
                return PTR_ERR(base);
 
index 7bf53cf..996c1c8 100644 (file)
@@ -532,7 +532,6 @@ static int mxs_spi_probe(struct platform_device *pdev)
        struct spi_master *master;
        struct mxs_spi *spi;
        struct mxs_ssp *ssp;
-       struct resource *iores;
        struct clk *clk;
        void __iomem *base;
        int devid, clk_freq;
@@ -545,12 +544,11 @@ static int mxs_spi_probe(struct platform_device *pdev)
         */
        const int clk_freq_default = 160000000;
 
-       iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        irq_err = platform_get_irq(pdev, 0);
        if (irq_err < 0)
                return irq_err;
 
-       base = devm_ioremap_resource(&pdev->dev, iores);
+       base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(base))
                return PTR_ERR(base);
 
diff --git a/drivers/spi/spi-npcm-fiu.c b/drivers/spi/spi-npcm-fiu.c
new file mode 100644 (file)
index 0000000..cb52fd8
--- /dev/null
@@ -0,0 +1,769 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2019 Nuvoton Technology corporation.
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/vmalloc.h>
+#include <linux/regmap.h>
+#include <linux/of_device.h>
+#include <linux/spi/spi-mem.h>
+#include <linux/mfd/syscon.h>
+
+/* NPCM7xx GCR module */
+#define NPCM7XX_INTCR3_OFFSET          0x9C
+#define NPCM7XX_INTCR3_FIU_FIX         BIT(6)
+
+/* Flash Interface Unit (FIU) Registers */
+#define NPCM_FIU_DRD_CFG               0x00
+#define NPCM_FIU_DWR_CFG               0x04
+#define NPCM_FIU_UMA_CFG               0x08
+#define NPCM_FIU_UMA_CTS               0x0C
+#define NPCM_FIU_UMA_CMD               0x10
+#define NPCM_FIU_UMA_ADDR              0x14
+#define NPCM_FIU_PRT_CFG               0x18
+#define NPCM_FIU_UMA_DW0               0x20
+#define NPCM_FIU_UMA_DW1               0x24
+#define NPCM_FIU_UMA_DW2               0x28
+#define NPCM_FIU_UMA_DW3               0x2C
+#define NPCM_FIU_UMA_DR0               0x30
+#define NPCM_FIU_UMA_DR1               0x34
+#define NPCM_FIU_UMA_DR2               0x38
+#define NPCM_FIU_UMA_DR3               0x3C
+#define NPCM_FIU_MAX_REG_LIMIT         0x80
+
+/* FIU Direct Read Configuration Register */
+#define NPCM_FIU_DRD_CFG_LCK           BIT(31)
+#define NPCM_FIU_DRD_CFG_R_BURST       GENMASK(25, 24)
+#define NPCM_FIU_DRD_CFG_ADDSIZ                GENMASK(17, 16)
+#define NPCM_FIU_DRD_CFG_DBW           GENMASK(13, 12)
+#define NPCM_FIU_DRD_CFG_ACCTYPE       GENMASK(9, 8)
+#define NPCM_FIU_DRD_CFG_RDCMD         GENMASK(7, 0)
+#define NPCM_FIU_DRD_ADDSIZ_SHIFT      16
+#define NPCM_FIU_DRD_DBW_SHIFT         12
+#define NPCM_FIU_DRD_ACCTYPE_SHIFT     8
+
+/* FIU Direct Write Configuration Register */
+#define NPCM_FIU_DWR_CFG_LCK           BIT(31)
+#define NPCM_FIU_DWR_CFG_W_BURST       GENMASK(25, 24)
+#define NPCM_FIU_DWR_CFG_ADDSIZ                GENMASK(17, 16)
+#define NPCM_FIU_DWR_CFG_ABPCK         GENMASK(11, 10)
+#define NPCM_FIU_DWR_CFG_DBPCK         GENMASK(9, 8)
+#define NPCM_FIU_DWR_CFG_WRCMD         GENMASK(7, 0)
+#define NPCM_FIU_DWR_ADDSIZ_SHIFT      16
+#define NPCM_FIU_DWR_ABPCK_SHIFT       10
+#define NPCM_FIU_DWR_DBPCK_SHIFT       8
+
+/* FIU UMA Configuration Register */
+#define NPCM_FIU_UMA_CFG_LCK           BIT(31)
+#define NPCM_FIU_UMA_CFG_CMMLCK                BIT(30)
+#define NPCM_FIU_UMA_CFG_RDATSIZ       GENMASK(28, 24)
+#define NPCM_FIU_UMA_CFG_DBSIZ         GENMASK(23, 21)
+#define NPCM_FIU_UMA_CFG_WDATSIZ       GENMASK(20, 16)
+#define NPCM_FIU_UMA_CFG_ADDSIZ                GENMASK(13, 11)
+#define NPCM_FIU_UMA_CFG_CMDSIZ                BIT(10)
+#define NPCM_FIU_UMA_CFG_RDBPCK                GENMASK(9, 8)
+#define NPCM_FIU_UMA_CFG_DBPCK         GENMASK(7, 6)
+#define NPCM_FIU_UMA_CFG_WDBPCK                GENMASK(5, 4)
+#define NPCM_FIU_UMA_CFG_ADBPCK                GENMASK(3, 2)
+#define NPCM_FIU_UMA_CFG_CMBPCK                GENMASK(1, 0)
+#define NPCM_FIU_UMA_CFG_ADBPCK_SHIFT  2
+#define NPCM_FIU_UMA_CFG_WDBPCK_SHIFT  4
+#define NPCM_FIU_UMA_CFG_DBPCK_SHIFT   6
+#define NPCM_FIU_UMA_CFG_RDBPCK_SHIFT  8
+#define NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT  11
+#define NPCM_FIU_UMA_CFG_WDATSIZ_SHIFT 16
+#define NPCM_FIU_UMA_CFG_DBSIZ_SHIFT   21
+#define NPCM_FIU_UMA_CFG_RDATSIZ_SHIFT 24
+
+/* FIU UMA Control and Status Register */
+#define NPCM_FIU_UMA_CTS_RDYIE         BIT(25)
+#define NPCM_FIU_UMA_CTS_RDYST         BIT(24)
+#define NPCM_FIU_UMA_CTS_SW_CS         BIT(16)
+#define NPCM_FIU_UMA_CTS_DEV_NUM       GENMASK(9, 8)
+#define NPCM_FIU_UMA_CTS_EXEC_DONE     BIT(0)
+#define NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT 8
+
+/* FIU UMA Command Register */
+#define NPCM_FIU_UMA_CMD_DUM3          GENMASK(31, 24)
+#define NPCM_FIU_UMA_CMD_DUM2          GENMASK(23, 16)
+#define NPCM_FIU_UMA_CMD_DUM1          GENMASK(15, 8)
+#define NPCM_FIU_UMA_CMD_CMD           GENMASK(7, 0)
+
+/* FIU UMA Address Register */
+#define NPCM_FIU_UMA_ADDR_UMA_ADDR     GENMASK(31, 0)
+#define NPCM_FIU_UMA_ADDR_AB3          GENMASK(31, 24)
+#define NPCM_FIU_UMA_ADDR_AB2          GENMASK(23, 16)
+#define NPCM_FIU_UMA_ADDR_AB1          GENMASK(15, 8)
+#define NPCM_FIU_UMA_ADDR_AB0          GENMASK(7, 0)
+
+/* FIU UMA Write Data Bytes 0-3 Register */
+#define NPCM_FIU_UMA_DW0_WB3           GENMASK(31, 24)
+#define NPCM_FIU_UMA_DW0_WB2           GENMASK(23, 16)
+#define NPCM_FIU_UMA_DW0_WB1           GENMASK(15, 8)
+#define NPCM_FIU_UMA_DW0_WB0           GENMASK(7, 0)
+
+/* FIU UMA Write Data Bytes 4-7 Register */
+#define NPCM_FIU_UMA_DW1_WB7           GENMASK(31, 24)
+#define NPCM_FIU_UMA_DW1_WB6           GENMASK(23, 16)
+#define NPCM_FIU_UMA_DW1_WB5           GENMASK(15, 8)
+#define NPCM_FIU_UMA_DW1_WB4           GENMASK(7, 0)
+
+/* FIU UMA Write Data Bytes 8-11 Register */
+#define NPCM_FIU_UMA_DW2_WB11          GENMASK(31, 24)
+#define NPCM_FIU_UMA_DW2_WB10          GENMASK(23, 16)
+#define NPCM_FIU_UMA_DW2_WB9           GENMASK(15, 8)
+#define NPCM_FIU_UMA_DW2_WB8           GENMASK(7, 0)
+
+/* FIU UMA Write Data Bytes 12-15 Register */
+#define NPCM_FIU_UMA_DW3_WB15          GENMASK(31, 24)
+#define NPCM_FIU_UMA_DW3_WB14          GENMASK(23, 16)
+#define NPCM_FIU_UMA_DW3_WB13          GENMASK(15, 8)
+#define NPCM_FIU_UMA_DW3_WB12          GENMASK(7, 0)
+
+/* FIU UMA Read Data Bytes 0-3 Register */
+#define NPCM_FIU_UMA_DR0_RB3           GENMASK(31, 24)
+#define NPCM_FIU_UMA_DR0_RB2           GENMASK(23, 16)
+#define NPCM_FIU_UMA_DR0_RB1           GENMASK(15, 8)
+#define NPCM_FIU_UMA_DR0_RB0           GENMASK(7, 0)
+
+/* FIU UMA Read Data Bytes 4-7 Register */
+#define NPCM_FIU_UMA_DR1_RB15          GENMASK(31, 24)
+#define NPCM_FIU_UMA_DR1_RB14          GENMASK(23, 16)
+#define NPCM_FIU_UMA_DR1_RB13          GENMASK(15, 8)
+#define NPCM_FIU_UMA_DR1_RB12          GENMASK(7, 0)
+
+/* FIU UMA Read Data Bytes 8-11 Register */
+#define NPCM_FIU_UMA_DR2_RB15          GENMASK(31, 24)
+#define NPCM_FIU_UMA_DR2_RB14          GENMASK(23, 16)
+#define NPCM_FIU_UMA_DR2_RB13          GENMASK(15, 8)
+#define NPCM_FIU_UMA_DR2_RB12          GENMASK(7, 0)
+
+/* FIU UMA Read Data Bytes 12-15 Register */
+#define NPCM_FIU_UMA_DR3_RB15          GENMASK(31, 24)
+#define NPCM_FIU_UMA_DR3_RB14          GENMASK(23, 16)
+#define NPCM_FIU_UMA_DR3_RB13          GENMASK(15, 8)
+#define NPCM_FIU_UMA_DR3_RB12          GENMASK(7, 0)
+
+/* FIU Read Mode */
+enum {
+       DRD_SINGLE_WIRE_MODE    = 0,
+       DRD_DUAL_IO_MODE        = 1,
+       DRD_QUAD_IO_MODE        = 2,
+       DRD_SPI_X_MODE          = 3,
+};
+
+enum {
+       DWR_ABPCK_BIT_PER_CLK   = 0,
+       DWR_ABPCK_2_BIT_PER_CLK = 1,
+       DWR_ABPCK_4_BIT_PER_CLK = 2,
+};
+
+enum {
+       DWR_DBPCK_BIT_PER_CLK   = 0,
+       DWR_DBPCK_2_BIT_PER_CLK = 1,
+       DWR_DBPCK_4_BIT_PER_CLK = 2,
+};
+
+#define NPCM_FIU_DRD_16_BYTE_BURST     0x3000000
+#define NPCM_FIU_DWR_16_BYTE_BURST     0x3000000
+
+#define MAP_SIZE_128MB                 0x8000000
+#define MAP_SIZE_16MB                  0x1000000
+#define MAP_SIZE_8MB                   0x800000
+
+#define NUM_BITS_IN_BYTE               8
+#define FIU_DRD_MAX_DUMMY_NUMBER       3
+#define NPCM_MAX_CHIP_NUM              4
+#define CHUNK_SIZE                     16
+#define UMA_MICRO_SEC_TIMEOUT          150
+
+enum {
+       FIU0 = 0,
+       FIU3,
+       FIUX,
+};
+
+struct npcm_fiu_info {
+       char *name;
+       u32 fiu_id;
+       u32 max_map_size;
+       u32 max_cs;
+};
+
+struct fiu_data {
+       const struct npcm_fiu_info *npcm_fiu_data_info;
+       int fiu_max;
+};
+
+static const struct npcm_fiu_info npxm7xx_fiu_info[] = {
+       {.name = "FIU0", .fiu_id = FIU0,
+               .max_map_size = MAP_SIZE_128MB, .max_cs = 2},
+       {.name = "FIU3", .fiu_id = FIU3,
+               .max_map_size = MAP_SIZE_128MB, .max_cs = 4},
+       {.name = "FIUX", .fiu_id = FIUX,
+               .max_map_size = MAP_SIZE_16MB, .max_cs = 2} };
+
+static const struct fiu_data npxm7xx_fiu_data = {
+       .npcm_fiu_data_info = npxm7xx_fiu_info,
+       .fiu_max = 3,
+};
+
+struct npcm_fiu_spi;
+
+struct npcm_fiu_chip {
+       void __iomem *flash_region_mapped_ptr;
+       struct npcm_fiu_spi *fiu;
+       unsigned long clkrate;
+       u32 chipselect;
+};
+
+struct npcm_fiu_spi {
+       struct npcm_fiu_chip chip[NPCM_MAX_CHIP_NUM];
+       const struct npcm_fiu_info *info;
+       struct spi_mem_op drd_op;
+       struct resource *res_mem;
+       struct regmap *regmap;
+       unsigned long clkrate;
+       struct device *dev;
+       struct clk *clk;
+       bool spix_mode;
+};
+
+static const struct regmap_config npcm_mtd_regmap_config = {
+       .reg_bits = 32,
+       .val_bits = 32,
+       .reg_stride = 4,
+       .max_register = NPCM_FIU_MAX_REG_LIMIT,
+};
+
+static void npcm_fiu_set_drd(struct npcm_fiu_spi *fiu,
+                            const struct spi_mem_op *op)
+{
+       regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
+                          NPCM_FIU_DRD_CFG_ACCTYPE,
+                          ilog2(op->addr.buswidth) <<
+                          NPCM_FIU_DRD_ACCTYPE_SHIFT);
+       fiu->drd_op.addr.buswidth = op->addr.buswidth;
+       regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
+                          NPCM_FIU_DRD_CFG_DBW,
+                          ((op->dummy.nbytes * ilog2(op->addr.buswidth))
+                           / NUM_BITS_IN_BYTE) << NPCM_FIU_DRD_DBW_SHIFT);
+       fiu->drd_op.dummy.nbytes = op->dummy.nbytes;
+       regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
+                          NPCM_FIU_DRD_CFG_RDCMD, op->cmd.opcode);
+       fiu->drd_op.cmd.opcode = op->cmd.opcode;
+       regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
+                          NPCM_FIU_DRD_CFG_ADDSIZ,
+                          (op->addr.nbytes - 3) << NPCM_FIU_DRD_ADDSIZ_SHIFT);
+       fiu->drd_op.addr.nbytes = op->addr.nbytes;
+}
+
+static ssize_t npcm_fiu_direct_read(struct spi_mem_dirmap_desc *desc,
+                                   u64 offs, size_t len, void *buf)
+{
+       struct npcm_fiu_spi *fiu =
+               spi_controller_get_devdata(desc->mem->spi->master);
+       struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
+       void __iomem *src = (void __iomem *)(chip->flash_region_mapped_ptr +
+                                            offs);
+       u8 *buf_rx = buf;
+       u32 i;
+
+       if (fiu->spix_mode) {
+               for (i = 0 ; i < len ; i++)
+                       *(buf_rx + i) = ioread8(src + i);
+       } else {
+               if (desc->info.op_tmpl.addr.buswidth != fiu->drd_op.addr.buswidth ||
+                   desc->info.op_tmpl.dummy.nbytes != fiu->drd_op.dummy.nbytes ||
+                   desc->info.op_tmpl.cmd.opcode != fiu->drd_op.cmd.opcode ||
+                   desc->info.op_tmpl.addr.nbytes != fiu->drd_op.addr.nbytes)
+                       npcm_fiu_set_drd(fiu, &desc->info.op_tmpl);
+
+               memcpy_fromio(buf_rx, src, len);
+       }
+
+       return len;
+}
+
+static ssize_t npcm_fiu_direct_write(struct spi_mem_dirmap_desc *desc,
+                                    u64 offs, size_t len, const void *buf)
+{
+       struct npcm_fiu_spi *fiu =
+               spi_controller_get_devdata(desc->mem->spi->master);
+       struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
+       void __iomem *dst = (void __iomem *)(chip->flash_region_mapped_ptr +
+                                            offs);
+       const u8 *buf_tx = buf;
+       u32 i;
+
+       if (fiu->spix_mode)
+               for (i = 0 ; i < len ; i++)
+                       iowrite8(*(buf_tx + i), dst + i);
+       else
+               memcpy_toio(dst, buf_tx, len);
+
+       return len;
+}
+
+static int npcm_fiu_uma_read(struct spi_mem *mem,
+                            const struct spi_mem_op *op, u32 addr,
+                             bool is_address_size, u8 *data, u32 data_size)
+{
+       struct npcm_fiu_spi *fiu =
+               spi_controller_get_devdata(mem->spi->master);
+       u32 uma_cfg = BIT(10);
+       u32 data_reg[4];
+       int ret;
+       u32 val;
+       u32 i;
+
+       regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
+                          NPCM_FIU_UMA_CTS_DEV_NUM,
+                          (mem->spi->chip_select <<
+                           NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
+       regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CMD,
+                          NPCM_FIU_UMA_CMD_CMD, op->cmd.opcode);
+
+       if (is_address_size) {
+               uma_cfg |= ilog2(op->cmd.buswidth);
+               uma_cfg |= ilog2(op->addr.buswidth)
+                       << NPCM_FIU_UMA_CFG_ADBPCK_SHIFT;
+               uma_cfg |= ilog2(op->dummy.buswidth)
+                       << NPCM_FIU_UMA_CFG_DBPCK_SHIFT;
+               uma_cfg |= ilog2(op->data.buswidth)
+                       << NPCM_FIU_UMA_CFG_RDBPCK_SHIFT;
+               uma_cfg |= op->dummy.nbytes << NPCM_FIU_UMA_CFG_DBSIZ_SHIFT;
+               uma_cfg |= op->addr.nbytes << NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT;
+               regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, addr);
+       } else {
+               regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, 0x0);
+       }
+
+       uma_cfg |= data_size << NPCM_FIU_UMA_CFG_RDATSIZ_SHIFT;
+       regmap_write(fiu->regmap, NPCM_FIU_UMA_CFG, uma_cfg);
+       regmap_write_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
+                         NPCM_FIU_UMA_CTS_EXEC_DONE,
+                         NPCM_FIU_UMA_CTS_EXEC_DONE);
+       ret = regmap_read_poll_timeout(fiu->regmap, NPCM_FIU_UMA_CTS, val,
+                                      (!(val & NPCM_FIU_UMA_CTS_EXEC_DONE)), 0,
+                                      UMA_MICRO_SEC_TIMEOUT);
+       if (ret)
+               return ret;
+
+       if (data_size) {
+               for (i = 0; i < DIV_ROUND_UP(data_size, 4); i++)
+                       regmap_read(fiu->regmap, NPCM_FIU_UMA_DR0 + (i * 4),
+                                   &data_reg[i]);
+               memcpy(data, data_reg, data_size);
+       }
+
+       return 0;
+}
+
+static int npcm_fiu_uma_write(struct spi_mem *mem,
+                             const struct spi_mem_op *op, u8 cmd,
+                             bool is_address_size, u8 *data, u32 data_size)
+{
+       struct npcm_fiu_spi *fiu =
+               spi_controller_get_devdata(mem->spi->master);
+       u32 uma_cfg = BIT(10);
+       u32 data_reg[4] = {0};
+       u32 val;
+       u32 i;
+
+       regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
+                          NPCM_FIU_UMA_CTS_DEV_NUM,
+                          (mem->spi->chip_select <<
+                           NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
+
+       regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CMD,
+                          NPCM_FIU_UMA_CMD_CMD, cmd);
+
+       if (data_size) {
+               memcpy(data_reg, data, data_size);
+               for (i = 0; i < DIV_ROUND_UP(data_size, 4); i++)
+                       regmap_write(fiu->regmap, NPCM_FIU_UMA_DW0 + (i * 4),
+                                    data_reg[i]);
+       }
+
+       if (is_address_size) {
+               uma_cfg |= ilog2(op->cmd.buswidth);
+               uma_cfg |= ilog2(op->addr.buswidth) <<
+                       NPCM_FIU_UMA_CFG_ADBPCK_SHIFT;
+               uma_cfg |= ilog2(op->data.buswidth) <<
+                       NPCM_FIU_UMA_CFG_WDBPCK_SHIFT;
+               uma_cfg |= op->addr.nbytes << NPCM_FIU_UMA_CFG_ADDSIZ_SHIFT;
+               regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, op->addr.val);
+       } else {
+               regmap_write(fiu->regmap, NPCM_FIU_UMA_ADDR, 0x0);
+       }
+
+       uma_cfg |= (data_size << NPCM_FIU_UMA_CFG_WDATSIZ_SHIFT);
+       regmap_write(fiu->regmap, NPCM_FIU_UMA_CFG, uma_cfg);
+
+       regmap_write_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
+                         NPCM_FIU_UMA_CTS_EXEC_DONE,
+                         NPCM_FIU_UMA_CTS_EXEC_DONE);
+
+       return regmap_read_poll_timeout(fiu->regmap, NPCM_FIU_UMA_CTS, val,
+                                      (!(val & NPCM_FIU_UMA_CTS_EXEC_DONE)), 0,
+                                       UMA_MICRO_SEC_TIMEOUT);
+}
+
+static int npcm_fiu_manualwrite(struct spi_mem *mem,
+                               const struct spi_mem_op *op)
+{
+       struct npcm_fiu_spi *fiu =
+               spi_controller_get_devdata(mem->spi->master);
+       u8 *data = (u8 *)op->data.buf.out;
+       u32 num_data_chunks;
+       u32 remain_data;
+       u32 idx = 0;
+       int ret;
+
+       num_data_chunks  = op->data.nbytes / CHUNK_SIZE;
+       remain_data  = op->data.nbytes % CHUNK_SIZE;
+
+       regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
+                          NPCM_FIU_UMA_CTS_DEV_NUM,
+                          (mem->spi->chip_select <<
+                           NPCM_FIU_UMA_CTS_DEV_NUM_SHIFT));
+       regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
+                          NPCM_FIU_UMA_CTS_SW_CS, 0);
+
+       ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, true, NULL, 0);
+       if (ret)
+               return ret;
+
+       /* Starting the data writing loop in multiples of 8 */
+       for (idx = 0; idx < num_data_chunks; ++idx) {
+               ret = npcm_fiu_uma_write(mem, op, data[0], false,
+                                        &data[1], CHUNK_SIZE - 1);
+               if (ret)
+                       return ret;
+
+               data += CHUNK_SIZE;
+       }
+
+       /* Handling chunk remains */
+       if (remain_data > 0) {
+               ret = npcm_fiu_uma_write(mem, op, data[0], false,
+                                        &data[1], remain_data - 1);
+               if (ret)
+                       return ret;
+       }
+
+       regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS,
+                          NPCM_FIU_UMA_CTS_SW_CS, NPCM_FIU_UMA_CTS_SW_CS);
+
+       return 0;
+}
+
+static int npcm_fiu_read(struct spi_mem *mem, const struct spi_mem_op *op)
+{
+       u8 *data = op->data.buf.in;
+       int i, readlen, currlen;
+       u8 *buf_ptr;
+       u32 addr;
+       int ret;
+
+       i = 0;
+       currlen = op->data.nbytes;
+
+       do {
+               addr = ((u32)op->addr.val + i);
+               if (currlen < 16)
+                       readlen = currlen;
+               else
+                       readlen = 16;
+
+               buf_ptr = data + i;
+               ret = npcm_fiu_uma_read(mem, op, addr, true, buf_ptr,
+                                       readlen);
+               if (ret)
+                       return ret;
+
+               i += readlen;
+               currlen -= 16;
+       } while (currlen > 0);
+
+       return 0;
+}
+
+static void npcm_fiux_set_direct_wr(struct npcm_fiu_spi *fiu)
+{
+       regmap_write(fiu->regmap, NPCM_FIU_DWR_CFG,
+                    NPCM_FIU_DWR_16_BYTE_BURST);
+       regmap_update_bits(fiu->regmap, NPCM_FIU_DWR_CFG,
+                          NPCM_FIU_DWR_CFG_ABPCK,
+                          DWR_ABPCK_4_BIT_PER_CLK << NPCM_FIU_DWR_ABPCK_SHIFT);
+       regmap_update_bits(fiu->regmap, NPCM_FIU_DWR_CFG,
+                          NPCM_FIU_DWR_CFG_DBPCK,
+                          DWR_DBPCK_4_BIT_PER_CLK << NPCM_FIU_DWR_DBPCK_SHIFT);
+}
+
+static void npcm_fiux_set_direct_rd(struct npcm_fiu_spi *fiu)
+{
+       u32 rx_dummy = 0;
+
+       regmap_write(fiu->regmap, NPCM_FIU_DRD_CFG,
+                    NPCM_FIU_DRD_16_BYTE_BURST);
+       regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
+                          NPCM_FIU_DRD_CFG_ACCTYPE,
+                          DRD_SPI_X_MODE << NPCM_FIU_DRD_ACCTYPE_SHIFT);
+       regmap_update_bits(fiu->regmap, NPCM_FIU_DRD_CFG,
+                          NPCM_FIU_DRD_CFG_DBW,
+                          rx_dummy << NPCM_FIU_DRD_DBW_SHIFT);
+}
+
+static int npcm_fiu_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
+{
+       struct npcm_fiu_spi *fiu =
+               spi_controller_get_devdata(mem->spi->master);
+       struct npcm_fiu_chip *chip = &fiu->chip[mem->spi->chip_select];
+       int ret = 0;
+       u8 *buf;
+
+       dev_dbg(fiu->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n",
+               op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
+               op->dummy.buswidth, op->data.buswidth, op->addr.val,
+               op->data.nbytes);
+
+       if (fiu->spix_mode || op->addr.nbytes > 4)
+               return -ENOTSUPP;
+
+       if (fiu->clkrate != chip->clkrate) {
+               ret = clk_set_rate(fiu->clk, chip->clkrate);
+               if (ret < 0)
+                       dev_warn(fiu->dev, "Failed setting %lu frequency, stay at %lu frequency\n",
+                                chip->clkrate, fiu->clkrate);
+               else
+                       fiu->clkrate = chip->clkrate;
+       }
+
+       if (op->data.dir == SPI_MEM_DATA_IN) {
+               if (!op->addr.nbytes) {
+                       buf = op->data.buf.in;
+                       ret = npcm_fiu_uma_read(mem, op, op->addr.val, false,
+                                               buf, op->data.nbytes);
+               } else {
+                       ret = npcm_fiu_read(mem, op);
+               }
+       } else  {
+               if (!op->addr.nbytes && !op->data.nbytes)
+                       ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false,
+                                                NULL, 0);
+               if (op->addr.nbytes && !op->data.nbytes) {
+                       int i;
+                       u8 buf_addr[4];
+                       u32 addr = op->addr.val;
+
+                       for (i = op->addr.nbytes - 1; i >= 0; i--) {
+                               buf_addr[i] = addr & 0xff;
+                               addr >>= 8;
+                       }
+                       ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false,
+                                                buf_addr, op->addr.nbytes);
+               }
+               if (!op->addr.nbytes && op->data.nbytes)
+                       ret = npcm_fiu_uma_write(mem, op, op->cmd.opcode, false,
+                                                (u8 *)op->data.buf.out,
+                                                op->data.nbytes);
+               if (op->addr.nbytes && op->data.nbytes)
+                       ret = npcm_fiu_manualwrite(mem, op);
+       }
+
+       return ret;
+}
+
+static int npcm_fiu_dirmap_create(struct spi_mem_dirmap_desc *desc)
+{
+       struct npcm_fiu_spi *fiu =
+               spi_controller_get_devdata(desc->mem->spi->master);
+       struct npcm_fiu_chip *chip = &fiu->chip[desc->mem->spi->chip_select];
+       struct regmap *gcr_regmap;
+
+       if (!fiu->res_mem) {
+               dev_warn(fiu->dev, "Reserved memory not defined, direct read disabled\n");
+               desc->nodirmap = true;
+               return 0;
+       }
+
+       if (!fiu->spix_mode &&
+           desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) {
+               desc->nodirmap = true;
+               return 0;
+       }
+
+       if (!chip->flash_region_mapped_ptr) {
+               chip->flash_region_mapped_ptr =
+                       devm_ioremap_nocache(fiu->dev, (fiu->res_mem->start +
+                                                       (fiu->info->max_map_size *
+                                                   desc->mem->spi->chip_select)),
+                                            (u32)desc->info.length);
+               if (!chip->flash_region_mapped_ptr) {
+                       dev_warn(fiu->dev, "Error mapping memory region, direct read disabled\n");
+                       desc->nodirmap = true;
+                       return 0;
+               }
+       }
+
+       if (of_device_is_compatible(fiu->dev->of_node, "nuvoton,npcm750-fiu")) {
+               gcr_regmap =
+                       syscon_regmap_lookup_by_compatible("nuvoton,npcm750-gcr");
+               if (IS_ERR(gcr_regmap)) {
+                       dev_warn(fiu->dev, "Didn't find nuvoton,npcm750-gcr, direct read disabled\n");
+                       desc->nodirmap = true;
+                       return 0;
+               }
+               regmap_update_bits(gcr_regmap, NPCM7XX_INTCR3_OFFSET,
+                                  NPCM7XX_INTCR3_FIU_FIX,
+                                  NPCM7XX_INTCR3_FIU_FIX);
+       }
+
+       if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_IN) {
+               if (!fiu->spix_mode)
+                       npcm_fiu_set_drd(fiu, &desc->info.op_tmpl);
+               else
+                       npcm_fiux_set_direct_rd(fiu);
+
+       } else {
+               npcm_fiux_set_direct_wr(fiu);
+       }
+
+       return 0;
+}
+
+static int npcm_fiu_setup(struct spi_device *spi)
+{
+       struct spi_controller *ctrl = spi->master;
+       struct npcm_fiu_spi *fiu = spi_controller_get_devdata(ctrl);
+       struct npcm_fiu_chip *chip;
+
+       chip = &fiu->chip[spi->chip_select];
+       chip->fiu = fiu;
+       chip->chipselect = spi->chip_select;
+       chip->clkrate = spi->max_speed_hz;
+
+       fiu->clkrate = clk_get_rate(fiu->clk);
+
+       return 0;
+}
+
+static const struct spi_controller_mem_ops npcm_fiu_mem_ops = {
+       .exec_op = npcm_fiu_exec_op,
+       .dirmap_create = npcm_fiu_dirmap_create,
+       .dirmap_read = npcm_fiu_direct_read,
+       .dirmap_write = npcm_fiu_direct_write,
+};
+
+static const struct of_device_id npcm_fiu_dt_ids[] = {
+       { .compatible = "nuvoton,npcm750-fiu", .data = &npxm7xx_fiu_data  },
+       { /* sentinel */ }
+};
+
+static int npcm_fiu_probe(struct platform_device *pdev)
+{
+       const struct fiu_data *fiu_data_match;
+       const struct of_device_id *match;
+       struct device *dev = &pdev->dev;
+       struct spi_controller *ctrl;
+       struct npcm_fiu_spi *fiu;
+       void __iomem *regbase;
+       struct resource *res;
+       int ret;
+       int id;
+
+       ctrl = spi_alloc_master(dev, sizeof(*fiu));
+       if (!ctrl)
+               return -ENOMEM;
+
+       fiu = spi_controller_get_devdata(ctrl);
+
+       match = of_match_device(npcm_fiu_dt_ids, dev);
+       if (!match || !match->data) {
+               dev_err(dev, "No compatible OF match\n");
+               return -ENODEV;
+       }
+
+       fiu_data_match = match->data;
+       id = of_alias_get_id(dev->of_node, "fiu");
+       if (id < 0 || id >= fiu_data_match->fiu_max) {
+               dev_err(dev, "Invalid platform device id: %d\n", id);
+               return -EINVAL;
+       }
+
+       fiu->info = &fiu_data_match->npcm_fiu_data_info[id];
+
+       platform_set_drvdata(pdev, fiu);
+       fiu->dev = dev;
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control");
+       regbase = devm_ioremap_resource(dev, res);
+       if (IS_ERR(regbase))
+               return PTR_ERR(regbase);
+
+       fiu->regmap = devm_regmap_init_mmio(dev, regbase,
+                                           &npcm_mtd_regmap_config);
+       if (IS_ERR(fiu->regmap)) {
+               dev_err(dev, "Failed to create regmap\n");
+               return PTR_ERR(fiu->regmap);
+       }
+
+       fiu->res_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+                                                   "memory");
+       fiu->clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(fiu->clk))
+               return PTR_ERR(fiu->clk);
+
+       fiu->spix_mode = of_property_read_bool(dev->of_node,
+                                              "nuvoton,spix-mode");
+
+       platform_set_drvdata(pdev, fiu);
+       clk_prepare_enable(fiu->clk);
+
+       ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD
+               | SPI_TX_DUAL | SPI_TX_QUAD;
+       ctrl->setup = npcm_fiu_setup;
+       ctrl->bus_num = -1;
+       ctrl->mem_ops = &npcm_fiu_mem_ops;
+       ctrl->num_chipselect = fiu->info->max_cs;
+       ctrl->dev.of_node = dev->of_node;
+
+       ret = devm_spi_register_master(dev, ctrl);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int npcm_fiu_remove(struct platform_device *pdev)
+{
+       struct npcm_fiu_spi *fiu = platform_get_drvdata(pdev);
+
+       clk_disable_unprepare(fiu->clk);
+       return 0;
+}
+
+MODULE_DEVICE_TABLE(of, npcm_fiu_dt_ids);
+
+static struct platform_driver npcm_fiu_driver = {
+       .driver = {
+               .name   = "NPCM-FIU",
+               .bus    = &platform_bus_type,
+               .of_match_table = npcm_fiu_dt_ids,
+       },
+       .probe      = npcm_fiu_probe,
+       .remove     = npcm_fiu_remove,
+};
+module_platform_driver(npcm_fiu_driver);
+
+MODULE_DESCRIPTION("Nuvoton FLASH Interface Unit SPI Controller Driver");
+MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>");
+MODULE_LICENSE("GPL v2");
index 734a2b9..b191d57 100644 (file)
@@ -341,7 +341,6 @@ static int npcm_pspi_probe(struct platform_device *pdev)
 {
        struct npcm_pspi *priv;
        struct spi_master *master;
-       struct resource *res;
        unsigned long clk_hz;
        struct device_node *np = pdev->dev.of_node;
        int num_cs, i;
@@ -368,8 +367,7 @@ static int npcm_pspi_probe(struct platform_device *pdev)
        priv->is_save_param = false;
        priv->id = pdev->id;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       priv->base = devm_ioremap_resource(&pdev->dev, res);
+       priv->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(priv->base)) {
                ret = PTR_ERR(priv->base);
                goto out_master_put;
@@ -388,7 +386,6 @@ static int npcm_pspi_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
-               dev_err(&pdev->dev, "failed to get IRQ\n");
                ret = irq;
                goto out_disable_clk;
        }
diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c
deleted file mode 100644 (file)
index 37e2034..0000000
+++ /dev/null
@@ -1,429 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2009 Nuvoton technology.
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_bitbang.h>
-
-#include <linux/platform_data/spi-nuc900.h>
-
-/* usi registers offset */
-#define USI_CNT                0x00
-#define USI_DIV                0x04
-#define USI_SSR                0x08
-#define USI_RX0                0x10
-#define USI_TX0                0x10
-
-/* usi register bit */
-#define ENINT          (0x01 << 17)
-#define ENFLG          (0x01 << 16)
-#define SLEEP          (0x0f << 12)
-#define TXNUM          (0x03 << 8)
-#define TXBITLEN       (0x1f << 3)
-#define TXNEG          (0x01 << 2)
-#define RXNEG          (0x01 << 1)
-#define LSB            (0x01 << 10)
-#define SELECTLEV      (0x01 << 2)
-#define SELECTPOL      (0x01 << 31)
-#define SELECTSLAVE    0x01
-#define GOBUSY         0x01
-
-struct nuc900_spi {
-       struct spi_bitbang       bitbang;
-       struct completion        done;
-       void __iomem            *regs;
-       int                      irq;
-       int                      len;
-       int                      count;
-       const unsigned char     *tx;
-       unsigned char           *rx;
-       struct clk              *clk;
-       struct spi_master       *master;
-       struct nuc900_spi_info *pdata;
-       spinlock_t              lock;
-};
-
-static inline struct nuc900_spi *to_hw(struct spi_device *sdev)
-{
-       return spi_master_get_devdata(sdev->master);
-}
-
-static void nuc900_slave_select(struct spi_device *spi, unsigned int ssr)
-{
-       struct nuc900_spi *hw = to_hw(spi);
-       unsigned int val;
-       unsigned int cs = spi->mode & SPI_CS_HIGH ? 1 : 0;
-       unsigned int cpol = spi->mode & SPI_CPOL ? 1 : 0;
-       unsigned long flags;
-
-       spin_lock_irqsave(&hw->lock, flags);
-
-       val = __raw_readl(hw->regs + USI_SSR);
-
-       if (!cs)
-               val &= ~SELECTLEV;
-       else
-               val |= SELECTLEV;
-
-       if (!ssr)
-               val &= ~SELECTSLAVE;
-       else
-               val |= SELECTSLAVE;
-
-       __raw_writel(val, hw->regs + USI_SSR);
-
-       val = __raw_readl(hw->regs + USI_CNT);
-
-       if (!cpol)
-               val &= ~SELECTPOL;
-       else
-               val |= SELECTPOL;
-
-       __raw_writel(val, hw->regs + USI_CNT);
-
-       spin_unlock_irqrestore(&hw->lock, flags);
-}
-
-static void nuc900_spi_chipsel(struct spi_device *spi, int value)
-{
-       switch (value) {
-       case BITBANG_CS_INACTIVE:
-               nuc900_slave_select(spi, 0);
-               break;
-
-       case BITBANG_CS_ACTIVE:
-               nuc900_slave_select(spi, 1);
-               break;
-       }
-}
-
-static void nuc900_spi_setup_txnum(struct nuc900_spi *hw, unsigned int txnum)
-{
-       unsigned int val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&hw->lock, flags);
-
-       val = __raw_readl(hw->regs + USI_CNT) & ~TXNUM;
-
-       if (txnum)
-               val |= txnum << 0x08;
-
-       __raw_writel(val, hw->regs + USI_CNT);
-
-       spin_unlock_irqrestore(&hw->lock, flags);
-
-}
-
-static void nuc900_spi_setup_txbitlen(struct nuc900_spi *hw,
-                                                       unsigned int txbitlen)
-{
-       unsigned int val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&hw->lock, flags);
-
-       val = __raw_readl(hw->regs + USI_CNT) & ~TXBITLEN;
-
-       val |= (txbitlen << 0x03);
-
-       __raw_writel(val, hw->regs + USI_CNT);
-
-       spin_unlock_irqrestore(&hw->lock, flags);
-}
-
-static void nuc900_spi_gobusy(struct nuc900_spi *hw)
-{
-       unsigned int val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&hw->lock, flags);
-
-       val = __raw_readl(hw->regs + USI_CNT);
-
-       val |= GOBUSY;
-
-       __raw_writel(val, hw->regs + USI_CNT);
-
-       spin_unlock_irqrestore(&hw->lock, flags);
-}
-
-static inline unsigned int hw_txbyte(struct nuc900_spi *hw, int count)
-{
-       return hw->tx ? hw->tx[count] : 0;
-}
-
-static int nuc900_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
-{
-       struct nuc900_spi *hw = to_hw(spi);
-
-       hw->tx = t->tx_buf;
-       hw->rx = t->rx_buf;
-       hw->len = t->len;
-       hw->count = 0;
-
-       __raw_writel(hw_txbyte(hw, 0x0), hw->regs + USI_TX0);
-
-       nuc900_spi_gobusy(hw);
-
-       wait_for_completion(&hw->done);
-
-       return hw->count;
-}
-
-static irqreturn_t nuc900_spi_irq(int irq, void *dev)
-{
-       struct nuc900_spi *hw = dev;
-       unsigned int status;
-       unsigned int count = hw->count;
-
-       status = __raw_readl(hw->regs + USI_CNT);
-       __raw_writel(status, hw->regs + USI_CNT);
-
-       if (status & ENFLG) {
-               hw->count++;
-
-               if (hw->rx)
-                       hw->rx[count] = __raw_readl(hw->regs + USI_RX0);
-               count++;
-
-               if (count < hw->len) {
-                       __raw_writel(hw_txbyte(hw, count), hw->regs + USI_TX0);
-                       nuc900_spi_gobusy(hw);
-               } else {
-                       complete(&hw->done);
-               }
-
-               return IRQ_HANDLED;
-       }
-
-       complete(&hw->done);
-       return IRQ_HANDLED;
-}
-
-static void nuc900_tx_edge(struct nuc900_spi *hw, unsigned int edge)
-{
-       unsigned int val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&hw->lock, flags);
-
-       val = __raw_readl(hw->regs + USI_CNT);
-
-       if (edge)
-               val |= TXNEG;
-       else
-               val &= ~TXNEG;
-       __raw_writel(val, hw->regs + USI_CNT);
-
-       spin_unlock_irqrestore(&hw->lock, flags);
-}
-
-static void nuc900_rx_edge(struct nuc900_spi *hw, unsigned int edge)
-{
-       unsigned int val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&hw->lock, flags);
-
-       val = __raw_readl(hw->regs + USI_CNT);
-
-       if (edge)
-               val |= RXNEG;
-       else
-               val &= ~RXNEG;
-       __raw_writel(val, hw->regs + USI_CNT);
-
-       spin_unlock_irqrestore(&hw->lock, flags);
-}
-
-static void nuc900_send_first(struct nuc900_spi *hw, unsigned int lsb)
-{
-       unsigned int val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&hw->lock, flags);
-
-       val = __raw_readl(hw->regs + USI_CNT);
-
-       if (lsb)
-               val |= LSB;
-       else
-               val &= ~LSB;
-       __raw_writel(val, hw->regs + USI_CNT);
-
-       spin_unlock_irqrestore(&hw->lock, flags);
-}
-
-static void nuc900_set_sleep(struct nuc900_spi *hw, unsigned int sleep)
-{
-       unsigned int val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&hw->lock, flags);
-
-       val = __raw_readl(hw->regs + USI_CNT) & ~SLEEP;
-
-       if (sleep)
-               val |= (sleep << 12);
-
-       __raw_writel(val, hw->regs + USI_CNT);
-
-       spin_unlock_irqrestore(&hw->lock, flags);
-}
-
-static void nuc900_enable_int(struct nuc900_spi *hw)
-{
-       unsigned int val;
-       unsigned long flags;
-
-       spin_lock_irqsave(&hw->lock, flags);
-
-       val = __raw_readl(hw->regs + USI_CNT);
-
-       val |= ENINT;
-
-       __raw_writel(val, hw->regs + USI_CNT);
-
-       spin_unlock_irqrestore(&hw->lock, flags);
-}
-
-static void nuc900_set_divider(struct nuc900_spi *hw)
-{
-       __raw_writel(hw->pdata->divider, hw->regs + USI_DIV);
-}
-
-static void nuc900_init_spi(struct nuc900_spi *hw)
-{
-       clk_enable(hw->clk);
-       spin_lock_init(&hw->lock);
-
-       nuc900_tx_edge(hw, hw->pdata->txneg);
-       nuc900_rx_edge(hw, hw->pdata->rxneg);
-       nuc900_send_first(hw, hw->pdata->lsb);
-       nuc900_set_sleep(hw, hw->pdata->sleep);
-       nuc900_spi_setup_txbitlen(hw, hw->pdata->txbitlen);
-       nuc900_spi_setup_txnum(hw, hw->pdata->txnum);
-       nuc900_set_divider(hw);
-       nuc900_enable_int(hw);
-}
-
-static int nuc900_spi_probe(struct platform_device *pdev)
-{
-       struct nuc900_spi *hw;
-       struct spi_master *master;
-       struct resource *res;
-       int err = 0;
-
-       master = spi_alloc_master(&pdev->dev, sizeof(struct nuc900_spi));
-       if (master == NULL) {
-               dev_err(&pdev->dev, "No memory for spi_master\n");
-               return -ENOMEM;
-       }
-
-       hw = spi_master_get_devdata(master);
-       hw->master = master;
-       hw->pdata  = dev_get_platdata(&pdev->dev);
-
-       if (hw->pdata == NULL) {
-               dev_err(&pdev->dev, "No platform data supplied\n");
-               err = -ENOENT;
-               goto err_pdata;
-       }
-
-       platform_set_drvdata(pdev, hw);
-       init_completion(&hw->done);
-
-       master->mode_bits          = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
-       if (hw->pdata->lsb)
-               master->mode_bits |= SPI_LSB_FIRST;
-       master->num_chipselect     = hw->pdata->num_cs;
-       master->bus_num            = hw->pdata->bus_num;
-       hw->bitbang.master         = hw->master;
-       hw->bitbang.chipselect     = nuc900_spi_chipsel;
-       hw->bitbang.txrx_bufs      = nuc900_spi_txrx;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       hw->regs = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(hw->regs)) {
-               err = PTR_ERR(hw->regs);
-               goto err_pdata;
-       }
-
-       hw->irq = platform_get_irq(pdev, 0);
-       if (hw->irq < 0) {
-               dev_err(&pdev->dev, "No IRQ specified\n");
-               err = -ENOENT;
-               goto err_pdata;
-       }
-
-       err = devm_request_irq(&pdev->dev, hw->irq, nuc900_spi_irq, 0,
-                               pdev->name, hw);
-       if (err) {
-               dev_err(&pdev->dev, "Cannot claim IRQ\n");
-               goto err_pdata;
-       }
-
-       hw->clk = devm_clk_get(&pdev->dev, "spi");
-       if (IS_ERR(hw->clk)) {
-               dev_err(&pdev->dev, "No clock for device\n");
-               err = PTR_ERR(hw->clk);
-               goto err_pdata;
-       }
-
-       mfp_set_groupg(&pdev->dev, NULL);
-       nuc900_init_spi(hw);
-
-       err = spi_bitbang_start(&hw->bitbang);
-       if (err) {
-               dev_err(&pdev->dev, "Failed to register SPI master\n");
-               goto err_register;
-       }
-
-       return 0;
-
-err_register:
-       clk_disable(hw->clk);
-err_pdata:
-       spi_master_put(hw->master);
-       return err;
-}
-
-static int nuc900_spi_remove(struct platform_device *dev)
-{
-       struct nuc900_spi *hw = platform_get_drvdata(dev);
-
-       spi_bitbang_stop(&hw->bitbang);
-       clk_disable(hw->clk);
-       spi_master_put(hw->master);
-       return 0;
-}
-
-static struct platform_driver nuc900_spi_driver = {
-       .probe          = nuc900_spi_probe,
-       .remove         = nuc900_spi_remove,
-       .driver         = {
-               .name   = "nuc900-spi",
-       },
-};
-module_platform_driver(nuc900_spi_driver);
-
-MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
-MODULE_DESCRIPTION("nuc900 spi driver!");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:nuc900-spi");
index 8894f98..501b923 100644 (file)
@@ -1007,10 +1007,8 @@ static int nxp_fspi_probe(struct platform_device *pdev)
 
        /* find the irq */
        ret = platform_get_irq(pdev, 0);
-       if (ret < 0) {
-               dev_err(dev, "failed to get the irq: %d\n", ret);
+       if (ret < 0)
                goto err_disable_clk;
-       }
 
        ret = devm_request_irq(dev, ret,
                        nxp_fspi_irq_handler, 0, pdev->name, f);
index bbc4ba6..e2331eb 100644 (file)
@@ -240,7 +240,6 @@ static int tiny_spi_probe(struct platform_device *pdev)
        struct tiny_spi_platform_data *platp = dev_get_platdata(&pdev->dev);
        struct tiny_spi *hw;
        struct spi_master *master;
-       struct resource *res;
        unsigned int i;
        int err = -ENODEV;
 
@@ -264,8 +263,7 @@ static int tiny_spi_probe(struct platform_device *pdev)
        hw->bitbang.txrx_bufs = tiny_spi_txrx_bufs;
 
        /* find and map our resources */
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       hw->base = devm_ioremap_resource(&pdev->dev, res);
+       hw->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(hw->base)) {
                err = PTR_ERR(hw->base);
                goto exit;
index b635526..86ad175 100644 (file)
@@ -570,7 +570,6 @@ static int pic32_sqi_probe(struct platform_device *pdev)
 {
        struct spi_master *master;
        struct pic32_sqi *sqi;
-       struct resource *reg;
        int ret;
 
        master = spi_alloc_master(&pdev->dev, sizeof(*sqi));
@@ -580,8 +579,7 @@ static int pic32_sqi_probe(struct platform_device *pdev)
        sqi = spi_master_get_devdata(master);
        sqi->master = master;
 
-       reg = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       sqi->regs = devm_ioremap_resource(&pdev->dev, reg);
+       sqi->regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(sqi->regs)) {
                ret = PTR_ERR(sqi->regs);
                goto err_free_master;
@@ -590,7 +588,6 @@ static int pic32_sqi_probe(struct platform_device *pdev)
        /* irq */
        sqi->irq = platform_get_irq(pdev, 0);
        if (sqi->irq < 0) {
-               dev_err(&pdev->dev, "no irq found\n");
                ret = sqi->irq;
                goto err_free_master;
        }
index 10cebea..69f517e 100644 (file)
@@ -711,22 +711,16 @@ static int pic32_spi_hw_probe(struct platform_device *pdev,
 
        /* get irq resources: err-irq, rx-irq, tx-irq */
        pic32s->fault_irq = platform_get_irq_byname(pdev, "fault");
-       if (pic32s->fault_irq < 0) {
-               dev_err(&pdev->dev, "fault-irq not found\n");
+       if (pic32s->fault_irq < 0)
                return pic32s->fault_irq;
-       }
 
        pic32s->rx_irq = platform_get_irq_byname(pdev, "rx");
-       if (pic32s->rx_irq < 0) {
-               dev_err(&pdev->dev, "rx-irq not found\n");
+       if (pic32s->rx_irq < 0)
                return pic32s->rx_irq;
-       }
 
        pic32s->tx_irq = platform_get_irq_byname(pdev, "tx");
-       if (pic32s->tx_irq < 0) {
-               dev_err(&pdev->dev, "tx-irq not found\n");
+       if (pic32s->tx_irq < 0)
                return pic32s->tx_irq;
-       }
 
        /* get clock */
        pic32s->clk = devm_clk_get(&pdev->dev, "mck0");
index e0f0611..250fd60 100644 (file)
@@ -424,7 +424,6 @@ static int qcom_qspi_probe(struct platform_device *pdev)
 {
        int ret;
        struct device *dev;
-       struct resource *res;
        struct spi_master *master;
        struct qcom_qspi *ctrl;
 
@@ -440,8 +439,7 @@ static int qcom_qspi_probe(struct platform_device *pdev)
 
        spin_lock_init(&ctrl->lock);
        ctrl->dev = dev;
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       ctrl->base = devm_ioremap_resource(dev, res);
+       ctrl->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(ctrl->base)) {
                ret = PTR_ERR(ctrl->base);
                goto exit_probe_master_put;
@@ -454,10 +452,8 @@ static int qcom_qspi_probe(struct platform_device *pdev)
                goto exit_probe_master_put;
 
        ret = platform_get_irq(pdev, 0);
-       if (ret < 0) {
-               dev_err(dev, "Failed to get irq %d\n", ret);
+       if (ret < 0)
                goto exit_probe_master_put;
-       }
        ret = devm_request_irq(dev, ret, qcom_qspi_irq,
                        IRQF_TRIGGER_HIGH, dev_name(dev), ctrl);
        if (ret) {
index 51f03d9..4c9620e 100644 (file)
@@ -135,12 +135,10 @@ static int rb4xx_spi_probe(struct platform_device *pdev)
        struct spi_master *master;
        struct clk *ahb_clk;
        struct rb4xx_spi *rbspi;
-       struct resource *r;
        int err;
        void __iomem *spi_base;
 
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       spi_base = devm_ioremap_resource(&pdev->dev, r);
+       spi_base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(spi_base))
                return PTR_ERR(spi_base);
 
index 48d8dff..2d6e37f 100644 (file)
@@ -487,7 +487,6 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
        struct s3c2410_spi_info *pdata;
        struct s3c24xx_spi *hw;
        struct spi_master *master;
-       struct resource *res;
        int err = 0;
 
        master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi));
@@ -536,8 +535,7 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
        dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang);
 
        /* find and map our resources */
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       hw->regs = devm_ioremap_resource(&pdev->dev, res);
+       hw->regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(hw->regs)) {
                err = PTR_ERR(hw->regs);
                goto err_no_pdata;
@@ -545,7 +543,6 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
 
        hw->irq = platform_get_irq(pdev, 0);
        if (hw->irq < 0) {
-               dev_err(&pdev->dev, "No IRQ specified\n");
                err = -ENOENT;
                goto err_no_pdata;
        }
index b50bdbc..8f13473 100644 (file)
@@ -1297,7 +1297,6 @@ static void sh_msiof_release_dma(struct sh_msiof_spi_priv *p)
 
 static int sh_msiof_spi_probe(struct platform_device *pdev)
 {
-       struct resource *r;
        struct spi_controller *ctlr;
        const struct sh_msiof_chipdata *chipdata;
        struct sh_msiof_spi_info *info;
@@ -1346,13 +1345,11 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
 
        i = platform_get_irq(pdev, 0);
        if (i < 0) {
-               dev_err(&pdev->dev, "cannot get IRQ\n");
                ret = i;
                goto err1;
        }
 
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       p->mapbase = devm_ioremap_resource(&pdev->dev, r);
+       p->mapbase = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(p->mapbase)) {
                ret = PTR_ERR(p->mapbase);
                goto err1;
index f1ee582..20bdae5 100644 (file)
@@ -437,10 +437,8 @@ static int spi_sh_probe(struct platform_device *pdev)
        }
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(&pdev->dev, "platform_get_irq error: %d\n", irq);
+       if (irq < 0)
                return irq;
-       }
 
        master = spi_alloc_master(&pdev->dev, sizeof(struct spi_sh_data));
        if (master == NULL) {
index 93ec2c6..35254bd 100644 (file)
@@ -292,7 +292,6 @@ sifive_spi_transfer_one(struct spi_master *master, struct spi_device *device,
 static int sifive_spi_probe(struct platform_device *pdev)
 {
        struct sifive_spi *spi;
-       struct resource *res;
        int ret, irq, num_cs;
        u32 cs_bits, max_bits_per_word;
        struct spi_master *master;
@@ -307,8 +306,7 @@ static int sifive_spi_probe(struct platform_device *pdev)
        init_completion(&spi->done);
        platform_set_drvdata(pdev, master);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       spi->regs = devm_ioremap_resource(&pdev->dev, res);
+       spi->regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(spi->regs)) {
                ret = PTR_ERR(spi->regs);
                goto put_master;
@@ -323,7 +321,6 @@ static int sifive_spi_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
-               dev_err(&pdev->dev, "Unable to find interrupt\n");
                ret = irq;
                goto put_master;
        }
index 71b882a..e1e6391 100644 (file)
@@ -1070,7 +1070,6 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
 {
        struct sirfsoc_spi *sspi;
        struct spi_master *master;
-       struct resource *mem_res;
        const struct sirf_spi_comp_data *spi_comp_data;
        int irq;
        int ret;
@@ -1097,8 +1096,7 @@ static int spi_sirfsoc_probe(struct platform_device *pdev)
        sspi->fifo_level_chk_mask = (sspi->fifo_size / 4) - 1;
        sspi->dat_max_frm_len = spi_comp_data->dat_max_frm_len;
        sspi->fifo_size = spi_comp_data->fifo_size;
-       mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       sspi->base = devm_ioremap_resource(&pdev->dev, mem_res);
+       sspi->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(sspi->base)) {
                ret = PTR_ERR(sspi->base);
                goto free_master;
index d107543..61bc43b 100644 (file)
@@ -410,7 +410,6 @@ static int mtk_spi_slave_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
-               dev_err(&pdev->dev, "failed to get irq (%d)\n", irq);
                ret = irq;
                goto err_put_ctlr;
        }
index df5960b..9a05128 100644 (file)
@@ -86,6 +86,7 @@
 #define BIT_WDG_EN                     BIT(2)
 
 /* Definition of PMIC reset status register */
+#define HWRST_STATUS_SECURITY          0x02
 #define HWRST_STATUS_RECOVERY          0x20
 #define HWRST_STATUS_NORMAL            0x40
 #define HWRST_STATUS_ALARM             0x50
@@ -97,6 +98,8 @@
 #define HWRST_STATUS_AUTODLOADER       0xa0
 #define HWRST_STATUS_IQMODE            0xb0
 #define HWRST_STATUS_SPRDISK           0xc0
+#define HWRST_STATUS_FACTORYTEST       0xe0
+#define HWRST_STATUS_WATCHDOG          0xf0
 
 /* Use default timeout 50 ms that converts to watchdog values */
 #define WDG_LOAD_VAL                   ((50 * 1000) / 32768)
@@ -162,14 +165,16 @@ static int sprd_adi_read(struct sprd_adi *sadi, u32 reg_paddr, u32 *read_val)
        int read_timeout = ADI_READ_TIMEOUT;
        unsigned long flags;
        u32 val, rd_addr;
-       int ret;
-
-       ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
-                                         ADI_HWSPINLOCK_TIMEOUT,
-                                         &flags);
-       if (ret) {
-               dev_err(sadi->dev, "get the hw lock failed\n");
-               return ret;
+       int ret = 0;
+
+       if (sadi->hwlock) {
+               ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
+                                                 ADI_HWSPINLOCK_TIMEOUT,
+                                                 &flags);
+               if (ret) {
+                       dev_err(sadi->dev, "get the hw lock failed\n");
+                       return ret;
+               }
        }
 
        /*
@@ -216,7 +221,8 @@ static int sprd_adi_read(struct sprd_adi *sadi, u32 reg_paddr, u32 *read_val)
        *read_val = val & RD_VALUE_MASK;
 
 out:
-       hwspin_unlock_irqrestore(sadi->hwlock, &flags);
+       if (sadi->hwlock)
+               hwspin_unlock_irqrestore(sadi->hwlock, &flags);
        return ret;
 }
 
@@ -227,12 +233,14 @@ static int sprd_adi_write(struct sprd_adi *sadi, u32 reg_paddr, u32 val)
        unsigned long flags;
        int ret;
 
-       ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
-                                         ADI_HWSPINLOCK_TIMEOUT,
-                                         &flags);
-       if (ret) {
-               dev_err(sadi->dev, "get the hw lock failed\n");
-               return ret;
+       if (sadi->hwlock) {
+               ret = hwspin_lock_timeout_irqsave(sadi->hwlock,
+                                                 ADI_HWSPINLOCK_TIMEOUT,
+                                                 &flags);
+               if (ret) {
+                       dev_err(sadi->dev, "get the hw lock failed\n");
+                       return ret;
+               }
        }
 
        ret = sprd_adi_drain_fifo(sadi);
@@ -258,7 +266,8 @@ static int sprd_adi_write(struct sprd_adi *sadi, u32 reg_paddr, u32 val)
        }
 
 out:
-       hwspin_unlock_irqrestore(sadi->hwlock, &flags);
+       if (sadi->hwlock)
+               hwspin_unlock_irqrestore(sadi->hwlock, &flags);
        return ret;
 }
 
@@ -307,6 +316,18 @@ static int sprd_adi_transfer_one(struct spi_controller *ctlr,
        return 0;
 }
 
+static void sprd_adi_set_wdt_rst_mode(struct sprd_adi *sadi)
+{
+#ifdef CONFIG_SPRD_WATCHDOG
+       u32 val;
+
+       /* Set default watchdog reboot mode */
+       sprd_adi_read(sadi, sadi->slave_pbase + PMIC_RST_STATUS, &val);
+       val |= HWRST_STATUS_WATCHDOG;
+       sprd_adi_write(sadi, sadi->slave_pbase + PMIC_RST_STATUS, val);
+#endif
+}
+
 static int sprd_adi_restart_handler(struct notifier_block *this,
                                    unsigned long mode, void *cmd)
 {
@@ -336,11 +357,16 @@ static int sprd_adi_restart_handler(struct notifier_block *this,
                reboot_mode = HWRST_STATUS_IQMODE;
        else if (!strncmp(cmd, "sprdisk", 7))
                reboot_mode = HWRST_STATUS_SPRDISK;
+       else if (!strncmp(cmd, "tospanic", 8))
+               reboot_mode = HWRST_STATUS_SECURITY;
+       else if (!strncmp(cmd, "factorytest", 11))
+               reboot_mode = HWRST_STATUS_FACTORYTEST;
        else
                reboot_mode = HWRST_STATUS_NORMAL;
 
        /* Record the reboot mode */
        sprd_adi_read(sadi, sadi->slave_pbase + PMIC_RST_STATUS, &val);
+       val &= ~HWRST_STATUS_WATCHDOG;
        val |= reboot_mode;
        sprd_adi_write(sadi, sadi->slave_pbase + PMIC_RST_STATUS, val);
 
@@ -380,9 +406,6 @@ static void sprd_adi_hw_init(struct sprd_adi *sadi)
        const __be32 *list;
        u32 tmp;
 
-       /* Address bits select default 12 bits */
-       writel_relaxed(0, sadi->base + REG_ADI_CTRL0);
-
        /* Set all channels as default priority */
        writel_relaxed(0, sadi->base + REG_ADI_CHN_PRIL);
        writel_relaxed(0, sadi->base + REG_ADI_CHN_PRIH);
@@ -459,19 +482,30 @@ static int sprd_adi_probe(struct platform_device *pdev)
        sadi->slave_pbase = res->start + ADI_SLAVE_OFFSET;
        sadi->ctlr = ctlr;
        sadi->dev = &pdev->dev;
-       ret = of_hwspin_lock_get_id_byname(np, "adi");
-       if (ret < 0) {
-               dev_err(&pdev->dev, "can not get the hardware spinlock\n");
-               goto put_ctlr;
-       }
-
-       sadi->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, ret);
-       if (!sadi->hwlock) {
-               ret = -ENXIO;
-               goto put_ctlr;
+       ret = of_hwspin_lock_get_id(np, 0);
+       if (ret > 0 || (IS_ENABLED(CONFIG_HWSPINLOCK) && ret == 0)) {
+               sadi->hwlock =
+                       devm_hwspin_lock_request_specific(&pdev->dev, ret);
+               if (!sadi->hwlock) {
+                       ret = -ENXIO;
+                       goto put_ctlr;
+               }
+       } else {
+               switch (ret) {
+               case -ENOENT:
+                       dev_info(&pdev->dev, "no hardware spinlock supplied\n");
+                       break;
+               default:
+                       dev_err(&pdev->dev,
+                               "failed to find hwlock id, %d\n", ret);
+                       /* fall-through */
+               case -EPROBE_DEFER:
+                       goto put_ctlr;
+               }
        }
 
        sprd_adi_hw_init(sadi);
+       sprd_adi_set_wdt_rst_mode(sadi);
 
        ctlr->dev.of_node = pdev->dev.of_node;
        ctlr->bus_num = pdev->id;
index 1b7eebb..8c9021b 100644 (file)
@@ -843,10 +843,8 @@ static int sprd_spi_irq_init(struct platform_device *pdev, struct sprd_spi *ss)
        int ret;
 
        ss->irq = platform_get_irq(pdev, 0);
-       if (ss->irq < 0) {
-               dev_err(&pdev->dev, "failed to get irq resource\n");
+       if (ss->irq < 0)
                return ss->irq;
-       }
 
        ret = devm_request_irq(&pdev->dev, ss->irq, sprd_spi_handle_irq,
                                0, pdev->name, ss);
index 840a6bf..0c24c49 100644 (file)
@@ -298,7 +298,6 @@ static int spi_st_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        struct spi_master *master;
-       struct resource *res;
        struct spi_st *spi_st;
        int irq, ret = 0;
        u32 var;
@@ -331,8 +330,7 @@ static int spi_st_probe(struct platform_device *pdev)
        init_completion(&spi_st->done);
 
        /* Get resources */
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       spi_st->base = devm_ioremap_resource(&pdev->dev, res);
+       spi_st->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(spi_st->base)) {
                ret = PTR_ERR(spi_st->base);
                goto clk_disable;
index 655e4af..9ac6f9f 100644 (file)
@@ -570,11 +570,8 @@ static int stm32_qspi_probe(struct platform_device *pdev)
        }
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               if (irq != -EPROBE_DEFER)
-                       dev_err(dev, "IRQ error missing or invalid\n");
+       if (irq < 0)
                return irq;
-       }
 
        ret = devm_request_irq(dev, irq, stm32_qspi_irq, 0,
                               dev_name(dev), qspi);
index 5194bc0..cbfac65 100644 (file)
@@ -428,7 +428,6 @@ static int sun4i_spi_probe(struct platform_device *pdev)
 {
        struct spi_master *master;
        struct sun4i_spi *sspi;
-       struct resource *res;
        int ret = 0, irq;
 
        master = spi_alloc_master(&pdev->dev, sizeof(struct sun4i_spi));
@@ -440,8 +439,7 @@ static int sun4i_spi_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, master);
        sspi = spi_master_get_devdata(master);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       sspi->base_addr = devm_ioremap_resource(&pdev->dev, res);
+       sspi->base_addr = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(sspi->base_addr)) {
                ret = PTR_ERR(sspi->base_addr);
                goto err_free_master;
@@ -449,7 +447,6 @@ static int sun4i_spi_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
-               dev_err(&pdev->dev, "No spi IRQ specified\n");
                ret = -ENXIO;
                goto err_free_master;
        }
index ee2bdaf..ec7967b 100644 (file)
@@ -435,7 +435,6 @@ static int sun6i_spi_probe(struct platform_device *pdev)
 {
        struct spi_master *master;
        struct sun6i_spi *sspi;
-       struct resource *res;
        int ret = 0, irq;
 
        master = spi_alloc_master(&pdev->dev, sizeof(struct sun6i_spi));
@@ -447,8 +446,7 @@ static int sun6i_spi_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, master);
        sspi = spi_master_get_devdata(master);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       sspi->base_addr = devm_ioremap_resource(&pdev->dev, res);
+       sspi->base_addr = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(sspi->base_addr)) {
                ret = PTR_ERR(sspi->base_addr);
                goto err_free_master;
@@ -456,7 +454,6 @@ static int sun6i_spi_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
-               dev_err(&pdev->dev, "No spi IRQ specified\n");
                ret = -ENXIO;
                goto err_free_master;
        }
index f99abd8..ae17c99 100644 (file)
@@ -670,7 +670,6 @@ static int synquacer_spi_probe(struct platform_device *pdev)
 
        rx_irq = platform_get_irq(pdev, 0);
        if (rx_irq <= 0) {
-               dev_err(&pdev->dev, "get rx_irq failed (%d)\n", rx_irq);
                ret = rx_irq;
                goto put_spi;
        }
@@ -685,7 +684,6 @@ static int synquacer_spi_probe(struct platform_device *pdev)
 
        tx_irq = platform_get_irq(pdev, 1);
        if (tx_irq <= 0) {
-               dev_err(&pdev->dev, "get tx_irq failed (%d)\n", tx_irq);
                ret = tx_irq;
                goto put_spi;
        }
index cd714a4..a841a72 100644 (file)
@@ -419,7 +419,6 @@ static int tegra_sflash_probe(struct platform_device *pdev)
 {
        struct spi_master       *master;
        struct tegra_sflash_data        *tsd;
-       struct resource         *r;
        int ret;
        const struct of_device_id *match;
 
@@ -451,8 +450,7 @@ static int tegra_sflash_probe(struct platform_device *pdev)
                                 &master->max_speed_hz))
                master->max_speed_hz = 25000000; /* 25MHz */
 
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       tsd->base = devm_ioremap_resource(&pdev->dev, r);
+       tsd->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(tsd->base)) {
                ret = PTR_ERR(tsd->base);
                goto exit_free_master;
index 6ca6007..3cb6537 100644 (file)
@@ -717,7 +717,6 @@ static int ti_qspi_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
-               dev_err(&pdev->dev, "no irq resource?\n");
                ret = irq;
                goto free_master;
        }
index b32c77d..47cde18 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/bitfield.h>
 #include <linux/bitops.h>
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/module.h>
@@ -16,6 +17,7 @@
 #include <asm/unaligned.h>
 
 #define SSI_TIMEOUT_MS         2000
+#define SSI_POLL_TIMEOUT_US    200
 #define SSI_MAX_CLK_DIVIDER    254
 #define SSI_MIN_CLK_DIVIDER    4
 
@@ -214,6 +216,7 @@ static void uniphier_spi_setup_transfer(struct spi_device *spi,
        if (!priv->is_save_param || priv->mode != spi->mode) {
                uniphier_spi_set_mode(spi);
                priv->mode = spi->mode;
+               priv->is_save_param = false;
        }
 
        if (!priv->is_save_param || priv->bits_per_word != t->bits_per_word) {
@@ -226,8 +229,7 @@ static void uniphier_spi_setup_transfer(struct spi_device *spi,
                priv->speed_hz = t->speed_hz;
        }
 
-       if (!priv->is_save_param)
-               priv->is_save_param = true;
+       priv->is_save_param = true;
 
        /* reset FIFOs */
        val = SSI_FC_TXFFL | SSI_FC_RXFFL;
@@ -290,21 +292,23 @@ static void uniphier_spi_recv(struct uniphier_spi_priv *priv)
 
 static void uniphier_spi_fill_tx_fifo(struct uniphier_spi_priv *priv)
 {
-       unsigned int tx_count;
+       unsigned int fifo_threshold, fill_bytes;
        u32 val;
 
-       tx_count = DIV_ROUND_UP(priv->tx_bytes,
+       fifo_threshold = DIV_ROUND_UP(priv->rx_bytes,
                                bytes_per_word(priv->bits_per_word));
-       tx_count = min(tx_count, SSI_FIFO_DEPTH);
+       fifo_threshold = min(fifo_threshold, SSI_FIFO_DEPTH);
+
+       fill_bytes = fifo_threshold - (priv->rx_bytes - priv->tx_bytes);
 
        /* set fifo threshold */
        val = readl(priv->base + SSI_FC);
        val &= ~(SSI_FC_TXFTH_MASK | SSI_FC_RXFTH_MASK);
-       val |= FIELD_PREP(SSI_FC_TXFTH_MASK, tx_count);
-       val |= FIELD_PREP(SSI_FC_RXFTH_MASK, tx_count);
+       val |= FIELD_PREP(SSI_FC_TXFTH_MASK, fifo_threshold);
+       val |= FIELD_PREP(SSI_FC_RXFTH_MASK, fifo_threshold);
        writel(val, priv->base + SSI_FC);
 
-       while (tx_count--)
+       while (fill_bytes--)
                uniphier_spi_send(priv);
 }
 
@@ -323,20 +327,14 @@ static void uniphier_spi_set_cs(struct spi_device *spi, bool enable)
        writel(val, priv->base + SSI_FPS);
 }
 
-static int uniphier_spi_transfer_one(struct spi_master *master,
-                                    struct spi_device *spi,
-                                    struct spi_transfer *t)
+static int uniphier_spi_transfer_one_irq(struct spi_master *master,
+                                        struct spi_device *spi,
+                                        struct spi_transfer *t)
 {
        struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
        struct device *dev = master->dev.parent;
        unsigned long time_left;
 
-       /* Terminate and return success for 0 byte length transfer */
-       if (!t->len)
-               return 0;
-
-       uniphier_spi_setup_transfer(spi, t);
-
        reinit_completion(&priv->xfer_done);
 
        uniphier_spi_fill_tx_fifo(priv);
@@ -356,6 +354,59 @@ static int uniphier_spi_transfer_one(struct spi_master *master,
        return priv->error;
 }
 
+static int uniphier_spi_transfer_one_poll(struct spi_master *master,
+                                         struct spi_device *spi,
+                                         struct spi_transfer *t)
+{
+       struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
+       int loop = SSI_POLL_TIMEOUT_US * 10;
+
+       while (priv->tx_bytes) {
+               uniphier_spi_fill_tx_fifo(priv);
+
+               while ((priv->rx_bytes - priv->tx_bytes) > 0) {
+                       while (!(readl(priv->base + SSI_SR) & SSI_SR_RNE)
+                                                               && loop--)
+                               ndelay(100);
+
+                       if (loop == -1)
+                               goto irq_transfer;
+
+                       uniphier_spi_recv(priv);
+               }
+       }
+
+       return 0;
+
+irq_transfer:
+       return uniphier_spi_transfer_one_irq(master, spi, t);
+}
+
+static int uniphier_spi_transfer_one(struct spi_master *master,
+                                    struct spi_device *spi,
+                                    struct spi_transfer *t)
+{
+       struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
+       unsigned long threshold;
+
+       /* Terminate and return success for 0 byte length transfer */
+       if (!t->len)
+               return 0;
+
+       uniphier_spi_setup_transfer(spi, t);
+
+       /*
+        * If the transfer operation will take longer than
+        * SSI_POLL_TIMEOUT_US, it should use irq.
+        */
+       threshold = DIV_ROUND_UP(SSI_POLL_TIMEOUT_US * priv->speed_hz,
+                                       USEC_PER_SEC * BITS_PER_BYTE);
+       if (t->len > threshold)
+               return uniphier_spi_transfer_one_irq(master, spi, t);
+       else
+               return uniphier_spi_transfer_one_poll(master, spi, t);
+}
+
 static int uniphier_spi_prepare_transfer_hardware(struct spi_master *master)
 {
        struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
@@ -419,7 +470,6 @@ static int uniphier_spi_probe(struct platform_device *pdev)
 {
        struct uniphier_spi_priv *priv;
        struct spi_master *master;
-       struct resource *res;
        unsigned long clk_rate;
        int irq;
        int ret;
@@ -434,8 +484,7 @@ static int uniphier_spi_probe(struct platform_device *pdev)
        priv->master = master;
        priv->is_save_param = false;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       priv->base = devm_ioremap_resource(&pdev->dev, res);
+       priv->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(priv->base)) {
                ret = PTR_ERR(priv->base);
                goto out_master_put;
@@ -454,7 +503,6 @@ static int uniphier_spi_probe(struct platform_device *pdev)
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
-               dev_err(&pdev->dev, "failed to get IRQ\n");
                ret = irq;
                goto out_disable_clk;
        }
index 1dc479f..797ac0e 100644 (file)
@@ -370,7 +370,6 @@ static int xlp_spi_probe(struct platform_device *pdev)
 {
        struct spi_master *master;
        struct xlp_spi_priv *xspi;
-       struct resource *res;
        struct clk *clk;
        int irq, err;
 
@@ -378,16 +377,13 @@ static int xlp_spi_probe(struct platform_device *pdev)
        if (!xspi)
                return -ENOMEM;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       xspi->base = devm_ioremap_resource(&pdev->dev, res);
+       xspi->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(xspi->base))
                return PTR_ERR(xspi->base);
 
        irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(&pdev->dev, "no IRQ resource found: %d\n", irq);
+       if (irq < 0)
                return irq;
-       }
        err = devm_request_irq(&pdev->dev, irq, xlp_spi_interrupt, 0,
                        pdev->name, xspi);
        if (err) {
index c6bee67..5cf6993 100644 (file)
@@ -620,7 +620,6 @@ static int zynq_qspi_probe(struct platform_device *pdev)
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
        struct zynq_qspi *xqspi;
-       struct resource *res;
        u32 num_cs;
 
        ctlr = spi_alloc_master(&pdev->dev, sizeof(*xqspi));
@@ -630,8 +629,7 @@ static int zynq_qspi_probe(struct platform_device *pdev)
        xqspi = spi_controller_get_devdata(ctlr);
        xqspi->dev = dev;
        platform_set_drvdata(pdev, xqspi);
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       xqspi->regs = devm_ioremap_resource(&pdev->dev, res);
+       xqspi->regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(xqspi->regs)) {
                ret = PTR_ERR(xqspi->regs);
                goto remove_master;
@@ -671,7 +669,6 @@ static int zynq_qspi_probe(struct platform_device *pdev)
        xqspi->irq = platform_get_irq(pdev, 0);
        if (xqspi->irq <= 0) {
                ret = -ENXIO;
-               dev_err(&pdev->dev, "irq resource not found\n");
                goto remove_master;
        }
        ret = devm_request_irq(&pdev->dev, xqspi->irq, zynq_qspi_irq,
@@ -695,7 +692,7 @@ static int zynq_qspi_probe(struct platform_device *pdev)
        ctlr->setup = zynq_qspi_setup_op;
        ctlr->max_speed_hz = clk_get_rate(xqspi->refclk) / 2;
        ctlr->dev.of_node = np;
-       ret = spi_register_controller(ctlr);
+       ret = devm_spi_register_controller(&pdev->dev, ctlr);
        if (ret) {
                dev_err(&pdev->dev, "spi_register_master failed\n");
                goto clk_dis_all;
index 07a83ca..60c4de4 100644 (file)
@@ -1016,7 +1016,6 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
        int ret = 0;
        struct spi_master *master;
        struct zynqmp_qspi *xqspi;
-       struct resource *res;
        struct device *dev = &pdev->dev;
 
        eemi_ops = zynqmp_pm_get_eemi_ops();
@@ -1031,8 +1030,7 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
        master->dev.of_node = pdev->dev.of_node;
        platform_set_drvdata(pdev, master);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       xqspi->regs = devm_ioremap_resource(&pdev->dev, res);
+       xqspi->regs = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(xqspi->regs)) {
                ret = PTR_ERR(xqspi->regs);
                goto remove_master;
@@ -1077,7 +1075,6 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
        xqspi->irq = platform_get_irq(pdev, 0);
        if (xqspi->irq <= 0) {
                ret = -ENXIO;
-               dev_err(dev, "irq resource not found\n");
                goto clk_dis_all;
        }
        ret = devm_request_irq(&pdev->dev, xqspi->irq, zynqmp_qspi_irq,
index 75ac046..f8b4654 100644 (file)
@@ -1265,8 +1265,9 @@ EXPORT_SYMBOL_GPL(spi_finalize_current_transfer);
  */
 static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread)
 {
-       unsigned long flags;
+       struct spi_message *msg;
        bool was_busy = false;
+       unsigned long flags;
        int ret;
 
        /* Lock queue */
@@ -1325,10 +1326,10 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread)
        }
 
        /* Extract head of queue */
-       ctlr->cur_msg =
-               list_first_entry(&ctlr->queue, struct spi_message, queue);
+       msg = list_first_entry(&ctlr->queue, struct spi_message, queue);
+       ctlr->cur_msg = msg;
 
-       list_del_init(&ctlr->cur_msg->queue);
+       list_del_init(&msg->queue);
        if (ctlr->busy)
                was_busy = true;
        else
@@ -1361,7 +1362,7 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread)
                        if (ctlr->auto_runtime_pm)
                                pm_runtime_put(ctlr->dev.parent);
 
-                       ctlr->cur_msg->status = ret;
+                       msg->status = ret;
                        spi_finalize_current_message(ctlr);
 
                        mutex_unlock(&ctlr->io_mutex);
@@ -1369,28 +1370,28 @@ static void __spi_pump_messages(struct spi_controller *ctlr, bool in_kthread)
                }
        }
 
-       trace_spi_message_start(ctlr->cur_msg);
+       trace_spi_message_start(msg);
 
        if (ctlr->prepare_message) {
-               ret = ctlr->prepare_message(ctlr, ctlr->cur_msg);
+               ret = ctlr->prepare_message(ctlr, msg);
                if (ret) {
                        dev_err(&ctlr->dev, "failed to prepare message: %d\n",
                                ret);
-                       ctlr->cur_msg->status = ret;
+                       msg->status = ret;
                        spi_finalize_current_message(ctlr);
                        goto out;
                }
                ctlr->cur_msg_prepared = true;
        }
 
-       ret = spi_map_msg(ctlr, ctlr->cur_msg);
+       ret = spi_map_msg(ctlr, msg);
        if (ret) {
-               ctlr->cur_msg->status = ret;
+               msg->status = ret;
                spi_finalize_current_message(ctlr);
                goto out;
        }
 
-       ret = ctlr->transfer_one_message(ctlr, ctlr->cur_msg);
+       ret = ctlr->transfer_one_message(ctlr, msg);
        if (ret) {
                dev_err(&ctlr->dev,
                        "failed to transfer one message from queue\n");
@@ -1434,7 +1435,7 @@ static void spi_pump_messages(struct kthread_work *work)
  */
 static void spi_set_thread_rt(struct spi_controller *ctlr)
 {
-       struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 };
+       struct sched_param param = { .sched_priority = MAX_RT_PRIO / 2 };
 
        dev_info(&ctlr->dev,
                "will run message pump with realtime priority\n");
@@ -2105,8 +2106,8 @@ static int match_true(struct device *dev, void *data)
        return 1;
 }
 
-static ssize_t spi_slave_show(struct device *dev,
-                             struct device_attribute *attr, char *buf)
+static ssize_t slave_show(struct device *dev, struct device_attribute *attr,
+                         char *buf)
 {
        struct spi_controller *ctlr = container_of(dev, struct spi_controller,
                                                   dev);
@@ -2117,9 +2118,8 @@ static ssize_t spi_slave_show(struct device *dev,
                       child ? to_spi_device(child)->modalias : NULL);
 }
 
-static ssize_t spi_slave_store(struct device *dev,
-                              struct device_attribute *attr, const char *buf,
-                              size_t count)
+static ssize_t slave_store(struct device *dev, struct device_attribute *attr,
+                          const char *buf, size_t count)
 {
        struct spi_controller *ctlr = container_of(dev, struct spi_controller,
                                                   dev);
@@ -2157,7 +2157,7 @@ static ssize_t spi_slave_store(struct device *dev,
        return count;
 }
 
-static DEVICE_ATTR(slave, 0644, spi_slave_show, spi_slave_store);
+static DEVICE_ATTR_RW(slave);
 
 static struct attribute *spi_slave_attrs[] = {
        &dev_attr_slave.attr,
@@ -2188,8 +2188,10 @@ extern struct class spi_slave_class;     /* dummy */
  * __spi_alloc_controller - allocate an SPI master or slave controller
  * @dev: the controller, possibly using the platform_bus
  * @size: how much zeroed driver-private data to allocate; the pointer to this
- *     memory is in the driver_data field of the returned device,
- *     accessible with spi_controller_get_devdata().
+ *     memory is in the driver_data field of the returned device, accessible
+ *     with spi_controller_get_devdata(); the memory is cacheline aligned;
+ *     drivers granting DMA access to portions of their private data need to
+ *     round up @size using ALIGN(size, dma_get_cache_alignment()).
  * @slave: flag indicating whether to allocate an SPI master (false) or SPI
  *     slave (true) controller
  * Context: can sleep
@@ -2211,11 +2213,12 @@ struct spi_controller *__spi_alloc_controller(struct device *dev,
                                              unsigned int size, bool slave)
 {
        struct spi_controller   *ctlr;
+       size_t ctlr_size = ALIGN(sizeof(*ctlr), dma_get_cache_alignment());
 
        if (!dev)
                return NULL;
 
-       ctlr = kzalloc(size + sizeof(*ctlr), GFP_KERNEL);
+       ctlr = kzalloc(size + ctlr_size, GFP_KERNEL);
        if (!ctlr)
                return NULL;
 
@@ -2229,14 +2232,14 @@ struct spi_controller *__spi_alloc_controller(struct device *dev,
                ctlr->dev.class = &spi_master_class;
        ctlr->dev.parent = dev;
        pm_suspend_ignore_children(&ctlr->dev, true);
-       spi_controller_set_devdata(ctlr, &ctlr[1]);
+       spi_controller_set_devdata(ctlr, (void *)ctlr + ctlr_size);
 
        return ctlr;
 }
 EXPORT_SYMBOL_GPL(__spi_alloc_controller);
 
 #ifdef CONFIG_OF
-static int of_spi_register_master(struct spi_controller *ctlr)
+static int of_spi_get_gpio_numbers(struct spi_controller *ctlr)
 {
        int nb, i, *cs;
        struct device_node *np = ctlr->dev.of_node;
@@ -2269,7 +2272,7 @@ static int of_spi_register_master(struct spi_controller *ctlr)
        return 0;
 }
 #else
-static int of_spi_register_master(struct spi_controller *ctlr)
+static int of_spi_get_gpio_numbers(struct spi_controller *ctlr)
 {
        return 0;
 }
@@ -2456,7 +2459,7 @@ int spi_register_controller(struct spi_controller *ctlr)
                        ctlr->mode_bits |= SPI_CS_HIGH;
                } else {
                        /* Legacy code path for GPIOs from DT */
-                       status = of_spi_register_master(ctlr);
+                       status = of_spi_get_gpio_numbers(ctlr);
                        if (status)
                                return status;
                }
index aa94270..13b0269 100644 (file)
@@ -148,6 +148,7 @@ u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg)
                         */
                        optee_cq_wait_for_completion(&optee->call_queue, &w);
                } else if (OPTEE_SMC_RETURN_IS_RPC(res.a0)) {
+                       might_sleep();
                        param.a0 = res.a0;
                        param.a1 = res.a1;
                        param.a2 = res.a2;
index 3083dba..514169e 100644 (file)
@@ -739,7 +739,8 @@ config SERIAL_PNX8XXX_CONSOLE
 
 config SERIAL_HS_LPC32XX
        tristate "LPC32XX high speed serial port support"
-       depends on ARCH_LPC32XX && OF
+       depends on ARCH_LPC32XX || COMPILE_TEST
+       depends on OF
        select SERIAL_CORE
        help
          Support for the LPC32XX high speed serial ports (up to 900kbps).
@@ -855,16 +856,6 @@ config SERIAL_CPM_CONSOLE
          your boot loader (lilo or loadlin) about how to pass options to the
          kernel at boot time.)
 
-config SERIAL_SGI_L1_CONSOLE
-       bool "SGI Altix L1 serial console support"
-       depends on IA64_GENERIC || IA64_SGI_SN2
-       select SERIAL_CORE
-       select SERIAL_CORE_CONSOLE
-       help
-               If you have an SGI Altix and you would like to use the system
-               controller serial port as your console (you want this!),
-               say Y.  Otherwise, say N.
-
 config SERIAL_PIC32
        tristate "Microchip PIC32 serial support"
        depends on MACH_PIC32
@@ -982,23 +973,6 @@ config SERIAL_JSM
          To compile this driver as a module, choose M here: the
          module will be called jsm.
 
-config SERIAL_SGI_IOC4
-       tristate "SGI IOC4 controller serial support"
-       depends on (IA64_GENERIC || IA64_SGI_SN2) && SGI_IOC4
-       select SERIAL_CORE
-       help
-               If you have an SGI Altix with an IOC4 based Base IO card
-               and wish to use the serial ports on this card, say Y.
-               Otherwise, say N.
-
-config SERIAL_SGI_IOC3
-       tristate "SGI Altix IOC3 serial support"
-       depends on (IA64_GENERIC || IA64_SGI_SN2) && SGI_IOC3
-       select SERIAL_CORE
-       help
-         If you have an SGI Altix with an IOC3 serial card,
-         say Y or M.  Otherwise, say N.
-
 config SERIAL_MSM
        tristate "MSM on-chip serial port support"
        depends on ARCH_QCOM
index 15a0fcc..d2f4487 100644 (file)
@@ -41,7 +41,6 @@ obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o
 obj-$(CONFIG_SERIAL_DZ) += dz.o
 obj-$(CONFIG_SERIAL_ZS) += zs.o
 obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o
-obj-$(CONFIG_SERIAL_SGI_L1_CONSOLE) += sn_console.o
 obj-$(CONFIG_SERIAL_CPM) += cpm_uart/
 obj-$(CONFIG_SERIAL_IMX) += imx.o
 obj-$(CONFIG_SERIAL_MPC52xx) += mpc52xx_uart.o
@@ -53,8 +52,6 @@ obj-$(CONFIG_SERIAL_SC16IS7XX_CORE) += sc16is7xx.o
 obj-$(CONFIG_SERIAL_JSM) += jsm/
 obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o
 obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o
-obj-$(CONFIG_SERIAL_SGI_IOC4) += ioc4_serial.o
-obj-$(CONFIG_SERIAL_SGI_IOC3) += ioc3_serial.o
 obj-$(CONFIG_SERIAL_ATMEL) += atmel_serial.o
 obj-$(CONFIG_SERIAL_UARTLITE) += uartlite.o
 obj-$(CONFIG_SERIAL_MSM) += msm_serial.o
diff --git a/drivers/tty/serial/ioc3_serial.c b/drivers/tty/serial/ioc3_serial.c
deleted file mode 100644 (file)
index d8a1cdd..0000000
+++ /dev/null
@@ -1,2195 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2005 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-/*
- * This file contains a module version of the ioc3 serial driver. This
- * includes all the support functions needed (support functions, etc.)
- * and the serial driver itself.
- */
-#include <linux/errno.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/circ_buf.h>
-#include <linux/serial_reg.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/serial_core.h>
-#include <linux/ioc3.h>
-#include <linux/slab.h>
-
-/*
- * Interesting things about the ioc3
- */
-
-#define LOGICAL_PORTS          2       /* rs232(0) and rs422(1) */
-#define PORTS_PER_CARD         2
-#define LOGICAL_PORTS_PER_CARD (PORTS_PER_CARD * LOGICAL_PORTS)
-#define MAX_CARDS              8
-#define MAX_LOGICAL_PORTS      (LOGICAL_PORTS_PER_CARD * MAX_CARDS)
-
-/* determine given the sio_ir what port it applies to */
-#define GET_PORT_FROM_SIO_IR(_x)       (_x & SIO_IR_SA) ? 0 : 1
-
-
-/*
- * we have 2 logical ports (rs232, rs422) for each physical port
- * evens are rs232, odds are rs422
- */
-#define GET_PHYSICAL_PORT(_x)  ((_x) >> 1)
-#define GET_LOGICAL_PORT(_x)   ((_x) & 1)
-#define IS_PHYSICAL_PORT(_x)   !((_x) & 1)
-#define IS_RS232(_x)           !((_x) & 1)
-
-static unsigned int Num_of_ioc3_cards;
-static unsigned int Submodule_slot;
-
-/* defining this will get you LOTS of great debug info */
-//#define DEBUG_INTERRUPTS
-#define DPRINT_CONFIG(_x...)   ;
-//#define DPRINT_CONFIG(_x...)  printk _x
-#define NOT_PROGRESS() ;
-//#define NOT_PROGRESS()       printk("%s : fails %d\n", __func__, __LINE__)
-
-/* number of characters we want to transmit to the lower level at a time */
-#define MAX_CHARS              256
-#define FIFO_SIZE              (MAX_CHARS-1)   /* it's a uchar */
-
-/* Device name we're using */
-#define DEVICE_NAME            "ttySIOC"
-#define DEVICE_MAJOR           204
-#define DEVICE_MINOR           116
-
-/* flags for next_char_state */
-#define NCS_BREAK              0x1
-#define NCS_PARITY             0x2
-#define NCS_FRAMING            0x4
-#define NCS_OVERRUN            0x8
-
-/* cause we need SOME parameters ... */
-#define MIN_BAUD_SUPPORTED     1200
-#define MAX_BAUD_SUPPORTED     115200
-
-/* protocol types supported */
-#define PROTO_RS232            0
-#define PROTO_RS422            1
-
-/* Notification types */
-#define N_DATA_READY           0x01
-#define N_OUTPUT_LOWAT         0x02
-#define N_BREAK                        0x04
-#define N_PARITY_ERROR         0x08
-#define N_FRAMING_ERROR                0x10
-#define N_OVERRUN_ERROR                0x20
-#define N_DDCD                 0x40
-#define N_DCTS                 0x80
-
-#define N_ALL_INPUT            (N_DATA_READY | N_BREAK                    \
-                                       | N_PARITY_ERROR | N_FRAMING_ERROR \
-                                       | N_OVERRUN_ERROR | N_DDCD | N_DCTS)
-
-#define N_ALL_OUTPUT           N_OUTPUT_LOWAT
-
-#define N_ALL_ERRORS           (N_PARITY_ERROR | N_FRAMING_ERROR \
-                                               | N_OVERRUN_ERROR)
-
-#define N_ALL                  (N_DATA_READY | N_OUTPUT_LOWAT | N_BREAK    \
-                                       | N_PARITY_ERROR | N_FRAMING_ERROR  \
-                                       | N_OVERRUN_ERROR | N_DDCD | N_DCTS)
-
-#define SER_CLK_SPEED(prediv)  ((22000000 << 1) / prediv)
-#define SER_DIVISOR(x, clk)    (((clk) + (x) * 8) / ((x) * 16))
-#define DIVISOR_TO_BAUD(div, clk) ((clk) / 16 / (div))
-
-/* Some masks */
-#define LCR_MASK_BITS_CHAR     (UART_LCR_WLEN5 | UART_LCR_WLEN6 \
-                                       | UART_LCR_WLEN7 | UART_LCR_WLEN8)
-#define LCR_MASK_STOP_BITS     (UART_LCR_STOP)
-
-#define PENDING(_a, _p)                (readl(&(_p)->vma->sio_ir) & (_a)->ic_enable)
-
-#define RING_BUF_SIZE          4096
-#define BUF_SIZE_BIT           SBBR_L_SIZE
-#define PROD_CONS_MASK         PROD_CONS_PTR_4K
-
-#define TOTAL_RING_BUF_SIZE    (RING_BUF_SIZE * 4)
-
-/* driver specific - one per card */
-struct ioc3_card {
-       struct {
-               /* uart ports are allocated here */
-               struct uart_port icp_uart_port[LOGICAL_PORTS];
-               /* the ioc3_port used for this port */
-               struct ioc3_port *icp_port;
-       } ic_port[PORTS_PER_CARD];
-       /* currently enabled interrupts */
-       uint32_t ic_enable;
-};
-
-/* Local port info for each IOC3 serial port */
-struct ioc3_port {
-       /* handy reference material */
-       struct uart_port *ip_port;
-       struct ioc3_card *ip_card;
-       struct ioc3_driver_data *ip_idd;
-       struct ioc3_submodule *ip_is;
-
-       /* pci mem addresses for this port */
-       struct ioc3_serialregs __iomem *ip_serial_regs;
-       struct ioc3_uartregs __iomem *ip_uart_regs;
-
-       /* Ring buffer page for this port */
-       dma_addr_t ip_dma_ringbuf;
-       /* vaddr of ring buffer */
-       struct ring_buffer *ip_cpu_ringbuf;
-
-       /* Rings for this port */
-       struct ring *ip_inring;
-       struct ring *ip_outring;
-
-       /* Hook to port specific values */
-       struct port_hooks *ip_hooks;
-
-       spinlock_t ip_lock;
-
-       /* Various rx/tx parameters */
-       int ip_baud;
-       int ip_tx_lowat;
-       int ip_rx_timeout;
-
-       /* Copy of notification bits */
-       int ip_notify;
-
-       /* Shadow copies of various registers so we don't need to PIO
-        * read them constantly
-        */
-       uint32_t ip_sscr;
-       uint32_t ip_tx_prod;
-       uint32_t ip_rx_cons;
-       unsigned char ip_flags;
-};
-
-/* tx low water mark.  We need to notify the driver whenever tx is getting
- * close to empty so it can refill the tx buffer and keep things going.
- * Let's assume that if we interrupt 1 ms before the tx goes idle, we'll
- * have no trouble getting in more chars in time (I certainly hope so).
- */
-#define TX_LOWAT_LATENCY      1000
-#define TX_LOWAT_HZ          (1000000 / TX_LOWAT_LATENCY)
-#define TX_LOWAT_CHARS(baud) (baud / 10 / TX_LOWAT_HZ)
-
-/* Flags per port */
-#define INPUT_HIGH             0x01
-       /* used to signify that we have turned off the rx_high
-        * temporarily - we need to drain the fifo and don't
-        * want to get blasted with interrupts.
-        */
-#define DCD_ON                 0x02
-       /* DCD state is on */
-#define LOWAT_WRITTEN          0x04
-#define READ_ABORTED           0x08
-       /* the read was aborted - used to avaoid infinate looping
-        * in the interrupt handler
-        */
-#define INPUT_ENABLE           0x10
-
-/* Since each port has different register offsets and bitmasks
- * for everything, we'll store those that we need in tables so we
- * don't have to be constantly checking the port we are dealing with.
- */
-struct port_hooks {
-       uint32_t intr_delta_dcd;
-       uint32_t intr_delta_cts;
-       uint32_t intr_tx_mt;
-       uint32_t intr_rx_timer;
-       uint32_t intr_rx_high;
-       uint32_t intr_tx_explicit;
-       uint32_t intr_clear;
-       uint32_t intr_all;
-       char rs422_select_pin;
-};
-
-static struct port_hooks hooks_array[PORTS_PER_CARD] = {
-       /* values for port A */
-       {
-       .intr_delta_dcd = SIO_IR_SA_DELTA_DCD,
-       .intr_delta_cts = SIO_IR_SA_DELTA_CTS,
-       .intr_tx_mt = SIO_IR_SA_TX_MT,
-       .intr_rx_timer = SIO_IR_SA_RX_TIMER,
-       .intr_rx_high = SIO_IR_SA_RX_HIGH,
-       .intr_tx_explicit = SIO_IR_SA_TX_EXPLICIT,
-       .intr_clear = (SIO_IR_SA_TX_MT | SIO_IR_SA_RX_FULL
-                               | SIO_IR_SA_RX_HIGH
-                               | SIO_IR_SA_RX_TIMER
-                               | SIO_IR_SA_DELTA_DCD
-                               | SIO_IR_SA_DELTA_CTS
-                               | SIO_IR_SA_INT
-                               | SIO_IR_SA_TX_EXPLICIT
-                               | SIO_IR_SA_MEMERR),
-       .intr_all =  SIO_IR_SA,
-       .rs422_select_pin = GPPR_UARTA_MODESEL_PIN,
-        },
-
-       /* values for port B */
-       {
-       .intr_delta_dcd = SIO_IR_SB_DELTA_DCD,
-       .intr_delta_cts = SIO_IR_SB_DELTA_CTS,
-       .intr_tx_mt = SIO_IR_SB_TX_MT,
-       .intr_rx_timer = SIO_IR_SB_RX_TIMER,
-       .intr_rx_high = SIO_IR_SB_RX_HIGH,
-       .intr_tx_explicit = SIO_IR_SB_TX_EXPLICIT,
-       .intr_clear = (SIO_IR_SB_TX_MT | SIO_IR_SB_RX_FULL
-                               | SIO_IR_SB_RX_HIGH
-                               | SIO_IR_SB_RX_TIMER
-                               | SIO_IR_SB_DELTA_DCD
-                               | SIO_IR_SB_DELTA_CTS
-                               | SIO_IR_SB_INT
-                               | SIO_IR_SB_TX_EXPLICIT
-                               | SIO_IR_SB_MEMERR),
-       .intr_all = SIO_IR_SB,
-       .rs422_select_pin = GPPR_UARTB_MODESEL_PIN,
-        }
-};
-
-struct ring_entry {
-       union {
-               struct {
-                       uint32_t alldata;
-                       uint32_t allsc;
-               } all;
-               struct {
-                       char data[4];   /* data bytes */
-                       char sc[4];     /* status/control */
-               } s;
-       } u;
-};
-
-/* Test the valid bits in any of the 4 sc chars using "allsc" member */
-#define RING_ANY_VALID \
-       ((uint32_t)(RXSB_MODEM_VALID | RXSB_DATA_VALID) * 0x01010101)
-
-#define ring_sc                u.s.sc
-#define ring_data      u.s.data
-#define ring_allsc     u.all.allsc
-
-/* Number of entries per ring buffer. */
-#define ENTRIES_PER_RING (RING_BUF_SIZE / (int) sizeof(struct ring_entry))
-
-/* An individual ring */
-struct ring {
-       struct ring_entry entries[ENTRIES_PER_RING];
-};
-
-/* The whole enchilada */
-struct ring_buffer {
-       struct ring TX_A;
-       struct ring RX_A;
-       struct ring TX_B;
-       struct ring RX_B;
-};
-
-/* Get a ring from a port struct */
-#define RING(_p, _wh)  &(((struct ring_buffer *)((_p)->ip_cpu_ringbuf))->_wh)
-
-/* for Infinite loop detection  */
-#define MAXITER                10000000
-
-
-/**
- * set_baud - Baud rate setting code
- * @port: port to set
- * @baud: baud rate to use
- */
-static int set_baud(struct ioc3_port *port, int baud)
-{
-       int divisor;
-       int actual_baud;
-       int diff;
-       int lcr, prediv;
-       struct ioc3_uartregs __iomem *uart;
-
-       for (prediv = 6; prediv < 64; prediv++) {
-               divisor = SER_DIVISOR(baud, SER_CLK_SPEED(prediv));
-               if (!divisor)
-                       continue;       /* invalid divisor */
-               actual_baud = DIVISOR_TO_BAUD(divisor, SER_CLK_SPEED(prediv));
-
-               diff = actual_baud - baud;
-               if (diff < 0)
-                       diff = -diff;
-
-               /* if we're within 1% we've found a match */
-               if (diff * 100 <= actual_baud)
-                       break;
-       }
-
-       /* if the above loop completed, we didn't match
-        * the baud rate.  give up.
-        */
-       if (prediv == 64) {
-               NOT_PROGRESS();
-               return 1;
-       }
-
-       uart = port->ip_uart_regs;
-       lcr = readb(&uart->iu_lcr);
-
-       writeb(lcr | UART_LCR_DLAB, &uart->iu_lcr);
-       writeb((unsigned char)divisor, &uart->iu_dll);
-       writeb((unsigned char)(divisor >> 8), &uart->iu_dlm);
-       writeb((unsigned char)prediv, &uart->iu_scr);
-       writeb((unsigned char)lcr, &uart->iu_lcr);
-
-       return 0;
-}
-
-/**
- * get_ioc3_port - given a uart port, return the control structure
- * @the_port: uart port to find
- */
-static struct ioc3_port *get_ioc3_port(struct uart_port *the_port)
-{
-       struct ioc3_driver_data *idd = dev_get_drvdata(the_port->dev);
-       struct ioc3_card *card_ptr = idd->data[Submodule_slot];
-       int ii, jj;
-
-       if (!card_ptr) {
-               NOT_PROGRESS();
-               return NULL;
-       }
-       for (ii = 0; ii < PORTS_PER_CARD; ii++) {
-               for (jj = 0; jj < LOGICAL_PORTS; jj++) {
-                       if (the_port == &card_ptr->ic_port[ii].icp_uart_port[jj])
-                               return card_ptr->ic_port[ii].icp_port;
-               }
-       }
-       NOT_PROGRESS();
-       return NULL;
-}
-
-/**
- * port_init - Initialize the sio and ioc3 hardware for a given port
- *                     called per port from attach...
- * @port: port to initialize
- */
-static inline int port_init(struct ioc3_port *port)
-{
-       uint32_t sio_cr;
-       struct port_hooks *hooks = port->ip_hooks;
-       struct ioc3_uartregs __iomem *uart;
-       int reset_loop_counter = 0xfffff;
-       struct ioc3_driver_data *idd = port->ip_idd;
-
-       /* Idle the IOC3 serial interface */
-       writel(SSCR_RESET, &port->ip_serial_regs->sscr);
-
-       /* Wait until any pending bus activity for this port has ceased */
-       do {
-               sio_cr = readl(&idd->vma->sio_cr);
-               if (reset_loop_counter-- <= 0) {
-                       printk(KERN_WARNING
-                              "IOC3 unable to come out of reset"
-                               " scr 0x%x\n", sio_cr);
-                       return -1;
-               }
-       } while (!(sio_cr & SIO_CR_ARB_DIAG_IDLE) &&
-              (((sio_cr &= SIO_CR_ARB_DIAG) == SIO_CR_ARB_DIAG_TXA)
-               || sio_cr == SIO_CR_ARB_DIAG_TXB
-               || sio_cr == SIO_CR_ARB_DIAG_RXA
-               || sio_cr == SIO_CR_ARB_DIAG_RXB));
-
-       /* Finish reset sequence */
-       writel(0, &port->ip_serial_regs->sscr);
-
-       /* Once RESET is done, reload cached tx_prod and rx_cons values
-        * and set rings to empty by making prod == cons
-        */
-       port->ip_tx_prod = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK;
-       writel(port->ip_tx_prod, &port->ip_serial_regs->stpir);
-       port->ip_rx_cons = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
-       writel(port->ip_rx_cons | SRCIR_ARM, &port->ip_serial_regs->srcir);
-
-       /* Disable interrupts for this 16550 */
-       uart = port->ip_uart_regs;
-       writeb(0, &uart->iu_lcr);
-       writeb(0, &uart->iu_ier);
-
-       /* Set the default baud */
-       set_baud(port, port->ip_baud);
-
-       /* Set line control to 8 bits no parity */
-       writeb(UART_LCR_WLEN8 | 0, &uart->iu_lcr);
-       /* UART_LCR_STOP == 1 stop */
-
-       /* Enable the FIFOs */
-       writeb(UART_FCR_ENABLE_FIFO, &uart->iu_fcr);
-       /* then reset 16550 FIFOs */
-       writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
-              &uart->iu_fcr);
-
-       /* Clear modem control register */
-       writeb(0, &uart->iu_mcr);
-
-       /* Clear deltas in modem status register */
-       writel(0, &port->ip_serial_regs->shadow);
-
-       /* Only do this once per port pair */
-       if (port->ip_hooks == &hooks_array[0]) {
-               unsigned long ring_pci_addr;
-               uint32_t __iomem *sbbr_l, *sbbr_h;
-
-               sbbr_l = &idd->vma->sbbr_l;
-               sbbr_h = &idd->vma->sbbr_h;
-               ring_pci_addr = (unsigned long __iomem)port->ip_dma_ringbuf;
-               DPRINT_CONFIG(("%s: ring_pci_addr 0x%p\n",
-                              __func__, (void *)ring_pci_addr));
-
-               writel((unsigned int)((uint64_t) ring_pci_addr >> 32), sbbr_h);
-               writel((unsigned int)ring_pci_addr | BUF_SIZE_BIT, sbbr_l);
-       }
-
-       /* Set the receive timeout value to 10 msec */
-       writel(SRTR_HZ / 100, &port->ip_serial_regs->srtr);
-
-       /* Set rx threshold, enable DMA */
-       /* Set high water mark at 3/4 of full ring */
-       port->ip_sscr = (ENTRIES_PER_RING * 3 / 4);
-
-       /* uart experiences pauses at high baud rate reducing actual
-        * throughput by 10% or so unless we enable high speed polling
-        * XXX when this hardware bug is resolved we should revert to
-        * normal polling speed
-        */
-       port->ip_sscr |= SSCR_HIGH_SPD;
-
-       writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-
-       /* Disable and clear all serial related interrupt bits */
-       port->ip_card->ic_enable &= ~hooks->intr_clear;
-       ioc3_disable(port->ip_is, idd, hooks->intr_clear);
-       ioc3_ack(port->ip_is, idd, hooks->intr_clear);
-       return 0;
-}
-
-/**
- * enable_intrs - enable interrupts
- * @port: port to enable
- * @mask: mask to use
- */
-static void enable_intrs(struct ioc3_port *port, uint32_t mask)
-{
-       if ((port->ip_card->ic_enable & mask) != mask) {
-               port->ip_card->ic_enable |= mask;
-               ioc3_enable(port->ip_is, port->ip_idd, mask);
-       }
-}
-
-/**
- * local_open - local open a port
- * @port: port to open
- */
-static inline int local_open(struct ioc3_port *port)
-{
-       int spiniter = 0;
-
-       port->ip_flags = INPUT_ENABLE;
-
-       /* Pause the DMA interface if necessary */
-       if (port->ip_sscr & SSCR_DMA_EN) {
-               writel(port->ip_sscr | SSCR_DMA_PAUSE,
-                      &port->ip_serial_regs->sscr);
-               while ((readl(&port->ip_serial_regs->sscr)
-                       & SSCR_PAUSE_STATE) == 0) {
-                       spiniter++;
-                       if (spiniter > MAXITER) {
-                               NOT_PROGRESS();
-                               return -1;
-                       }
-               }
-       }
-
-       /* Reset the input fifo.  If the uart received chars while the port
-        * was closed and DMA is not enabled, the uart may have a bunch of
-        * chars hanging around in its rx fifo which will not be discarded
-        * by rclr in the upper layer. We must get rid of them here.
-        */
-       writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR,
-              &port->ip_uart_regs->iu_fcr);
-
-       writeb(UART_LCR_WLEN8, &port->ip_uart_regs->iu_lcr);
-       /* UART_LCR_STOP == 1 stop */
-
-       /* Re-enable DMA, set default threshold to intr whenever there is
-        * data available.
-        */
-       port->ip_sscr &= ~SSCR_RX_THRESHOLD;
-       port->ip_sscr |= 1;     /* default threshold */
-
-       /* Plug in the new sscr.  This implicitly clears the DMA_PAUSE
-        * flag if it was set above
-        */
-       writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-       port->ip_tx_lowat = 1;
-       return 0;
-}
-
-/**
- * set_rx_timeout - Set rx timeout and threshold values.
- * @port: port to use
- * @timeout: timeout value in ticks
- */
-static inline int set_rx_timeout(struct ioc3_port *port, int timeout)
-{
-       int threshold;
-
-       port->ip_rx_timeout = timeout;
-
-       /* Timeout is in ticks.  Let's figure out how many chars we
-        * can receive at the current baud rate in that interval
-        * and set the rx threshold to that amount.  There are 4 chars
-        * per ring entry, so we'll divide the number of chars that will
-        * arrive in timeout by 4.
-        * So .... timeout * baud / 10 / HZ / 4, with HZ = 100.
-        */
-       threshold = timeout * port->ip_baud / 4000;
-       if (threshold == 0)
-               threshold = 1;  /* otherwise we'll intr all the time! */
-
-       if ((unsigned)threshold > (unsigned)SSCR_RX_THRESHOLD)
-               return 1;
-
-       port->ip_sscr &= ~SSCR_RX_THRESHOLD;
-       port->ip_sscr |= threshold;
-       writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-
-       /* Now set the rx timeout to the given value
-        * again timeout * SRTR_HZ / HZ
-        */
-       timeout = timeout * SRTR_HZ / 100;
-       if (timeout > SRTR_CNT)
-               timeout = SRTR_CNT;
-       writel(timeout, &port->ip_serial_regs->srtr);
-       return 0;
-}
-
-/**
- * config_port - config the hardware
- * @port: port to config
- * @baud: baud rate for the port
- * @byte_size: data size
- * @stop_bits: number of stop bits
- * @parenb: parity enable ?
- * @parodd: odd parity ?
- */
-static inline int
-config_port(struct ioc3_port *port,
-           int baud, int byte_size, int stop_bits, int parenb, int parodd)
-{
-       char lcr, sizebits;
-       int spiniter = 0;
-
-       DPRINT_CONFIG(("%s: line %d baud %d byte_size %d stop %d parenb %d "
-                       "parodd %d\n",
-                      __func__, ((struct uart_port *)port->ip_port)->line,
-                       baud, byte_size, stop_bits, parenb, parodd));
-
-       if (set_baud(port, baud))
-               return 1;
-
-       switch (byte_size) {
-       case 5:
-               sizebits = UART_LCR_WLEN5;
-               break;
-       case 6:
-               sizebits = UART_LCR_WLEN6;
-               break;
-       case 7:
-               sizebits = UART_LCR_WLEN7;
-               break;
-       case 8:
-               sizebits = UART_LCR_WLEN8;
-               break;
-       default:
-               return 1;
-       }
-
-       /* Pause the DMA interface if necessary */
-       if (port->ip_sscr & SSCR_DMA_EN) {
-               writel(port->ip_sscr | SSCR_DMA_PAUSE,
-                      &port->ip_serial_regs->sscr);
-               while ((readl(&port->ip_serial_regs->sscr)
-                       & SSCR_PAUSE_STATE) == 0) {
-                       spiniter++;
-                       if (spiniter > MAXITER)
-                               return -1;
-               }
-       }
-
-       /* Clear relevant fields in lcr */
-       lcr = readb(&port->ip_uart_regs->iu_lcr);
-       lcr &= ~(LCR_MASK_BITS_CHAR | UART_LCR_EPAR |
-                UART_LCR_PARITY | LCR_MASK_STOP_BITS);
-
-       /* Set byte size in lcr */
-       lcr |= sizebits;
-
-       /* Set parity */
-       if (parenb) {
-               lcr |= UART_LCR_PARITY;
-               if (!parodd)
-                       lcr |= UART_LCR_EPAR;
-       }
-
-       /* Set stop bits */
-       if (stop_bits)
-               lcr |= UART_LCR_STOP /* 2 stop bits */ ;
-
-       writeb(lcr, &port->ip_uart_regs->iu_lcr);
-
-       /* Re-enable the DMA interface if necessary */
-       if (port->ip_sscr & SSCR_DMA_EN) {
-               writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-       }
-       port->ip_baud = baud;
-
-       /* When we get within this number of ring entries of filling the
-        * entire ring on tx, place an EXPLICIT intr to generate a lowat
-        * notification when output has drained.
-        */
-       port->ip_tx_lowat = (TX_LOWAT_CHARS(baud) + 3) / 4;
-       if (port->ip_tx_lowat == 0)
-               port->ip_tx_lowat = 1;
-
-       set_rx_timeout(port, 2);
-       return 0;
-}
-
-/**
- * do_write - Write bytes to the port.  Returns the number of bytes
- *                     actually written. Called from transmit_chars
- * @port: port to use
- * @buf: the stuff to write
- * @len: how many bytes in 'buf'
- */
-static inline int do_write(struct ioc3_port *port, char *buf, int len)
-{
-       int prod_ptr, cons_ptr, total = 0;
-       struct ring *outring;
-       struct ring_entry *entry;
-       struct port_hooks *hooks = port->ip_hooks;
-
-       BUG_ON(!(len >= 0));
-
-       prod_ptr = port->ip_tx_prod;
-       cons_ptr = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK;
-       outring = port->ip_outring;
-
-       /* Maintain a 1-entry red-zone.  The ring buffer is full when
-        * (cons - prod) % ring_size is 1.  Rather than do this subtraction
-        * in the body of the loop, I'll do it now.
-        */
-       cons_ptr = (cons_ptr - (int)sizeof(struct ring_entry)) & PROD_CONS_MASK;
-
-       /* Stuff the bytes into the output */
-       while ((prod_ptr != cons_ptr) && (len > 0)) {
-               int xx;
-
-               /* Get 4 bytes (one ring entry) at a time */
-               entry = (struct ring_entry *)((caddr_t) outring + prod_ptr);
-
-               /* Invalidate all entries */
-               entry->ring_allsc = 0;
-
-               /* Copy in some bytes */
-               for (xx = 0; (xx < 4) && (len > 0); xx++) {
-                       entry->ring_data[xx] = *buf++;
-                       entry->ring_sc[xx] = TXCB_VALID;
-                       len--;
-                       total++;
-               }
-
-               /* If we are within some small threshold of filling up the
-                * entire ring buffer, we must place an EXPLICIT intr here
-                * to generate a lowat interrupt in case we subsequently
-                * really do fill up the ring and the caller goes to sleep.
-                * No need to place more than one though.
-                */
-               if (!(port->ip_flags & LOWAT_WRITTEN) &&
-                   ((cons_ptr - prod_ptr) & PROD_CONS_MASK)
-                   <= port->ip_tx_lowat * (int)sizeof(struct ring_entry)) {
-                       port->ip_flags |= LOWAT_WRITTEN;
-                       entry->ring_sc[0] |= TXCB_INT_WHEN_DONE;
-               }
-
-               /* Go on to next entry */
-               prod_ptr += sizeof(struct ring_entry);
-               prod_ptr &= PROD_CONS_MASK;
-       }
-
-       /* If we sent something, start DMA if necessary */
-       if (total > 0 && !(port->ip_sscr & SSCR_DMA_EN)) {
-               port->ip_sscr |= SSCR_DMA_EN;
-               writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-       }
-
-       /* Store the new producer pointer.  If tx is disabled, we stuff the
-        * data into the ring buffer, but we don't actually start tx.
-        */
-       if (!uart_tx_stopped(port->ip_port)) {
-               writel(prod_ptr, &port->ip_serial_regs->stpir);
-
-               /* If we are now transmitting, enable tx_mt interrupt so we
-                * can disable DMA if necessary when the tx finishes.
-                */
-               if (total > 0)
-                       enable_intrs(port, hooks->intr_tx_mt);
-       }
-       port->ip_tx_prod = prod_ptr;
-
-       return total;
-}
-
-/**
- * disable_intrs - disable interrupts
- * @port: port to enable
- * @mask: mask to use
- */
-static inline void disable_intrs(struct ioc3_port *port, uint32_t mask)
-{
-       if (port->ip_card->ic_enable & mask) {
-               ioc3_disable(port->ip_is, port->ip_idd, mask);
-               port->ip_card->ic_enable &= ~mask;
-       }
-}
-
-/**
- * set_notification - Modify event notification
- * @port: port to use
- * @mask: events mask
- * @set_on: set ?
- */
-static int set_notification(struct ioc3_port *port, int mask, int set_on)
-{
-       struct port_hooks *hooks = port->ip_hooks;
-       uint32_t intrbits, sscrbits;
-
-       BUG_ON(!mask);
-
-       intrbits = sscrbits = 0;
-
-       if (mask & N_DATA_READY)
-               intrbits |= (hooks->intr_rx_timer | hooks->intr_rx_high);
-       if (mask & N_OUTPUT_LOWAT)
-               intrbits |= hooks->intr_tx_explicit;
-       if (mask & N_DDCD) {
-               intrbits |= hooks->intr_delta_dcd;
-               sscrbits |= SSCR_RX_RING_DCD;
-       }
-       if (mask & N_DCTS)
-               intrbits |= hooks->intr_delta_cts;
-
-       if (set_on) {
-               enable_intrs(port, intrbits);
-               port->ip_notify |= mask;
-               port->ip_sscr |= sscrbits;
-       } else {
-               disable_intrs(port, intrbits);
-               port->ip_notify &= ~mask;
-               port->ip_sscr &= ~sscrbits;
-       }
-
-       /* We require DMA if either DATA_READY or DDCD notification is
-        * currently requested. If neither of these is requested and
-        * there is currently no tx in progress, DMA may be disabled.
-        */
-       if (port->ip_notify & (N_DATA_READY | N_DDCD))
-               port->ip_sscr |= SSCR_DMA_EN;
-       else if (!(port->ip_card->ic_enable & hooks->intr_tx_mt))
-               port->ip_sscr &= ~SSCR_DMA_EN;
-
-       writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-       return 0;
-}
-
-/**
- * set_mcr - set the master control reg
- * @the_port: port to use
- * @mask1: mcr mask
- * @mask2: shadow mask
- */
-static inline int set_mcr(struct uart_port *the_port,
-                         int mask1, int mask2)
-{
-       struct ioc3_port *port = get_ioc3_port(the_port);
-       uint32_t shadow;
-       int spiniter = 0;
-       char mcr;
-
-       if (!port)
-               return -1;
-
-       /* Pause the DMA interface if necessary */
-       if (port->ip_sscr & SSCR_DMA_EN) {
-               writel(port->ip_sscr | SSCR_DMA_PAUSE,
-                      &port->ip_serial_regs->sscr);
-               while ((readl(&port->ip_serial_regs->sscr)
-                       & SSCR_PAUSE_STATE) == 0) {
-                       spiniter++;
-                       if (spiniter > MAXITER)
-                               return -1;
-               }
-       }
-       shadow = readl(&port->ip_serial_regs->shadow);
-       mcr = (shadow & 0xff000000) >> 24;
-
-       /* Set new value */
-       mcr |= mask1;
-       shadow |= mask2;
-       writeb(mcr, &port->ip_uart_regs->iu_mcr);
-       writel(shadow, &port->ip_serial_regs->shadow);
-
-       /* Re-enable the DMA interface if necessary */
-       if (port->ip_sscr & SSCR_DMA_EN) {
-               writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-       }
-       return 0;
-}
-
-/**
- * ioc3_set_proto - set the protocol for the port
- * @port: port to use
- * @proto: protocol to use
- */
-static int ioc3_set_proto(struct ioc3_port *port, int proto)
-{
-       struct port_hooks *hooks = port->ip_hooks;
-
-       switch (proto) {
-       default:
-       case PROTO_RS232:
-               /* Clear the appropriate GIO pin */
-               DPRINT_CONFIG(("%s: rs232\n", __func__));
-               writel(0, (&port->ip_idd->vma->gppr[0]
-                                       + hooks->rs422_select_pin));
-               break;
-
-       case PROTO_RS422:
-               /* Set the appropriate GIO pin */
-               DPRINT_CONFIG(("%s: rs422\n", __func__));
-               writel(1, (&port->ip_idd->vma->gppr[0]
-                                       + hooks->rs422_select_pin));
-               break;
-       }
-       return 0;
-}
-
-/**
- * transmit_chars - upper level write, called with the_port->lock
- * @the_port: port to write
- */
-static void transmit_chars(struct uart_port *the_port)
-{
-       int xmit_count, tail, head;
-       int result;
-       char *start;
-       struct tty_struct *tty;
-       struct ioc3_port *port = get_ioc3_port(the_port);
-       struct uart_state *state;
-
-       if (!the_port)
-               return;
-       if (!port)
-               return;
-
-       state = the_port->state;
-       tty = state->port.tty;
-
-       if (uart_circ_empty(&state->xmit) || uart_tx_stopped(the_port)) {
-               /* Nothing to do or hw stopped */
-               set_notification(port, N_ALL_OUTPUT, 0);
-               return;
-       }
-
-       head = state->xmit.head;
-       tail = state->xmit.tail;
-       start = (char *)&state->xmit.buf[tail];
-
-       /* write out all the data or until the end of the buffer */
-       xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail);
-       if (xmit_count > 0) {
-               result = do_write(port, start, xmit_count);
-               if (result > 0) {
-                       /* booking */
-                       xmit_count -= result;
-                       the_port->icount.tx += result;
-                       /* advance the pointers */
-                       tail += result;
-                       tail &= UART_XMIT_SIZE - 1;
-                       state->xmit.tail = tail;
-                       start = (char *)&state->xmit.buf[tail];
-               }
-       }
-       if (uart_circ_chars_pending(&state->xmit) < WAKEUP_CHARS)
-               uart_write_wakeup(the_port);
-
-       if (uart_circ_empty(&state->xmit)) {
-               set_notification(port, N_OUTPUT_LOWAT, 0);
-       } else {
-               set_notification(port, N_OUTPUT_LOWAT, 1);
-       }
-}
-
-/**
- * ioc3_change_speed - change the speed of the port
- * @the_port: port to change
- * @new_termios: new termios settings
- * @old_termios: old termios settings
- */
-static void
-ioc3_change_speed(struct uart_port *the_port,
-                 struct ktermios *new_termios, struct ktermios *old_termios)
-{
-       struct ioc3_port *port = get_ioc3_port(the_port);
-       unsigned int cflag, iflag;
-       int baud;
-       int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8;
-       struct uart_state *state = the_port->state;
-
-       cflag = new_termios->c_cflag;
-       iflag = new_termios->c_iflag;
-
-       switch (cflag & CSIZE) {
-       case CS5:
-               new_data = 5;
-               break;
-       case CS6:
-               new_data = 6;
-               break;
-       case CS7:
-               new_data = 7;
-               break;
-       case CS8:
-               new_data = 8;
-               break;
-       default:
-               /* cuz we always need a default ... */
-               new_data = 5;
-               break;
-       }
-       if (cflag & CSTOPB) {
-               new_stop = 1;
-       }
-       if (cflag & PARENB) {
-               new_parity_enable = 1;
-               if (cflag & PARODD)
-                       new_parity = 1;
-       }
-       baud = uart_get_baud_rate(the_port, new_termios, old_termios,
-                                 MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED);
-       DPRINT_CONFIG(("%s: returned baud %d for line %d\n", __func__, baud,
-                               the_port->line));
-
-       if (!the_port->fifosize)
-               the_port->fifosize = FIFO_SIZE;
-       uart_update_timeout(the_port, cflag, baud);
-
-       the_port->ignore_status_mask = N_ALL_INPUT;
-
-       state->port.low_latency = 1;
-
-       if (iflag & IGNPAR)
-               the_port->ignore_status_mask &= ~(N_PARITY_ERROR
-                                                 | N_FRAMING_ERROR);
-       if (iflag & IGNBRK) {
-               the_port->ignore_status_mask &= ~N_BREAK;
-               if (iflag & IGNPAR)
-                       the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
-       }
-       if (!(cflag & CREAD)) {
-               /* ignore everything */
-               the_port->ignore_status_mask &= ~N_DATA_READY;
-       }
-
-       if (cflag & CRTSCTS) {
-               /* enable hardware flow control */
-               port->ip_sscr |= SSCR_HFC_EN;
-       }
-       else {
-               /* disable hardware flow control */
-               port->ip_sscr &= ~SSCR_HFC_EN;
-       }
-       writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-
-       /* Set the configuration and proper notification call */
-       DPRINT_CONFIG(("%s : port 0x%p line %d cflag 0%o "
-                      "config_port(baud %d data %d stop %d penable %d "
-                       " parity %d), notification 0x%x\n",
-                      __func__, (void *)port, the_port->line, cflag, baud,
-                      new_data, new_stop, new_parity_enable, new_parity,
-                      the_port->ignore_status_mask));
-
-       if ((config_port(port, baud,    /* baud */
-                        new_data,      /* byte size */
-                        new_stop,      /* stop bits */
-                        new_parity_enable,     /* set parity */
-                        new_parity)) >= 0) {   /* parity 1==odd */
-               set_notification(port, the_port->ignore_status_mask, 1);
-       }
-}
-
-/**
- * ic3_startup_local - Start up the serial port - returns >= 0 if no errors
- * @the_port: Port to operate on
- */
-static inline int ic3_startup_local(struct uart_port *the_port)
-{
-       struct ioc3_port *port;
-
-       if (!the_port) {
-               NOT_PROGRESS();
-               return -1;
-       }
-
-       port = get_ioc3_port(the_port);
-       if (!port) {
-               NOT_PROGRESS();
-               return -1;
-       }
-
-       local_open(port);
-
-       /* set the protocol */
-       ioc3_set_proto(port, IS_RS232(the_port->line) ? PROTO_RS232 :
-                                                       PROTO_RS422);
-       return 0;
-}
-
-/*
- * ioc3_cb_output_lowat - called when the output low water mark is hit
- * @port: port to output
- */
-static void ioc3_cb_output_lowat(struct ioc3_port *port)
-{
-       unsigned long pflags;
-
-       /* the_port->lock is set on the call here */
-       if (port->ip_port) {
-               spin_lock_irqsave(&port->ip_port->lock, pflags);
-               transmit_chars(port->ip_port);
-               spin_unlock_irqrestore(&port->ip_port->lock, pflags);
-       }
-}
-
-/*
- * ioc3_cb_post_ncs - called for some basic errors
- * @port: port to use
- * @ncs: event
- */
-static void ioc3_cb_post_ncs(struct uart_port *the_port, int ncs)
-{
-       struct uart_icount *icount;
-
-       icount = &the_port->icount;
-
-       if (ncs & NCS_BREAK)
-               icount->brk++;
-       if (ncs & NCS_FRAMING)
-               icount->frame++;
-       if (ncs & NCS_OVERRUN)
-               icount->overrun++;
-       if (ncs & NCS_PARITY)
-               icount->parity++;
-}
-
-/**
- * do_read - Read in bytes from the port.  Return the number of bytes
- *                     actually read.
- * @the_port: port to use
- * @buf: place to put the stuff we read
- * @len: how big 'buf' is
- */
-
-static inline int do_read(struct uart_port *the_port, char *buf, int len)
-{
-       int prod_ptr, cons_ptr, total;
-       struct ioc3_port *port = get_ioc3_port(the_port);
-       struct ring *inring;
-       struct ring_entry *entry;
-       struct port_hooks *hooks;
-       int byte_num;
-       char *sc;
-       int loop_counter;
-
-       BUG_ON(!(len >= 0));
-       BUG_ON(!port);
-       hooks = port->ip_hooks;
-
-       /* There is a nasty timing issue in the IOC3. When the rx_timer
-        * expires or the rx_high condition arises, we take an interrupt.
-        * At some point while servicing the interrupt, we read bytes from
-        * the ring buffer and re-arm the rx_timer.  However the rx_timer is
-        * not started until the first byte is received *after* it is armed,
-        * and any bytes pending in the rx construction buffers are not drained
-        * to memory until either there are 4 bytes available or the rx_timer
-        * expires.  This leads to a potential situation where data is left
-        * in the construction buffers forever - 1 to 3 bytes were received
-        * after the interrupt was generated but before the rx_timer was
-        * re-armed. At that point as long as no subsequent bytes are received
-        * the timer will never be started and the bytes will remain in the
-        * construction buffer forever.  The solution is to execute a DRAIN
-        * command after rearming the timer.  This way any bytes received before
-        * the DRAIN will be drained to memory, and any bytes received after
-        * the DRAIN will start the TIMER and be drained when it expires.
-        * Luckily, this only needs to be done when the DMA buffer is empty
-        * since there is no requirement that this function return all
-        * available data as long as it returns some.
-        */
-       /* Re-arm the timer */
-
-       writel(port->ip_rx_cons | SRCIR_ARM, &port->ip_serial_regs->srcir);
-
-       prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
-       cons_ptr = port->ip_rx_cons;
-
-       if (prod_ptr == cons_ptr) {
-               int reset_dma = 0;
-
-               /* Input buffer appears empty, do a flush. */
-
-               /* DMA must be enabled for this to work. */
-               if (!(port->ip_sscr & SSCR_DMA_EN)) {
-                       port->ip_sscr |= SSCR_DMA_EN;
-                       reset_dma = 1;
-               }
-
-               /* Potential race condition: we must reload the srpir after
-                * issuing the drain command, otherwise we could think the rx
-                * buffer is empty, then take a very long interrupt, and when
-                * we come back it's full and we wait forever for the drain to
-                * complete.
-                */
-               writel(port->ip_sscr | SSCR_RX_DRAIN,
-                      &port->ip_serial_regs->sscr);
-               prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
-
-               /* We must not wait for the DRAIN to complete unless there are
-                * at least 8 bytes (2 ring entries) available to receive the
-                * data otherwise the DRAIN will never complete and we'll
-                * deadlock here.
-                * In fact, to make things easier, I'll just ignore the flush if
-                * there is any data at all now available.
-                */
-               if (prod_ptr == cons_ptr) {
-                       loop_counter = 0;
-                       while (readl(&port->ip_serial_regs->sscr) &
-                              SSCR_RX_DRAIN) {
-                               loop_counter++;
-                               if (loop_counter > MAXITER)
-                                       return -1;
-                       }
-
-                       /* SIGH. We have to reload the prod_ptr *again* since
-                        * the drain may have caused it to change
-                        */
-                       prod_ptr = readl(&port->ip_serial_regs->srpir)
-                           & PROD_CONS_MASK;
-               }
-               if (reset_dma) {
-                       port->ip_sscr &= ~SSCR_DMA_EN;
-                       writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-               }
-       }
-       inring = port->ip_inring;
-       port->ip_flags &= ~READ_ABORTED;
-
-       total = 0;
-       loop_counter = 0xfffff; /* to avoid hangs */
-
-       /* Grab bytes from the hardware */
-       while ((prod_ptr != cons_ptr) && (len > 0)) {
-               entry = (struct ring_entry *)((caddr_t) inring + cons_ptr);
-
-               if (loop_counter-- <= 0) {
-                       printk(KERN_WARNING "IOC3 serial: "
-                              "possible hang condition/"
-                              "port stuck on read (line %d).\n",
-                               the_port->line);
-                       break;
-               }
-
-               /* According to the producer pointer, this ring entry
-                * must contain some data.  But if the PIO happened faster
-                * than the DMA, the data may not be available yet, so let's
-                * wait until it arrives.
-                */
-               if ((entry->ring_allsc & RING_ANY_VALID) == 0) {
-                       /* Indicate the read is aborted so we don't disable
-                        * the interrupt thinking that the consumer is
-                        * congested.
-                        */
-                       port->ip_flags |= READ_ABORTED;
-                       len = 0;
-                       break;
-               }
-
-               /* Load the bytes/status out of the ring entry */
-               for (byte_num = 0; byte_num < 4 && len > 0; byte_num++) {
-                       sc = &(entry->ring_sc[byte_num]);
-
-                       /* Check for change in modem state or overrun */
-                       if ((*sc & RXSB_MODEM_VALID)
-                           && (port->ip_notify & N_DDCD)) {
-                               /* Notify upper layer if DCD dropped */
-                               if ((port->ip_flags & DCD_ON)
-                                   && !(*sc & RXSB_DCD)) {
-                                       /* If we have already copied some data,
-                                        * return it.  We'll pick up the carrier
-                                        * drop on the next pass.  That way we
-                                        * don't throw away the data that has
-                                        * already been copied back to
-                                        * the caller's buffer.
-                                        */
-                                       if (total > 0) {
-                                               len = 0;
-                                               break;
-                                       }
-                                       port->ip_flags &= ~DCD_ON;
-
-                                       /* Turn off this notification so the
-                                        * carrier drop protocol won't see it
-                                        * again when it does a read.
-                                        */
-                                       *sc &= ~RXSB_MODEM_VALID;
-
-                                       /* To keep things consistent, we need
-                                        * to update the consumer pointer so
-                                        * the next reader won't come in and
-                                        * try to read the same ring entries
-                                        * again. This must be done here before
-                                        * the dcd change.
-                                        */
-
-                                       if ((entry->ring_allsc & RING_ANY_VALID)
-                                           == 0) {
-                                               cons_ptr += (int)sizeof
-                                                   (struct ring_entry);
-                                               cons_ptr &= PROD_CONS_MASK;
-                                       }
-                                       writel(cons_ptr,
-                                              &port->ip_serial_regs->srcir);
-                                       port->ip_rx_cons = cons_ptr;
-
-                                       /* Notify upper layer of carrier drop */
-                                       if ((port->ip_notify & N_DDCD)
-                                           && port->ip_port) {
-                                               uart_handle_dcd_change
-                                                       (port->ip_port, 0);
-                                               wake_up_interruptible
-                                                   (&the_port->state->
-                                                    port.delta_msr_wait);
-                                       }
-
-                                       /* If we had any data to return, we
-                                        * would have returned it above.
-                                        */
-                                       return 0;
-                               }
-                       }
-                       if (*sc & RXSB_MODEM_VALID) {
-                               /* Notify that an input overrun occurred */
-                               if ((*sc & RXSB_OVERRUN)
-                                   && (port->ip_notify & N_OVERRUN_ERROR)) {
-                                       ioc3_cb_post_ncs(the_port, NCS_OVERRUN);
-                               }
-                               /* Don't look at this byte again */
-                               *sc &= ~RXSB_MODEM_VALID;
-                       }
-
-                       /* Check for valid data or RX errors */
-                       if ((*sc & RXSB_DATA_VALID) &&
-                           ((*sc & (RXSB_PAR_ERR
-                                    | RXSB_FRAME_ERR | RXSB_BREAK))
-                            && (port->ip_notify & (N_PARITY_ERROR
-                                                   | N_FRAMING_ERROR
-                                                   | N_BREAK)))) {
-                               /* There is an error condition on the next byte.
-                                * If we have already transferred some bytes,
-                                * we'll stop here. Otherwise if this is the
-                                * first byte to be read, we'll just transfer
-                                * it alone after notifying the
-                                * upper layer of its status.
-                                */
-                               if (total > 0) {
-                                       len = 0;
-                                       break;
-                               } else {
-                                       if ((*sc & RXSB_PAR_ERR) &&
-                                           (port->
-                                            ip_notify & N_PARITY_ERROR)) {
-                                               ioc3_cb_post_ncs(the_port,
-                                                                NCS_PARITY);
-                                       }
-                                       if ((*sc & RXSB_FRAME_ERR) &&
-                                           (port->
-                                            ip_notify & N_FRAMING_ERROR)) {
-                                               ioc3_cb_post_ncs(the_port,
-                                                                NCS_FRAMING);
-                                       }
-                                       if ((*sc & RXSB_BREAK)
-                                           && (port->ip_notify & N_BREAK)) {
-                                               ioc3_cb_post_ncs
-                                                   (the_port, NCS_BREAK);
-                                       }
-                                       len = 1;
-                               }
-                       }
-                       if (*sc & RXSB_DATA_VALID) {
-                               *sc &= ~RXSB_DATA_VALID;
-                               *buf = entry->ring_data[byte_num];
-                               buf++;
-                               len--;
-                               total++;
-                       }
-               }
-
-               /* If we used up this entry entirely, go on to the next one,
-                * otherwise we must have run out of buffer space, so
-                * leave the consumer pointer here for the next read in case
-                * there are still unread bytes in this entry.
-                */
-               if ((entry->ring_allsc & RING_ANY_VALID) == 0) {
-                       cons_ptr += (int)sizeof(struct ring_entry);
-                       cons_ptr &= PROD_CONS_MASK;
-               }
-       }
-
-       /* Update consumer pointer and re-arm rx timer interrupt */
-       writel(cons_ptr, &port->ip_serial_regs->srcir);
-       port->ip_rx_cons = cons_ptr;
-
-       /* If we have now dipped below the rx high water mark and we have
-        * rx_high interrupt turned off, we can now turn it back on again.
-        */
-       if ((port->ip_flags & INPUT_HIGH) && (((prod_ptr - cons_ptr)
-                                              & PROD_CONS_MASK) <
-                                             ((port->
-                                               ip_sscr &
-                                               SSCR_RX_THRESHOLD)
-                                              << PROD_CONS_PTR_OFF))) {
-               port->ip_flags &= ~INPUT_HIGH;
-               enable_intrs(port, hooks->intr_rx_high);
-       }
-       return total;
-}
-
-/**
- * receive_chars - upper level read.
- * @the_port: port to read from
- */
-static int receive_chars(struct uart_port *the_port)
-{
-       unsigned char ch[MAX_CHARS];
-       int read_count = 0, read_room, flip = 0;
-       struct uart_state *state = the_port->state;
-       struct ioc3_port *port = get_ioc3_port(the_port);
-       unsigned long pflags;
-
-       /* Make sure all the pointers are "good" ones */
-       if (!state)
-               return 0;
-
-       if (!(port->ip_flags & INPUT_ENABLE))
-               return 0;
-
-       spin_lock_irqsave(&the_port->lock, pflags);
-
-       read_count = do_read(the_port, ch, MAX_CHARS);
-       if (read_count > 0) {
-               flip = 1;
-               read_room = tty_insert_flip_string(&state->port, ch,
-                               read_count);
-               the_port->icount.rx += read_count;
-       }
-       spin_unlock_irqrestore(&the_port->lock, pflags);
-
-       if (flip)
-               tty_flip_buffer_push(&state->port);
-
-       return read_count;
-}
-
-/**
- * ioc3uart_intr_one - lowest level (per port) interrupt handler.
- * @is : submodule
- * @idd: driver data
- * @pending: interrupts to handle
- */
-
-static inline int
-ioc3uart_intr_one(struct ioc3_submodule *is,
-                       struct ioc3_driver_data *idd,
-                       unsigned int pending)
-{
-       int port_num = GET_PORT_FROM_SIO_IR(pending);
-       struct port_hooks *hooks;
-       unsigned int rx_high_rd_aborted = 0;
-       unsigned long flags;
-       struct uart_port *the_port;
-       struct ioc3_port *port;
-       int loop_counter;
-       struct ioc3_card *card_ptr;
-       unsigned int sio_ir;
-
-       card_ptr = idd->data[is->id];
-       port = card_ptr->ic_port[port_num].icp_port;
-       hooks = port->ip_hooks;
-
-       /* Possible race condition here: The tx_mt interrupt bit may be
-        * cleared without the intervention of the interrupt handler,
-        * e.g. by a write.  If the top level interrupt handler reads a
-        * tx_mt, then some other processor does a write, starting up
-        * output, then we come in here, see the tx_mt and stop DMA, the
-        * output started by the other processor will hang.  Thus we can
-        * only rely on tx_mt being legitimate if it is read while the
-        * port lock is held.  Therefore this bit must be ignored in the
-        * passed in interrupt mask which was read by the top level
-        * interrupt handler since the port lock was not held at the time
-        * it was read.  We can only rely on this bit being accurate if it
-        * is read while the port lock is held.  So we'll clear it for now,
-        * and reload it later once we have the port lock.
-        */
-
-       sio_ir = pending & ~(hooks->intr_tx_mt);
-       spin_lock_irqsave(&port->ip_lock, flags);
-
-       loop_counter = MAXITER; /* to avoid hangs */
-
-       do {
-               uint32_t shadow;
-
-               if (loop_counter-- <= 0) {
-                       printk(KERN_WARNING "IOC3 serial: "
-                              "possible hang condition/"
-                              "port stuck on interrupt (line %d).\n",
-                               ((struct uart_port *)port->ip_port)->line);
-                       break;
-               }
-               /* Handle a DCD change */
-               if (sio_ir & hooks->intr_delta_dcd) {
-                       ioc3_ack(is, idd, hooks->intr_delta_dcd);
-                       shadow = readl(&port->ip_serial_regs->shadow);
-
-                       if ((port->ip_notify & N_DDCD)
-                           && (shadow & SHADOW_DCD)
-                           && (port->ip_port)) {
-                               the_port = port->ip_port;
-                               uart_handle_dcd_change(the_port,
-                                               shadow & SHADOW_DCD);
-                               wake_up_interruptible
-                                   (&the_port->state->port.delta_msr_wait);
-                       } else if ((port->ip_notify & N_DDCD)
-                                  && !(shadow & SHADOW_DCD)) {
-                               /* Flag delta DCD/no DCD */
-                               uart_handle_dcd_change(port->ip_port,
-                                               shadow & SHADOW_DCD);
-                               port->ip_flags |= DCD_ON;
-                       }
-               }
-
-               /* Handle a CTS change */
-               if (sio_ir & hooks->intr_delta_cts) {
-                       ioc3_ack(is, idd, hooks->intr_delta_cts);
-                       shadow = readl(&port->ip_serial_regs->shadow);
-
-                       if ((port->ip_notify & N_DCTS) && (port->ip_port)) {
-                               the_port = port->ip_port;
-                               uart_handle_cts_change(the_port, shadow
-                                               & SHADOW_CTS);
-                               wake_up_interruptible
-                                   (&the_port->state->port.delta_msr_wait);
-                       }
-               }
-
-               /* rx timeout interrupt.  Must be some data available.  Put this
-                * before the check for rx_high since servicing this condition
-                * may cause that condition to clear.
-                */
-               if (sio_ir & hooks->intr_rx_timer) {
-                       ioc3_ack(is, idd, hooks->intr_rx_timer);
-                       if ((port->ip_notify & N_DATA_READY)
-                                               && (port->ip_port)) {
-                               receive_chars(port->ip_port);
-                       }
-               }
-
-               /* rx high interrupt. Must be after rx_timer.  */
-               else if (sio_ir & hooks->intr_rx_high) {
-                       /* Data available, notify upper layer */
-                       if ((port->ip_notify & N_DATA_READY) && port->ip_port) {
-                               receive_chars(port->ip_port);
-                       }
-
-                       /* We can't ACK this interrupt.  If receive_chars didn't
-                        * cause the condition to clear, we'll have to disable
-                        * the interrupt until the data is drained.
-                        * If the read was aborted, don't disable the interrupt
-                        * as this may cause us to hang indefinitely.  An
-                        * aborted read generally means that this interrupt
-                        * hasn't been delivered to the cpu yet anyway, even
-                        * though we see it as asserted when we read the sio_ir.
-                        */
-                       if ((sio_ir = PENDING(card_ptr, idd))
-                                       & hooks->intr_rx_high) {
-                               if (port->ip_flags & READ_ABORTED) {
-                                       rx_high_rd_aborted++;
-                               }
-                               else {
-                                       card_ptr->ic_enable &= ~hooks->intr_rx_high;
-                                       port->ip_flags |= INPUT_HIGH;
-                               }
-                       }
-               }
-
-               /* We got a low water interrupt: notify upper layer to
-                * send more data.  Must come before tx_mt since servicing
-                * this condition may cause that condition to clear.
-                */
-               if (sio_ir & hooks->intr_tx_explicit) {
-                       port->ip_flags &= ~LOWAT_WRITTEN;
-                       ioc3_ack(is, idd, hooks->intr_tx_explicit);
-                       if (port->ip_notify & N_OUTPUT_LOWAT)
-                               ioc3_cb_output_lowat(port);
-               }
-
-               /* Handle tx_mt.  Must come after tx_explicit.  */
-               else if (sio_ir & hooks->intr_tx_mt) {
-                       /* If we are expecting a lowat notification
-                        * and we get to this point it probably means that for
-                        * some reason the tx_explicit didn't work as expected
-                        * (that can legitimately happen if the output buffer is
-                        * filled up in just the right way).
-                        * So send the notification now.
-                        */
-                       if (port->ip_notify & N_OUTPUT_LOWAT) {
-                               ioc3_cb_output_lowat(port);
-
-                               /* We need to reload the sio_ir since the lowat
-                                * call may have caused another write to occur,
-                                * clearing the tx_mt condition.
-                                */
-                               sio_ir = PENDING(card_ptr, idd);
-                       }
-
-                       /* If the tx_mt condition still persists even after the
-                        * lowat call, we've got some work to do.
-                        */
-                       if (sio_ir & hooks->intr_tx_mt) {
-                               /* If we are not currently expecting DMA input,
-                                * and the transmitter has just gone idle,
-                                * there is no longer any reason for DMA, so
-                                * disable it.
-                                */
-                               if (!(port->ip_notify
-                                     & (N_DATA_READY | N_DDCD))) {
-                                       BUG_ON(!(port->ip_sscr
-                                                & SSCR_DMA_EN));
-                                       port->ip_sscr &= ~SSCR_DMA_EN;
-                                       writel(port->ip_sscr,
-                                              &port->ip_serial_regs->sscr);
-                               }
-                               /* Prevent infinite tx_mt interrupt */
-                               card_ptr->ic_enable &= ~hooks->intr_tx_mt;
-                       }
-               }
-               sio_ir = PENDING(card_ptr, idd);
-
-               /* if the read was aborted and only hooks->intr_rx_high,
-                * clear hooks->intr_rx_high, so we do not loop forever.
-                */
-
-               if (rx_high_rd_aborted && (sio_ir == hooks->intr_rx_high)) {
-                       sio_ir &= ~hooks->intr_rx_high;
-               }
-       } while (sio_ir & hooks->intr_all);
-
-       spin_unlock_irqrestore(&port->ip_lock, flags);
-       ioc3_enable(is, idd, card_ptr->ic_enable);
-       return 0;
-}
-
-/**
- * ioc3uart_intr - field all serial interrupts
- * @is : submodule
- * @idd: driver data
- * @pending: interrupts to handle
- *
- */
-
-static int ioc3uart_intr(struct ioc3_submodule *is,
-                       struct ioc3_driver_data *idd,
-                       unsigned int pending)
-{
-       int ret = 0;
-
-       /*
-        * The upper level interrupt handler sends interrupts for both ports
-        * here. So we need to call for each port with its interrupts.
-        */
-
-       if (pending & SIO_IR_SA)
-               ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SA);
-       if (pending & SIO_IR_SB)
-               ret |= ioc3uart_intr_one(is, idd, pending & SIO_IR_SB);
-
-       return ret;
-}
-
-/**
- * ic3_type
- * @port: Port to operate with (we ignore since we only have one port)
- *
- */
-static const char *ic3_type(struct uart_port *the_port)
-{
-       if (IS_RS232(the_port->line))
-               return "SGI IOC3 Serial [rs232]";
-       else
-               return "SGI IOC3 Serial [rs422]";
-}
-
-/**
- * ic3_tx_empty - Is the transmitter empty?
- * @port: Port to operate on
- *
- */
-static unsigned int ic3_tx_empty(struct uart_port *the_port)
-{
-       unsigned int ret = 0;
-       struct ioc3_port *port = get_ioc3_port(the_port);
-
-       if (readl(&port->ip_serial_regs->shadow) & SHADOW_TEMT)
-               ret = TIOCSER_TEMT;
-       return ret;
-}
-
-/**
- * ic3_stop_tx - stop the transmitter
- * @port: Port to operate on
- *
- */
-static void ic3_stop_tx(struct uart_port *the_port)
-{
-       struct ioc3_port *port = get_ioc3_port(the_port);
-
-       if (port)
-               set_notification(port, N_OUTPUT_LOWAT, 0);
-}
-
-/**
- * ic3_stop_rx - stop the receiver
- * @port: Port to operate on
- *
- */
-static void ic3_stop_rx(struct uart_port *the_port)
-{
-       struct ioc3_port *port = get_ioc3_port(the_port);
-
-       if (port)
-               port->ip_flags &= ~INPUT_ENABLE;
-}
-
-/**
- * null_void_function
- * @port: Port to operate on
- *
- */
-static void null_void_function(struct uart_port *the_port)
-{
-}
-
-/**
- * ic3_shutdown - shut down the port - free irq and disable
- * @port: port to shut down
- *
- */
-static void ic3_shutdown(struct uart_port *the_port)
-{
-       unsigned long port_flags;
-       struct ioc3_port *port;
-       struct uart_state *state;
-
-       port = get_ioc3_port(the_port);
-       if (!port)
-               return;
-
-       state = the_port->state;
-       wake_up_interruptible(&state->port.delta_msr_wait);
-
-       spin_lock_irqsave(&the_port->lock, port_flags);
-       set_notification(port, N_ALL, 0);
-       spin_unlock_irqrestore(&the_port->lock, port_flags);
-}
-
-/**
- * ic3_set_mctrl - set control lines (dtr, rts, etc)
- * @port: Port to operate on
- * @mctrl: Lines to set/unset
- *
- */
-static void ic3_set_mctrl(struct uart_port *the_port, unsigned int mctrl)
-{
-       unsigned char mcr = 0;
-
-       if (mctrl & TIOCM_RTS)
-               mcr |= UART_MCR_RTS;
-       if (mctrl & TIOCM_DTR)
-               mcr |= UART_MCR_DTR;
-       if (mctrl & TIOCM_OUT1)
-               mcr |= UART_MCR_OUT1;
-       if (mctrl & TIOCM_OUT2)
-               mcr |= UART_MCR_OUT2;
-       if (mctrl & TIOCM_LOOP)
-               mcr |= UART_MCR_LOOP;
-
-       set_mcr(the_port, mcr, SHADOW_DTR);
-}
-
-/**
- * ic3_get_mctrl - get control line info
- * @port: port to operate on
- *
- */
-static unsigned int ic3_get_mctrl(struct uart_port *the_port)
-{
-       struct ioc3_port *port = get_ioc3_port(the_port);
-       uint32_t shadow;
-       unsigned int ret = 0;
-
-       if (!port)
-               return 0;
-
-       shadow = readl(&port->ip_serial_regs->shadow);
-       if (shadow & SHADOW_DCD)
-               ret |= TIOCM_CD;
-       if (shadow & SHADOW_DR)
-               ret |= TIOCM_DSR;
-       if (shadow & SHADOW_CTS)
-               ret |= TIOCM_CTS;
-       return ret;
-}
-
-/**
- * ic3_start_tx - Start transmitter. Called with the_port->lock
- * @port: Port to operate on
- *
- */
-static void ic3_start_tx(struct uart_port *the_port)
-{
-       struct ioc3_port *port = get_ioc3_port(the_port);
-
-       if (port) {
-               set_notification(port, N_OUTPUT_LOWAT, 1);
-               enable_intrs(port, port->ip_hooks->intr_tx_mt);
-       }
-}
-
-/**
- * ic3_break_ctl - handle breaks
- * @port: Port to operate on
- * @break_state: Break state
- *
- */
-static void ic3_break_ctl(struct uart_port *the_port, int break_state)
-{
-}
-
-/**
- * ic3_startup - Start up the serial port - always return 0 (We're always on)
- * @port: Port to operate on
- *
- */
-static int ic3_startup(struct uart_port *the_port)
-{
-       int retval;
-       struct ioc3_port *port;
-       struct ioc3_card *card_ptr;
-       unsigned long port_flags;
-
-       if (!the_port) {
-               NOT_PROGRESS();
-               return -ENODEV;
-       }
-       port = get_ioc3_port(the_port);
-       if (!port) {
-               NOT_PROGRESS();
-               return -ENODEV;
-       }
-       card_ptr = port->ip_card;
-       port->ip_port = the_port;
-
-       if (!card_ptr) {
-               NOT_PROGRESS();
-               return -ENODEV;
-       }
-
-       /* Start up the serial port */
-       spin_lock_irqsave(&the_port->lock, port_flags);
-       retval = ic3_startup_local(the_port);
-       spin_unlock_irqrestore(&the_port->lock, port_flags);
-       return retval;
-}
-
-/**
- * ic3_set_termios - set termios stuff
- * @port: port to operate on
- * @termios: New settings
- * @termios: Old
- *
- */
-static void
-ic3_set_termios(struct uart_port *the_port,
-               struct ktermios *termios, struct ktermios *old_termios)
-{
-       unsigned long port_flags;
-
-       spin_lock_irqsave(&the_port->lock, port_flags);
-       ioc3_change_speed(the_port, termios, old_termios);
-       spin_unlock_irqrestore(&the_port->lock, port_flags);
-}
-
-/**
- * ic3_request_port - allocate resources for port - no op....
- * @port: port to operate on
- *
- */
-static int ic3_request_port(struct uart_port *port)
-{
-       return 0;
-}
-
-/* Associate the uart functions above - given to serial core */
-static const struct uart_ops ioc3_ops = {
-       .tx_empty = ic3_tx_empty,
-       .set_mctrl = ic3_set_mctrl,
-       .get_mctrl = ic3_get_mctrl,
-       .stop_tx = ic3_stop_tx,
-       .start_tx = ic3_start_tx,
-       .stop_rx = ic3_stop_rx,
-       .break_ctl = ic3_break_ctl,
-       .startup = ic3_startup,
-       .shutdown = ic3_shutdown,
-       .set_termios = ic3_set_termios,
-       .type = ic3_type,
-       .release_port = null_void_function,
-       .request_port = ic3_request_port,
-};
-
-/*
- * Boot-time initialization code
- */
-
-static struct uart_driver ioc3_uart = {
-       .owner = THIS_MODULE,
-       .driver_name = "ioc3_serial",
-       .dev_name = DEVICE_NAME,
-       .major = DEVICE_MAJOR,
-       .minor = DEVICE_MINOR,
-       .nr = MAX_LOGICAL_PORTS
-};
-
-/**
- * ioc3_serial_core_attach - register with serial core
- *             This is done during pci probing
- * @is: submodule struct for this
- * @idd: handle for this card
- */
-static inline int ioc3_serial_core_attach( struct ioc3_submodule *is,
-                               struct ioc3_driver_data *idd)
-{
-       struct ioc3_port *port;
-       struct uart_port *the_port;
-       struct ioc3_card *card_ptr = idd->data[is->id];
-       int ii, phys_port;
-       struct pci_dev *pdev = idd->pdev;
-
-       DPRINT_CONFIG(("%s: attach pdev 0x%p - card_ptr 0x%p\n",
-                      __func__, pdev, (void *)card_ptr));
-
-       if (!card_ptr)
-               return -ENODEV;
-
-       /* once around for each logical port on this card */
-       for (ii = 0; ii < LOGICAL_PORTS_PER_CARD; ii++) {
-               phys_port = GET_PHYSICAL_PORT(ii);
-               the_port = &card_ptr->ic_port[phys_port].
-                               icp_uart_port[GET_LOGICAL_PORT(ii)];
-               port = card_ptr->ic_port[phys_port].icp_port;
-               port->ip_port = the_port;
-
-               DPRINT_CONFIG(("%s: attach the_port 0x%p / port 0x%p [%d/%d]\n",
-                       __func__, (void *)the_port, (void *)port,
-                               phys_port, ii));
-
-               /* membase, iobase and mapbase just need to be non-0 */
-               the_port->membase = (unsigned char __iomem *)1;
-               the_port->iobase = (pdev->bus->number << 16) |  ii;
-               the_port->line = (Num_of_ioc3_cards << 2) | ii;
-               the_port->mapbase = 1;
-               the_port->type = PORT_16550A;
-               the_port->fifosize = FIFO_SIZE;
-               the_port->ops = &ioc3_ops;
-               the_port->irq = idd->irq_io;
-               the_port->dev = &pdev->dev;
-
-               if (uart_add_one_port(&ioc3_uart, the_port) < 0) {
-                       printk(KERN_WARNING
-                         "%s: unable to add port %d bus %d\n",
-                              __func__, the_port->line, pdev->bus->number);
-               } else {
-                       DPRINT_CONFIG(("IOC3 serial port %d irq %d bus %d\n",
-                         the_port->line, the_port->irq, pdev->bus->number));
-               }
-
-               /* all ports are rs232 for now */
-               if (IS_PHYSICAL_PORT(ii))
-                       ioc3_set_proto(port, PROTO_RS232);
-       }
-       return 0;
-}
-
-/**
- * ioc3uart_remove - register detach function
- * @is: submodule struct for this submodule
- * @idd: ioc3 driver data for this submodule
- */
-
-static int ioc3uart_remove(struct ioc3_submodule *is,
-                       struct ioc3_driver_data *idd)
-{
-       struct ioc3_card *card_ptr = idd->data[is->id];
-       struct uart_port *the_port;
-       struct ioc3_port *port;
-       int ii;
-
-       if (card_ptr) {
-               for (ii = 0; ii < LOGICAL_PORTS_PER_CARD; ii++) {
-                       the_port = &card_ptr->ic_port[GET_PHYSICAL_PORT(ii)].
-                                       icp_uart_port[GET_LOGICAL_PORT(ii)];
-                       if (the_port)
-                               uart_remove_one_port(&ioc3_uart, the_port);
-                       port = card_ptr->ic_port[GET_PHYSICAL_PORT(ii)].icp_port;
-                       if (port && IS_PHYSICAL_PORT(ii)
-                                       && (GET_PHYSICAL_PORT(ii) == 0)) {
-                               pci_free_consistent(port->ip_idd->pdev,
-                                       TOTAL_RING_BUF_SIZE,
-                                       (void *)port->ip_cpu_ringbuf,
-                                       port->ip_dma_ringbuf);
-                               kfree(port);
-                               card_ptr->ic_port[GET_PHYSICAL_PORT(ii)].
-                                                       icp_port = NULL;
-                       }
-               }
-               kfree(card_ptr);
-               idd->data[is->id] = NULL;
-       }
-       return 0;
-}
-
-/**
- * ioc3uart_probe - card probe function called from shim driver
- * @is: submodule struct for this submodule
- * @idd: ioc3 driver data for this card
- */
-
-static int
-ioc3uart_probe(struct ioc3_submodule *is, struct ioc3_driver_data *idd)
-{
-       struct pci_dev *pdev = idd->pdev;
-       struct ioc3_card *card_ptr;
-       int ret = 0;
-       struct ioc3_port *port;
-       struct ioc3_port *ports[PORTS_PER_CARD];
-       int phys_port;
-       int cnt;
-
-       DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __func__, is, idd));
-
-       card_ptr = kzalloc(sizeof(struct ioc3_card), GFP_KERNEL);
-       if (!card_ptr) {
-               printk(KERN_WARNING "ioc3_attach_one"
-                      ": unable to get memory for the IOC3\n");
-               return -ENOMEM;
-       }
-       idd->data[is->id] = card_ptr;
-       Submodule_slot = is->id;
-
-       writel(((UARTA_BASE >> 3) << SIO_CR_SER_A_BASE_SHIFT) |
-               ((UARTB_BASE >> 3) << SIO_CR_SER_B_BASE_SHIFT) |
-               (0xf << SIO_CR_CMD_PULSE_SHIFT), &idd->vma->sio_cr);
-
-       pci_write_config_dword(pdev, PCI_LAT, 0xff00);
-
-       /* Enable serial port mode select generic PIO pins as outputs */
-       ioc3_gpcr_set(idd, GPCR_UARTA_MODESEL | GPCR_UARTB_MODESEL);
-
-       /* Create port structures for each port */
-       for (phys_port = 0; phys_port < PORTS_PER_CARD; phys_port++) {
-               port = kzalloc(sizeof(struct ioc3_port), GFP_KERNEL);
-               if (!port) {
-                       printk(KERN_WARNING
-                              "IOC3 serial memory not available for port\n");
-                       ret = -ENOMEM;
-                       goto out4;
-               }
-               spin_lock_init(&port->ip_lock);
-
-               /* we need to remember the previous ones, to point back to
-                * them farther down - setting up the ring buffers.
-                */
-               ports[phys_port] = port;
-
-               /* init to something useful */
-               card_ptr->ic_port[phys_port].icp_port = port;
-               port->ip_is = is;
-               port->ip_idd = idd;
-               port->ip_baud = 9600;
-               port->ip_card = card_ptr;
-               port->ip_hooks = &hooks_array[phys_port];
-
-               /* Setup each port */
-               if (phys_port == 0) {
-                       port->ip_serial_regs = &idd->vma->port_a;
-                       port->ip_uart_regs = &idd->vma->sregs.uarta;
-
-                       DPRINT_CONFIG(("%s : Port A ip_serial_regs 0x%p "
-                                      "ip_uart_regs 0x%p\n",
-                                      __func__,
-                                      (void *)port->ip_serial_regs,
-                                      (void *)port->ip_uart_regs));
-
-                       /* setup ring buffers */
-                       port->ip_cpu_ringbuf = pci_alloc_consistent(pdev,
-                               TOTAL_RING_BUF_SIZE, &port->ip_dma_ringbuf);
-
-                       BUG_ON(!((((int64_t) port->ip_dma_ringbuf) &
-                                 (TOTAL_RING_BUF_SIZE - 1)) == 0));
-                       port->ip_inring = RING(port, RX_A);
-                       port->ip_outring = RING(port, TX_A);
-                       DPRINT_CONFIG(("%s : Port A ip_cpu_ringbuf 0x%p "
-                                      "ip_dma_ringbuf 0x%p, ip_inring 0x%p "
-                                       "ip_outring 0x%p\n",
-                                      __func__,
-                                      (void *)port->ip_cpu_ringbuf,
-                                      (void *)port->ip_dma_ringbuf,
-                                      (void *)port->ip_inring,
-                                      (void *)port->ip_outring));
-               }
-               else {
-                       port->ip_serial_regs = &idd->vma->port_b;
-                       port->ip_uart_regs = &idd->vma->sregs.uartb;
-
-                       DPRINT_CONFIG(("%s : Port B ip_serial_regs 0x%p "
-                                      "ip_uart_regs 0x%p\n",
-                                      __func__,
-                                      (void *)port->ip_serial_regs,
-                                      (void *)port->ip_uart_regs));
-
-                       /* share the ring buffers */
-                       port->ip_dma_ringbuf =
-                           ports[phys_port - 1]->ip_dma_ringbuf;
-                       port->ip_cpu_ringbuf =
-                           ports[phys_port - 1]->ip_cpu_ringbuf;
-                       port->ip_inring = RING(port, RX_B);
-                       port->ip_outring = RING(port, TX_B);
-                       DPRINT_CONFIG(("%s : Port B ip_cpu_ringbuf 0x%p "
-                                      "ip_dma_ringbuf 0x%p, ip_inring 0x%p "
-                                       "ip_outring 0x%p\n",
-                                      __func__,
-                                      (void *)port->ip_cpu_ringbuf,
-                                      (void *)port->ip_dma_ringbuf,
-                                      (void *)port->ip_inring,
-                                      (void *)port->ip_outring));
-               }
-
-               DPRINT_CONFIG(("%s : port %d [addr 0x%p] card_ptr 0x%p",
-                              __func__,
-                              phys_port, (void *)port, (void *)card_ptr));
-               DPRINT_CONFIG((" ip_serial_regs 0x%p ip_uart_regs 0x%p\n",
-                              (void *)port->ip_serial_regs,
-                              (void *)port->ip_uart_regs));
-
-               /* Initialize the hardware for IOC3 */
-               port_init(port);
-
-               DPRINT_CONFIG(("%s: phys_port %d port 0x%p inring 0x%p "
-                              "outring 0x%p\n",
-                              __func__,
-                              phys_port, (void *)port,
-                              (void *)port->ip_inring,
-                              (void *)port->ip_outring));
-
-       }
-
-       /* register port with the serial core */
-
-       ret = ioc3_serial_core_attach(is, idd);
-       if (ret)
-               goto out4;
-
-       Num_of_ioc3_cards++;
-
-       return ret;
-
-       /* error exits that give back resources */
-out4:
-       for (cnt = 0; cnt < phys_port; cnt++)
-               kfree(ports[cnt]);
-
-       kfree(card_ptr);
-       return ret;
-}
-
-static struct ioc3_submodule ioc3uart_ops = {
-       .name = "IOC3uart",
-       .probe = ioc3uart_probe,
-       .remove = ioc3uart_remove,
-       /* call .intr for both ports initially */
-       .irq_mask = SIO_IR_SA | SIO_IR_SB,
-       .intr = ioc3uart_intr,
-       .owner = THIS_MODULE,
-};
-
-/**
- * ioc3_detect - module init called,
- */
-static int __init ioc3uart_init(void)
-{
-       int ret;
-
-       /* register with serial core */
-       if ((ret = uart_register_driver(&ioc3_uart)) < 0) {
-               printk(KERN_WARNING
-                      "%s: Couldn't register IOC3 uart serial driver\n",
-                      __func__);
-               return ret;
-       }
-       ret = ioc3_register_submodule(&ioc3uart_ops);
-       if (ret)
-               uart_unregister_driver(&ioc3_uart);
-       return ret;
-}
-
-static void __exit ioc3uart_exit(void)
-{
-       ioc3_unregister_submodule(&ioc3uart_ops);
-       uart_unregister_driver(&ioc3_uart);
-}
-
-module_init(ioc3uart_init);
-module_exit(ioc3uart_exit);
-
-MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) <pfg@sgi.com>");
-MODULE_DESCRIPTION("Serial PCI driver module for SGI IOC3 card");
-MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/ioc4_serial.c b/drivers/tty/serial/ioc4_serial.c
deleted file mode 100644 (file)
index db5b979..0000000
+++ /dev/null
@@ -1,2955 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2003-2006 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-
-/*
- * This file contains a module version of the ioc4 serial driver. This
- * includes all the support functions needed (support functions, etc.)
- * and the serial driver itself.
- */
-#include <linux/errno.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/circ_buf.h>
-#include <linux/serial_reg.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/ioc4.h>
-#include <linux/serial_core.h>
-#include <linux/slab.h>
-
-/*
- * interesting things about the ioc4
- */
-
-#define IOC4_NUM_SERIAL_PORTS  4       /* max ports per card */
-#define IOC4_NUM_CARDS         8       /* max cards per partition */
-
-#define        GET_SIO_IR(_n)  (_n == 0) ? (IOC4_SIO_IR_S0) : \
-                               (_n == 1) ? (IOC4_SIO_IR_S1) : \
-                               (_n == 2) ? (IOC4_SIO_IR_S2) : \
-                               (IOC4_SIO_IR_S3)
-
-#define        GET_OTHER_IR(_n)  (_n == 0) ? (IOC4_OTHER_IR_S0_MEMERR) : \
-                               (_n == 1) ? (IOC4_OTHER_IR_S1_MEMERR) : \
-                               (_n == 2) ? (IOC4_OTHER_IR_S2_MEMERR) : \
-                               (IOC4_OTHER_IR_S3_MEMERR)
-
-
-/*
- * All IOC4 registers are 32 bits wide.
- */
-
-/*
- * PCI Memory Space Map
- */
-#define IOC4_PCI_ERR_ADDR_L     0x000  /* Low Error Address */
-#define IOC4_PCI_ERR_ADDR_VLD          (0x1 << 0)
-#define IOC4_PCI_ERR_ADDR_MST_ID_MSK    (0xf << 1)
-#define IOC4_PCI_ERR_ADDR_MST_NUM_MSK   (0xe << 1)
-#define IOC4_PCI_ERR_ADDR_MST_TYP_MSK   (0x1 << 1)
-#define IOC4_PCI_ERR_ADDR_MUL_ERR       (0x1 << 5)
-#define IOC4_PCI_ERR_ADDR_ADDR_MSK      (0x3ffffff << 6)
-
-/* Interrupt types */
-#define        IOC4_SIO_INTR_TYPE      0
-#define        IOC4_OTHER_INTR_TYPE    1
-#define        IOC4_NUM_INTR_TYPES     2
-
-/* Bitmasks for IOC4_SIO_IR, IOC4_SIO_IEC, and IOC4_SIO_IES  */
-#define IOC4_SIO_IR_S0_TX_MT      0x00000001   /* Serial port 0 TX empty */
-#define IOC4_SIO_IR_S0_RX_FULL    0x00000002   /* Port 0 RX buf full */
-#define IOC4_SIO_IR_S0_RX_HIGH    0x00000004   /* Port 0 RX hiwat */
-#define IOC4_SIO_IR_S0_RX_TIMER           0x00000008   /* Port 0 RX timeout */
-#define IOC4_SIO_IR_S0_DELTA_DCD   0x00000010  /* Port 0 delta DCD */
-#define IOC4_SIO_IR_S0_DELTA_CTS   0x00000020  /* Port 0 delta CTS */
-#define IOC4_SIO_IR_S0_INT        0x00000040   /* Port 0 pass-thru intr */
-#define IOC4_SIO_IR_S0_TX_EXPLICIT 0x00000080  /* Port 0 explicit TX thru */
-#define IOC4_SIO_IR_S1_TX_MT      0x00000100   /* Serial port 1 */
-#define IOC4_SIO_IR_S1_RX_FULL    0x00000200   /* */
-#define IOC4_SIO_IR_S1_RX_HIGH    0x00000400   /* */
-#define IOC4_SIO_IR_S1_RX_TIMER           0x00000800   /* */
-#define IOC4_SIO_IR_S1_DELTA_DCD   0x00001000  /* */
-#define IOC4_SIO_IR_S1_DELTA_CTS   0x00002000  /* */
-#define IOC4_SIO_IR_S1_INT        0x00004000   /* */
-#define IOC4_SIO_IR_S1_TX_EXPLICIT 0x00008000  /* */
-#define IOC4_SIO_IR_S2_TX_MT      0x00010000   /* Serial port 2 */
-#define IOC4_SIO_IR_S2_RX_FULL    0x00020000   /* */
-#define IOC4_SIO_IR_S2_RX_HIGH    0x00040000   /* */
-#define IOC4_SIO_IR_S2_RX_TIMER           0x00080000   /* */
-#define IOC4_SIO_IR_S2_DELTA_DCD   0x00100000  /* */
-#define IOC4_SIO_IR_S2_DELTA_CTS   0x00200000  /* */
-#define IOC4_SIO_IR_S2_INT        0x00400000   /* */
-#define IOC4_SIO_IR_S2_TX_EXPLICIT 0x00800000  /* */
-#define IOC4_SIO_IR_S3_TX_MT      0x01000000   /* Serial port 3 */
-#define IOC4_SIO_IR_S3_RX_FULL    0x02000000   /* */
-#define IOC4_SIO_IR_S3_RX_HIGH    0x04000000   /* */
-#define IOC4_SIO_IR_S3_RX_TIMER           0x08000000   /* */
-#define IOC4_SIO_IR_S3_DELTA_DCD   0x10000000  /* */
-#define IOC4_SIO_IR_S3_DELTA_CTS   0x20000000  /* */
-#define IOC4_SIO_IR_S3_INT        0x40000000   /* */
-#define IOC4_SIO_IR_S3_TX_EXPLICIT 0x80000000  /* */
-
-/* Per device interrupt masks */
-#define IOC4_SIO_IR_S0         (IOC4_SIO_IR_S0_TX_MT | \
-                                IOC4_SIO_IR_S0_RX_FULL | \
-                                IOC4_SIO_IR_S0_RX_HIGH | \
-                                IOC4_SIO_IR_S0_RX_TIMER | \
-                                IOC4_SIO_IR_S0_DELTA_DCD | \
-                                IOC4_SIO_IR_S0_DELTA_CTS | \
-                                IOC4_SIO_IR_S0_INT | \
-                                IOC4_SIO_IR_S0_TX_EXPLICIT)
-#define IOC4_SIO_IR_S1         (IOC4_SIO_IR_S1_TX_MT | \
-                                IOC4_SIO_IR_S1_RX_FULL | \
-                                IOC4_SIO_IR_S1_RX_HIGH | \
-                                IOC4_SIO_IR_S1_RX_TIMER | \
-                                IOC4_SIO_IR_S1_DELTA_DCD | \
-                                IOC4_SIO_IR_S1_DELTA_CTS | \
-                                IOC4_SIO_IR_S1_INT | \
-                                IOC4_SIO_IR_S1_TX_EXPLICIT)
-#define IOC4_SIO_IR_S2         (IOC4_SIO_IR_S2_TX_MT | \
-                                IOC4_SIO_IR_S2_RX_FULL | \
-                                IOC4_SIO_IR_S2_RX_HIGH | \
-                                IOC4_SIO_IR_S2_RX_TIMER | \
-                                IOC4_SIO_IR_S2_DELTA_DCD | \
-                                IOC4_SIO_IR_S2_DELTA_CTS | \
-                                IOC4_SIO_IR_S2_INT | \
-                                IOC4_SIO_IR_S2_TX_EXPLICIT)
-#define IOC4_SIO_IR_S3         (IOC4_SIO_IR_S3_TX_MT | \
-                                IOC4_SIO_IR_S3_RX_FULL | \
-                                IOC4_SIO_IR_S3_RX_HIGH | \
-                                IOC4_SIO_IR_S3_RX_TIMER | \
-                                IOC4_SIO_IR_S3_DELTA_DCD | \
-                                IOC4_SIO_IR_S3_DELTA_CTS | \
-                                IOC4_SIO_IR_S3_INT | \
-                                IOC4_SIO_IR_S3_TX_EXPLICIT)
-
-/* Bitmasks for IOC4_OTHER_IR, IOC4_OTHER_IEC, and IOC4_OTHER_IES  */
-#define IOC4_OTHER_IR_ATA_INT          0x00000001  /* ATAPI intr pass-thru */
-#define IOC4_OTHER_IR_ATA_MEMERR       0x00000002  /* ATAPI DMA PCI error */
-#define IOC4_OTHER_IR_S0_MEMERR                0x00000004  /* Port 0 PCI error */
-#define IOC4_OTHER_IR_S1_MEMERR                0x00000008  /* Port 1 PCI error */
-#define IOC4_OTHER_IR_S2_MEMERR                0x00000010  /* Port 2 PCI error */
-#define IOC4_OTHER_IR_S3_MEMERR                0x00000020  /* Port 3 PCI error */
-#define IOC4_OTHER_IR_KBD_INT          0x00000040  /* Keyboard/mouse */
-#define IOC4_OTHER_IR_RESERVED         0x007fff80  /* Reserved */
-#define IOC4_OTHER_IR_RT_INT           0x00800000  /* INT_OUT section output */
-#define IOC4_OTHER_IR_GEN_INT          0xff000000  /* Generic pins */
-
-#define IOC4_OTHER_IR_SER_MEMERR (IOC4_OTHER_IR_S0_MEMERR | IOC4_OTHER_IR_S1_MEMERR | \
-                                 IOC4_OTHER_IR_S2_MEMERR | IOC4_OTHER_IR_S3_MEMERR)
-
-/* Bitmasks for IOC4_SIO_CR */
-#define IOC4_SIO_CR_CMD_PULSE_SHIFT              0  /* byte bus strobe shift */
-#define IOC4_SIO_CR_ARB_DIAG_TX0       0x00000000
-#define IOC4_SIO_CR_ARB_DIAG_RX0       0x00000010
-#define IOC4_SIO_CR_ARB_DIAG_TX1       0x00000020
-#define IOC4_SIO_CR_ARB_DIAG_RX1       0x00000030
-#define IOC4_SIO_CR_ARB_DIAG_TX2       0x00000040
-#define IOC4_SIO_CR_ARB_DIAG_RX2       0x00000050
-#define IOC4_SIO_CR_ARB_DIAG_TX3       0x00000060
-#define IOC4_SIO_CR_ARB_DIAG_RX3       0x00000070
-#define IOC4_SIO_CR_SIO_DIAG_IDLE      0x00000080  /* 0 -> active request among
-                                                          serial ports (ro) */
-/* Defs for some of the generic I/O pins */
-#define IOC4_GPCR_UART0_MODESEL           0x10 /* Pin is output to port 0
-                                                  mode sel */
-#define IOC4_GPCR_UART1_MODESEL           0x20 /* Pin is output to port 1
-                                                  mode sel */
-#define IOC4_GPCR_UART2_MODESEL           0x40 /* Pin is output to port 2
-                                                  mode sel */
-#define IOC4_GPCR_UART3_MODESEL           0x80 /* Pin is output to port 3
-                                                  mode sel */
-
-#define IOC4_GPPR_UART0_MODESEL_PIN   4        /* GIO pin controlling
-                                          uart 0 mode select */
-#define IOC4_GPPR_UART1_MODESEL_PIN   5        /* GIO pin controlling
-                                          uart 1 mode select */
-#define IOC4_GPPR_UART2_MODESEL_PIN   6        /* GIO pin controlling
-                                          uart 2 mode select */
-#define IOC4_GPPR_UART3_MODESEL_PIN   7        /* GIO pin controlling
-                                          uart 3 mode select */
-
-/* Bitmasks for serial RX status byte */
-#define IOC4_RXSB_OVERRUN       0x01   /* Char(s) lost */
-#define IOC4_RXSB_PAR_ERR      0x02    /* Parity error */
-#define IOC4_RXSB_FRAME_ERR    0x04    /* Framing error */
-#define IOC4_RXSB_BREAK                0x08    /* Break character */
-#define IOC4_RXSB_CTS          0x10    /* State of CTS */
-#define IOC4_RXSB_DCD          0x20    /* State of DCD */
-#define IOC4_RXSB_MODEM_VALID   0x40   /* DCD, CTS, and OVERRUN are valid */
-#define IOC4_RXSB_DATA_VALID    0x80   /* Data byte, FRAME_ERR PAR_ERR
-                                        * & BREAK valid */
-
-/* Bitmasks for serial TX control byte */
-#define IOC4_TXCB_INT_WHEN_DONE 0x20   /* Interrupt after this byte is sent */
-#define IOC4_TXCB_INVALID      0x00    /* Byte is invalid */
-#define IOC4_TXCB_VALID                0x40    /* Byte is valid */
-#define IOC4_TXCB_MCR          0x80    /* Data<7:0> to modem control reg */
-#define IOC4_TXCB_DELAY                0xc0    /* Delay data<7:0> mSec */
-
-/* Bitmasks for IOC4_SBBR_L */
-#define IOC4_SBBR_L_SIZE       0x00000001  /* 0 == 1KB rings, 1 == 4KB rings */
-
-/* Bitmasks for IOC4_SSCR_<3:0> */
-#define IOC4_SSCR_RX_THRESHOLD  0x000001ff  /* Hiwater mark */
-#define IOC4_SSCR_TX_TIMER_BUSY 0x00010000  /* TX timer in progress */
-#define IOC4_SSCR_HFC_EN       0x00020000  /* Hardware flow control enabled */
-#define IOC4_SSCR_RX_RING_DCD   0x00040000  /* Post RX record on delta-DCD */
-#define IOC4_SSCR_RX_RING_CTS   0x00080000  /* Post RX record on delta-CTS */
-#define IOC4_SSCR_DIAG         0x00200000  /* Bypass clock divider for sim */
-#define IOC4_SSCR_RX_DRAIN     0x08000000  /* Drain RX buffer to memory */
-#define IOC4_SSCR_DMA_EN       0x10000000  /* Enable ring buffer DMA */
-#define IOC4_SSCR_DMA_PAUSE    0x20000000  /* Pause DMA */
-#define IOC4_SSCR_PAUSE_STATE   0x40000000  /* Sets when PAUSE takes effect */
-#define IOC4_SSCR_RESET                0x80000000  /* Reset DMA channels */
-
-/* All producer/consumer pointers are the same bitfield */
-#define IOC4_PROD_CONS_PTR_4K   0x00000ff8     /* For 4K buffers */
-#define IOC4_PROD_CONS_PTR_1K   0x000003f8     /* For 1K buffers */
-#define IOC4_PROD_CONS_PTR_OFF           3
-
-/* Bitmasks for IOC4_SRCIR_<3:0> */
-#define IOC4_SRCIR_ARM         0x80000000      /* Arm RX timer */
-
-/* Bitmasks for IOC4_SHADOW_<3:0> */
-#define IOC4_SHADOW_DR  0x00000001     /* Data ready */
-#define IOC4_SHADOW_OE  0x00000002     /* Overrun error */
-#define IOC4_SHADOW_PE  0x00000004     /* Parity error */
-#define IOC4_SHADOW_FE  0x00000008     /* Framing error */
-#define IOC4_SHADOW_BI  0x00000010     /* Break interrupt */
-#define IOC4_SHADOW_THRE 0x00000020    /* Xmit holding register empty */
-#define IOC4_SHADOW_TEMT 0x00000040    /* Xmit shift register empty */
-#define IOC4_SHADOW_RFCE 0x00000080    /* Char in RX fifo has an error */
-#define IOC4_SHADOW_DCTS 0x00010000    /* Delta clear to send */
-#define IOC4_SHADOW_DDCD 0x00080000    /* Delta data carrier detect */
-#define IOC4_SHADOW_CTS         0x00100000     /* Clear to send */
-#define IOC4_SHADOW_DCD         0x00800000     /* Data carrier detect */
-#define IOC4_SHADOW_DTR         0x01000000     /* Data terminal ready */
-#define IOC4_SHADOW_RTS         0x02000000     /* Request to send */
-#define IOC4_SHADOW_OUT1 0x04000000    /* 16550 OUT1 bit */
-#define IOC4_SHADOW_OUT2 0x08000000    /* 16550 OUT2 bit */
-#define IOC4_SHADOW_LOOP 0x10000000    /* Loopback enabled */
-
-/* Bitmasks for IOC4_SRTR_<3:0> */
-#define IOC4_SRTR_CNT          0x00000fff      /* Reload value for RX timer */
-#define IOC4_SRTR_CNT_VAL      0x0fff0000      /* Current value of RX timer */
-#define IOC4_SRTR_CNT_VAL_SHIFT         16
-#define IOC4_SRTR_HZ                 16000     /* SRTR clock frequency */
-
-/* Serial port register map used for DMA and PIO serial I/O */
-struct ioc4_serialregs {
-       uint32_t sscr;
-       uint32_t stpir;
-       uint32_t stcir;
-       uint32_t srpir;
-       uint32_t srcir;
-       uint32_t srtr;
-       uint32_t shadow;
-};
-
-/* IOC4 UART register map */
-struct ioc4_uartregs {
-       char i4u_lcr;
-       union {
-               char iir;       /* read only */
-               char fcr;       /* write only */
-       } u3;
-       union {
-               char ier;       /* DLAB == 0 */
-               char dlm;       /* DLAB == 1 */
-       } u2;
-       union {
-               char rbr;       /* read only, DLAB == 0 */
-               char thr;       /* write only, DLAB == 0 */
-               char dll;       /* DLAB == 1 */
-       } u1;
-       char i4u_scr;
-       char i4u_msr;
-       char i4u_lsr;
-       char i4u_mcr;
-};
-
-/* short names */
-#define i4u_dll u1.dll
-#define i4u_ier u2.ier
-#define i4u_dlm u2.dlm
-#define i4u_fcr u3.fcr
-
-/* Serial port registers used for DMA serial I/O */
-struct ioc4_serial {
-       uint32_t sbbr01_l;
-       uint32_t sbbr01_h;
-       uint32_t sbbr23_l;
-       uint32_t sbbr23_h;
-
-       struct ioc4_serialregs port_0;
-       struct ioc4_serialregs port_1;
-       struct ioc4_serialregs port_2;
-       struct ioc4_serialregs port_3;
-       struct ioc4_uartregs uart_0;
-       struct ioc4_uartregs uart_1;
-       struct ioc4_uartregs uart_2;
-       struct ioc4_uartregs uart_3;
-};
-
-/* UART clock speed */
-#define IOC4_SER_XIN_CLK_66     66666667
-#define IOC4_SER_XIN_CLK_33     33333333
-
-#define IOC4_W_IES             0
-#define IOC4_W_IEC             1
-
-typedef void ioc4_intr_func_f(void *, uint32_t);
-typedef ioc4_intr_func_f *ioc4_intr_func_t;
-
-static unsigned int Num_of_ioc4_cards;
-
-/* defining this will get you LOTS of great debug info */
-//#define DEBUG_INTERRUPTS
-#define DPRINT_CONFIG(_x...)   ;
-//#define DPRINT_CONFIG(_x...) printk _x
-
-/* number of characters left in xmit buffer before we ask for more */
-#define WAKEUP_CHARS   256
-
-/* number of characters we want to transmit to the lower level at a time */
-#define IOC4_MAX_CHARS 256
-#define IOC4_FIFO_CHARS        255
-
-/* Device name we're using */
-#define DEVICE_NAME_RS232  "ttyIOC"
-#define DEVICE_NAME_RS422  "ttyAIOC"
-#define DEVICE_MAJOR      204
-#define DEVICE_MINOR_RS232 50
-#define DEVICE_MINOR_RS422 84
-
-
-/* register offsets */
-#define IOC4_SERIAL_OFFSET     0x300
-
-/* flags for next_char_state */
-#define NCS_BREAK      0x1
-#define NCS_PARITY     0x2
-#define NCS_FRAMING    0x4
-#define NCS_OVERRUN    0x8
-
-/* cause we need SOME parameters ... */
-#define MIN_BAUD_SUPPORTED     1200
-#define MAX_BAUD_SUPPORTED     115200
-
-/* protocol types supported */
-#define PROTO_RS232    3
-#define PROTO_RS422    7
-
-/* Notification types */
-#define N_DATA_READY   0x01
-#define N_OUTPUT_LOWAT 0x02
-#define N_BREAK                0x04
-#define N_PARITY_ERROR 0x08
-#define N_FRAMING_ERROR        0x10
-#define N_OVERRUN_ERROR        0x20
-#define N_DDCD         0x40
-#define N_DCTS         0x80
-
-#define N_ALL_INPUT    (N_DATA_READY | N_BREAK |                       \
-                        N_PARITY_ERROR | N_FRAMING_ERROR |             \
-                        N_OVERRUN_ERROR | N_DDCD | N_DCTS)
-
-#define N_ALL_OUTPUT   N_OUTPUT_LOWAT
-
-#define N_ALL_ERRORS   (N_PARITY_ERROR | N_FRAMING_ERROR | N_OVERRUN_ERROR)
-
-#define N_ALL          (N_DATA_READY | N_OUTPUT_LOWAT | N_BREAK |      \
-                        N_PARITY_ERROR | N_FRAMING_ERROR |             \
-                        N_OVERRUN_ERROR | N_DDCD | N_DCTS)
-
-#define SER_DIVISOR(_x, clk)           (((clk) + (_x) * 8) / ((_x) * 16))
-#define DIVISOR_TO_BAUD(div, clk)      ((clk) / 16 / (div))
-
-/* Some masks */
-#define LCR_MASK_BITS_CHAR     (UART_LCR_WLEN5 | UART_LCR_WLEN6 \
-                                       | UART_LCR_WLEN7 | UART_LCR_WLEN8)
-#define LCR_MASK_STOP_BITS     (UART_LCR_STOP)
-
-#define PENDING(_p)    (readl(&(_p)->ip_mem->sio_ir.raw) & _p->ip_ienb)
-#define READ_SIO_IR(_p) readl(&(_p)->ip_mem->sio_ir.raw)
-
-/* Default to 4k buffers */
-#ifdef IOC4_1K_BUFFERS
-#define RING_BUF_SIZE 1024
-#define IOC4_BUF_SIZE_BIT 0
-#define PROD_CONS_MASK IOC4_PROD_CONS_PTR_1K
-#else
-#define RING_BUF_SIZE 4096
-#define IOC4_BUF_SIZE_BIT IOC4_SBBR_L_SIZE
-#define PROD_CONS_MASK IOC4_PROD_CONS_PTR_4K
-#endif
-
-#define TOTAL_RING_BUF_SIZE (RING_BUF_SIZE * 4)
-
-/*
- * This is the entry saved by the driver - one per card
- */
-
-#define UART_PORT_MIN          0
-#define UART_PORT_RS232                UART_PORT_MIN
-#define UART_PORT_RS422                1
-#define UART_PORT_COUNT                2       /* one for each mode */
-
-struct ioc4_control {
-       int ic_irq;
-       struct {
-               /* uart ports are allocated here - 1 for rs232, 1 for rs422 */
-               struct uart_port icp_uart_port[UART_PORT_COUNT];
-               /* Handy reference material */
-               struct ioc4_port *icp_port;
-       } ic_port[IOC4_NUM_SERIAL_PORTS];
-       struct ioc4_soft *ic_soft;
-};
-
-/*
- * per-IOC4 data structure
- */
-#define MAX_IOC4_INTR_ENTS     (8 * sizeof(uint32_t))
-struct ioc4_soft {
-       struct ioc4_misc_regs __iomem *is_ioc4_misc_addr;
-       struct ioc4_serial __iomem *is_ioc4_serial_addr;
-
-       /* Each interrupt type has an entry in the array */
-       struct ioc4_intr_type {
-
-               /*
-                * Each in-use entry in this array contains at least
-                * one nonzero bit in sd_bits; no two entries in this
-                * array have overlapping sd_bits values.
-                */
-               struct ioc4_intr_info {
-                       uint32_t sd_bits;
-                       ioc4_intr_func_f *sd_intr;
-                       void *sd_info;
-               } is_intr_info[MAX_IOC4_INTR_ENTS];
-
-               /* Number of entries active in the above array */
-               atomic_t is_num_intrs;
-       } is_intr_type[IOC4_NUM_INTR_TYPES];
-
-       /* is_ir_lock must be held while
-        * modifying sio_ie values, so
-        * we can be sure that sio_ie is
-        * not changing when we read it
-        * along with sio_ir.
-        */
-       spinlock_t is_ir_lock;  /* SIO_IE[SC] mod lock */
-};
-
-/* Local port info for each IOC4 serial ports */
-struct ioc4_port {
-       struct uart_port *ip_port;      /* current active port ptr */
-       /* Ptrs for all ports */
-       struct uart_port *ip_all_ports[UART_PORT_COUNT];
-       /* Back ptrs for this port */
-       struct ioc4_control *ip_control;
-       struct pci_dev *ip_pdev;
-       struct ioc4_soft *ip_ioc4_soft;
-
-       /* pci mem addresses */
-       struct ioc4_misc_regs __iomem *ip_mem;
-       struct ioc4_serial __iomem *ip_serial;
-       struct ioc4_serialregs __iomem *ip_serial_regs;
-       struct ioc4_uartregs __iomem *ip_uart_regs;
-
-       /* Ring buffer page for this port */
-       dma_addr_t ip_dma_ringbuf;
-       /* vaddr of ring buffer */
-       struct ring_buffer *ip_cpu_ringbuf;
-
-       /* Rings for this port */
-       struct ring *ip_inring;
-       struct ring *ip_outring;
-
-       /* Hook to port specific values */
-       struct hooks *ip_hooks;
-
-       spinlock_t ip_lock;
-
-       /* Various rx/tx parameters */
-       int ip_baud;
-       int ip_tx_lowat;
-       int ip_rx_timeout;
-
-       /* Copy of notification bits */
-       int ip_notify;
-
-       /* Shadow copies of various registers so we don't need to PIO
-        * read them constantly
-        */
-       uint32_t ip_ienb;       /* Enabled interrupts */
-       uint32_t ip_sscr;
-       uint32_t ip_tx_prod;
-       uint32_t ip_rx_cons;
-       int ip_pci_bus_speed;
-       unsigned char ip_flags;
-};
-
-/* tx low water mark.  We need to notify the driver whenever tx is getting
- * close to empty so it can refill the tx buffer and keep things going.
- * Let's assume that if we interrupt 1 ms before the tx goes idle, we'll
- * have no trouble getting in more chars in time (I certainly hope so).
- */
-#define TX_LOWAT_LATENCY      1000
-#define TX_LOWAT_HZ          (1000000 / TX_LOWAT_LATENCY)
-#define TX_LOWAT_CHARS(baud) (baud / 10 / TX_LOWAT_HZ)
-
-/* Flags per port */
-#define INPUT_HIGH     0x01
-#define DCD_ON         0x02
-#define LOWAT_WRITTEN  0x04
-#define READ_ABORTED   0x08
-#define PORT_ACTIVE    0x10
-#define PORT_INACTIVE  0       /* This is the value when "off" */
-
-
-/* Since each port has different register offsets and bitmasks
- * for everything, we'll store those that we need in tables so we
- * don't have to be constantly checking the port we are dealing with.
- */
-struct hooks {
-       uint32_t intr_delta_dcd;
-       uint32_t intr_delta_cts;
-       uint32_t intr_tx_mt;
-       uint32_t intr_rx_timer;
-       uint32_t intr_rx_high;
-       uint32_t intr_tx_explicit;
-       uint32_t intr_dma_error;
-       uint32_t intr_clear;
-       uint32_t intr_all;
-       int rs422_select_pin;
-};
-
-static struct hooks hooks_array[IOC4_NUM_SERIAL_PORTS] = {
-       /* Values for port 0 */
-       {
-        IOC4_SIO_IR_S0_DELTA_DCD, IOC4_SIO_IR_S0_DELTA_CTS,
-        IOC4_SIO_IR_S0_TX_MT, IOC4_SIO_IR_S0_RX_TIMER,
-        IOC4_SIO_IR_S0_RX_HIGH, IOC4_SIO_IR_S0_TX_EXPLICIT,
-        IOC4_OTHER_IR_S0_MEMERR,
-        (IOC4_SIO_IR_S0_TX_MT | IOC4_SIO_IR_S0_RX_FULL |
-         IOC4_SIO_IR_S0_RX_HIGH | IOC4_SIO_IR_S0_RX_TIMER |
-         IOC4_SIO_IR_S0_DELTA_DCD | IOC4_SIO_IR_S0_DELTA_CTS |
-         IOC4_SIO_IR_S0_INT | IOC4_SIO_IR_S0_TX_EXPLICIT),
-        IOC4_SIO_IR_S0, IOC4_GPPR_UART0_MODESEL_PIN,
-        },
-
-       /* Values for port 1 */
-       {
-        IOC4_SIO_IR_S1_DELTA_DCD, IOC4_SIO_IR_S1_DELTA_CTS,
-        IOC4_SIO_IR_S1_TX_MT, IOC4_SIO_IR_S1_RX_TIMER,
-        IOC4_SIO_IR_S1_RX_HIGH, IOC4_SIO_IR_S1_TX_EXPLICIT,
-        IOC4_OTHER_IR_S1_MEMERR,
-        (IOC4_SIO_IR_S1_TX_MT | IOC4_SIO_IR_S1_RX_FULL |
-         IOC4_SIO_IR_S1_RX_HIGH | IOC4_SIO_IR_S1_RX_TIMER |
-         IOC4_SIO_IR_S1_DELTA_DCD | IOC4_SIO_IR_S1_DELTA_CTS |
-         IOC4_SIO_IR_S1_INT | IOC4_SIO_IR_S1_TX_EXPLICIT),
-        IOC4_SIO_IR_S1, IOC4_GPPR_UART1_MODESEL_PIN,
-        },
-
-       /* Values for port 2 */
-       {
-        IOC4_SIO_IR_S2_DELTA_DCD, IOC4_SIO_IR_S2_DELTA_CTS,
-        IOC4_SIO_IR_S2_TX_MT, IOC4_SIO_IR_S2_RX_TIMER,
-        IOC4_SIO_IR_S2_RX_HIGH, IOC4_SIO_IR_S2_TX_EXPLICIT,
-        IOC4_OTHER_IR_S2_MEMERR,
-        (IOC4_SIO_IR_S2_TX_MT | IOC4_SIO_IR_S2_RX_FULL |
-         IOC4_SIO_IR_S2_RX_HIGH | IOC4_SIO_IR_S2_RX_TIMER |
-         IOC4_SIO_IR_S2_DELTA_DCD | IOC4_SIO_IR_S2_DELTA_CTS |
-         IOC4_SIO_IR_S2_INT | IOC4_SIO_IR_S2_TX_EXPLICIT),
-        IOC4_SIO_IR_S2, IOC4_GPPR_UART2_MODESEL_PIN,
-        },
-
-       /* Values for port 3 */
-       {
-        IOC4_SIO_IR_S3_DELTA_DCD, IOC4_SIO_IR_S3_DELTA_CTS,
-        IOC4_SIO_IR_S3_TX_MT, IOC4_SIO_IR_S3_RX_TIMER,
-        IOC4_SIO_IR_S3_RX_HIGH, IOC4_SIO_IR_S3_TX_EXPLICIT,
-        IOC4_OTHER_IR_S3_MEMERR,
-        (IOC4_SIO_IR_S3_TX_MT | IOC4_SIO_IR_S3_RX_FULL |
-         IOC4_SIO_IR_S3_RX_HIGH | IOC4_SIO_IR_S3_RX_TIMER |
-         IOC4_SIO_IR_S3_DELTA_DCD | IOC4_SIO_IR_S3_DELTA_CTS |
-         IOC4_SIO_IR_S3_INT | IOC4_SIO_IR_S3_TX_EXPLICIT),
-        IOC4_SIO_IR_S3, IOC4_GPPR_UART3_MODESEL_PIN,
-        }
-};
-
-/* A ring buffer entry */
-struct ring_entry {
-       union {
-               struct {
-                       uint32_t alldata;
-                       uint32_t allsc;
-               } all;
-               struct {
-                       char data[4];   /* data bytes */
-                       char sc[4];     /* status/control */
-               } s;
-       } u;
-};
-
-/* Test the valid bits in any of the 4 sc chars using "allsc" member */
-#define RING_ANY_VALID \
-       ((uint32_t)(IOC4_RXSB_MODEM_VALID | IOC4_RXSB_DATA_VALID) * 0x01010101)
-
-#define ring_sc     u.s.sc
-#define ring_data   u.s.data
-#define ring_allsc  u.all.allsc
-
-/* Number of entries per ring buffer. */
-#define ENTRIES_PER_RING (RING_BUF_SIZE / (int) sizeof(struct ring_entry))
-
-/* An individual ring */
-struct ring {
-       struct ring_entry entries[ENTRIES_PER_RING];
-};
-
-/* The whole enchilada */
-struct ring_buffer {
-       struct ring TX_0_OR_2;
-       struct ring RX_0_OR_2;
-       struct ring TX_1_OR_3;
-       struct ring RX_1_OR_3;
-};
-
-/* Get a ring from a port struct */
-#define RING(_p, _wh)  &(((struct ring_buffer *)((_p)->ip_cpu_ringbuf))->_wh)
-
-/* Infinite loop detection.
- */
-#define MAXITER 10000000
-
-/* Prototypes */
-static void receive_chars(struct uart_port *);
-static void handle_intr(void *arg, uint32_t sio_ir);
-
-/*
- * port_is_active - determines if this port is currently active
- * @port: ptr to soft struct for this port
- * @uart_port: uart port to test for
- */
-static inline int port_is_active(struct ioc4_port *port,
-               struct uart_port *uart_port)
-{
-       if (port) {
-               if ((port->ip_flags & PORT_ACTIVE)
-                                       && (port->ip_port == uart_port))
-                       return 1;
-       }
-       return 0;
-}
-
-
-/**
- * write_ireg - write the interrupt regs
- * @ioc4_soft: ptr to soft struct for this port
- * @val: value to write
- * @which: which register
- * @type: which ireg set
- */
-static inline void
-write_ireg(struct ioc4_soft *ioc4_soft, uint32_t val, int which, int type)
-{
-       struct ioc4_misc_regs __iomem *mem = ioc4_soft->is_ioc4_misc_addr;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ioc4_soft->is_ir_lock, flags);
-
-       switch (type) {
-       case IOC4_SIO_INTR_TYPE:
-               switch (which) {
-               case IOC4_W_IES:
-                       writel(val, &mem->sio_ies.raw);
-                       break;
-
-               case IOC4_W_IEC:
-                       writel(val, &mem->sio_iec.raw);
-                       break;
-               }
-               break;
-
-       case IOC4_OTHER_INTR_TYPE:
-               switch (which) {
-               case IOC4_W_IES:
-                       writel(val, &mem->other_ies.raw);
-                       break;
-
-               case IOC4_W_IEC:
-                       writel(val, &mem->other_iec.raw);
-                       break;
-               }
-               break;
-
-       default:
-               break;
-       }
-       spin_unlock_irqrestore(&ioc4_soft->is_ir_lock, flags);
-}
-
-/**
- * set_baud - Baud rate setting code
- * @port: port to set
- * @baud: baud rate to use
- */
-static int set_baud(struct ioc4_port *port, int baud)
-{
-       int actual_baud;
-       int diff;
-       int lcr;
-       unsigned short divisor;
-       struct ioc4_uartregs __iomem *uart;
-
-       divisor = SER_DIVISOR(baud, port->ip_pci_bus_speed);
-       if (!divisor)
-               return 1;
-       actual_baud = DIVISOR_TO_BAUD(divisor, port->ip_pci_bus_speed);
-
-       diff = actual_baud - baud;
-       if (diff < 0)
-               diff = -diff;
-
-       /* If we're within 1%, we've found a match */
-       if (diff * 100 > actual_baud)
-               return 1;
-
-       uart = port->ip_uart_regs;
-       lcr = readb(&uart->i4u_lcr);
-       writeb(lcr | UART_LCR_DLAB, &uart->i4u_lcr);
-       writeb((unsigned char)divisor, &uart->i4u_dll);
-       writeb((unsigned char)(divisor >> 8), &uart->i4u_dlm);
-       writeb(lcr, &uart->i4u_lcr);
-       return 0;
-}
-
-
-/**
- * get_ioc4_port - given a uart port, return the control structure
- * @port: uart port
- * @set: set this port as current
- */
-static struct ioc4_port *get_ioc4_port(struct uart_port *the_port, int set)
-{
-       struct ioc4_driver_data *idd = dev_get_drvdata(the_port->dev);
-       struct ioc4_control *control = idd->idd_serial_data;
-       struct ioc4_port *port;
-       int port_num, port_type;
-
-       if (control) {
-               for ( port_num = 0; port_num < IOC4_NUM_SERIAL_PORTS;
-                                                       port_num++ ) {
-                       port = control->ic_port[port_num].icp_port;
-                       if (!port)
-                               continue;
-                       for (port_type = UART_PORT_MIN;
-                                               port_type < UART_PORT_COUNT;
-                                               port_type++) {
-                               if (the_port == port->ip_all_ports
-                                                       [port_type]) {
-                                       /* set local copy */
-                                       if (set) {
-                                               port->ip_port = the_port;
-                                       }
-                                       return port;
-                               }
-                       }
-               }
-       }
-       return NULL;
-}
-
-/* The IOC4 hardware provides no atomic way to determine if interrupts
- * are pending since two reads are required to do so.  The handler must
- * read the SIO_IR and the SIO_IES, and take the logical and of the
- * two.  When this value is zero, all interrupts have been serviced and
- * the handler may return.
- *
- * This has the unfortunate "hole" that, if some other CPU or
- * some other thread or some higher level interrupt manages to
- * modify SIO_IE between our reads of SIO_IR and SIO_IE, we may
- * think we have observed SIO_IR&SIO_IE==0 when in fact this
- * condition never really occurred.
- *
- * To solve this, we use a simple spinlock that must be held
- * whenever modifying SIO_IE; holding this lock while observing
- * both SIO_IR and SIO_IE guarantees that we do not falsely
- * conclude that no enabled interrupts are pending.
- */
-
-static inline uint32_t
-pending_intrs(struct ioc4_soft *soft, int type)
-{
-       struct ioc4_misc_regs __iomem *mem = soft->is_ioc4_misc_addr;
-       unsigned long flag;
-       uint32_t intrs = 0;
-
-       BUG_ON(!((type == IOC4_SIO_INTR_TYPE)
-              || (type == IOC4_OTHER_INTR_TYPE)));
-
-       spin_lock_irqsave(&soft->is_ir_lock, flag);
-
-       switch (type) {
-       case IOC4_SIO_INTR_TYPE:
-               intrs = readl(&mem->sio_ir.raw) & readl(&mem->sio_ies.raw);
-               break;
-
-       case IOC4_OTHER_INTR_TYPE:
-               intrs = readl(&mem->other_ir.raw) & readl(&mem->other_ies.raw);
-
-               /* Don't process any ATA interrupte */
-               intrs &= ~(IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR);
-               break;
-
-       default:
-               break;
-       }
-       spin_unlock_irqrestore(&soft->is_ir_lock, flag);
-       return intrs;
-}
-
-/**
- * port_init - Initialize the sio and ioc4 hardware for a given port
- *                     called per port from attach...
- * @port: port to initialize
- */
-static inline int port_init(struct ioc4_port *port)
-{
-       uint32_t sio_cr;
-       struct hooks *hooks = port->ip_hooks;
-       struct ioc4_uartregs __iomem *uart;
-
-       /* Idle the IOC4 serial interface */
-       writel(IOC4_SSCR_RESET, &port->ip_serial_regs->sscr);
-
-       /* Wait until any pending bus activity for this port has ceased */
-       do
-               sio_cr = readl(&port->ip_mem->sio_cr.raw);
-       while (!(sio_cr & IOC4_SIO_CR_SIO_DIAG_IDLE));
-
-       /* Finish reset sequence */
-       writel(0, &port->ip_serial_regs->sscr);
-
-       /* Once RESET is done, reload cached tx_prod and rx_cons values
-        * and set rings to empty by making prod == cons
-        */
-       port->ip_tx_prod = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK;
-       writel(port->ip_tx_prod, &port->ip_serial_regs->stpir);
-       port->ip_rx_cons = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
-       writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir);
-
-       /* Disable interrupts for this 16550 */
-       uart = port->ip_uart_regs;
-       writeb(0, &uart->i4u_lcr);
-       writeb(0, &uart->i4u_ier);
-
-       /* Set the default baud */
-       set_baud(port, port->ip_baud);
-
-       /* Set line control to 8 bits no parity */
-       writeb(UART_LCR_WLEN8 | 0, &uart->i4u_lcr);
-                                       /* UART_LCR_STOP == 1 stop */
-
-       /* Enable the FIFOs */
-       writeb(UART_FCR_ENABLE_FIFO, &uart->i4u_fcr);
-       /* then reset 16550 FIFOs */
-       writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT,
-                       &uart->i4u_fcr);
-
-       /* Clear modem control register */
-       writeb(0, &uart->i4u_mcr);
-
-       /* Clear deltas in modem status register */
-       readb(&uart->i4u_msr);
-
-       /* Only do this once per port pair */
-       if (port->ip_hooks == &hooks_array[0]
-                           || port->ip_hooks == &hooks_array[2]) {
-               unsigned long ring_pci_addr;
-               uint32_t __iomem *sbbr_l;
-               uint32_t __iomem *sbbr_h;
-
-               if (port->ip_hooks == &hooks_array[0]) {
-                       sbbr_l = &port->ip_serial->sbbr01_l;
-                       sbbr_h = &port->ip_serial->sbbr01_h;
-               } else {
-                       sbbr_l = &port->ip_serial->sbbr23_l;
-                       sbbr_h = &port->ip_serial->sbbr23_h;
-               }
-
-               ring_pci_addr = (unsigned long __iomem)port->ip_dma_ringbuf;
-               DPRINT_CONFIG(("%s: ring_pci_addr 0x%lx\n",
-                                       __func__, ring_pci_addr));
-
-               writel((unsigned int)((uint64_t)ring_pci_addr >> 32), sbbr_h);
-               writel((unsigned int)ring_pci_addr | IOC4_BUF_SIZE_BIT, sbbr_l);
-       }
-
-       /* Set the receive timeout value to 10 msec */
-       writel(IOC4_SRTR_HZ / 100, &port->ip_serial_regs->srtr);
-
-       /* Set rx threshold, enable DMA */
-       /* Set high water mark at 3/4 of full ring */
-       port->ip_sscr = (ENTRIES_PER_RING * 3 / 4);
-       writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-
-       /* Disable and clear all serial related interrupt bits */
-       write_ireg(port->ip_ioc4_soft, hooks->intr_clear,
-                      IOC4_W_IEC, IOC4_SIO_INTR_TYPE);
-       port->ip_ienb &= ~hooks->intr_clear;
-       writel(hooks->intr_clear, &port->ip_mem->sio_ir.raw);
-       return 0;
-}
-
-/**
- * handle_dma_error_intr - service any pending DMA error interrupts for the
- *                     given port - 2nd level called via sd_intr
- * @arg: handler arg
- * @other_ir: ioc4regs
- */
-static void handle_dma_error_intr(void *arg, uint32_t other_ir)
-{
-       struct ioc4_port *port = (struct ioc4_port *)arg;
-       struct hooks *hooks = port->ip_hooks;
-       unsigned long flags;
-
-       spin_lock_irqsave(&port->ip_lock, flags);
-
-       /* ACK the interrupt */
-       writel(hooks->intr_dma_error, &port->ip_mem->other_ir.raw);
-
-       if (readl(&port->ip_mem->pci_err_addr_l.raw) & IOC4_PCI_ERR_ADDR_VLD) {
-               printk(KERN_ERR
-                       "PCI error address is 0x%llx, "
-                               "master is serial port %c %s\n",
-                    (((uint64_t)readl(&port->ip_mem->pci_err_addr_h)
-                                                        << 32)
-                               | readl(&port->ip_mem->pci_err_addr_l.raw))
-                                       & IOC4_PCI_ERR_ADDR_ADDR_MSK, '1' +
-                    ((char)(readl(&port->ip_mem->pci_err_addr_l.raw) &
-                            IOC4_PCI_ERR_ADDR_MST_NUM_MSK) >> 1),
-                    (readl(&port->ip_mem->pci_err_addr_l.raw)
-                               & IOC4_PCI_ERR_ADDR_MST_TYP_MSK)
-                               ? "RX" : "TX");
-
-               if (readl(&port->ip_mem->pci_err_addr_l.raw)
-                                               & IOC4_PCI_ERR_ADDR_MUL_ERR) {
-                       printk(KERN_ERR
-                               "Multiple errors occurred\n");
-               }
-       }
-       spin_unlock_irqrestore(&port->ip_lock, flags);
-
-       /* Re-enable DMA error interrupts */
-       write_ireg(port->ip_ioc4_soft, hooks->intr_dma_error, IOC4_W_IES,
-                                               IOC4_OTHER_INTR_TYPE);
-}
-
-/**
- * intr_connect - interrupt connect function
- * @soft: soft struct for this card
- * @type: interrupt type
- * @intrbits: bit pattern to set
- * @intr: handler function
- * @info: handler arg
- */
-static void
-intr_connect(struct ioc4_soft *soft, int type,
-                 uint32_t intrbits, ioc4_intr_func_f * intr, void *info)
-{
-       int i;
-       struct ioc4_intr_info *intr_ptr;
-
-       BUG_ON(!((type == IOC4_SIO_INTR_TYPE)
-              || (type == IOC4_OTHER_INTR_TYPE)));
-
-       i = atomic_inc_return(&soft-> is_intr_type[type].is_num_intrs) - 1;
-       BUG_ON(!(i < MAX_IOC4_INTR_ENTS || (printk("i %d\n", i), 0)));
-
-       /* Save off the lower level interrupt handler */
-       intr_ptr = &soft->is_intr_type[type].is_intr_info[i];
-       intr_ptr->sd_bits = intrbits;
-       intr_ptr->sd_intr = intr;
-       intr_ptr->sd_info = info;
-}
-
-/**
- * ioc4_intr - Top level IOC4 interrupt handler.
- * @irq: irq value
- * @arg: handler arg
- */
-
-static irqreturn_t ioc4_intr(int irq, void *arg)
-{
-       struct ioc4_soft *soft;
-       uint32_t this_ir, this_mir;
-       int xx, num_intrs = 0;
-       int intr_type;
-       int handled = 0;
-       struct ioc4_intr_info *intr_info;
-
-       soft = arg;
-       for (intr_type = 0; intr_type < IOC4_NUM_INTR_TYPES; intr_type++) {
-               num_intrs = (int)atomic_read(
-                               &soft->is_intr_type[intr_type].is_num_intrs);
-
-               this_mir = this_ir = pending_intrs(soft, intr_type);
-
-               /* Farm out the interrupt to the various drivers depending on
-                * which interrupt bits are set.
-                */
-               for (xx = 0; xx < num_intrs; xx++) {
-                       intr_info = &soft->is_intr_type[intr_type].is_intr_info[xx];
-                       this_mir = this_ir & intr_info->sd_bits;
-                       if (this_mir) {
-                               /* Disable owned interrupts, call handler */
-                               handled++;
-                               write_ireg(soft, intr_info->sd_bits, IOC4_W_IEC,
-                                                               intr_type);
-                               intr_info->sd_intr(intr_info->sd_info, this_mir);
-                               this_ir &= ~this_mir;
-                       }
-               }
-       }
-#ifdef DEBUG_INTERRUPTS
-       {
-               struct ioc4_misc_regs __iomem *mem = soft->is_ioc4_misc_addr;
-               unsigned long flag;
-
-               spin_lock_irqsave(&soft->is_ir_lock, flag);
-               printk ("%s : %d : mem 0x%p sio_ir 0x%x sio_ies 0x%x "
-                               "other_ir 0x%x other_ies 0x%x mask 0x%x\n",
-                    __func__, __LINE__,
-                    (void *)mem, readl(&mem->sio_ir.raw),
-                    readl(&mem->sio_ies.raw),
-                    readl(&mem->other_ir.raw),
-                    readl(&mem->other_ies.raw),
-                    IOC4_OTHER_IR_ATA_INT | IOC4_OTHER_IR_ATA_MEMERR);
-               spin_unlock_irqrestore(&soft->is_ir_lock, flag);
-       }
-#endif
-       return handled ? IRQ_HANDLED : IRQ_NONE;
-}
-
-/**
- * ioc4_attach_local - Device initialization.
- *                     Called at *_attach() time for each
- *                     IOC4 with serial ports in the system.
- * @idd: Master module data for this IOC4
- */
-static inline int ioc4_attach_local(struct ioc4_driver_data *idd)
-{
-       struct ioc4_port *port;
-       struct ioc4_port *ports[IOC4_NUM_SERIAL_PORTS];
-       int port_number;
-       uint16_t ioc4_revid_min = 62;
-       uint16_t ioc4_revid;
-       struct pci_dev *pdev = idd->idd_pdev;
-       struct ioc4_control* control = idd->idd_serial_data;
-       struct ioc4_soft *soft = control->ic_soft;
-       void __iomem *ioc4_misc = idd->idd_misc_regs;
-       void __iomem *ioc4_serial = soft->is_ioc4_serial_addr;
-
-       /* IOC4 firmware must be at least rev 62 */
-       pci_read_config_word(pdev, PCI_COMMAND_SPECIAL, &ioc4_revid);
-
-       printk(KERN_INFO "IOC4 firmware revision %d\n", ioc4_revid);
-       if (ioc4_revid < ioc4_revid_min) {
-               printk(KERN_WARNING
-                   "IOC4 serial not supported on firmware rev %d, "
-                               "please upgrade to rev %d or higher\n",
-                               ioc4_revid, ioc4_revid_min);
-               return -EPERM;
-       }
-       BUG_ON(ioc4_misc == NULL);
-       BUG_ON(ioc4_serial == NULL);
-
-       /* Create port structures for each port */
-       for (port_number = 0; port_number < IOC4_NUM_SERIAL_PORTS;
-                                                       port_number++) {
-               port = kzalloc(sizeof(struct ioc4_port), GFP_KERNEL);
-               if (!port) {
-                       printk(KERN_WARNING
-                               "IOC4 serial memory not available for port\n");
-                       goto free;
-               }
-               spin_lock_init(&port->ip_lock);
-
-               /* we need to remember the previous ones, to point back to
-                * them farther down - setting up the ring buffers.
-                */
-               ports[port_number] = port;
-
-               /* Allocate buffers and jumpstart the hardware.  */
-               control->ic_port[port_number].icp_port = port;
-               port->ip_ioc4_soft = soft;
-               port->ip_pdev = pdev;
-               port->ip_ienb = 0;
-               /* Use baud rate calculations based on detected PCI
-                * bus speed.  Simply test whether the PCI clock is
-                * running closer to 66MHz or 33MHz.
-                */
-               if (idd->count_period/IOC4_EXTINT_COUNT_DIVISOR < 20) {
-                       port->ip_pci_bus_speed = IOC4_SER_XIN_CLK_66;
-               } else {
-                       port->ip_pci_bus_speed = IOC4_SER_XIN_CLK_33;
-               }
-               port->ip_baud = 9600;
-               port->ip_control = control;
-               port->ip_mem = ioc4_misc;
-               port->ip_serial = ioc4_serial;
-
-               /* point to the right hook */
-               port->ip_hooks = &hooks_array[port_number];
-
-               /* Get direct hooks to the serial regs and uart regs
-                * for this port
-                */
-               switch (port_number) {
-               case 0:
-                       port->ip_serial_regs = &(port->ip_serial->port_0);
-                       port->ip_uart_regs = &(port->ip_serial->uart_0);
-                       break;
-               case 1:
-                       port->ip_serial_regs = &(port->ip_serial->port_1);
-                       port->ip_uart_regs = &(port->ip_serial->uart_1);
-                       break;
-               case 2:
-                       port->ip_serial_regs = &(port->ip_serial->port_2);
-                       port->ip_uart_regs = &(port->ip_serial->uart_2);
-                       break;
-               default:
-               case 3:
-                       port->ip_serial_regs = &(port->ip_serial->port_3);
-                       port->ip_uart_regs = &(port->ip_serial->uart_3);
-                       break;
-               }
-
-               /* ring buffers are 1 to a pair of ports */
-               if (port_number && (port_number & 1)) {
-                       /* odd use the evens buffer */
-                       port->ip_dma_ringbuf =
-                                       ports[port_number - 1]->ip_dma_ringbuf;
-                       port->ip_cpu_ringbuf =
-                                       ports[port_number - 1]->ip_cpu_ringbuf;
-                       port->ip_inring = RING(port, RX_1_OR_3);
-                       port->ip_outring = RING(port, TX_1_OR_3);
-
-               } else {
-                       if (port->ip_dma_ringbuf == 0) {
-                               port->ip_cpu_ringbuf = pci_alloc_consistent
-                                       (pdev, TOTAL_RING_BUF_SIZE,
-                                       &port->ip_dma_ringbuf);
-
-                       }
-                       BUG_ON(!((((int64_t)port->ip_dma_ringbuf) &
-                               (TOTAL_RING_BUF_SIZE - 1)) == 0));
-                       DPRINT_CONFIG(("%s : ip_cpu_ringbuf 0x%p "
-                                               "ip_dma_ringbuf 0x%p\n",
-                                       __func__,
-                                       (void *)port->ip_cpu_ringbuf,
-                                       (void *)port->ip_dma_ringbuf));
-                       port->ip_inring = RING(port, RX_0_OR_2);
-                       port->ip_outring = RING(port, TX_0_OR_2);
-               }
-               DPRINT_CONFIG(("%s : port %d [addr 0x%p] control 0x%p",
-                               __func__,
-                               port_number, (void *)port, (void *)control));
-               DPRINT_CONFIG((" ip_serial_regs 0x%p ip_uart_regs 0x%p\n",
-                               (void *)port->ip_serial_regs,
-                               (void *)port->ip_uart_regs));
-
-               /* Initialize the hardware for IOC4 */
-               port_init(port);
-
-               DPRINT_CONFIG(("%s: port_number %d port 0x%p inring 0x%p "
-                                               "outring 0x%p\n",
-                               __func__,
-                               port_number, (void *)port,
-                               (void *)port->ip_inring,
-                               (void *)port->ip_outring));
-
-               /* Attach interrupt handlers */
-               intr_connect(soft, IOC4_SIO_INTR_TYPE,
-                               GET_SIO_IR(port_number),
-                               handle_intr, port);
-
-               intr_connect(soft, IOC4_OTHER_INTR_TYPE,
-                               GET_OTHER_IR(port_number),
-                               handle_dma_error_intr, port);
-       }
-       return 0;
-
-free:
-       while (port_number)
-               kfree(ports[--port_number]);
-       return -ENOMEM;
-}
-
-/**
- * enable_intrs - enable interrupts
- * @port: port to enable
- * @mask: mask to use
- */
-static void enable_intrs(struct ioc4_port *port, uint32_t mask)
-{
-       struct hooks *hooks = port->ip_hooks;
-
-       if ((port->ip_ienb & mask) != mask) {
-               write_ireg(port->ip_ioc4_soft, mask, IOC4_W_IES,
-                                               IOC4_SIO_INTR_TYPE);
-               port->ip_ienb |= mask;
-       }
-
-       if (port->ip_ienb)
-               write_ireg(port->ip_ioc4_soft, hooks->intr_dma_error,
-                               IOC4_W_IES, IOC4_OTHER_INTR_TYPE);
-}
-
-/**
- * local_open - local open a port
- * @port: port to open
- */
-static inline int local_open(struct ioc4_port *port)
-{
-       int spiniter = 0;
-
-       port->ip_flags = PORT_ACTIVE;
-
-       /* Pause the DMA interface if necessary */
-       if (port->ip_sscr & IOC4_SSCR_DMA_EN) {
-               writel(port->ip_sscr | IOC4_SSCR_DMA_PAUSE,
-                       &port->ip_serial_regs->sscr);
-               while((readl(&port->ip_serial_regs-> sscr)
-                               & IOC4_SSCR_PAUSE_STATE) == 0) {
-                       spiniter++;
-                       if (spiniter > MAXITER) {
-                               port->ip_flags = PORT_INACTIVE;
-                               return -1;
-                       }
-               }
-       }
-
-       /* Reset the input fifo.  If the uart received chars while the port
-        * was closed and DMA is not enabled, the uart may have a bunch of
-        * chars hanging around in its rx fifo which will not be discarded
-        * by rclr in the upper layer. We must get rid of them here.
-        */
-       writeb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR,
-                               &port->ip_uart_regs->i4u_fcr);
-
-       writeb(UART_LCR_WLEN8, &port->ip_uart_regs->i4u_lcr);
-                                       /* UART_LCR_STOP == 1 stop */
-
-       /* Re-enable DMA, set default threshold to intr whenever there is
-        * data available.
-        */
-       port->ip_sscr &= ~IOC4_SSCR_RX_THRESHOLD;
-       port->ip_sscr |= 1;     /* default threshold */
-
-       /* Plug in the new sscr.  This implicitly clears the DMA_PAUSE
-        * flag if it was set above
-        */
-       writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-       port->ip_tx_lowat = 1;
-       return 0;
-}
-
-/**
- * set_rx_timeout - Set rx timeout and threshold values.
- * @port: port to use
- * @timeout: timeout value in ticks
- */
-static inline int set_rx_timeout(struct ioc4_port *port, int timeout)
-{
-       int threshold;
-
-       port->ip_rx_timeout = timeout;
-
-       /* Timeout is in ticks.  Let's figure out how many chars we
-        * can receive at the current baud rate in that interval
-        * and set the rx threshold to that amount.  There are 4 chars
-        * per ring entry, so we'll divide the number of chars that will
-        * arrive in timeout by 4.
-        * So .... timeout * baud / 10 / HZ / 4, with HZ = 100.
-        */
-       threshold = timeout * port->ip_baud / 4000;
-       if (threshold == 0)
-               threshold = 1;  /* otherwise we'll intr all the time! */
-
-       if ((unsigned)threshold > (unsigned)IOC4_SSCR_RX_THRESHOLD)
-               return 1;
-
-       port->ip_sscr &= ~IOC4_SSCR_RX_THRESHOLD;
-       port->ip_sscr |= threshold;
-
-       writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-
-       /* Now set the rx timeout to the given value
-        * again timeout * IOC4_SRTR_HZ / HZ
-        */
-       timeout = timeout * IOC4_SRTR_HZ / 100;
-       if (timeout > IOC4_SRTR_CNT)
-               timeout = IOC4_SRTR_CNT;
-
-       writel(timeout, &port->ip_serial_regs->srtr);
-       return 0;
-}
-
-/**
- * config_port - config the hardware
- * @port: port to config
- * @baud: baud rate for the port
- * @byte_size: data size
- * @stop_bits: number of stop bits
- * @parenb: parity enable ?
- * @parodd: odd parity ?
- */
-static inline int
-config_port(struct ioc4_port *port,
-           int baud, int byte_size, int stop_bits, int parenb, int parodd)
-{
-       char lcr, sizebits;
-       int spiniter = 0;
-
-       DPRINT_CONFIG(("%s: baud %d byte_size %d stop %d parenb %d parodd %d\n",
-               __func__, baud, byte_size, stop_bits, parenb, parodd));
-
-       if (set_baud(port, baud))
-               return 1;
-
-       switch (byte_size) {
-       case 5:
-               sizebits = UART_LCR_WLEN5;
-               break;
-       case 6:
-               sizebits = UART_LCR_WLEN6;
-               break;
-       case 7:
-               sizebits = UART_LCR_WLEN7;
-               break;
-       case 8:
-               sizebits = UART_LCR_WLEN8;
-               break;
-       default:
-               return 1;
-       }
-
-       /* Pause the DMA interface if necessary */
-       if (port->ip_sscr & IOC4_SSCR_DMA_EN) {
-               writel(port->ip_sscr | IOC4_SSCR_DMA_PAUSE,
-                       &port->ip_serial_regs->sscr);
-               while((readl(&port->ip_serial_regs->sscr)
-                                               & IOC4_SSCR_PAUSE_STATE) == 0) {
-                       spiniter++;
-                       if (spiniter > MAXITER)
-                               return -1;
-               }
-       }
-
-       /* Clear relevant fields in lcr */
-       lcr = readb(&port->ip_uart_regs->i4u_lcr);
-       lcr &= ~(LCR_MASK_BITS_CHAR | UART_LCR_EPAR |
-                UART_LCR_PARITY | LCR_MASK_STOP_BITS);
-
-       /* Set byte size in lcr */
-       lcr |= sizebits;
-
-       /* Set parity */
-       if (parenb) {
-               lcr |= UART_LCR_PARITY;
-               if (!parodd)
-                       lcr |= UART_LCR_EPAR;
-       }
-
-       /* Set stop bits */
-       if (stop_bits)
-               lcr |= UART_LCR_STOP /* 2 stop bits */ ;
-
-       writeb(lcr, &port->ip_uart_regs->i4u_lcr);
-
-       /* Re-enable the DMA interface if necessary */
-       if (port->ip_sscr & IOC4_SSCR_DMA_EN) {
-               writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-       }
-       port->ip_baud = baud;
-
-       /* When we get within this number of ring entries of filling the
-        * entire ring on tx, place an EXPLICIT intr to generate a lowat
-        * notification when output has drained.
-        */
-       port->ip_tx_lowat = (TX_LOWAT_CHARS(baud) + 3) / 4;
-       if (port->ip_tx_lowat == 0)
-               port->ip_tx_lowat = 1;
-
-       set_rx_timeout(port, 2);
-
-       return 0;
-}
-
-/**
- * do_write - Write bytes to the port.  Returns the number of bytes
- *                     actually written. Called from transmit_chars
- * @port: port to use
- * @buf: the stuff to write
- * @len: how many bytes in 'buf'
- */
-static inline int do_write(struct ioc4_port *port, char *buf, int len)
-{
-       int prod_ptr, cons_ptr, total = 0;
-       struct ring *outring;
-       struct ring_entry *entry;
-       struct hooks *hooks = port->ip_hooks;
-
-       BUG_ON(!(len >= 0));
-
-       prod_ptr = port->ip_tx_prod;
-       cons_ptr = readl(&port->ip_serial_regs->stcir) & PROD_CONS_MASK;
-       outring = port->ip_outring;
-
-       /* Maintain a 1-entry red-zone.  The ring buffer is full when
-        * (cons - prod) % ring_size is 1.  Rather than do this subtraction
-        * in the body of the loop, I'll do it now.
-        */
-       cons_ptr = (cons_ptr - (int)sizeof(struct ring_entry)) & PROD_CONS_MASK;
-
-       /* Stuff the bytes into the output */
-       while ((prod_ptr != cons_ptr) && (len > 0)) {
-               int xx;
-
-               /* Get 4 bytes (one ring entry) at a time */
-               entry = (struct ring_entry *)((caddr_t) outring + prod_ptr);
-
-               /* Invalidate all entries */
-               entry->ring_allsc = 0;
-
-               /* Copy in some bytes */
-               for (xx = 0; (xx < 4) && (len > 0); xx++) {
-                       entry->ring_data[xx] = *buf++;
-                       entry->ring_sc[xx] = IOC4_TXCB_VALID;
-                       len--;
-                       total++;
-               }
-
-               /* If we are within some small threshold of filling up the
-                * entire ring buffer, we must place an EXPLICIT intr here
-                * to generate a lowat interrupt in case we subsequently
-                * really do fill up the ring and the caller goes to sleep.
-                * No need to place more than one though.
-                */
-               if (!(port->ip_flags & LOWAT_WRITTEN) &&
-                       ((cons_ptr - prod_ptr) & PROD_CONS_MASK)
-                               <= port->ip_tx_lowat
-                                       * (int)sizeof(struct ring_entry)) {
-                       port->ip_flags |= LOWAT_WRITTEN;
-                       entry->ring_sc[0] |= IOC4_TXCB_INT_WHEN_DONE;
-               }
-
-               /* Go on to next entry */
-               prod_ptr += sizeof(struct ring_entry);
-               prod_ptr &= PROD_CONS_MASK;
-       }
-
-       /* If we sent something, start DMA if necessary */
-       if (total > 0 && !(port->ip_sscr & IOC4_SSCR_DMA_EN)) {
-               port->ip_sscr |= IOC4_SSCR_DMA_EN;
-               writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-       }
-
-       /* Store the new producer pointer.  If tx is disabled, we stuff the
-        * data into the ring buffer, but we don't actually start tx.
-        */
-       if (!uart_tx_stopped(port->ip_port)) {
-               writel(prod_ptr, &port->ip_serial_regs->stpir);
-
-               /* If we are now transmitting, enable tx_mt interrupt so we
-                * can disable DMA if necessary when the tx finishes.
-                */
-               if (total > 0)
-                       enable_intrs(port, hooks->intr_tx_mt);
-       }
-       port->ip_tx_prod = prod_ptr;
-       return total;
-}
-
-/**
- * disable_intrs - disable interrupts
- * @port: port to enable
- * @mask: mask to use
- */
-static void disable_intrs(struct ioc4_port *port, uint32_t mask)
-{
-       struct hooks *hooks = port->ip_hooks;
-
-       if (port->ip_ienb & mask) {
-               write_ireg(port->ip_ioc4_soft, mask, IOC4_W_IEC,
-                                       IOC4_SIO_INTR_TYPE);
-               port->ip_ienb &= ~mask;
-       }
-
-       if (!port->ip_ienb)
-               write_ireg(port->ip_ioc4_soft, hooks->intr_dma_error,
-                               IOC4_W_IEC, IOC4_OTHER_INTR_TYPE);
-}
-
-/**
- * set_notification - Modify event notification
- * @port: port to use
- * @mask: events mask
- * @set_on: set ?
- */
-static int set_notification(struct ioc4_port *port, int mask, int set_on)
-{
-       struct hooks *hooks = port->ip_hooks;
-       uint32_t intrbits, sscrbits;
-
-       BUG_ON(!mask);
-
-       intrbits = sscrbits = 0;
-
-       if (mask & N_DATA_READY)
-               intrbits |= (hooks->intr_rx_timer | hooks->intr_rx_high);
-       if (mask & N_OUTPUT_LOWAT)
-               intrbits |= hooks->intr_tx_explicit;
-       if (mask & N_DDCD) {
-               intrbits |= hooks->intr_delta_dcd;
-               sscrbits |= IOC4_SSCR_RX_RING_DCD;
-       }
-       if (mask & N_DCTS)
-               intrbits |= hooks->intr_delta_cts;
-
-       if (set_on) {
-               enable_intrs(port, intrbits);
-               port->ip_notify |= mask;
-               port->ip_sscr |= sscrbits;
-       } else {
-               disable_intrs(port, intrbits);
-               port->ip_notify &= ~mask;
-               port->ip_sscr &= ~sscrbits;
-       }
-
-       /* We require DMA if either DATA_READY or DDCD notification is
-        * currently requested. If neither of these is requested and
-        * there is currently no tx in progress, DMA may be disabled.
-        */
-       if (port->ip_notify & (N_DATA_READY | N_DDCD))
-               port->ip_sscr |= IOC4_SSCR_DMA_EN;
-       else if (!(port->ip_ienb & hooks->intr_tx_mt))
-               port->ip_sscr &= ~IOC4_SSCR_DMA_EN;
-
-       writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-       return 0;
-}
-
-/**
- * set_mcr - set the master control reg
- * @the_port: port to use
- * @mask1: mcr mask
- * @mask2: shadow mask
- */
-static inline int set_mcr(struct uart_port *the_port,
-               int mask1, int mask2)
-{
-       struct ioc4_port *port = get_ioc4_port(the_port, 0);
-       uint32_t shadow;
-       int spiniter = 0;
-       char mcr;
-
-       if (!port)
-               return -1;
-
-       /* Pause the DMA interface if necessary */
-       if (port->ip_sscr & IOC4_SSCR_DMA_EN) {
-               writel(port->ip_sscr | IOC4_SSCR_DMA_PAUSE,
-                       &port->ip_serial_regs->sscr);
-               while ((readl(&port->ip_serial_regs->sscr)
-                                       & IOC4_SSCR_PAUSE_STATE) == 0) {
-                       spiniter++;
-                       if (spiniter > MAXITER)
-                               return -1;
-               }
-       }
-       shadow = readl(&port->ip_serial_regs->shadow);
-       mcr = (shadow & 0xff000000) >> 24;
-
-       /* Set new value */
-       mcr |= mask1;
-       shadow |= mask2;
-
-       writeb(mcr, &port->ip_uart_regs->i4u_mcr);
-       writel(shadow, &port->ip_serial_regs->shadow);
-
-       /* Re-enable the DMA interface if necessary */
-       if (port->ip_sscr & IOC4_SSCR_DMA_EN) {
-               writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-       }
-       return 0;
-}
-
-/**
- * ioc4_set_proto - set the protocol for the port
- * @port: port to use
- * @proto: protocol to use
- */
-static int ioc4_set_proto(struct ioc4_port *port, int proto)
-{
-       struct hooks *hooks = port->ip_hooks;
-
-       switch (proto) {
-       case PROTO_RS232:
-               /* Clear the appropriate GIO pin */
-               writel(0, (&port->ip_mem->gppr[hooks->rs422_select_pin].raw));
-               break;
-
-       case PROTO_RS422:
-               /* Set the appropriate GIO pin */
-               writel(1, (&port->ip_mem->gppr[hooks->rs422_select_pin].raw));
-               break;
-
-       default:
-               return 1;
-       }
-       return 0;
-}
-
-/**
- * transmit_chars - upper level write, called with ip_lock
- * @the_port: port to write
- */
-static void transmit_chars(struct uart_port *the_port)
-{
-       int xmit_count, tail, head;
-       int result;
-       char *start;
-       struct tty_struct *tty;
-       struct ioc4_port *port = get_ioc4_port(the_port, 0);
-       struct uart_state *state;
-
-       if (!the_port)
-               return;
-       if (!port)
-               return;
-
-       state = the_port->state;
-       tty = state->port.tty;
-
-       if (uart_circ_empty(&state->xmit) || uart_tx_stopped(the_port)) {
-               /* Nothing to do or hw stopped */
-               set_notification(port, N_ALL_OUTPUT, 0);
-               return;
-       }
-
-       head = state->xmit.head;
-       tail = state->xmit.tail;
-       start = (char *)&state->xmit.buf[tail];
-
-       /* write out all the data or until the end of the buffer */
-       xmit_count = (head < tail) ? (UART_XMIT_SIZE - tail) : (head - tail);
-       if (xmit_count > 0) {
-               result = do_write(port, start, xmit_count);
-               if (result > 0) {
-                       /* booking */
-                       xmit_count -= result;
-                       the_port->icount.tx += result;
-                       /* advance the pointers */
-                       tail += result;
-                       tail &= UART_XMIT_SIZE - 1;
-                       state->xmit.tail = tail;
-                       start = (char *)&state->xmit.buf[tail];
-               }
-       }
-       if (uart_circ_chars_pending(&state->xmit) < WAKEUP_CHARS)
-               uart_write_wakeup(the_port);
-
-       if (uart_circ_empty(&state->xmit)) {
-               set_notification(port, N_OUTPUT_LOWAT, 0);
-       } else {
-               set_notification(port, N_OUTPUT_LOWAT, 1);
-       }
-}
-
-/**
- * ioc4_change_speed - change the speed of the port
- * @the_port: port to change
- * @new_termios: new termios settings
- * @old_termios: old termios settings
- */
-static void
-ioc4_change_speed(struct uart_port *the_port,
-                 struct ktermios *new_termios, struct ktermios *old_termios)
-{
-       struct ioc4_port *port = get_ioc4_port(the_port, 0);
-       int baud, bits;
-       unsigned cflag, iflag;
-       int new_parity = 0, new_parity_enable = 0, new_stop = 0, new_data = 8;
-       struct uart_state *state = the_port->state;
-
-       cflag = new_termios->c_cflag;
-       iflag = new_termios->c_iflag;
-
-       switch (cflag & CSIZE) {
-       case CS5:
-               new_data = 5;
-               bits = 7;
-               break;
-       case CS6:
-               new_data = 6;
-               bits = 8;
-               break;
-       case CS7:
-               new_data = 7;
-               bits = 9;
-               break;
-       case CS8:
-               new_data = 8;
-               bits = 10;
-               break;
-       default:
-               /* cuz we always need a default ... */
-               new_data = 5;
-               bits = 7;
-               break;
-       }
-       if (cflag & CSTOPB) {
-               bits++;
-               new_stop = 1;
-       }
-       if (cflag & PARENB) {
-               bits++;
-               new_parity_enable = 1;
-               if (cflag & PARODD)
-                       new_parity = 1;
-       }
-       baud = uart_get_baud_rate(the_port, new_termios, old_termios,
-                               MIN_BAUD_SUPPORTED, MAX_BAUD_SUPPORTED);
-       DPRINT_CONFIG(("%s: returned baud %d\n", __func__, baud));
-
-       /* default is 9600 */
-       if (!baud)
-               baud = 9600;
-
-       if (!the_port->fifosize)
-               the_port->fifosize = IOC4_FIFO_CHARS;
-       the_port->timeout = ((the_port->fifosize * HZ * bits) / (baud / 10));
-       the_port->timeout += HZ / 50;   /* Add .02 seconds of slop */
-
-       the_port->ignore_status_mask = N_ALL_INPUT;
-
-       state->port.low_latency = 1;
-
-       if (iflag & IGNPAR)
-               the_port->ignore_status_mask &= ~(N_PARITY_ERROR
-                                               | N_FRAMING_ERROR);
-       if (iflag & IGNBRK) {
-               the_port->ignore_status_mask &= ~N_BREAK;
-               if (iflag & IGNPAR)
-                       the_port->ignore_status_mask &= ~N_OVERRUN_ERROR;
-       }
-       if (!(cflag & CREAD)) {
-               /* ignore everything */
-               the_port->ignore_status_mask &= ~N_DATA_READY;
-       }
-
-       if (cflag & CRTSCTS) {
-               port->ip_sscr |= IOC4_SSCR_HFC_EN;
-       }
-       else {
-               port->ip_sscr &= ~IOC4_SSCR_HFC_EN;
-       }
-       writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-
-       /* Set the configuration and proper notification call */
-       DPRINT_CONFIG(("%s : port 0x%p cflag 0%o "
-               "config_port(baud %d data %d stop %d p enable %d parity %d),"
-               " notification 0x%x\n",
-            __func__, (void *)port, cflag, baud, new_data, new_stop,
-            new_parity_enable, new_parity, the_port->ignore_status_mask));
-
-       if ((config_port(port, baud,            /* baud */
-                        new_data,              /* byte size */
-                        new_stop,              /* stop bits */
-                        new_parity_enable,     /* set parity */
-                        new_parity)) >= 0) {   /* parity 1==odd */
-               set_notification(port, the_port->ignore_status_mask, 1);
-       }
-}
-
-/**
- * ic4_startup_local - Start up the serial port - returns >= 0 if no errors
- * @the_port: Port to operate on
- */
-static inline int ic4_startup_local(struct uart_port *the_port)
-{
-       struct ioc4_port *port;
-       struct uart_state *state;
-
-       if (!the_port)
-               return -1;
-
-       port = get_ioc4_port(the_port, 0);
-       if (!port)
-               return -1;
-
-       state = the_port->state;
-
-       local_open(port);
-
-       /* set the protocol - mapbase has the port type */
-       ioc4_set_proto(port, the_port->mapbase);
-
-       /* set the speed of the serial port */
-       ioc4_change_speed(the_port, &state->port.tty->termios,
-                         (struct ktermios *)0);
-
-       return 0;
-}
-
-/*
- * ioc4_cb_output_lowat - called when the output low water mark is hit
- * @the_port: port to output
- */
-static void ioc4_cb_output_lowat(struct uart_port *the_port)
-{
-       unsigned long pflags;
-
-       /* ip_lock is set on the call here */
-       if (the_port) {
-               spin_lock_irqsave(&the_port->lock, pflags);
-               transmit_chars(the_port);
-               spin_unlock_irqrestore(&the_port->lock, pflags);
-       }
-}
-
-/**
- * handle_intr - service any interrupts for the given port - 2nd level
- *                     called via sd_intr
- * @arg: handler arg
- * @sio_ir: ioc4regs
- */
-static void handle_intr(void *arg, uint32_t sio_ir)
-{
-       struct ioc4_port *port = (struct ioc4_port *)arg;
-       struct hooks *hooks = port->ip_hooks;
-       unsigned int rx_high_rd_aborted = 0;
-       unsigned long flags;
-       struct uart_port *the_port;
-       int loop_counter;
-
-       /* Possible race condition here: The tx_mt interrupt bit may be
-        * cleared without the intervention of the interrupt handler,
-        * e.g. by a write.  If the top level interrupt handler reads a
-        * tx_mt, then some other processor does a write, starting up
-        * output, then we come in here, see the tx_mt and stop DMA, the
-        * output started by the other processor will hang.  Thus we can
-        * only rely on tx_mt being legitimate if it is read while the
-        * port lock is held.  Therefore this bit must be ignored in the
-        * passed in interrupt mask which was read by the top level
-        * interrupt handler since the port lock was not held at the time
-        * it was read.  We can only rely on this bit being accurate if it
-        * is read while the port lock is held.  So we'll clear it for now,
-        * and reload it later once we have the port lock.
-        */
-       sio_ir &= ~(hooks->intr_tx_mt);
-
-       spin_lock_irqsave(&port->ip_lock, flags);
-
-       loop_counter = MAXITER; /* to avoid hangs */
-
-       do {
-               uint32_t shadow;
-
-               if ( loop_counter-- <= 0 ) {
-                       printk(KERN_WARNING "IOC4 serial: "
-                                       "possible hang condition/"
-                                       "port stuck on interrupt.\n");
-                       break;
-               }
-
-               /* Handle a DCD change */
-               if (sio_ir & hooks->intr_delta_dcd) {
-                       /* ACK the interrupt */
-                       writel(hooks->intr_delta_dcd,
-                               &port->ip_mem->sio_ir.raw);
-
-                       shadow = readl(&port->ip_serial_regs->shadow);
-
-                       if ((port->ip_notify & N_DDCD)
-                                       && (shadow & IOC4_SHADOW_DCD)
-                                       && (port->ip_port)) {
-                               the_port = port->ip_port;
-                               the_port->icount.dcd = 1;
-                               wake_up_interruptible
-                                           (&the_port->state->port.delta_msr_wait);
-                       } else if ((port->ip_notify & N_DDCD)
-                                       && !(shadow & IOC4_SHADOW_DCD)) {
-                               /* Flag delta DCD/no DCD */
-                               port->ip_flags |= DCD_ON;
-                       }
-               }
-
-               /* Handle a CTS change */
-               if (sio_ir & hooks->intr_delta_cts) {
-                       /* ACK the interrupt */
-                       writel(hooks->intr_delta_cts,
-                                       &port->ip_mem->sio_ir.raw);
-
-                       shadow = readl(&port->ip_serial_regs->shadow);
-
-                       if ((port->ip_notify & N_DCTS)
-                                       && (port->ip_port)) {
-                               the_port = port->ip_port;
-                               the_port->icount.cts =
-                                       (shadow & IOC4_SHADOW_CTS) ? 1 : 0;
-                               wake_up_interruptible
-                                       (&the_port->state->port.delta_msr_wait);
-                       }
-               }
-
-               /* rx timeout interrupt.  Must be some data available.  Put this
-                * before the check for rx_high since servicing this condition
-                * may cause that condition to clear.
-                */
-               if (sio_ir & hooks->intr_rx_timer) {
-                       /* ACK the interrupt */
-                       writel(hooks->intr_rx_timer,
-                               &port->ip_mem->sio_ir.raw);
-
-                       if ((port->ip_notify & N_DATA_READY)
-                                       && (port->ip_port)) {
-                               /* ip_lock is set on call here */
-                               receive_chars(port->ip_port);
-                       }
-               }
-
-               /* rx high interrupt. Must be after rx_timer.  */
-               else if (sio_ir & hooks->intr_rx_high) {
-                       /* Data available, notify upper layer */
-                       if ((port->ip_notify & N_DATA_READY)
-                                               && port->ip_port) {
-                               /* ip_lock is set on call here */
-                               receive_chars(port->ip_port);
-                       }
-
-                       /* We can't ACK this interrupt.  If receive_chars didn't
-                        * cause the condition to clear, we'll have to disable
-                        * the interrupt until the data is drained.
-                        * If the read was aborted, don't disable the interrupt
-                        * as this may cause us to hang indefinitely.  An
-                        * aborted read generally means that this interrupt
-                        * hasn't been delivered to the cpu yet anyway, even
-                        * though we see it as asserted when we read the sio_ir.
-                        */
-                       if ((sio_ir = PENDING(port)) & hooks->intr_rx_high) {
-                               if ((port->ip_flags & READ_ABORTED) == 0) {
-                                       port->ip_ienb &= ~hooks->intr_rx_high;
-                                       port->ip_flags |= INPUT_HIGH;
-                               } else {
-                                       rx_high_rd_aborted++;
-                               }
-                       }
-               }
-
-               /* We got a low water interrupt: notify upper layer to
-                * send more data.  Must come before tx_mt since servicing
-                * this condition may cause that condition to clear.
-                */
-               if (sio_ir & hooks->intr_tx_explicit) {
-                       port->ip_flags &= ~LOWAT_WRITTEN;
-
-                       /* ACK the interrupt */
-                       writel(hooks->intr_tx_explicit,
-                                       &port->ip_mem->sio_ir.raw);
-
-                       if (port->ip_notify & N_OUTPUT_LOWAT)
-                               ioc4_cb_output_lowat(port->ip_port);
-               }
-
-               /* Handle tx_mt.  Must come after tx_explicit.  */
-               else if (sio_ir & hooks->intr_tx_mt) {
-                       /* If we are expecting a lowat notification
-                        * and we get to this point it probably means that for
-                        * some reason the tx_explicit didn't work as expected
-                        * (that can legitimately happen if the output buffer is
-                        * filled up in just the right way).
-                        * So send the notification now.
-                        */
-                       if (port->ip_notify & N_OUTPUT_LOWAT) {
-                               ioc4_cb_output_lowat(port->ip_port);
-
-                               /* We need to reload the sio_ir since the lowat
-                                * call may have caused another write to occur,
-                                * clearing the tx_mt condition.
-                                */
-                               sio_ir = PENDING(port);
-                       }
-
-                       /* If the tx_mt condition still persists even after the
-                        * lowat call, we've got some work to do.
-                        */
-                       if (sio_ir & hooks->intr_tx_mt) {
-
-                               /* If we are not currently expecting DMA input,
-                                * and the transmitter has just gone idle,
-                                * there is no longer any reason for DMA, so
-                                * disable it.
-                                */
-                               if (!(port->ip_notify
-                                               & (N_DATA_READY | N_DDCD))) {
-                                       BUG_ON(!(port->ip_sscr
-                                                       & IOC4_SSCR_DMA_EN));
-                                       port->ip_sscr &= ~IOC4_SSCR_DMA_EN;
-                                       writel(port->ip_sscr,
-                                          &port->ip_serial_regs->sscr);
-                               }
-
-                               /* Prevent infinite tx_mt interrupt */
-                               port->ip_ienb &= ~hooks->intr_tx_mt;
-                       }
-               }
-               sio_ir = PENDING(port);
-
-               /* if the read was aborted and only hooks->intr_rx_high,
-                * clear hooks->intr_rx_high, so we do not loop forever.
-                */
-
-               if (rx_high_rd_aborted && (sio_ir == hooks->intr_rx_high)) {
-                       sio_ir &= ~hooks->intr_rx_high;
-               }
-       } while (sio_ir & hooks->intr_all);
-
-       spin_unlock_irqrestore(&port->ip_lock, flags);
-
-       /* Re-enable interrupts before returning from interrupt handler.
-        * Getting interrupted here is okay.  It'll just v() our semaphore, and
-        * we'll come through the loop again.
-        */
-
-       write_ireg(port->ip_ioc4_soft, port->ip_ienb, IOC4_W_IES,
-                                                       IOC4_SIO_INTR_TYPE);
-}
-
-/*
- * ioc4_cb_post_ncs - called for some basic errors
- * @port: port to use
- * @ncs: event
- */
-static void ioc4_cb_post_ncs(struct uart_port *the_port, int ncs)
-{
-       struct uart_icount *icount;
-
-       icount = &the_port->icount;
-
-       if (ncs & NCS_BREAK)
-               icount->brk++;
-       if (ncs & NCS_FRAMING)
-               icount->frame++;
-       if (ncs & NCS_OVERRUN)
-               icount->overrun++;
-       if (ncs & NCS_PARITY)
-               icount->parity++;
-}
-
-/**
- * do_read - Read in bytes from the port.  Return the number of bytes
- *                     actually read.
- * @the_port: port to use
- * @buf: place to put the stuff we read
- * @len: how big 'buf' is
- */
-
-static inline int do_read(struct uart_port *the_port, unsigned char *buf,
-                               int len)
-{
-       int prod_ptr, cons_ptr, total;
-       struct ioc4_port *port = get_ioc4_port(the_port, 0);
-       struct ring *inring;
-       struct ring_entry *entry;
-       struct hooks *hooks;
-       int byte_num;
-       char *sc;
-       int loop_counter;
-
-       BUG_ON(!(len >= 0));
-       BUG_ON(!port);
-       hooks = port->ip_hooks;
-
-       /* There is a nasty timing issue in the IOC4. When the rx_timer
-        * expires or the rx_high condition arises, we take an interrupt.
-        * At some point while servicing the interrupt, we read bytes from
-        * the ring buffer and re-arm the rx_timer.  However the rx_timer is
-        * not started until the first byte is received *after* it is armed,
-        * and any bytes pending in the rx construction buffers are not drained
-        * to memory until either there are 4 bytes available or the rx_timer
-        * expires.  This leads to a potential situation where data is left
-        * in the construction buffers forever - 1 to 3 bytes were received
-        * after the interrupt was generated but before the rx_timer was
-        * re-armed. At that point as long as no subsequent bytes are received
-        * the timer will never be started and the bytes will remain in the
-        * construction buffer forever.  The solution is to execute a DRAIN
-        * command after rearming the timer.  This way any bytes received before
-        * the DRAIN will be drained to memory, and any bytes received after
-        * the DRAIN will start the TIMER and be drained when it expires.
-        * Luckily, this only needs to be done when the DMA buffer is empty
-        * since there is no requirement that this function return all
-        * available data as long as it returns some.
-        */
-       /* Re-arm the timer */
-       writel(port->ip_rx_cons | IOC4_SRCIR_ARM, &port->ip_serial_regs->srcir);
-
-       prod_ptr = readl(&port->ip_serial_regs->srpir) & PROD_CONS_MASK;
-       cons_ptr = port->ip_rx_cons;
-
-       if (prod_ptr == cons_ptr) {
-               int reset_dma = 0;
-
-               /* Input buffer appears empty, do a flush. */
-
-               /* DMA must be enabled for this to work. */
-               if (!(port->ip_sscr & IOC4_SSCR_DMA_EN)) {
-                       port->ip_sscr |= IOC4_SSCR_DMA_EN;
-                       reset_dma = 1;
-               }
-
-               /* Potential race condition: we must reload the srpir after
-                * issuing the drain command, otherwise we could think the rx
-                * buffer is empty, then take a very long interrupt, and when
-                * we come back it's full and we wait forever for the drain to
-                * complete.
-                */
-               writel(port->ip_sscr | IOC4_SSCR_RX_DRAIN,
-                               &port->ip_serial_regs->sscr);
-               prod_ptr = readl(&port->ip_serial_regs->srpir)
-                               & PROD_CONS_MASK;
-
-               /* We must not wait for the DRAIN to complete unless there are
-                * at least 8 bytes (2 ring entries) available to receive the
-                * data otherwise the DRAIN will never complete and we'll
-                * deadlock here.
-                * In fact, to make things easier, I'll just ignore the flush if
-                * there is any data at all now available.
-                */
-               if (prod_ptr == cons_ptr) {
-                       loop_counter = 0;
-                       while (readl(&port->ip_serial_regs->sscr) &
-                                               IOC4_SSCR_RX_DRAIN) {
-                               loop_counter++;
-                               if (loop_counter > MAXITER)
-                                       return -1;
-                       }
-
-                       /* SIGH. We have to reload the prod_ptr *again* since
-                        * the drain may have caused it to change
-                        */
-                       prod_ptr = readl(&port->ip_serial_regs->srpir)
-                                                       & PROD_CONS_MASK;
-               }
-               if (reset_dma) {
-                       port->ip_sscr &= ~IOC4_SSCR_DMA_EN;
-                       writel(port->ip_sscr, &port->ip_serial_regs->sscr);
-               }
-       }
-       inring = port->ip_inring;
-       port->ip_flags &= ~READ_ABORTED;
-
-       total = 0;
-       loop_counter = 0xfffff; /* to avoid hangs */
-
-       /* Grab bytes from the hardware */
-       while ((prod_ptr != cons_ptr) && (len > 0)) {
-               entry = (struct ring_entry *)((caddr_t)inring + cons_ptr);
-
-               if ( loop_counter-- <= 0 ) {
-                       printk(KERN_WARNING "IOC4 serial: "
-                                       "possible hang condition/"
-                                       "port stuck on read.\n");
-                       break;
-               }
-
-               /* According to the producer pointer, this ring entry
-                * must contain some data.  But if the PIO happened faster
-                * than the DMA, the data may not be available yet, so let's
-                * wait until it arrives.
-                */
-               if ((entry->ring_allsc & RING_ANY_VALID) == 0) {
-                       /* Indicate the read is aborted so we don't disable
-                        * the interrupt thinking that the consumer is
-                        * congested.
-                        */
-                       port->ip_flags |= READ_ABORTED;
-                       len = 0;
-                       break;
-               }
-
-               /* Load the bytes/status out of the ring entry */
-               for (byte_num = 0; byte_num < 4 && len > 0; byte_num++) {
-                       sc = &(entry->ring_sc[byte_num]);
-
-                       /* Check for change in modem state or overrun */
-                       if ((*sc & IOC4_RXSB_MODEM_VALID)
-                                               && (port->ip_notify & N_DDCD)) {
-                               /* Notify upper layer if DCD dropped */
-
-                               if ((port->ip_flags & DCD_ON)
-                                               && !(*sc & IOC4_RXSB_DCD)) {
-
-                                       /* If we have already copied some data,
-                                        * return it.  We'll pick up the carrier
-                                        * drop on the next pass.  That way we
-                                        * don't throw away the data that has
-                                        * already been copied back to
-                                        * the caller's buffer.
-                                        */
-                                       if (total > 0) {
-                                               len = 0;
-                                               break;
-                                       }
-                                       port->ip_flags &= ~DCD_ON;
-
-                                       /* Turn off this notification so the
-                                        * carrier drop protocol won't see it
-                                        * again when it does a read.
-                                        */
-                                       *sc &= ~IOC4_RXSB_MODEM_VALID;
-
-                                       /* To keep things consistent, we need
-                                        * to update the consumer pointer so
-                                        * the next reader won't come in and
-                                        * try to read the same ring entries
-                                        * again. This must be done here before
-                                        * the dcd change.
-                                        */
-
-                                       if ((entry->ring_allsc & RING_ANY_VALID)
-                                                                       == 0) {
-                                               cons_ptr += (int)sizeof
-                                                       (struct ring_entry);
-                                               cons_ptr &= PROD_CONS_MASK;
-                                       }
-                                       writel(cons_ptr,
-                                               &port->ip_serial_regs->srcir);
-                                       port->ip_rx_cons = cons_ptr;
-
-                                       /* Notify upper layer of carrier drop */
-                                       if ((port->ip_notify & N_DDCD)
-                                                  && port->ip_port) {
-                                               the_port->icount.dcd = 0;
-                                               wake_up_interruptible
-                                                   (&the_port->state->
-                                                       port.delta_msr_wait);
-                                       }
-
-                                       /* If we had any data to return, we
-                                        * would have returned it above.
-                                        */
-                                       return 0;
-                               }
-                       }
-                       if (*sc & IOC4_RXSB_MODEM_VALID) {
-                               /* Notify that an input overrun occurred */
-                               if ((*sc & IOC4_RXSB_OVERRUN)
-                                   && (port->ip_notify & N_OVERRUN_ERROR)) {
-                                       ioc4_cb_post_ncs(the_port, NCS_OVERRUN);
-                               }
-                               /* Don't look at this byte again */
-                               *sc &= ~IOC4_RXSB_MODEM_VALID;
-                       }
-
-                       /* Check for valid data or RX errors */
-                       if ((*sc & IOC4_RXSB_DATA_VALID) &&
-                                       ((*sc & (IOC4_RXSB_PAR_ERR
-                                                       | IOC4_RXSB_FRAME_ERR
-                                                       | IOC4_RXSB_BREAK))
-                                       && (port->ip_notify & (N_PARITY_ERROR
-                                                       | N_FRAMING_ERROR
-                                                       | N_BREAK)))) {
-                               /* There is an error condition on the next byte.
-                                * If we have already transferred some bytes,
-                                * we'll stop here. Otherwise if this is the
-                                * first byte to be read, we'll just transfer
-                                * it alone after notifying the
-                                * upper layer of its status.
-                                */
-                               if (total > 0) {
-                                       len = 0;
-                                       break;
-                               } else {
-                                       if ((*sc & IOC4_RXSB_PAR_ERR) &&
-                                          (port->ip_notify & N_PARITY_ERROR)) {
-                                               ioc4_cb_post_ncs(the_port,
-                                                               NCS_PARITY);
-                                       }
-                                       if ((*sc & IOC4_RXSB_FRAME_ERR) &&
-                                          (port->ip_notify & N_FRAMING_ERROR)){
-                                               ioc4_cb_post_ncs(the_port,
-                                                               NCS_FRAMING);
-                                       }
-                                       if ((*sc & IOC4_RXSB_BREAK)
-                                           && (port->ip_notify & N_BREAK)) {
-                                                       ioc4_cb_post_ncs
-                                                                   (the_port,
-                                                                    NCS_BREAK);
-                                       }
-                                       len = 1;
-                               }
-                       }
-                       if (*sc & IOC4_RXSB_DATA_VALID) {
-                               *sc &= ~IOC4_RXSB_DATA_VALID;
-                               *buf = entry->ring_data[byte_num];
-                               buf++;
-                               len--;
-                               total++;
-                       }
-               }
-
-               /* If we used up this entry entirely, go on to the next one,
-                * otherwise we must have run out of buffer space, so
-                * leave the consumer pointer here for the next read in case
-                * there are still unread bytes in this entry.
-                */
-               if ((entry->ring_allsc & RING_ANY_VALID) == 0) {
-                       cons_ptr += (int)sizeof(struct ring_entry);
-                       cons_ptr &= PROD_CONS_MASK;
-               }
-       }
-
-       /* Update consumer pointer and re-arm rx timer interrupt */
-       writel(cons_ptr, &port->ip_serial_regs->srcir);
-       port->ip_rx_cons = cons_ptr;
-
-       /* If we have now dipped below the rx high water mark and we have
-        * rx_high interrupt turned off, we can now turn it back on again.
-        */
-       if ((port->ip_flags & INPUT_HIGH) && (((prod_ptr - cons_ptr)
-                       & PROD_CONS_MASK) < ((port->ip_sscr &
-                               IOC4_SSCR_RX_THRESHOLD)
-                                       << IOC4_PROD_CONS_PTR_OFF))) {
-               port->ip_flags &= ~INPUT_HIGH;
-               enable_intrs(port, hooks->intr_rx_high);
-       }
-       return total;
-}
-
-/**
- * receive_chars - upper level read. Called with ip_lock.
- * @the_port: port to read from
- */
-static void receive_chars(struct uart_port *the_port)
-{
-       unsigned char ch[IOC4_MAX_CHARS];
-       int read_count, request_count = IOC4_MAX_CHARS;
-       struct uart_icount *icount;
-       struct uart_state *state = the_port->state;
-       unsigned long pflags;
-
-       /* Make sure all the pointers are "good" ones */
-       if (!state)
-               return;
-
-       spin_lock_irqsave(&the_port->lock, pflags);
-
-       request_count = tty_buffer_request_room(&state->port, IOC4_MAX_CHARS);
-
-       if (request_count > 0) {
-               icount = &the_port->icount;
-               read_count = do_read(the_port, ch, request_count);
-               if (read_count > 0) {
-                       tty_insert_flip_string(&state->port, ch, read_count);
-                       icount->rx += read_count;
-               }
-       }
-
-       spin_unlock_irqrestore(&the_port->lock, pflags);
-
-       tty_flip_buffer_push(&state->port);
-}
-
-/**
- * ic4_type - What type of console are we?
- * @port: Port to operate with (we ignore since we only have one port)
- *
- */
-static const char *ic4_type(struct uart_port *the_port)
-{
-       if (the_port->mapbase == PROTO_RS232)
-               return "SGI IOC4 Serial [rs232]";
-       else
-               return "SGI IOC4 Serial [rs422]";
-}
-
-/**
- * ic4_tx_empty - Is the transmitter empty?
- * @port: Port to operate on
- *
- */
-static unsigned int ic4_tx_empty(struct uart_port *the_port)
-{
-       struct ioc4_port *port = get_ioc4_port(the_port, 0);
-       unsigned int ret = 0;
-
-       if (port_is_active(port, the_port)) {
-               if (readl(&port->ip_serial_regs->shadow) & IOC4_SHADOW_TEMT)
-                       ret = TIOCSER_TEMT;
-       }
-       return ret;
-}
-
-/**
- * ic4_stop_tx - stop the transmitter
- * @port: Port to operate on
- *
- */
-static void ic4_stop_tx(struct uart_port *the_port)
-{
-       struct ioc4_port *port = get_ioc4_port(the_port, 0);
-
-       if (port_is_active(port, the_port))
-               set_notification(port, N_OUTPUT_LOWAT, 0);
-}
-
-/**
- * null_void_function -
- * @port: Port to operate on
- *
- */
-static void null_void_function(struct uart_port *the_port)
-{
-}
-
-/**
- * ic4_shutdown - shut down the port - free irq and disable
- * @port: Port to shut down
- *
- */
-static void ic4_shutdown(struct uart_port *the_port)
-{
-       unsigned long port_flags;
-       struct ioc4_port *port;
-       struct uart_state *state;
-
-       port = get_ioc4_port(the_port, 0);
-       if (!port)
-               return;
-
-       state = the_port->state;
-       port->ip_port = NULL;
-
-       wake_up_interruptible(&state->port.delta_msr_wait);
-
-       if (state->port.tty)
-               set_bit(TTY_IO_ERROR, &state->port.tty->flags);
-
-       spin_lock_irqsave(&the_port->lock, port_flags);
-       set_notification(port, N_ALL, 0);
-       port->ip_flags = PORT_INACTIVE;
-       spin_unlock_irqrestore(&the_port->lock, port_flags);
-}
-
-/**
- * ic4_set_mctrl - set control lines (dtr, rts, etc)
- * @port: Port to operate on
- * @mctrl: Lines to set/unset
- *
- */
-static void ic4_set_mctrl(struct uart_port *the_port, unsigned int mctrl)
-{
-       unsigned char mcr = 0;
-       struct ioc4_port *port;
-
-       port = get_ioc4_port(the_port, 0);
-       if (!port_is_active(port, the_port))
-               return;
-
-       if (mctrl & TIOCM_RTS)
-               mcr |= UART_MCR_RTS;
-       if (mctrl & TIOCM_DTR)
-               mcr |= UART_MCR_DTR;
-       if (mctrl & TIOCM_OUT1)
-               mcr |= UART_MCR_OUT1;
-       if (mctrl & TIOCM_OUT2)
-               mcr |= UART_MCR_OUT2;
-       if (mctrl & TIOCM_LOOP)
-               mcr |= UART_MCR_LOOP;
-
-       set_mcr(the_port, mcr, IOC4_SHADOW_DTR);
-}
-
-/**
- * ic4_get_mctrl - get control line info
- * @port: port to operate on
- *
- */
-static unsigned int ic4_get_mctrl(struct uart_port *the_port)
-{
-       struct ioc4_port *port = get_ioc4_port(the_port, 0);
-       uint32_t shadow;
-       unsigned int ret = 0;
-
-       if (!port_is_active(port, the_port))
-               return 0;
-
-       shadow = readl(&port->ip_serial_regs->shadow);
-       if (shadow & IOC4_SHADOW_DCD)
-               ret |= TIOCM_CAR;
-       if (shadow & IOC4_SHADOW_DR)
-               ret |= TIOCM_DSR;
-       if (shadow & IOC4_SHADOW_CTS)
-               ret |= TIOCM_CTS;
-       return ret;
-}
-
-/**
- * ic4_start_tx - Start transmitter, flush any output
- * @port: Port to operate on
- *
- */
-static void ic4_start_tx(struct uart_port *the_port)
-{
-       struct ioc4_port *port = get_ioc4_port(the_port, 0);
-
-       if (port_is_active(port, the_port)) {
-               set_notification(port, N_OUTPUT_LOWAT, 1);
-               enable_intrs(port, port->ip_hooks->intr_tx_mt);
-       }
-}
-
-/**
- * ic4_break_ctl - handle breaks
- * @port: Port to operate on
- * @break_state: Break state
- *
- */
-static void ic4_break_ctl(struct uart_port *the_port, int break_state)
-{
-}
-
-/**
- * ic4_startup - Start up the serial port
- * @port: Port to operate on
- *
- */
-static int ic4_startup(struct uart_port *the_port)
-{
-       int retval;
-       struct ioc4_port *port;
-       struct ioc4_control *control;
-       struct uart_state *state;
-       unsigned long port_flags;
-
-       if (!the_port)
-               return -ENODEV;
-       port = get_ioc4_port(the_port, 1);
-       if (!port)
-               return -ENODEV;
-       state = the_port->state;
-
-       control = port->ip_control;
-       if (!control) {
-               port->ip_port = NULL;
-               return -ENODEV;
-       }
-
-       /* Start up the serial port */
-       spin_lock_irqsave(&the_port->lock, port_flags);
-       retval = ic4_startup_local(the_port);
-       spin_unlock_irqrestore(&the_port->lock, port_flags);
-       return retval;
-}
-
-/**
- * ic4_set_termios - set termios stuff
- * @port: port to operate on
- * @termios: New settings
- * @termios: Old
- *
- */
-static void
-ic4_set_termios(struct uart_port *the_port,
-               struct ktermios *termios, struct ktermios *old_termios)
-{
-       unsigned long port_flags;
-
-       spin_lock_irqsave(&the_port->lock, port_flags);
-       ioc4_change_speed(the_port, termios, old_termios);
-       spin_unlock_irqrestore(&the_port->lock, port_flags);
-}
-
-/**
- * ic4_request_port - allocate resources for port - no op....
- * @port: port to operate on
- *
- */
-static int ic4_request_port(struct uart_port *port)
-{
-       return 0;
-}
-
-/* Associate the uart functions above - given to serial core */
-
-static const struct uart_ops ioc4_ops = {
-       .tx_empty       = ic4_tx_empty,
-       .set_mctrl      = ic4_set_mctrl,
-       .get_mctrl      = ic4_get_mctrl,
-       .stop_tx        = ic4_stop_tx,
-       .start_tx       = ic4_start_tx,
-       .stop_rx        = null_void_function,
-       .break_ctl      = ic4_break_ctl,
-       .startup        = ic4_startup,
-       .shutdown       = ic4_shutdown,
-       .set_termios    = ic4_set_termios,
-       .type           = ic4_type,
-       .release_port   = null_void_function,
-       .request_port   = ic4_request_port,
-};
-
-/*
- * Boot-time initialization code
- */
-
-static struct uart_driver ioc4_uart_rs232 = {
-       .owner          = THIS_MODULE,
-       .driver_name    = "ioc4_serial_rs232",
-       .dev_name       = DEVICE_NAME_RS232,
-       .major          = DEVICE_MAJOR,
-       .minor          = DEVICE_MINOR_RS232,
-       .nr             = IOC4_NUM_CARDS * IOC4_NUM_SERIAL_PORTS,
-};
-
-static struct uart_driver ioc4_uart_rs422 = {
-       .owner          = THIS_MODULE,
-       .driver_name    = "ioc4_serial_rs422",
-       .dev_name       = DEVICE_NAME_RS422,
-       .major          = DEVICE_MAJOR,
-       .minor          = DEVICE_MINOR_RS422,
-       .nr             = IOC4_NUM_CARDS * IOC4_NUM_SERIAL_PORTS,
-};
-
-
-/**
- * ioc4_serial_remove_one - detach function
- *
- * @idd: IOC4 master module data for this IOC4
- */
-
-static int ioc4_serial_remove_one(struct ioc4_driver_data *idd)
-{
-       int port_num, port_type;
-       struct ioc4_control *control;
-       struct uart_port *the_port;
-       struct ioc4_port *port;
-       struct ioc4_soft *soft;
-
-       /* If serial driver did not attach, don't try to detach */
-       control = idd->idd_serial_data;
-       if (!control)
-               return 0;
-
-       for (port_num = 0; port_num < IOC4_NUM_SERIAL_PORTS; port_num++) {
-               for (port_type = UART_PORT_MIN;
-                                       port_type < UART_PORT_COUNT;
-                                       port_type++) {
-                       the_port = &control->ic_port[port_num].icp_uart_port
-                                                       [port_type];
-                       if (the_port) {
-                               switch (port_type) {
-                               case UART_PORT_RS422:
-                                       uart_remove_one_port(&ioc4_uart_rs422,
-                                                       the_port);
-                                       break;
-                               default:
-                               case UART_PORT_RS232:
-                                       uart_remove_one_port(&ioc4_uart_rs232,
-                                                       the_port);
-                                       break;
-                               }
-                       }
-               }
-               port = control->ic_port[port_num].icp_port;
-               /* we allocate in pairs */
-               if (!(port_num & 1) && port) {
-                       pci_free_consistent(port->ip_pdev,
-                                       TOTAL_RING_BUF_SIZE,
-                                       port->ip_cpu_ringbuf,
-                                       port->ip_dma_ringbuf);
-                       kfree(port);
-               }
-       }
-       soft = control->ic_soft;
-       if (soft) {
-               free_irq(control->ic_irq, soft);
-               if (soft->is_ioc4_serial_addr) {
-                       iounmap(soft->is_ioc4_serial_addr);
-                       release_mem_region((unsigned long)
-                            soft->is_ioc4_serial_addr,
-                               sizeof(struct ioc4_serial));
-               }
-               kfree(soft);
-       }
-       kfree(control);
-       idd->idd_serial_data = NULL;
-
-       return 0;
-}
-
-
-/**
- * ioc4_serial_core_attach_rs232 - register with serial core
- *             This is done during pci probing
- * @pdev: handle for this card
- */
-static inline int
-ioc4_serial_core_attach(struct pci_dev *pdev, int port_type)
-{
-       struct ioc4_port *port;
-       struct uart_port *the_port;
-       struct ioc4_driver_data *idd = pci_get_drvdata(pdev);
-       struct ioc4_control *control = idd->idd_serial_data;
-       int port_num;
-       int port_type_idx;
-       struct uart_driver *u_driver;
-
-
-       DPRINT_CONFIG(("%s: attach pdev 0x%p - control 0x%p\n",
-                       __func__, pdev, (void *)control));
-
-       if (!control)
-               return -ENODEV;
-
-       port_type_idx = (port_type == PROTO_RS232) ? UART_PORT_RS232
-                                               : UART_PORT_RS422;
-
-       u_driver = (port_type == PROTO_RS232)   ? &ioc4_uart_rs232
-                                               : &ioc4_uart_rs422;
-
-       /* once around for each port on this card */
-       for (port_num = 0; port_num < IOC4_NUM_SERIAL_PORTS; port_num++) {
-               the_port = &control->ic_port[port_num].icp_uart_port
-                                                       [port_type_idx];
-               port = control->ic_port[port_num].icp_port;
-               port->ip_all_ports[port_type_idx] = the_port;
-
-               DPRINT_CONFIG(("%s: attach the_port 0x%p / port 0x%p : type %s\n",
-                               __func__, (void *)the_port,
-                               (void *)port,
-                               port_type == PROTO_RS232 ? "rs232" : "rs422"));
-
-               /* membase, iobase and mapbase just need to be non-0 */
-               the_port->membase = (unsigned char __iomem *)1;
-               the_port->iobase = (pdev->bus->number << 16) |  port_num;
-               the_port->line = (Num_of_ioc4_cards << 2) | port_num;
-               the_port->mapbase = port_type;
-               the_port->type = PORT_16550A;
-               the_port->fifosize = IOC4_FIFO_CHARS;
-               the_port->ops = &ioc4_ops;
-               the_port->irq = control->ic_irq;
-               the_port->dev = &pdev->dev;
-               spin_lock_init(&the_port->lock);
-               if (uart_add_one_port(u_driver, the_port) < 0) {
-                       printk(KERN_WARNING
-                          "%s: unable to add port %d bus %d\n",
-                              __func__, the_port->line, pdev->bus->number);
-               } else {
-                       DPRINT_CONFIG(
-                           ("IOC4 serial port %d irq = %d, bus %d\n",
-                              the_port->line, the_port->irq, pdev->bus->number));
-               }
-       }
-       return 0;
-}
-
-/**
- * ioc4_serial_attach_one - register attach function
- *             called per card found from IOC4 master module.
- * @idd: Master module data for this IOC4
- */
-static int
-ioc4_serial_attach_one(struct ioc4_driver_data *idd)
-{
-       unsigned long tmp_addr1;
-       struct ioc4_serial __iomem *serial;
-       struct ioc4_soft *soft;
-       struct ioc4_control *control;
-       int ret = 0;
-
-
-       DPRINT_CONFIG(("%s (0x%p, 0x%p)\n", __func__, idd->idd_pdev,
-                                                       idd->idd_pci_id));
-
-       /* PCI-RT does not bring out serial connections.
-        * Do not attach to this particular IOC4.
-        */
-       if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
-               return 0;
-
-       /* request serial registers */
-       tmp_addr1 = idd->idd_bar0 + IOC4_SERIAL_OFFSET;
-
-       if (!request_mem_region(tmp_addr1, sizeof(struct ioc4_serial),
-                                       "sioc4_uart")) {
-               printk(KERN_WARNING
-                       "ioc4 (%p): unable to get request region for "
-                               "uart space\n", (void *)idd->idd_pdev);
-               ret = -ENODEV;
-               goto out1;
-       }
-       serial = ioremap(tmp_addr1, sizeof(struct ioc4_serial));
-       if (!serial) {
-               printk(KERN_WARNING
-                        "ioc4 (%p) : unable to remap ioc4 serial register\n",
-                               (void *)idd->idd_pdev);
-               ret = -ENODEV;
-               goto out2;
-       }
-       DPRINT_CONFIG(("%s : mem 0x%p, serial 0x%p\n",
-                               __func__, (void *)idd->idd_misc_regs,
-                               (void *)serial));
-
-       /* Get memory for the new card */
-       control = kzalloc(sizeof(struct ioc4_control), GFP_KERNEL);
-
-       if (!control) {
-               printk(KERN_WARNING "ioc4_attach_one"
-                      ": unable to get memory for the IOC4\n");
-               ret = -ENOMEM;
-               goto out2;
-       }
-       idd->idd_serial_data = control;
-
-       /* Allocate the soft structure */
-       soft = kzalloc(sizeof(struct ioc4_soft), GFP_KERNEL);
-       if (!soft) {
-               printk(KERN_WARNING
-                      "ioc4 (%p): unable to get memory for the soft struct\n",
-                      (void *)idd->idd_pdev);
-               ret = -ENOMEM;
-               goto out3;
-       }
-
-       spin_lock_init(&soft->is_ir_lock);
-       soft->is_ioc4_misc_addr = idd->idd_misc_regs;
-       soft->is_ioc4_serial_addr = serial;
-
-       /* Init the IOC4 */
-       writel(0xf << IOC4_SIO_CR_CMD_PULSE_SHIFT,
-              &idd->idd_misc_regs->sio_cr.raw);
-
-       /* Enable serial port mode select generic PIO pins as outputs */
-       writel(IOC4_GPCR_UART0_MODESEL | IOC4_GPCR_UART1_MODESEL
-               | IOC4_GPCR_UART2_MODESEL | IOC4_GPCR_UART3_MODESEL,
-               &idd->idd_misc_regs->gpcr_s.raw);
-
-       /* Clear and disable all serial interrupts */
-       write_ireg(soft, ~0, IOC4_W_IEC, IOC4_SIO_INTR_TYPE);
-       writel(~0, &idd->idd_misc_regs->sio_ir.raw);
-       write_ireg(soft, IOC4_OTHER_IR_SER_MEMERR, IOC4_W_IEC,
-                  IOC4_OTHER_INTR_TYPE);
-       writel(IOC4_OTHER_IR_SER_MEMERR, &idd->idd_misc_regs->other_ir.raw);
-       control->ic_soft = soft;
-
-       /* Hook up interrupt handler */
-       if (!request_irq(idd->idd_pdev->irq, ioc4_intr, IRQF_SHARED,
-                               "sgi-ioc4serial", soft)) {
-               control->ic_irq = idd->idd_pdev->irq;
-       } else {
-               printk(KERN_WARNING
-                   "%s : request_irq fails for IRQ 0x%x\n ",
-                       __func__, idd->idd_pdev->irq);
-       }
-       ret = ioc4_attach_local(idd);
-       if (ret)
-               goto out4;
-
-       /* register port with the serial core - 1 rs232, 1 rs422 */
-
-       ret = ioc4_serial_core_attach(idd->idd_pdev, PROTO_RS232);
-       if (ret)
-               goto out4;
-
-       ret = ioc4_serial_core_attach(idd->idd_pdev, PROTO_RS422);
-       if (ret)
-               goto out5;
-
-       Num_of_ioc4_cards++;
-
-       return ret;
-
-       /* error exits that give back resources */
-out5:
-       ioc4_serial_remove_one(idd);
-       return ret;
-out4:
-       kfree(soft);
-out3:
-       kfree(control);
-out2:
-       if (serial)
-               iounmap(serial);
-       release_mem_region(tmp_addr1, sizeof(struct ioc4_serial));
-out1:
-
-       return ret;
-}
-
-
-static struct ioc4_submodule ioc4_serial_submodule = {
-       .is_name = "IOC4_serial",
-       .is_owner = THIS_MODULE,
-       .is_probe = ioc4_serial_attach_one,
-       .is_remove = ioc4_serial_remove_one,
-};
-
-/**
- * ioc4_serial_init - module init
- */
-static int __init ioc4_serial_init(void)
-{
-       int ret;
-
-       /* register with serial core */
-       if ((ret = uart_register_driver(&ioc4_uart_rs232)) < 0) {
-               printk(KERN_WARNING
-                       "%s: Couldn't register rs232 IOC4 serial driver\n",
-                       __func__);
-               goto out;
-       }
-       if ((ret = uart_register_driver(&ioc4_uart_rs422)) < 0) {
-               printk(KERN_WARNING
-                       "%s: Couldn't register rs422 IOC4 serial driver\n",
-                       __func__);
-               goto out_uart_rs232;
-       }
-
-       /* register with IOC4 main module */
-       ret = ioc4_register_submodule(&ioc4_serial_submodule);
-       if (ret)
-               goto out_uart_rs422;
-       return 0;
-
-out_uart_rs422:
-       uart_unregister_driver(&ioc4_uart_rs422);
-out_uart_rs232:
-       uart_unregister_driver(&ioc4_uart_rs232);
-out:
-       return ret;
-}
-
-static void __exit ioc4_serial_exit(void)
-{
-       ioc4_unregister_submodule(&ioc4_serial_submodule);
-       uart_unregister_driver(&ioc4_uart_rs232);
-       uart_unregister_driver(&ioc4_uart_rs422);
-}
-
-late_initcall(ioc4_serial_init); /* Call only after tty init is done */
-module_exit(ioc4_serial_exit);
-
-MODULE_AUTHOR("Pat Gefre - Silicon Graphics Inc. (SGI) <pfg@sgi.com>");
-MODULE_DESCRIPTION("Serial PCI driver module for SGI IOC4 Base-IO Card");
-MODULE_LICENSE("GPL");
index f4e27d0..d3843f7 100644 (file)
@@ -25,8 +25,8 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/of.h>
-#include <mach/platform.h>
-#include <mach/hardware.h>
+#include <linux/sizes.h>
+#include <linux/soc/nxp/lpc32xx-misc.h>
 
 /*
  * High Speed UART register offsets
@@ -81,6 +81,8 @@
 #define LPC32XX_HSU_TX_TL8B                    (0x2 << 0)
 #define LPC32XX_HSU_TX_TL16B                   (0x3 << 0)
 
+#define LPC32XX_MAIN_OSC_FREQ                  13000000
+
 #define MODNAME "lpc32xx_hsuart"
 
 struct lpc32xx_hsuart_port {
@@ -151,8 +153,6 @@ static void lpc32xx_hsuart_console_write(struct console *co, const char *s,
        local_irq_restore(flags);
 }
 
-static void lpc32xx_loopback_set(resource_size_t mapbase, int state);
-
 static int __init lpc32xx_hsuart_console_setup(struct console *co,
                                               char *options)
 {
@@ -439,35 +439,6 @@ static void serial_lpc32xx_break_ctl(struct uart_port *port,
        spin_unlock_irqrestore(&port->lock, flags);
 }
 
-/* LPC3250 Errata HSUART.1: Hang workaround via loopback mode on inactivity */
-static void lpc32xx_loopback_set(resource_size_t mapbase, int state)
-{
-       int bit;
-       u32 tmp;
-
-       switch (mapbase) {
-       case LPC32XX_HS_UART1_BASE:
-               bit = 0;
-               break;
-       case LPC32XX_HS_UART2_BASE:
-               bit = 1;
-               break;
-       case LPC32XX_HS_UART7_BASE:
-               bit = 6;
-               break;
-       default:
-               WARN(1, "lpc32xx_hs: Warning: Unknown port at %08x\n", mapbase);
-               return;
-       }
-
-       tmp = readl(LPC32XX_UARTCTL_CLOOP);
-       if (state)
-               tmp |= (1 << bit);
-       else
-               tmp &= ~(1 << bit);
-       writel(tmp, LPC32XX_UARTCTL_CLOOP);
-}
-
 /* port->lock is not held.  */
 static int serial_lpc32xx_startup(struct uart_port *port)
 {
diff --git a/drivers/tty/serial/sn_console.c b/drivers/tty/serial/sn_console.c
deleted file mode 100644 (file)
index 2834933..0000000
+++ /dev/null
@@ -1,1036 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * C-Brick Serial Port (and console) driver for SGI Altix machines.
- *
- * This driver is NOT suitable for talking to the l1-controller for
- * anything other than 'console activities' --- please use the l1
- * driver for that.
- *
- *
- * Copyright (c) 2004-2006 Silicon Graphics, Inc.  All Rights Reserved.
- *
- * Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
- * Mountain View, CA  94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/sysrq.h>
-#include <linux/circ_buf.h>
-#include <linux/serial_reg.h>
-#include <linux/delay.h> /* for mdelay */
-#include <linux/miscdevice.h>
-#include <linux/serial_core.h>
-
-#include <asm/io.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/sn_sal.h>
-
-/* number of characters we can transmit to the SAL console at a time */
-#define SN_SAL_MAX_CHARS 120
-
-/* 64K, when we're asynch, it must be at least printk's LOG_BUF_LEN to
- * avoid losing chars, (always has to be a power of 2) */
-#define SN_SAL_BUFFER_SIZE (64 * (1 << 10))
-
-#define SN_SAL_UART_FIFO_DEPTH 16
-#define SN_SAL_UART_FIFO_SPEED_CPS (9600/10)
-
-/* sn_transmit_chars() calling args */
-#define TRANSMIT_BUFFERED      0
-#define TRANSMIT_RAW           1
-
-/* To use dynamic numbers only and not use the assigned major and minor,
- * define the following.. */
-                                 /* #define USE_DYNAMIC_MINOR 1 *//* use dynamic minor number */
-#define USE_DYNAMIC_MINOR 0    /* Don't rely on misc_register dynamic minor */
-
-/* Device name we're using */
-#define DEVICE_NAME "ttySG"
-#define DEVICE_NAME_DYNAMIC "ttySG0"   /* need full name for misc_register */
-/* The major/minor we are using, ignored for USE_DYNAMIC_MINOR */
-#define DEVICE_MAJOR 204
-#define DEVICE_MINOR 40
-
-#ifdef CONFIG_MAGIC_SYSRQ
-static char sysrq_serial_str[] = "\eSYS";
-static char *sysrq_serial_ptr = sysrq_serial_str;
-static unsigned long sysrq_requested;
-#endif /* CONFIG_MAGIC_SYSRQ */
-
-/*
- * Port definition - this kinda drives it all
- */
-struct sn_cons_port {
-       struct timer_list sc_timer;
-       struct uart_port sc_port;
-       struct sn_sal_ops {
-               int (*sal_puts_raw) (const char *s, int len);
-               int (*sal_puts) (const char *s, int len);
-               int (*sal_getc) (void);
-               int (*sal_input_pending) (void);
-               void (*sal_wakeup_transmit) (struct sn_cons_port *, int);
-       } *sc_ops;
-       unsigned long sc_interrupt_timeout;
-       int sc_is_asynch;
-};
-
-static struct sn_cons_port sal_console_port;
-static int sn_process_input;
-
-/* Only used if USE_DYNAMIC_MINOR is set to 1 */
-static struct miscdevice misc; /* used with misc_register for dynamic */
-
-extern void early_sn_setup(void);
-
-#undef DEBUG
-#ifdef DEBUG
-static int sn_debug_printf(const char *fmt, ...);
-#define DPRINTF(x...) sn_debug_printf(x)
-#else
-#define DPRINTF(x...) do { } while (0)
-#endif
-
-/* Prototypes */
-static int snt_hw_puts_raw(const char *, int);
-static int snt_hw_puts_buffered(const char *, int);
-static int snt_poll_getc(void);
-static int snt_poll_input_pending(void);
-static int snt_intr_getc(void);
-static int snt_intr_input_pending(void);
-static void sn_transmit_chars(struct sn_cons_port *, int);
-
-/* A table for polling:
- */
-static struct sn_sal_ops poll_ops = {
-       .sal_puts_raw = snt_hw_puts_raw,
-       .sal_puts = snt_hw_puts_raw,
-       .sal_getc = snt_poll_getc,
-       .sal_input_pending = snt_poll_input_pending
-};
-
-/* A table for interrupts enabled */
-static struct sn_sal_ops intr_ops = {
-       .sal_puts_raw = snt_hw_puts_raw,
-       .sal_puts = snt_hw_puts_buffered,
-       .sal_getc = snt_intr_getc,
-       .sal_input_pending = snt_intr_input_pending,
-       .sal_wakeup_transmit = sn_transmit_chars
-};
-
-/* the console does output in two distinctly different ways:
- * synchronous (raw) and asynchronous (buffered).  initially, early_printk
- * does synchronous output.  any data written goes directly to the SAL
- * to be output (incidentally, it is internally buffered by the SAL)
- * after interrupts and timers are initialized and available for use,
- * the console init code switches to asynchronous output.  this is
- * also the earliest opportunity to begin polling for console input.
- * after console initialization, console output and tty (serial port)
- * output is buffered and sent to the SAL asynchronously (either by
- * timer callback or by UART interrupt) */
-
-/* routines for running the console in polling mode */
-
-/**
- * snt_poll_getc - Get a character from the console in polling mode
- *
- */
-static int snt_poll_getc(void)
-{
-       int ch;
-
-       ia64_sn_console_getc(&ch);
-       return ch;
-}
-
-/**
- * snt_poll_input_pending - Check if any input is waiting - polling mode.
- *
- */
-static int snt_poll_input_pending(void)
-{
-       int status, input;
-
-       status = ia64_sn_console_check(&input);
-       return !status && input;
-}
-
-/* routines for an interrupt driven console (normal) */
-
-/**
- * snt_intr_getc - Get a character from the console, interrupt mode
- *
- */
-static int snt_intr_getc(void)
-{
-       return ia64_sn_console_readc();
-}
-
-/**
- * snt_intr_input_pending - Check if input is pending, interrupt mode
- *
- */
-static int snt_intr_input_pending(void)
-{
-       return ia64_sn_console_intr_status() & SAL_CONSOLE_INTR_RECV;
-}
-
-/* these functions are polled and interrupt */
-
-/**
- * snt_hw_puts_raw - Send raw string to the console, polled or interrupt mode
- * @s: String
- * @len: Length
- *
- */
-static int snt_hw_puts_raw(const char *s, int len)
-{
-       /* this will call the PROM and not return until this is done */
-       return ia64_sn_console_putb(s, len);
-}
-
-/**
- * snt_hw_puts_buffered - Send string to console, polled or interrupt mode
- * @s: String
- * @len: Length
- *
- */
-static int snt_hw_puts_buffered(const char *s, int len)
-{
-       /* queue data to the PROM */
-       return ia64_sn_console_xmit_chars((char *)s, len);
-}
-
-/* uart interface structs
- * These functions are associated with the uart_port that the serial core
- * infrastructure calls.
- *
- * Note: Due to how the console works, many routines are no-ops.
- */
-
-/**
- * snp_type - What type of console are we?
- * @port: Port to operate with (we ignore since we only have one port)
- *
- */
-static const char *snp_type(struct uart_port *port)
-{
-       return ("SGI SN L1");
-}
-
-/**
- * snp_tx_empty - Is the transmitter empty?  We pretend we're always empty
- * @port: Port to operate on (we ignore since we only have one port)
- *
- */
-static unsigned int snp_tx_empty(struct uart_port *port)
-{
-       return 1;
-}
-
-/**
- * snp_stop_tx - stop the transmitter - no-op for us
- * @port: Port to operat eon - we ignore - no-op function
- *
- */
-static void snp_stop_tx(struct uart_port *port)
-{
-}
-
-/**
- * snp_release_port - Free i/o and resources for port - no-op for us
- * @port: Port to operate on - we ignore - no-op function
- *
- */
-static void snp_release_port(struct uart_port *port)
-{
-}
-
-/**
- * snp_shutdown - shut down the port - free irq and disable - no-op for us
- * @port: Port to shut down - we ignore
- *
- */
-static void snp_shutdown(struct uart_port *port)
-{
-}
-
-/**
- * snp_set_mctrl - set control lines (dtr, rts, etc) - no-op for our console
- * @port: Port to operate on - we ignore
- * @mctrl: Lines to set/unset - we ignore
- *
- */
-static void snp_set_mctrl(struct uart_port *port, unsigned int mctrl)
-{
-}
-
-/**
- * snp_get_mctrl - get contorl line info, we just return a static value
- * @port: port to operate on - we only have one port so we ignore this
- *
- */
-static unsigned int snp_get_mctrl(struct uart_port *port)
-{
-       return TIOCM_CAR | TIOCM_RNG | TIOCM_DSR | TIOCM_CTS;
-}
-
-/**
- * snp_stop_rx - Stop the receiver - we ignor ethis
- * @port: Port to operate on - we ignore
- *
- */
-static void snp_stop_rx(struct uart_port *port)
-{
-}
-
-/**
- * snp_start_tx - Start transmitter
- * @port: Port to operate on
- *
- */
-static void snp_start_tx(struct uart_port *port)
-{
-       if (sal_console_port.sc_ops->sal_wakeup_transmit)
-               sal_console_port.sc_ops->sal_wakeup_transmit(&sal_console_port,
-                                                            TRANSMIT_BUFFERED);
-
-}
-
-/**
- * snp_break_ctl - handle breaks - ignored by us
- * @port: Port to operate on
- * @break_state: Break state
- *
- */
-static void snp_break_ctl(struct uart_port *port, int break_state)
-{
-}
-
-/**
- * snp_startup - Start up the serial port - always return 0 (We're always on)
- * @port: Port to operate on
- *
- */
-static int snp_startup(struct uart_port *port)
-{
-       return 0;
-}
-
-/**
- * snp_set_termios - set termios stuff - we ignore these
- * @port: port to operate on
- * @termios: New settings
- * @termios: Old
- *
- */
-static void
-snp_set_termios(struct uart_port *port, struct ktermios *termios,
-               struct ktermios *old)
-{
-}
-
-/**
- * snp_request_port - allocate resources for port - ignored by us
- * @port: port to operate on
- *
- */
-static int snp_request_port(struct uart_port *port)
-{
-       return 0;
-}
-
-/**
- * snp_config_port - allocate resources, set up - we ignore,  we're always on
- * @port: Port to operate on
- * @flags: flags used for port setup
- *
- */
-static void snp_config_port(struct uart_port *port, int flags)
-{
-}
-
-/* Associate the uart functions above - given to serial core */
-
-static const struct uart_ops sn_console_ops = {
-       .tx_empty = snp_tx_empty,
-       .set_mctrl = snp_set_mctrl,
-       .get_mctrl = snp_get_mctrl,
-       .stop_tx = snp_stop_tx,
-       .start_tx = snp_start_tx,
-       .stop_rx = snp_stop_rx,
-       .break_ctl = snp_break_ctl,
-       .startup = snp_startup,
-       .shutdown = snp_shutdown,
-       .set_termios = snp_set_termios,
-       .pm = NULL,
-       .type = snp_type,
-       .release_port = snp_release_port,
-       .request_port = snp_request_port,
-       .config_port = snp_config_port,
-       .verify_port = NULL,
-};
-
-/* End of uart struct functions and defines */
-
-#ifdef DEBUG
-
-/**
- * sn_debug_printf - close to hardware debugging printf
- * @fmt: printf format
- *
- * This is as "close to the metal" as we can get, used when the driver
- * itself may be broken.
- *
- */
-static int sn_debug_printf(const char *fmt, ...)
-{
-       static char printk_buf[1024];
-       int printed_len;
-       va_list args;
-
-       va_start(args, fmt);
-       printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
-
-       if (!sal_console_port.sc_ops) {
-               sal_console_port.sc_ops = &poll_ops;
-               early_sn_setup();
-       }
-       sal_console_port.sc_ops->sal_puts_raw(printk_buf, printed_len);
-
-       va_end(args);
-       return printed_len;
-}
-#endif                         /* DEBUG */
-
-/*
- * Interrupt handling routines.
- */
-
-/**
- * sn_receive_chars - Grab characters, pass them to tty layer
- * @port: Port to operate on
- * @flags: irq flags
- *
- * Note: If we're not registered with the serial core infrastructure yet,
- * we don't try to send characters to it...
- *
- */
-static void
-sn_receive_chars(struct sn_cons_port *port, unsigned long flags)
-{
-       struct tty_port *tport = NULL;
-       int ch;
-
-       if (!port) {
-               printk(KERN_ERR "sn_receive_chars - port NULL so can't receive\n");
-               return;
-       }
-
-       if (!port->sc_ops) {
-               printk(KERN_ERR "sn_receive_chars - port->sc_ops  NULL so can't receive\n");
-               return;
-       }
-
-       if (port->sc_port.state) {
-               /* The serial_core stuffs are initialized, use them */
-               tport = &port->sc_port.state->port;
-       }
-
-       while (port->sc_ops->sal_input_pending()) {
-               ch = port->sc_ops->sal_getc();
-               if (ch < 0) {
-                       printk(KERN_ERR "sn_console: An error occurred while "
-                              "obtaining data from the console (0x%0x)\n", ch);
-                       break;
-               }
-#ifdef CONFIG_MAGIC_SYSRQ
-                if (sysrq_requested) {
-                        unsigned long sysrq_timeout = sysrq_requested + HZ*5;
-
-                        sysrq_requested = 0;
-                        if (ch && time_before(jiffies, sysrq_timeout)) {
-                                spin_unlock_irqrestore(&port->sc_port.lock, flags);
-                                handle_sysrq(ch);
-                                spin_lock_irqsave(&port->sc_port.lock, flags);
-                                /* ignore actual sysrq command char */
-                                continue;
-                        }
-                }
-                if (ch == *sysrq_serial_ptr) {
-                        if (!(*++sysrq_serial_ptr)) {
-                                sysrq_requested = jiffies;
-                                sysrq_serial_ptr = sysrq_serial_str;
-                        }
-                       /*
-                        * ignore the whole sysrq string except for the
-                        * leading escape
-                        */
-                       if (ch != '\e')
-                               continue;
-                }
-                else
-                       sysrq_serial_ptr = sysrq_serial_str;
-#endif /* CONFIG_MAGIC_SYSRQ */
-
-               /* record the character to pass up to the tty layer */
-               if (tport) {
-                       if (tty_insert_flip_char(tport, ch, TTY_NORMAL) == 0)
-                               break;
-               }
-               port->sc_port.icount.rx++;
-       }
-
-       if (tport)
-               tty_flip_buffer_push(tport);
-}
-
-/**
- * sn_transmit_chars - grab characters from serial core, send off
- * @port: Port to operate on
- * @raw: Transmit raw or buffered
- *
- * Note: If we're early, before we're registered with serial core, the
- * writes are going through sn_sal_console_write because that's how
- * register_console has been set up.  We currently could have asynch
- * polls calling this function due to sn_sal_switch_to_asynch but we can
- * ignore them until we register with the serial core stuffs.
- *
- */
-static void sn_transmit_chars(struct sn_cons_port *port, int raw)
-{
-       int xmit_count, tail, head, loops, ii;
-       int result;
-       char *start;
-       struct circ_buf *xmit;
-
-       if (!port)
-               return;
-
-       BUG_ON(!port->sc_is_asynch);
-
-       if (port->sc_port.state) {
-               /* We're initialized, using serial core infrastructure */
-               xmit = &port->sc_port.state->xmit;
-       } else {
-               /* Probably sn_sal_switch_to_asynch has been run but serial core isn't
-                * initialized yet.  Just return.  Writes are going through
-                * sn_sal_console_write (due to register_console) at this time.
-                */
-               return;
-       }
-
-       if (uart_circ_empty(xmit) || uart_tx_stopped(&port->sc_port)) {
-               /* Nothing to do. */
-               ia64_sn_console_intr_disable(SAL_CONSOLE_INTR_XMIT);
-               return;
-       }
-
-       head = xmit->head;
-       tail = xmit->tail;
-       start = &xmit->buf[tail];
-
-       /* twice around gets the tail to the end of the buffer and
-        * then to the head, if needed */
-       loops = (head < tail) ? 2 : 1;
-
-       for (ii = 0; ii < loops; ii++) {
-               xmit_count = (head < tail) ?
-                   (UART_XMIT_SIZE - tail) : (head - tail);
-
-               if (xmit_count > 0) {
-                       if (raw == TRANSMIT_RAW)
-                               result =
-                                   port->sc_ops->sal_puts_raw(start,
-                                                              xmit_count);
-                       else
-                               result =
-                                   port->sc_ops->sal_puts(start, xmit_count);
-#ifdef DEBUG
-                       if (!result)
-                               DPRINTF("`");
-#endif
-                       if (result > 0) {
-                               xmit_count -= result;
-                               port->sc_port.icount.tx += result;
-                               tail += result;
-                               tail &= UART_XMIT_SIZE - 1;
-                               xmit->tail = tail;
-                               start = &xmit->buf[tail];
-                       }
-               }
-       }
-
-       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-               uart_write_wakeup(&port->sc_port);
-
-       if (uart_circ_empty(xmit))
-               snp_stop_tx(&port->sc_port);    /* no-op for us */
-}
-
-/**
- * sn_sal_interrupt - Handle console interrupts
- * @irq: irq #, useful for debug statements
- * @dev_id: our pointer to our port (sn_cons_port which contains the uart port)
- *
- */
-static irqreturn_t sn_sal_interrupt(int irq, void *dev_id)
-{
-       struct sn_cons_port *port = (struct sn_cons_port *)dev_id;
-       unsigned long flags;
-       int status = ia64_sn_console_intr_status();
-
-       if (!port)
-               return IRQ_NONE;
-
-       spin_lock_irqsave(&port->sc_port.lock, flags);
-       if (status & SAL_CONSOLE_INTR_RECV) {
-               sn_receive_chars(port, flags);
-       }
-       if (status & SAL_CONSOLE_INTR_XMIT) {
-               sn_transmit_chars(port, TRANSMIT_BUFFERED);
-       }
-       spin_unlock_irqrestore(&port->sc_port.lock, flags);
-       return IRQ_HANDLED;
-}
-
-/**
- * sn_sal_timer_poll - this function handles polled console mode
- * @data: A pointer to our sn_cons_port (which contains the uart port)
- *
- * data is the pointer that init_timer will store for us.  This function is
- * associated with init_timer to see if there is any console traffic.
- * Obviously not used in interrupt mode
- *
- */
-static void sn_sal_timer_poll(struct timer_list *t)
-{
-       struct sn_cons_port *port = from_timer(port, t, sc_timer);
-       unsigned long flags;
-
-       if (!port)
-               return;
-
-       if (!port->sc_port.irq) {
-               spin_lock_irqsave(&port->sc_port.lock, flags);
-               if (sn_process_input)
-                       sn_receive_chars(port, flags);
-               sn_transmit_chars(port, TRANSMIT_RAW);
-               spin_unlock_irqrestore(&port->sc_port.lock, flags);
-               mod_timer(&port->sc_timer,
-                         jiffies + port->sc_interrupt_timeout);
-       }
-}
-
-/*
- * Boot-time initialization code
- */
-
-/**
- * sn_sal_switch_to_asynch - Switch to async mode (as opposed to synch)
- * @port: Our sn_cons_port (which contains the uart port)
- *
- * So this is used by sn_sal_serial_console_init (early on, before we're
- * registered with serial core).  It's also used by sn_sal_init
- * right after we've registered with serial core.  The later only happens
- * if we didn't already come through here via sn_sal_serial_console_init.
- *
- */
-static void __init sn_sal_switch_to_asynch(struct sn_cons_port *port)
-{
-       unsigned long flags;
-
-       if (!port)
-               return;
-
-       DPRINTF("sn_console: about to switch to asynchronous console\n");
-
-       /* without early_printk, we may be invoked late enough to race
-        * with other cpus doing console IO at this point, however
-        * console interrupts will never be enabled */
-       spin_lock_irqsave(&port->sc_port.lock, flags);
-
-       /* early_printk invocation may have done this for us */
-       if (!port->sc_ops)
-               port->sc_ops = &poll_ops;
-
-       /* we can't turn on the console interrupt (as request_irq
-        * calls kmalloc, which isn't set up yet), so we rely on a
-        * timer to poll for input and push data from the console
-        * buffer.
-        */
-       timer_setup(&port->sc_timer, sn_sal_timer_poll, 0);
-
-       if (IS_RUNNING_ON_SIMULATOR())
-               port->sc_interrupt_timeout = 6;
-       else {
-               /* 960cps / 16 char FIFO = 60HZ
-                * HZ / (SN_SAL_FIFO_SPEED_CPS / SN_SAL_FIFO_DEPTH) */
-               port->sc_interrupt_timeout =
-                   HZ * SN_SAL_UART_FIFO_DEPTH / SN_SAL_UART_FIFO_SPEED_CPS;
-       }
-       mod_timer(&port->sc_timer, jiffies + port->sc_interrupt_timeout);
-
-       port->sc_is_asynch = 1;
-       spin_unlock_irqrestore(&port->sc_port.lock, flags);
-}
-
-/**
- * sn_sal_switch_to_interrupts - Switch to interrupt driven mode
- * @port: Our sn_cons_port (which contains the uart port)
- *
- * In sn_sal_init, after we're registered with serial core and
- * the port is added, this function is called to switch us to interrupt
- * mode.  We were previously in asynch/polling mode (using init_timer).
- *
- * We attempt to switch to interrupt mode here by calling
- * request_irq.  If that works out, we enable receive interrupts.
- */
-static void __init sn_sal_switch_to_interrupts(struct sn_cons_port *port)
-{
-       unsigned long flags;
-
-       if (port) {
-               DPRINTF("sn_console: switching to interrupt driven console\n");
-
-               if (request_irq(SGI_UART_VECTOR, sn_sal_interrupt,
-                               IRQF_SHARED,
-                               "SAL console driver", port) >= 0) {
-                       spin_lock_irqsave(&port->sc_port.lock, flags);
-                       port->sc_port.irq = SGI_UART_VECTOR;
-                       port->sc_ops = &intr_ops;
-                       irq_set_handler(port->sc_port.irq, handle_level_irq);
-
-                       /* turn on receive interrupts */
-                       ia64_sn_console_intr_enable(SAL_CONSOLE_INTR_RECV);
-                       spin_unlock_irqrestore(&port->sc_port.lock, flags);
-               }
-               else {
-                       printk(KERN_INFO
-                           "sn_console: console proceeding in polled mode\n");
-               }
-       }
-}
-
-/*
- * Kernel console definitions
- */
-
-static void sn_sal_console_write(struct console *, const char *, unsigned);
-static int sn_sal_console_setup(struct console *, char *);
-static struct uart_driver sal_console_uart;
-extern struct tty_driver *uart_console_device(struct console *, int *);
-
-static struct console sal_console = {
-       .name = DEVICE_NAME,
-       .write = sn_sal_console_write,
-       .device = uart_console_device,
-       .setup = sn_sal_console_setup,
-       .index = -1,            /* unspecified */
-       .data = &sal_console_uart,
-};
-
-#define SAL_CONSOLE    &sal_console
-
-static struct uart_driver sal_console_uart = {
-       .owner = THIS_MODULE,
-       .driver_name = "sn_console",
-       .dev_name = DEVICE_NAME,
-       .major = 0,             /* major/minor set at registration time per USE_DYNAMIC_MINOR */
-       .minor = 0,
-       .nr = 1,                /* one port */
-       .cons = SAL_CONSOLE,
-};
-
-/**
- * sn_sal_init - When the kernel loads us, get us rolling w/ serial core
- *
- * Before this is called, we've been printing kernel messages in a special
- * early mode not making use of the serial core infrastructure.  When our
- * driver is loaded for real, we register the driver and port with serial
- * core and try to enable interrupt driven mode.
- *
- */
-static int __init sn_sal_init(void)
-{
-       int retval;
-
-       if (!ia64_platform_is("sn2"))
-               return 0;
-
-       printk(KERN_INFO "sn_console: Console driver init\n");
-
-       if (USE_DYNAMIC_MINOR == 1) {
-               misc.minor = MISC_DYNAMIC_MINOR;
-               misc.name = DEVICE_NAME_DYNAMIC;
-               retval = misc_register(&misc);
-               if (retval != 0) {
-                       printk(KERN_WARNING "Failed to register console "
-                              "device using misc_register.\n");
-                       return -ENODEV;
-               }
-               sal_console_uart.major = MISC_MAJOR;
-               sal_console_uart.minor = misc.minor;
-       } else {
-               sal_console_uart.major = DEVICE_MAJOR;
-               sal_console_uart.minor = DEVICE_MINOR;
-       }
-
-       /* We register the driver and the port before switching to interrupts
-        * or async above so the proper uart structures are populated */
-
-       if (uart_register_driver(&sal_console_uart) < 0) {
-               printk
-                   ("ERROR sn_sal_init failed uart_register_driver, line %d\n",
-                    __LINE__);
-               return -ENODEV;
-       }
-
-       spin_lock_init(&sal_console_port.sc_port.lock);
-
-       /* Setup the port struct with the minimum needed */
-       sal_console_port.sc_port.membase = (char *)1;   /* just needs to be non-zero */
-       sal_console_port.sc_port.type = PORT_16550A;
-       sal_console_port.sc_port.fifosize = SN_SAL_MAX_CHARS;
-       sal_console_port.sc_port.ops = &sn_console_ops;
-       sal_console_port.sc_port.line = 0;
-
-       if (uart_add_one_port(&sal_console_uart, &sal_console_port.sc_port) < 0) {
-               /* error - not sure what I'd do - so I'll do nothing */
-               printk(KERN_ERR "%s: unable to add port\n", __func__);
-       }
-
-       /* when this driver is compiled in, the console initialization
-        * will have already switched us into asynchronous operation
-        * before we get here through the initcalls */
-       if (!sal_console_port.sc_is_asynch) {
-               sn_sal_switch_to_asynch(&sal_console_port);
-       }
-
-       /* at this point (device_init) we can try to turn on interrupts */
-       if (!IS_RUNNING_ON_SIMULATOR()) {
-               sn_sal_switch_to_interrupts(&sal_console_port);
-       }
-       sn_process_input = 1;
-       return 0;
-}
-device_initcall(sn_sal_init);
-
-/**
- * puts_raw_fixed - sn_sal_console_write helper for adding \r's as required
- * @puts_raw : puts function to do the writing
- * @s: input string
- * @count: length
- *
- * We need a \r ahead of every \n for direct writes through
- * ia64_sn_console_putb (what sal_puts_raw below actually does).
- *
- */
-
-static void puts_raw_fixed(int (*puts_raw) (const char *s, int len),
-                          const char *s, int count)
-{
-       const char *s1;
-
-       /* Output '\r' before each '\n' */
-       while ((s1 = memchr(s, '\n', count)) != NULL) {
-               puts_raw(s, s1 - s);
-               puts_raw("\r\n", 2);
-               count -= s1 + 1 - s;
-               s = s1 + 1;
-       }
-       puts_raw(s, count);
-}
-
-/**
- * sn_sal_console_write - Print statements before serial core available
- * @console: Console to operate on - we ignore since we have just one
- * @s: String to send
- * @count: length
- *
- * This is referenced in the console struct.  It is used for early
- * console printing before we register with serial core and for things
- * such as kdb.  The console_lock must be held when we get here.
- *
- * This function has some code for trying to print output even if the lock
- * is held.  We try to cover the case where a lock holder could have died.
- * We don't use this special case code if we're not registered with serial
- * core yet.  After we're registered with serial core, the only time this
- * function would be used is for high level kernel output like magic sys req,
- * kdb, and printk's.
- */
-static void
-sn_sal_console_write(struct console *co, const char *s, unsigned count)
-{
-       unsigned long flags = 0;
-       struct sn_cons_port *port = &sal_console_port;
-       static int stole_lock = 0;
-
-       BUG_ON(!port->sc_is_asynch);
-
-       /* We can't look at the xmit buffer if we're not registered with serial core
-        *  yet.  So only do the fancy recovery after registering
-        */
-       if (!port->sc_port.state) {
-               /* Not yet registered with serial core - simple case */
-               puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
-               return;
-       }
-
-       /* somebody really wants this output, might be an
-        * oops, kdb, panic, etc.  make sure they get it. */
-       if (!spin_trylock_irqsave(&port->sc_port.lock, flags)) {
-               int lhead = port->sc_port.state->xmit.head;
-               int ltail = port->sc_port.state->xmit.tail;
-               int counter, got_lock = 0;
-
-               /*
-                * We attempt to determine if someone has died with the
-                * lock. We wait ~20 secs after the head and tail ptrs
-                * stop moving and assume the lock holder is not functional
-                * and plow ahead. If the lock is freed within the time out
-                * period we re-get the lock and go ahead normally. We also
-                * remember if we have plowed ahead so that we don't have
-                * to wait out the time out period again - the asumption
-                * is that we will time out again.
-                */
-
-               for (counter = 0; counter < 150; mdelay(125), counter++) {
-                       if (stole_lock)
-                               break;
-
-                       if (spin_trylock_irqsave(&port->sc_port.lock, flags)) {
-                               got_lock = 1;
-                               break;
-                       } else {
-                               /* still locked */
-                               if ((lhead != port->sc_port.state->xmit.head)
-                                   || (ltail !=
-                                       port->sc_port.state->xmit.tail)) {
-                                       lhead =
-                                               port->sc_port.state->xmit.head;
-                                       ltail =
-                                               port->sc_port.state->xmit.tail;
-                                       counter = 0;
-                               }
-                       }
-               }
-               /* flush anything in the serial core xmit buffer, raw */
-               sn_transmit_chars(port, 1);
-               if (got_lock) {
-                       spin_unlock_irqrestore(&port->sc_port.lock, flags);
-                       stole_lock = 0;
-               } else {
-                       /* fell thru */
-                       stole_lock = 1;
-               }
-               puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
-       } else {
-               stole_lock = 0;
-               sn_transmit_chars(port, 1);
-               spin_unlock_irqrestore(&port->sc_port.lock, flags);
-
-               puts_raw_fixed(port->sc_ops->sal_puts_raw, s, count);
-       }
-}
-
-
-/**
- * sn_sal_console_setup - Set up console for early printing
- * @co: Console to work with
- * @options: Options to set
- *
- * Altix console doesn't do anything with baud rates, etc, anyway.
- *
- * This isn't required since not providing the setup function in the
- * console struct is ok.  However, other patches like KDB plop something
- * here so providing it is easier.
- *
- */
-static int sn_sal_console_setup(struct console *co, char *options)
-{
-       return 0;
-}
-
-/**
- * sn_sal_console_write_early - simple early output routine
- * @co - console struct
- * @s - string to print
- * @count - count
- *
- * Simple function to provide early output, before even
- * sn_sal_serial_console_init is called.  Referenced in the
- * console struct registerd in sn_serial_console_early_setup.
- *
- */
-static void __init
-sn_sal_console_write_early(struct console *co, const char *s, unsigned count)
-{
-       puts_raw_fixed(sal_console_port.sc_ops->sal_puts_raw, s, count);
-}
-
-/* Used for very early console printing - again, before
- * sn_sal_serial_console_init is run */
-static struct console sal_console_early __initdata = {
-       .name = "sn_sal",
-       .write = sn_sal_console_write_early,
-       .flags = CON_PRINTBUFFER,
-       .index = -1,
-};
-
-/**
- * sn_serial_console_early_setup - Sets up early console output support
- *
- * Register a console early on...  This is for output before even
- * sn_sal_serial_cosnole_init is called.  This function is called from
- * setup.c.  This allows us to do really early polled writes. When
- * sn_sal_serial_console_init is called, this console is unregistered
- * and a new one registered.
- */
-int __init sn_serial_console_early_setup(void)
-{
-       if (!ia64_platform_is("sn2"))
-               return -1;
-
-       sal_console_port.sc_ops = &poll_ops;
-       spin_lock_init(&sal_console_port.sc_port.lock);
-       early_sn_setup();       /* Find SAL entry points */
-       register_console(&sal_console_early);
-
-       return 0;
-}
-
-/**
- * sn_sal_serial_console_init - Early console output - set up for register
- *
- * This function is called when regular console init happens.  Because we
- * support even earlier console output with sn_serial_console_early_setup
- * (called from setup.c directly), this function unregisters the really
- * early console.
- *
- * Note: Even if setup.c doesn't register sal_console_early, unregistering
- * it here doesn't hurt anything.
- *
- */
-static int __init sn_sal_serial_console_init(void)
-{
-       if (ia64_platform_is("sn2")) {
-               sn_sal_switch_to_asynch(&sal_console_port);
-               DPRINTF("sn_sal_serial_console_init : register console\n");
-               register_console(&sal_console);
-               unregister_console(&sal_console_early);
-       }
-       return 0;
-}
-
-console_initcall(sn_sal_serial_console_init);
index 6a5ee8e..67ad40b 100644 (file)
@@ -709,12 +709,6 @@ static int _gadget_stop_activity(struct usb_gadget *gadget)
        struct ci_hdrc    *ci = container_of(gadget, struct ci_hdrc, gadget);
        unsigned long flags;
 
-       spin_lock_irqsave(&ci->lock, flags);
-       ci->gadget.speed = USB_SPEED_UNKNOWN;
-       ci->remote_wakeup = 0;
-       ci->suspended = 0;
-       spin_unlock_irqrestore(&ci->lock, flags);
-
        /* flush all endpoints */
        gadget_for_each_ep(ep, gadget) {
                usb_ep_fifo_flush(ep);
@@ -732,6 +726,12 @@ static int _gadget_stop_activity(struct usb_gadget *gadget)
                ci->status = NULL;
        }
 
+       spin_lock_irqsave(&ci->lock, flags);
+       ci->gadget.speed = USB_SPEED_UNKNOWN;
+       ci->remote_wakeup = 0;
+       ci->suspended = 0;
+       spin_unlock_irqrestore(&ci->lock, flags);
+
        return 0;
 }
 
@@ -1303,6 +1303,10 @@ static int ep_disable(struct usb_ep *ep)
                return -EBUSY;
 
        spin_lock_irqsave(hwep->lock, flags);
+       if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
+               spin_unlock_irqrestore(hwep->lock, flags);
+               return 0;
+       }
 
        /* only internal SW should disable ctrl endpts */
 
@@ -1392,6 +1396,10 @@ static int ep_queue(struct usb_ep *ep, struct usb_request *req,
                return -EINVAL;
 
        spin_lock_irqsave(hwep->lock, flags);
+       if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
+               spin_unlock_irqrestore(hwep->lock, flags);
+               return 0;
+       }
        retval = _ep_queue(ep, req, gfp_flags);
        spin_unlock_irqrestore(hwep->lock, flags);
        return retval;
@@ -1415,8 +1423,8 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
                return -EINVAL;
 
        spin_lock_irqsave(hwep->lock, flags);
-
-       hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
+       if (hwep->ci->gadget.speed != USB_SPEED_UNKNOWN)
+               hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
 
        list_for_each_entry_safe(node, tmpnode, &hwreq->tds, td) {
                dma_pool_free(hwep->td_pool, node->ptr, node->dma);
@@ -1487,6 +1495,10 @@ static void ep_fifo_flush(struct usb_ep *ep)
        }
 
        spin_lock_irqsave(hwep->lock, flags);
+       if (hwep->ci->gadget.speed == USB_SPEED_UNKNOWN) {
+               spin_unlock_irqrestore(hwep->lock, flags);
+               return;
+       }
 
        hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
 
@@ -1559,6 +1571,10 @@ static int ci_udc_wakeup(struct usb_gadget *_gadget)
        int ret = 0;
 
        spin_lock_irqsave(&ci->lock, flags);
+       if (ci->gadget.speed == USB_SPEED_UNKNOWN) {
+               spin_unlock_irqrestore(&ci->lock, flags);
+               return 0;
+       }
        if (!ci->remote_wakeup) {
                ret = -EOPNOTSUPP;
                goto out;
index a7824a5..70afb2c 100644 (file)
@@ -587,10 +587,20 @@ static int wdm_flush(struct file *file, fl_owner_t id)
 {
        struct wdm_device *desc = file->private_data;
 
-       wait_event(desc->wait, !test_bit(WDM_IN_USE, &desc->flags));
+       wait_event(desc->wait,
+                       /*
+                        * needs both flags. We cannot do with one
+                        * because resetting it would cause a race
+                        * with write() yet we need to signal
+                        * a disconnect
+                        */
+                       !test_bit(WDM_IN_USE, &desc->flags) ||
+                       test_bit(WDM_DISCONNECTING, &desc->flags));
 
        /* cannot dereference desc->intf if WDM_DISCONNECTING */
-       if (desc->werr < 0 && !test_bit(WDM_DISCONNECTING, &desc->flags))
+       if (test_bit(WDM_DISCONNECTING, &desc->flags))
+               return -ENODEV;
+       if (desc->werr < 0)
                dev_err(&desc->intf->dev, "Error in flush path: %d\n",
                        desc->werr);
 
@@ -974,8 +984,6 @@ static void wdm_disconnect(struct usb_interface *intf)
        spin_lock_irqsave(&desc->iuspin, flags);
        set_bit(WDM_DISCONNECTING, &desc->flags);
        set_bit(WDM_READ, &desc->flags);
-       /* to terminate pending flushes */
-       clear_bit(WDM_IN_USE, &desc->flags);
        spin_unlock_irqrestore(&desc->iuspin, flags);
        wake_up_all(&desc->wait);
        mutex_lock(&desc->rlock);
index 4942122..36858dd 100644 (file)
@@ -2362,8 +2362,11 @@ static int usbtmc_probe(struct usb_interface *intf,
                goto err_put;
        }
 
+       retcode = -EINVAL;
        data->bulk_in = bulk_in->bEndpointAddress;
        data->wMaxPacketSize = usb_endpoint_maxp(bulk_in);
+       if (!data->wMaxPacketSize)
+               goto err_put;
        dev_dbg(&intf->dev, "Found bulk in endpoint at %u\n", data->bulk_in);
 
        data->bulk_out = bulk_out->bEndpointAddress;
index 0343246..7537681 100644 (file)
@@ -216,17 +216,18 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
                /* EHCI, OHCI */
                hcd->rsrc_start = pci_resource_start(dev, 0);
                hcd->rsrc_len = pci_resource_len(dev, 0);
-               if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
-                               driver->description)) {
+               if (!devm_request_mem_region(&dev->dev, hcd->rsrc_start,
+                               hcd->rsrc_len, driver->description)) {
                        dev_dbg(&dev->dev, "controller already in use\n");
                        retval = -EBUSY;
                        goto put_hcd;
                }
-               hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len);
+               hcd->regs = devm_ioremap_nocache(&dev->dev, hcd->rsrc_start,
+                               hcd->rsrc_len);
                if (hcd->regs == NULL) {
                        dev_dbg(&dev->dev, "error mapping memory\n");
                        retval = -EFAULT;
-                       goto release_mem_region;
+                       goto put_hcd;
                }
 
        } else {
@@ -240,8 +241,8 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 
                        hcd->rsrc_start = pci_resource_start(dev, region);
                        hcd->rsrc_len = pci_resource_len(dev, region);
-                       if (request_region(hcd->rsrc_start, hcd->rsrc_len,
-                                       driver->description))
+                       if (devm_request_region(&dev->dev, hcd->rsrc_start,
+                                       hcd->rsrc_len, driver->description))
                                break;
                }
                if (region == PCI_ROM_RESOURCE) {
@@ -275,20 +276,13 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
        }
 
        if (retval != 0)
-               goto unmap_registers;
+               goto put_hcd;
        device_wakeup_enable(hcd->self.controller);
 
        if (pci_dev_run_wake(dev))
                pm_runtime_put_noidle(&dev->dev);
        return retval;
 
-unmap_registers:
-       if (driver->flags & HCD_MEMORY) {
-               iounmap(hcd->regs);
-release_mem_region:
-               release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-       } else
-               release_region(hcd->rsrc_start, hcd->rsrc_len);
 put_hcd:
        usb_put_hcd(hcd);
 disable_pci:
@@ -347,14 +341,6 @@ void usb_hcd_pci_remove(struct pci_dev *dev)
                dev_set_drvdata(&dev->dev, NULL);
                up_read(&companions_rwsem);
        }
-
-       if (hcd->driver->flags & HCD_MEMORY) {
-               iounmap(hcd->regs);
-               release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
-       } else {
-               release_region(hcd->rsrc_start, hcd->rsrc_len);
-       }
-
        usb_put_hcd(hcd);
        pci_disable_device(dev);
 }
index ef0259a..d7e6116 100644 (file)
@@ -45,7 +45,8 @@ config USB_AT91
 
 config USB_LPC32XX
        tristate "LPC32XX USB Peripheral Controller"
-       depends on ARCH_LPC32XX && I2C
+       depends on ARCH_LPC32XX
+       depends on I2C
        select USB_ISP1301
        help
           This option selects the USB device controller in the LPC32xx SoC.
index 5f1b14f..c65aed3 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
+#include <linux/prefetch.h>
 #include <linux/proc_fs.h>
 #include <linux/slab.h>
 #include <linux/usb/ch9.h>
@@ -35,8 +36,6 @@
 #include <linux/seq_file.h>
 #endif
 
-#include <mach/hardware.h>
-
 /*
  * USB device configuration structure
  */
@@ -2265,7 +2264,7 @@ static void udc_handle_ep0_setup(struct lpc32xx_udc *udc)
                default:
                        break;
                }
-
+               break;
 
        case USB_REQ_SET_ADDRESS:
                if (reqtype == (USB_TYPE_STANDARD | USB_RECIP_DEVICE)) {
index 40b5de5..73d233d 100644 (file)
@@ -441,7 +441,8 @@ config USB_OHCI_HCD_S3C2410
 
 config USB_OHCI_HCD_LPC32XX
        tristate "Support for LPC on-chip OHCI USB controller"
-       depends on USB_OHCI_HCD && ARCH_LPC32XX
+       depends on USB_OHCI_HCD
+       depends on ARCH_LPC32XX || COMPILE_TEST
        depends on USB_ISP1301
        default y
        ---help---
index b457fda..1fe3dee 100644 (file)
@@ -419,8 +419,7 @@ static void ohci_usb_reset (struct ohci_hcd *ohci)
  * other cases where the next software may expect clean state from the
  * "firmware".  this is bus-neutral, unlike shutdown() methods.
  */
-static void
-ohci_shutdown (struct usb_hcd *hcd)
+static void _ohci_shutdown(struct usb_hcd *hcd)
 {
        struct ohci_hcd *ohci;
 
@@ -436,6 +435,16 @@ ohci_shutdown (struct usb_hcd *hcd)
        ohci->rh_state = OHCI_RH_HALTED;
 }
 
+static void ohci_shutdown(struct usb_hcd *hcd)
+{
+       struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+       unsigned long flags;
+
+       spin_lock_irqsave(&ohci->lock, flags);
+       _ohci_shutdown(hcd);
+       spin_unlock_irqrestore(&ohci->lock, flags);
+}
+
 /*-------------------------------------------------------------------------*
  * HC functions
  *-------------------------------------------------------------------------*/
@@ -760,7 +769,7 @@ static void io_watchdog_func(struct timer_list *t)
  died:
                        usb_hc_died(ohci_to_hcd(ohci));
                        ohci_dump(ohci);
-                       ohci_shutdown(ohci_to_hcd(ohci));
+                       _ohci_shutdown(ohci_to_hcd(ohci));
                        goto done;
                } else {
                        /* No write back because the done queue was empty */
index f5f5326..c561881 100644 (file)
 
 #include "ohci.h"
 
-#include <mach/hardware.h>
-
 #define USB_CONFIG_BASE                0x31020000
-#define USB_OTG_STAT_CONTROL   IO_ADDRESS(USB_CONFIG_BASE + 0x110)
 
 /* USB_OTG_STAT_CONTROL bit defines */
 #define TRANSPARENT_I2C_EN     (1 << 7)
@@ -122,19 +119,33 @@ static inline void isp1301_vbus_off(void)
 
 static void ohci_nxp_start_hc(void)
 {
-       unsigned long tmp = __raw_readl(USB_OTG_STAT_CONTROL) | HOST_EN;
+       void __iomem *usb_otg_stat_control = ioremap(USB_CONFIG_BASE + 0x110, 4);
+       unsigned long tmp;
+
+       if (WARN_ON(!usb_otg_stat_control))
+               return;
+
+       tmp = __raw_readl(usb_otg_stat_control) | HOST_EN;
 
-       __raw_writel(tmp, USB_OTG_STAT_CONTROL);
+       __raw_writel(tmp, usb_otg_stat_control);
        isp1301_vbus_on();
+
+       iounmap(usb_otg_stat_control);
 }
 
 static void ohci_nxp_stop_hc(void)
 {
+       void __iomem *usb_otg_stat_control = ioremap(USB_CONFIG_BASE + 0x110, 4);
        unsigned long tmp;
 
+       if (WARN_ON(!usb_otg_stat_control))
+               return;
+
        isp1301_vbus_off();
-       tmp = __raw_readl(USB_OTG_STAT_CONTROL) & ~HOST_EN;
-       __raw_writel(tmp, USB_OTG_STAT_CONTROL);
+       tmp = __raw_readl(usb_otg_stat_control) & ~HOST_EN;
+       __raw_writel(tmp, usb_otg_stat_control);
+
+       iounmap(usb_otg_stat_control);
 }
 
 static int ohci_hcd_nxp_probe(struct platform_device *pdev)
index 8616c52..2b0ccd1 100644 (file)
@@ -104,7 +104,7 @@ static int xhci_rcar_is_gen2(struct device *dev)
        return of_device_is_compatible(node, "renesas,xhci-r8a7790") ||
                of_device_is_compatible(node, "renesas,xhci-r8a7791") ||
                of_device_is_compatible(node, "renesas,xhci-r8a7793") ||
-               of_device_is_compatible(node, "renensas,rcar-gen2-xhci");
+               of_device_is_compatible(node, "renesas,rcar-gen2-xhci");
 }
 
 static int xhci_rcar_is_gen3(struct device *dev)
index dafc659..2ff7c91 100644 (file)
@@ -1194,6 +1194,16 @@ static int tegra_xusb_probe(struct platform_device *pdev)
 
        tegra_xusb_config(tegra, regs);
 
+       /*
+        * The XUSB Falcon microcontroller can only address 40 bits, so set
+        * the DMA mask accordingly.
+        */
+       err = dma_set_mask_and_coherent(tegra->dev, DMA_BIT_MASK(40));
+       if (err < 0) {
+               dev_err(&pdev->dev, "failed to set DMA mask: %d\n", err);
+               goto put_rpm;
+       }
+
        err = tegra_xusb_load_firmware(tegra);
        if (err < 0) {
                dev_err(&pdev->dev, "failed to load firmware: %d\n", err);
index cc794e2..1d9ce9c 100644 (file)
@@ -38,7 +38,7 @@ MODULE_LICENSE("GPL");
 
 static int auto_delink_en = 1;
 module_param(auto_delink_en, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(auto_delink_en, "enable auto delink");
+MODULE_PARM_DESC(auto_delink_en, "auto delink mode (0=firmware, 1=software [default])");
 
 #ifdef CONFIG_REALTEK_AUTOPM
 static int ss_en = 1;
@@ -996,12 +996,15 @@ static int init_realtek_cr(struct us_data *us)
                        goto INIT_FAIL;
        }
 
-       if (CHECK_FW_VER(chip, 0x5888) || CHECK_FW_VER(chip, 0x5889) ||
-           CHECK_FW_VER(chip, 0x5901))
-               SET_AUTO_DELINK(chip);
-       if (STATUS_LEN(chip) == 16) {
-               if (SUPPORT_AUTO_DELINK(chip))
+       if (CHECK_PID(chip, 0x0138) || CHECK_PID(chip, 0x0158) ||
+           CHECK_PID(chip, 0x0159)) {
+               if (CHECK_FW_VER(chip, 0x5888) || CHECK_FW_VER(chip, 0x5889) ||
+                               CHECK_FW_VER(chip, 0x5901))
                        SET_AUTO_DELINK(chip);
+               if (STATUS_LEN(chip) == 16) {
+                       if (SUPPORT_AUTO_DELINK(chip))
+                               SET_AUTO_DELINK(chip);
+               }
        }
 #ifdef CONFIG_REALTEK_AUTOPM
        if (ss_en)
index ea0d27a..1cd9b63 100644 (file)
@@ -2100,7 +2100,7 @@ UNUSUAL_DEV(  0x14cd, 0x6600, 0x0201, 0x0201,
                US_FL_IGNORE_RESIDUE ),
 
 /* Reported by Michael Büsch <m@bues.ch> */
-UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0116,
+UNUSUAL_DEV(  0x152d, 0x0567, 0x0114, 0x0117,
                "JMicron",
                "USB to ATA/ATAPI Bridge",
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
index 15abe1d..bcfdb55 100644 (file)
@@ -1446,7 +1446,7 @@ static enum pdo_err tcpm_caps_err(struct tcpm_port *port, const u32 *pdo,
                                else if ((pdo_min_voltage(pdo[i]) ==
                                          pdo_min_voltage(pdo[i - 1])) &&
                                         (pdo_max_voltage(pdo[i]) ==
-                                         pdo_min_voltage(pdo[i - 1])))
+                                         pdo_max_voltage(pdo[i - 1])))
                                        return PDO_ERR_DUPE_PDO;
                                break;
                        /*
index 054391f..ad830ab 100644 (file)
@@ -650,12 +650,13 @@ unpin_exit:
 }
 
 static long vfio_sync_unpin(struct vfio_dma *dma, struct vfio_domain *domain,
-                               struct list_head *regions)
+                           struct list_head *regions,
+                           struct iommu_iotlb_gather *iotlb_gather)
 {
        long unlocked = 0;
        struct vfio_regions *entry, *next;
 
-       iommu_tlb_sync(domain->domain);
+       iommu_tlb_sync(domain->domain, iotlb_gather);
 
        list_for_each_entry_safe(entry, next, regions, list) {
                unlocked += vfio_unpin_pages_remote(dma,
@@ -685,18 +686,19 @@ static size_t unmap_unpin_fast(struct vfio_domain *domain,
                               struct vfio_dma *dma, dma_addr_t *iova,
                               size_t len, phys_addr_t phys, long *unlocked,
                               struct list_head *unmapped_list,
-                              int *unmapped_cnt)
+                              int *unmapped_cnt,
+                              struct iommu_iotlb_gather *iotlb_gather)
 {
        size_t unmapped = 0;
        struct vfio_regions *entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 
        if (entry) {
-               unmapped = iommu_unmap_fast(domain->domain, *iova, len);
+               unmapped = iommu_unmap_fast(domain->domain, *iova, len,
+                                           iotlb_gather);
 
                if (!unmapped) {
                        kfree(entry);
                } else {
-                       iommu_tlb_range_add(domain->domain, *iova, unmapped);
                        entry->iova = *iova;
                        entry->phys = phys;
                        entry->len  = unmapped;
@@ -712,8 +714,8 @@ static size_t unmap_unpin_fast(struct vfio_domain *domain,
         * or in case of errors.
         */
        if (*unmapped_cnt >= VFIO_IOMMU_TLB_SYNC_MAX || !unmapped) {
-               *unlocked += vfio_sync_unpin(dma, domain,
-                                            unmapped_list);
+               *unlocked += vfio_sync_unpin(dma, domain, unmapped_list,
+                                            iotlb_gather);
                *unmapped_cnt = 0;
        }
 
@@ -744,6 +746,7 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma,
        dma_addr_t iova = dma->iova, end = dma->iova + dma->size;
        struct vfio_domain *domain, *d;
        LIST_HEAD(unmapped_region_list);
+       struct iommu_iotlb_gather iotlb_gather;
        int unmapped_region_cnt = 0;
        long unlocked = 0;
 
@@ -768,6 +771,7 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma,
                cond_resched();
        }
 
+       iommu_iotlb_gather_init(&iotlb_gather);
        while (iova < end) {
                size_t unmapped, len;
                phys_addr_t phys, next;
@@ -796,7 +800,8 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma,
                 */
                unmapped = unmap_unpin_fast(domain, dma, &iova, len, phys,
                                            &unlocked, &unmapped_region_list,
-                                           &unmapped_region_cnt);
+                                           &unmapped_region_cnt,
+                                           &iotlb_gather);
                if (!unmapped) {
                        unmapped = unmap_unpin_slow(domain, dma, &iova, len,
                                                    phys, &unlocked);
@@ -807,8 +812,10 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma,
 
        dma->iommu_mapped = false;
 
-       if (unmapped_region_cnt)
-               unlocked += vfio_sync_unpin(dma, domain, &unmapped_region_list);
+       if (unmapped_region_cnt) {
+               unlocked += vfio_sync_unpin(dma, domain, &unmapped_region_list,
+                                           &iotlb_gather);
+       }
 
        if (do_accounting) {
                vfio_lock_acct(dma, -unlocked, true);
index 9e90e96..7804869 100644 (file)
  * Using this limit prevents one virtqueue from starving others. */
 #define VHOST_TEST_WEIGHT 0x80000
 
+/* Max number of packets transferred before requeueing the job.
+ * Using this limit prevents one virtqueue from starving others with
+ * pkts.
+ */
+#define VHOST_TEST_PKT_WEIGHT 256
+
 enum {
        VHOST_TEST_VQ = 0,
        VHOST_TEST_VQ_MAX = 1,
@@ -80,10 +86,8 @@ static void handle_vq(struct vhost_test *n)
                }
                vhost_add_used_and_signal(&n->dev, vq, head, 0);
                total_len += len;
-               if (unlikely(total_len >= VHOST_TEST_WEIGHT)) {
-                       vhost_poll_queue(&vq->poll);
+               if (unlikely(vhost_exceeds_weight(vq, 0, total_len)))
                        break;
-               }
        }
 
        mutex_unlock(&vq->mutex);
@@ -115,7 +119,8 @@ static int vhost_test_open(struct inode *inode, struct file *f)
        dev = &n->dev;
        vqs[VHOST_TEST_VQ] = &n->vqs[VHOST_TEST_VQ];
        n->vqs[VHOST_TEST_VQ].handle_kick = handle_vq_kick;
-       vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX);
+       vhost_dev_init(dev, vqs, VHOST_TEST_VQ_MAX, UIO_MAXIOV,
+                      VHOST_TEST_PKT_WEIGHT, VHOST_TEST_WEIGHT);
 
        f->private_data = n;
 
index 0536f85..36ca2cf 100644 (file)
@@ -203,7 +203,6 @@ EXPORT_SYMBOL_GPL(vhost_poll_init);
 int vhost_poll_start(struct vhost_poll *poll, struct file *file)
 {
        __poll_t mask;
-       int ret = 0;
 
        if (poll->wqh)
                return 0;
@@ -213,10 +212,10 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file)
                vhost_poll_wakeup(&poll->wait, 0, 0, poll_to_key(mask));
        if (mask & EPOLLERR) {
                vhost_poll_stop(poll);
-               ret = -EINVAL;
+               return -EINVAL;
        }
 
-       return ret;
+       return 0;
 }
 EXPORT_SYMBOL_GPL(vhost_poll_start);
 
@@ -298,160 +297,6 @@ static void vhost_vq_meta_reset(struct vhost_dev *d)
                __vhost_vq_meta_reset(d->vqs[i]);
 }
 
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-static void vhost_map_unprefetch(struct vhost_map *map)
-{
-       kfree(map->pages);
-       map->pages = NULL;
-       map->npages = 0;
-       map->addr = NULL;
-}
-
-static void vhost_uninit_vq_maps(struct vhost_virtqueue *vq)
-{
-       struct vhost_map *map[VHOST_NUM_ADDRS];
-       int i;
-
-       spin_lock(&vq->mmu_lock);
-       for (i = 0; i < VHOST_NUM_ADDRS; i++) {
-               map[i] = rcu_dereference_protected(vq->maps[i],
-                                 lockdep_is_held(&vq->mmu_lock));
-               if (map[i])
-                       rcu_assign_pointer(vq->maps[i], NULL);
-       }
-       spin_unlock(&vq->mmu_lock);
-
-       synchronize_rcu();
-
-       for (i = 0; i < VHOST_NUM_ADDRS; i++)
-               if (map[i])
-                       vhost_map_unprefetch(map[i]);
-
-}
-
-static void vhost_reset_vq_maps(struct vhost_virtqueue *vq)
-{
-       int i;
-
-       vhost_uninit_vq_maps(vq);
-       for (i = 0; i < VHOST_NUM_ADDRS; i++)
-               vq->uaddrs[i].size = 0;
-}
-
-static bool vhost_map_range_overlap(struct vhost_uaddr *uaddr,
-                                    unsigned long start,
-                                    unsigned long end)
-{
-       if (unlikely(!uaddr->size))
-               return false;
-
-       return !(end < uaddr->uaddr || start > uaddr->uaddr - 1 + uaddr->size);
-}
-
-static void vhost_invalidate_vq_start(struct vhost_virtqueue *vq,
-                                     int index,
-                                     unsigned long start,
-                                     unsigned long end)
-{
-       struct vhost_uaddr *uaddr = &vq->uaddrs[index];
-       struct vhost_map *map;
-       int i;
-
-       if (!vhost_map_range_overlap(uaddr, start, end))
-               return;
-
-       spin_lock(&vq->mmu_lock);
-       ++vq->invalidate_count;
-
-       map = rcu_dereference_protected(vq->maps[index],
-                                       lockdep_is_held(&vq->mmu_lock));
-       if (map) {
-               if (uaddr->write) {
-                       for (i = 0; i < map->npages; i++)
-                               set_page_dirty(map->pages[i]);
-               }
-               rcu_assign_pointer(vq->maps[index], NULL);
-       }
-       spin_unlock(&vq->mmu_lock);
-
-       if (map) {
-               synchronize_rcu();
-               vhost_map_unprefetch(map);
-       }
-}
-
-static void vhost_invalidate_vq_end(struct vhost_virtqueue *vq,
-                                   int index,
-                                   unsigned long start,
-                                   unsigned long end)
-{
-       if (!vhost_map_range_overlap(&vq->uaddrs[index], start, end))
-               return;
-
-       spin_lock(&vq->mmu_lock);
-       --vq->invalidate_count;
-       spin_unlock(&vq->mmu_lock);
-}
-
-static int vhost_invalidate_range_start(struct mmu_notifier *mn,
-                                       const struct mmu_notifier_range *range)
-{
-       struct vhost_dev *dev = container_of(mn, struct vhost_dev,
-                                            mmu_notifier);
-       int i, j;
-
-       if (!mmu_notifier_range_blockable(range))
-               return -EAGAIN;
-
-       for (i = 0; i < dev->nvqs; i++) {
-               struct vhost_virtqueue *vq = dev->vqs[i];
-
-               for (j = 0; j < VHOST_NUM_ADDRS; j++)
-                       vhost_invalidate_vq_start(vq, j,
-                                                 range->start,
-                                                 range->end);
-       }
-
-       return 0;
-}
-
-static void vhost_invalidate_range_end(struct mmu_notifier *mn,
-                                      const struct mmu_notifier_range *range)
-{
-       struct vhost_dev *dev = container_of(mn, struct vhost_dev,
-                                            mmu_notifier);
-       int i, j;
-
-       for (i = 0; i < dev->nvqs; i++) {
-               struct vhost_virtqueue *vq = dev->vqs[i];
-
-               for (j = 0; j < VHOST_NUM_ADDRS; j++)
-                       vhost_invalidate_vq_end(vq, j,
-                                               range->start,
-                                               range->end);
-       }
-}
-
-static const struct mmu_notifier_ops vhost_mmu_notifier_ops = {
-       .invalidate_range_start = vhost_invalidate_range_start,
-       .invalidate_range_end = vhost_invalidate_range_end,
-};
-
-static void vhost_init_maps(struct vhost_dev *dev)
-{
-       struct vhost_virtqueue *vq;
-       int i, j;
-
-       dev->mmu_notifier.ops = &vhost_mmu_notifier_ops;
-
-       for (i = 0; i < dev->nvqs; ++i) {
-               vq = dev->vqs[i];
-               for (j = 0; j < VHOST_NUM_ADDRS; j++)
-                       RCU_INIT_POINTER(vq->maps[j], NULL);
-       }
-}
-#endif
-
 static void vhost_vq_reset(struct vhost_dev *dev,
                           struct vhost_virtqueue *vq)
 {
@@ -480,11 +325,7 @@ static void vhost_vq_reset(struct vhost_dev *dev,
        vq->busyloop_timeout = 0;
        vq->umem = NULL;
        vq->iotlb = NULL;
-       vq->invalidate_count = 0;
        __vhost_vq_meta_reset(vq);
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       vhost_reset_vq_maps(vq);
-#endif
 }
 
 static int vhost_worker(void *data)
@@ -634,9 +475,7 @@ void vhost_dev_init(struct vhost_dev *dev,
        INIT_LIST_HEAD(&dev->read_list);
        INIT_LIST_HEAD(&dev->pending_list);
        spin_lock_init(&dev->iotlb_lock);
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       vhost_init_maps(dev);
-#endif
+
 
        for (i = 0; i < dev->nvqs; ++i) {
                vq = dev->vqs[i];
@@ -645,7 +484,6 @@ void vhost_dev_init(struct vhost_dev *dev,
                vq->heads = NULL;
                vq->dev = dev;
                mutex_init(&vq->mutex);
-               spin_lock_init(&vq->mmu_lock);
                vhost_vq_reset(dev, vq);
                if (vq->handle_kick)
                        vhost_poll_init(&vq->poll, vq->handle_kick,
@@ -725,18 +563,7 @@ long vhost_dev_set_owner(struct vhost_dev *dev)
        if (err)
                goto err_cgroup;
 
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       err = mmu_notifier_register(&dev->mmu_notifier, dev->mm);
-       if (err)
-               goto err_mmu_notifier;
-#endif
-
        return 0;
-
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-err_mmu_notifier:
-       vhost_dev_free_iovecs(dev);
-#endif
 err_cgroup:
        kthread_stop(worker);
        dev->worker = NULL;
@@ -827,107 +654,6 @@ static void vhost_clear_msg(struct vhost_dev *dev)
        spin_unlock(&dev->iotlb_lock);
 }
 
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-static void vhost_setup_uaddr(struct vhost_virtqueue *vq,
-                             int index, unsigned long uaddr,
-                             size_t size, bool write)
-{
-       struct vhost_uaddr *addr = &vq->uaddrs[index];
-
-       addr->uaddr = uaddr;
-       addr->size = size;
-       addr->write = write;
-}
-
-static void vhost_setup_vq_uaddr(struct vhost_virtqueue *vq)
-{
-       vhost_setup_uaddr(vq, VHOST_ADDR_DESC,
-                         (unsigned long)vq->desc,
-                         vhost_get_desc_size(vq, vq->num),
-                         false);
-       vhost_setup_uaddr(vq, VHOST_ADDR_AVAIL,
-                         (unsigned long)vq->avail,
-                         vhost_get_avail_size(vq, vq->num),
-                         false);
-       vhost_setup_uaddr(vq, VHOST_ADDR_USED,
-                         (unsigned long)vq->used,
-                         vhost_get_used_size(vq, vq->num),
-                         true);
-}
-
-static int vhost_map_prefetch(struct vhost_virtqueue *vq,
-                              int index)
-{
-       struct vhost_map *map;
-       struct vhost_uaddr *uaddr = &vq->uaddrs[index];
-       struct page **pages;
-       int npages = DIV_ROUND_UP(uaddr->size, PAGE_SIZE);
-       int npinned;
-       void *vaddr, *v;
-       int err;
-       int i;
-
-       spin_lock(&vq->mmu_lock);
-
-       err = -EFAULT;
-       if (vq->invalidate_count)
-               goto err;
-
-       err = -ENOMEM;
-       map = kmalloc(sizeof(*map), GFP_ATOMIC);
-       if (!map)
-               goto err;
-
-       pages = kmalloc_array(npages, sizeof(struct page *), GFP_ATOMIC);
-       if (!pages)
-               goto err_pages;
-
-       err = EFAULT;
-       npinned = __get_user_pages_fast(uaddr->uaddr, npages,
-                                       uaddr->write, pages);
-       if (npinned > 0)
-               release_pages(pages, npinned);
-       if (npinned != npages)
-               goto err_gup;
-
-       for (i = 0; i < npinned; i++)
-               if (PageHighMem(pages[i]))
-                       goto err_gup;
-
-       vaddr = v = page_address(pages[0]);
-
-       /* For simplicity, fallback to userspace address if VA is not
-        * contigious.
-        */
-       for (i = 1; i < npinned; i++) {
-               v += PAGE_SIZE;
-               if (v != page_address(pages[i]))
-                       goto err_gup;
-       }
-
-       map->addr = vaddr + (uaddr->uaddr & (PAGE_SIZE - 1));
-       map->npages = npages;
-       map->pages = pages;
-
-       rcu_assign_pointer(vq->maps[index], map);
-       /* No need for a synchronize_rcu(). This function should be
-        * called by dev->worker so we are serialized with all
-        * readers.
-        */
-       spin_unlock(&vq->mmu_lock);
-
-       return 0;
-
-err_gup:
-       kfree(pages);
-err_pages:
-       kfree(map);
-err:
-       spin_unlock(&vq->mmu_lock);
-       return err;
-}
-#endif
-
 void vhost_dev_cleanup(struct vhost_dev *dev)
 {
        int i;
@@ -957,16 +683,8 @@ void vhost_dev_cleanup(struct vhost_dev *dev)
                kthread_stop(dev->worker);
                dev->worker = NULL;
        }
-       if (dev->mm) {
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-               mmu_notifier_unregister(&dev->mmu_notifier, dev->mm);
-#endif
+       if (dev->mm)
                mmput(dev->mm);
-       }
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       for (i = 0; i < dev->nvqs; i++)
-               vhost_uninit_vq_maps(dev->vqs[i]);
-#endif
        dev->mm = NULL;
 }
 EXPORT_SYMBOL_GPL(vhost_dev_cleanup);
@@ -1195,26 +913,6 @@ static inline void __user *__vhost_get_user(struct vhost_virtqueue *vq,
 
 static inline int vhost_put_avail_event(struct vhost_virtqueue *vq)
 {
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       struct vhost_map *map;
-       struct vring_used *used;
-
-       if (!vq->iotlb) {
-               rcu_read_lock();
-
-               map = rcu_dereference(vq->maps[VHOST_ADDR_USED]);
-               if (likely(map)) {
-                       used = map->addr;
-                       *((__virtio16 *)&used->ring[vq->num]) =
-                               cpu_to_vhost16(vq, vq->avail_idx);
-                       rcu_read_unlock();
-                       return 0;
-               }
-
-               rcu_read_unlock();
-       }
-#endif
-
        return vhost_put_user(vq, cpu_to_vhost16(vq, vq->avail_idx),
                              vhost_avail_event(vq));
 }
@@ -1223,27 +921,6 @@ static inline int vhost_put_used(struct vhost_virtqueue *vq,
                                 struct vring_used_elem *head, int idx,
                                 int count)
 {
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       struct vhost_map *map;
-       struct vring_used *used;
-       size_t size;
-
-       if (!vq->iotlb) {
-               rcu_read_lock();
-
-               map = rcu_dereference(vq->maps[VHOST_ADDR_USED]);
-               if (likely(map)) {
-                       used = map->addr;
-                       size = count * sizeof(*head);
-                       memcpy(used->ring + idx, head, size);
-                       rcu_read_unlock();
-                       return 0;
-               }
-
-               rcu_read_unlock();
-       }
-#endif
-
        return vhost_copy_to_user(vq, vq->used->ring + idx, head,
                                  count * sizeof(*head));
 }
@@ -1251,25 +928,6 @@ static inline int vhost_put_used(struct vhost_virtqueue *vq,
 static inline int vhost_put_used_flags(struct vhost_virtqueue *vq)
 
 {
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       struct vhost_map *map;
-       struct vring_used *used;
-
-       if (!vq->iotlb) {
-               rcu_read_lock();
-
-               map = rcu_dereference(vq->maps[VHOST_ADDR_USED]);
-               if (likely(map)) {
-                       used = map->addr;
-                       used->flags = cpu_to_vhost16(vq, vq->used_flags);
-                       rcu_read_unlock();
-                       return 0;
-               }
-
-               rcu_read_unlock();
-       }
-#endif
-
        return vhost_put_user(vq, cpu_to_vhost16(vq, vq->used_flags),
                              &vq->used->flags);
 }
@@ -1277,25 +935,6 @@ static inline int vhost_put_used_flags(struct vhost_virtqueue *vq)
 static inline int vhost_put_used_idx(struct vhost_virtqueue *vq)
 
 {
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       struct vhost_map *map;
-       struct vring_used *used;
-
-       if (!vq->iotlb) {
-               rcu_read_lock();
-
-               map = rcu_dereference(vq->maps[VHOST_ADDR_USED]);
-               if (likely(map)) {
-                       used = map->addr;
-                       used->idx = cpu_to_vhost16(vq, vq->last_used_idx);
-                       rcu_read_unlock();
-                       return 0;
-               }
-
-               rcu_read_unlock();
-       }
-#endif
-
        return vhost_put_user(vq, cpu_to_vhost16(vq, vq->last_used_idx),
                              &vq->used->idx);
 }
@@ -1341,50 +980,12 @@ static void vhost_dev_unlock_vqs(struct vhost_dev *d)
 static inline int vhost_get_avail_idx(struct vhost_virtqueue *vq,
                                      __virtio16 *idx)
 {
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       struct vhost_map *map;
-       struct vring_avail *avail;
-
-       if (!vq->iotlb) {
-               rcu_read_lock();
-
-               map = rcu_dereference(vq->maps[VHOST_ADDR_AVAIL]);
-               if (likely(map)) {
-                       avail = map->addr;
-                       *idx = avail->idx;
-                       rcu_read_unlock();
-                       return 0;
-               }
-
-               rcu_read_unlock();
-       }
-#endif
-
        return vhost_get_avail(vq, *idx, &vq->avail->idx);
 }
 
 static inline int vhost_get_avail_head(struct vhost_virtqueue *vq,
                                       __virtio16 *head, int idx)
 {
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       struct vhost_map *map;
-       struct vring_avail *avail;
-
-       if (!vq->iotlb) {
-               rcu_read_lock();
-
-               map = rcu_dereference(vq->maps[VHOST_ADDR_AVAIL]);
-               if (likely(map)) {
-                       avail = map->addr;
-                       *head = avail->ring[idx & (vq->num - 1)];
-                       rcu_read_unlock();
-                       return 0;
-               }
-
-               rcu_read_unlock();
-       }
-#endif
-
        return vhost_get_avail(vq, *head,
                               &vq->avail->ring[idx & (vq->num - 1)]);
 }
@@ -1392,98 +993,24 @@ static inline int vhost_get_avail_head(struct vhost_virtqueue *vq,
 static inline int vhost_get_avail_flags(struct vhost_virtqueue *vq,
                                        __virtio16 *flags)
 {
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       struct vhost_map *map;
-       struct vring_avail *avail;
-
-       if (!vq->iotlb) {
-               rcu_read_lock();
-
-               map = rcu_dereference(vq->maps[VHOST_ADDR_AVAIL]);
-               if (likely(map)) {
-                       avail = map->addr;
-                       *flags = avail->flags;
-                       rcu_read_unlock();
-                       return 0;
-               }
-
-               rcu_read_unlock();
-       }
-#endif
-
        return vhost_get_avail(vq, *flags, &vq->avail->flags);
 }
 
 static inline int vhost_get_used_event(struct vhost_virtqueue *vq,
                                       __virtio16 *event)
 {
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       struct vhost_map *map;
-       struct vring_avail *avail;
-
-       if (!vq->iotlb) {
-               rcu_read_lock();
-               map = rcu_dereference(vq->maps[VHOST_ADDR_AVAIL]);
-               if (likely(map)) {
-                       avail = map->addr;
-                       *event = (__virtio16)avail->ring[vq->num];
-                       rcu_read_unlock();
-                       return 0;
-               }
-               rcu_read_unlock();
-       }
-#endif
-
        return vhost_get_avail(vq, *event, vhost_used_event(vq));
 }
 
 static inline int vhost_get_used_idx(struct vhost_virtqueue *vq,
                                     __virtio16 *idx)
 {
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       struct vhost_map *map;
-       struct vring_used *used;
-
-       if (!vq->iotlb) {
-               rcu_read_lock();
-
-               map = rcu_dereference(vq->maps[VHOST_ADDR_USED]);
-               if (likely(map)) {
-                       used = map->addr;
-                       *idx = used->idx;
-                       rcu_read_unlock();
-                       return 0;
-               }
-
-               rcu_read_unlock();
-       }
-#endif
-
        return vhost_get_used(vq, *idx, &vq->used->idx);
 }
 
 static inline int vhost_get_desc(struct vhost_virtqueue *vq,
                                 struct vring_desc *desc, int idx)
 {
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       struct vhost_map *map;
-       struct vring_desc *d;
-
-       if (!vq->iotlb) {
-               rcu_read_lock();
-
-               map = rcu_dereference(vq->maps[VHOST_ADDR_DESC]);
-               if (likely(map)) {
-                       d = map->addr;
-                       *desc = *(d + idx);
-                       rcu_read_unlock();
-                       return 0;
-               }
-
-               rcu_read_unlock();
-       }
-#endif
-
        return vhost_copy_from_user(vq, desc, vq->desc + idx, sizeof(*desc));
 }
 
@@ -1824,32 +1351,12 @@ static bool iotlb_access_ok(struct vhost_virtqueue *vq,
        return true;
 }
 
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-static void vhost_vq_map_prefetch(struct vhost_virtqueue *vq)
-{
-       struct vhost_map __rcu *map;
-       int i;
-
-       for (i = 0; i < VHOST_NUM_ADDRS; i++) {
-               rcu_read_lock();
-               map = rcu_dereference(vq->maps[i]);
-               rcu_read_unlock();
-               if (unlikely(!map))
-                       vhost_map_prefetch(vq, i);
-       }
-}
-#endif
-
 int vq_meta_prefetch(struct vhost_virtqueue *vq)
 {
        unsigned int num = vq->num;
 
-       if (!vq->iotlb) {
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-               vhost_vq_map_prefetch(vq);
-#endif
+       if (!vq->iotlb)
                return 1;
-       }
 
        return iotlb_access_ok(vq, VHOST_ACCESS_RO, (u64)(uintptr_t)vq->desc,
                               vhost_get_desc_size(vq, num), VHOST_ADDR_DESC) &&
@@ -2060,16 +1567,6 @@ static long vhost_vring_set_num_addr(struct vhost_dev *d,
 
        mutex_lock(&vq->mutex);
 
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       /* Unregister MMU notifer to allow invalidation callback
-        * can access vq->uaddrs[] without holding a lock.
-        */
-       if (d->mm)
-               mmu_notifier_unregister(&d->mmu_notifier, d->mm);
-
-       vhost_uninit_vq_maps(vq);
-#endif
-
        switch (ioctl) {
        case VHOST_SET_VRING_NUM:
                r = vhost_vring_set_num(d, vq, argp);
@@ -2081,13 +1578,6 @@ static long vhost_vring_set_num_addr(struct vhost_dev *d,
                BUG();
        }
 
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       vhost_setup_vq_uaddr(vq);
-
-       if (d->mm)
-               mmu_notifier_register(&d->mmu_notifier, d->mm);
-#endif
-
        mutex_unlock(&vq->mutex);
 
        return r;
@@ -2688,7 +2178,7 @@ static int get_indirect(struct vhost_virtqueue *vq,
                /* If this is an input descriptor, increment that count. */
                if (access == VHOST_ACCESS_WO) {
                        *in_num += ret;
-                       if (unlikely(log)) {
+                       if (unlikely(log && ret)) {
                                log[*log_num].addr = vhost64_to_cpu(vq, desc.addr);
                                log[*log_num].len = vhost32_to_cpu(vq, desc.len);
                                ++*log_num;
@@ -2829,7 +2319,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
                        /* If this is an input descriptor,
                         * increment that count. */
                        *in_num += ret;
-                       if (unlikely(log)) {
+                       if (unlikely(log && ret)) {
                                log[*log_num].addr = vhost64_to_cpu(vq, desc.addr);
                                log[*log_num].len = vhost32_to_cpu(vq, desc.len);
                                ++*log_num;
index 42a8c2a..e9ed272 100644 (file)
@@ -12,9 +12,6 @@
 #include <linux/virtio_config.h>
 #include <linux/virtio_ring.h>
 #include <linux/atomic.h>
-#include <linux/pagemap.h>
-#include <linux/mmu_notifier.h>
-#include <asm/cacheflush.h>
 
 struct vhost_work;
 typedef void (*vhost_work_fn_t)(struct vhost_work *work);
@@ -83,24 +80,6 @@ enum vhost_uaddr_type {
        VHOST_NUM_ADDRS = 3,
 };
 
-struct vhost_map {
-       int npages;
-       void *addr;
-       struct page **pages;
-};
-
-struct vhost_uaddr {
-       unsigned long uaddr;
-       size_t size;
-       bool write;
-};
-
-#if defined(CONFIG_MMU_NOTIFIER) && ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE == 0
-#define VHOST_ARCH_CAN_ACCEL_UACCESS 0
-#else
-#define VHOST_ARCH_CAN_ACCEL_UACCESS 0
-#endif
-
 /* The virtqueue structure describes a queue attached to a device. */
 struct vhost_virtqueue {
        struct vhost_dev *dev;
@@ -111,22 +90,7 @@ struct vhost_virtqueue {
        struct vring_desc __user *desc;
        struct vring_avail __user *avail;
        struct vring_used __user *used;
-
-#if VHOST_ARCH_CAN_ACCEL_UACCESS
-       /* Read by memory accessors, modified by meta data
-        * prefetching, MMU notifier and vring ioctl().
-        * Synchonrized through mmu_lock (writers) and RCU (writers
-        * and readers).
-        */
-       struct vhost_map __rcu *maps[VHOST_NUM_ADDRS];
-       /* Read by MMU notifier, modified by vring ioctl(),
-        * synchronized through MMU notifier
-        * registering/unregistering.
-        */
-       struct vhost_uaddr uaddrs[VHOST_NUM_ADDRS];
-#endif
        const struct vhost_umem_node *meta_iotlb[VHOST_NUM_ADDRS];
-
        struct file *kick;
        struct eventfd_ctx *call_ctx;
        struct eventfd_ctx *error_ctx;
@@ -181,8 +145,6 @@ struct vhost_virtqueue {
        bool user_be;
 #endif
        u32 busyloop_timeout;
-       spinlock_t mmu_lock;
-       int invalidate_count;
 };
 
 struct vhost_msg_node {
@@ -196,9 +158,6 @@ struct vhost_msg_node {
 
 struct vhost_dev {
        struct mm_struct *mm;
-#ifdef CONFIG_MMU_NOTIFIER
-       struct mmu_notifier mmu_notifier;
-#endif
        struct mutex mutex;
        struct vhost_virtqueue **vqs;
        int nvqs;
index 6b2de93..5f83cd7 100644 (file)
@@ -1924,20 +1924,6 @@ config FB_S3C2410_DEBUG
          Turn on debugging messages. Note that you can set/unset at run time
          through sysfs
 
-config FB_NUC900
-       tristate "NUC900 LCD framebuffer support"
-       depends on FB && ARCH_W90X900
-       select FB_CFB_FILLRECT
-       select FB_CFB_COPYAREA
-       select FB_CFB_IMAGEBLIT
-       ---help---
-         Frame buffer driver for the built-in LCD controller in the Nuvoton
-         NUC900 processor
-
-config GPM1040A0_320X240
-       bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD"
-       depends on FB_NUC900
-
 config FB_SM501
        tristate "Silicon Motion SM501 framebuffer support"
        depends on FB && MFD_SM501
index 7dc4861..aab7155 100644 (file)
@@ -116,7 +116,6 @@ obj-y                             += omap2/
 obj-$(CONFIG_XEN_FBDEV_FRONTEND)  += xen-fbfront.o
 obj-$(CONFIG_FB_CARMINE)          += carminefb.o
 obj-$(CONFIG_FB_MB862XX)         += mb862xx/
-obj-$(CONFIG_FB_NUC900)           += nuc900fb.o
 obj-$(CONFIG_FB_JZ4740)                  += jz4740_fb.o
 obj-$(CONFIG_FB_PUV3_UNIGFX)      += fb-puv3.o
 obj-$(CONFIG_FB_HYPERV)                  += hyperv_fb.o
index fc9dfb0..51f5d1c 100644 (file)
@@ -763,17 +763,17 @@ static void tt_get_par(struct atafb_par *par)
 {
        unsigned long addr;
        par->hw.tt.mode = shifter_tt.tt_shiftmode;
-       par->hw.tt.sync = shifter.syncmode;
-       addr = ((shifter.bas_hi & 0xff) << 16) |
-              ((shifter.bas_md & 0xff) << 8)  |
-              ((shifter.bas_lo & 0xff));
+       par->hw.tt.sync = shifter_st.syncmode;
+       addr = ((shifter_st.bas_hi & 0xff) << 16) |
+              ((shifter_st.bas_md & 0xff) << 8)  |
+              ((shifter_st.bas_lo & 0xff));
        par->screen_base = atari_stram_to_virt(addr);
 }
 
 static void tt_set_par(struct atafb_par *par)
 {
        shifter_tt.tt_shiftmode = par->hw.tt.mode;
-       shifter.syncmode = par->hw.tt.sync;
+       shifter_st.syncmode = par->hw.tt.sync;
        /* only set screen_base if really necessary */
        if (current_par.screen_base != par->screen_base)
                fbhw->set_screen_base(par->screen_base);
@@ -1543,7 +1543,7 @@ static void falcon_get_par(struct atafb_par *par)
        hw->f_shift = videl.f_shift;
        hw->vid_control = videl.control;
        hw->vid_mode = videl.mode;
-       hw->sync = shifter.syncmode & 0x1;
+       hw->sync = shifter_st.syncmode & 0x1;
        hw->xoffset = videl.xoffset & 0xf;
        hw->hht = videl.hht;
        hw->hbb = videl.hbb;
@@ -1558,9 +1558,9 @@ static void falcon_get_par(struct atafb_par *par)
        hw->vde = videl.vde;
        hw->vss = videl.vss;
 
-       addr = (shifter.bas_hi & 0xff) << 16 |
-              (shifter.bas_md & 0xff) << 8  |
-              (shifter.bas_lo & 0xff);
+       addr = (shifter_st.bas_hi & 0xff) << 16 |
+              (shifter_st.bas_md & 0xff) << 8  |
+              (shifter_st.bas_lo & 0xff);
        par->screen_base = atari_stram_to_virt(addr);
 
        /* derived parameters */
@@ -1605,7 +1605,7 @@ static irqreturn_t falcon_vbl_switcher(int irq, void *dummy)
                        /* Turn off external clocks. Read sets all output bits to 1. */
                        *(volatile unsigned short *)0xffff9202;
                }
-               shifter.syncmode = hw->sync;
+               shifter_st.syncmode = hw->sync;
 
                videl.hht = hw->hht;
                videl.hbb = hw->hbb;
@@ -1952,18 +1952,18 @@ static void stste_get_par(struct atafb_par *par)
 {
        unsigned long addr;
        par->hw.st.mode = shifter_tt.st_shiftmode;
-       par->hw.st.sync = shifter.syncmode;
-       addr = ((shifter.bas_hi & 0xff) << 16) |
-              ((shifter.bas_md & 0xff) << 8);
+       par->hw.st.sync = shifter_st.syncmode;
+       addr = ((shifter_st.bas_hi & 0xff) << 16) |
+              ((shifter_st.bas_md & 0xff) << 8);
        if (ATARIHW_PRESENT(EXTD_SHIFTER))
-               addr |= (shifter.bas_lo & 0xff);
+               addr |= (shifter_st.bas_lo & 0xff);
        par->screen_base = atari_stram_to_virt(addr);
 }
 
 static void stste_set_par(struct atafb_par *par)
 {
        shifter_tt.st_shiftmode = par->hw.st.mode;
-       shifter.syncmode = par->hw.st.sync;
+       shifter_st.syncmode = par->hw.st.sync;
        /* only set screen_base if really necessary */
        if (current_par.screen_base != par->screen_base)
                fbhw->set_screen_base(par->screen_base);
@@ -2018,10 +2018,10 @@ static void stste_set_screen_base(void *s_base)
        unsigned long addr;
        addr = atari_stram_to_phys(s_base);
        /* Setup Screen Memory */
-       shifter.bas_hi = (unsigned char)((addr & 0xff0000) >> 16);
-       shifter.bas_md = (unsigned char)((addr & 0x00ff00) >> 8);
+       shifter_st.bas_hi = (unsigned char)((addr & 0xff0000) >> 16);
+       shifter_st.bas_md = (unsigned char)((addr & 0x00ff00) >> 8);
        if (ATARIHW_PRESENT(EXTD_SHIFTER))
-               shifter.bas_lo = (unsigned char)(addr & 0x0000ff);
+               shifter_st.bas_lo = (unsigned char)(addr & 0x0000ff);
 }
 
 #endif /* ATAFB_STE */
@@ -2265,9 +2265,9 @@ static void set_screen_base(void *s_base)
 
        addr = atari_stram_to_phys(s_base);
        /* Setup Screen Memory */
-       shifter.bas_hi = (unsigned char)((addr & 0xff0000) >> 16);
-       shifter.bas_md = (unsigned char)((addr & 0x00ff00) >> 8);
-       shifter.bas_lo = (unsigned char)(addr & 0x0000ff);
+       shifter_st.bas_hi = (unsigned char)((addr & 0xff0000) >> 16);
+       shifter_st.bas_md = (unsigned char)((addr & 0x00ff00) >> 8);
+       shifter_st.bas_lo = (unsigned char)(addr & 0x0000ff);
 }
 
 static int pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
index b1cf248..2d3dcc5 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 #include <linux/cpufreq.h>
 #include <linux/console.h>
+#include <linux/regulator/consumer.h>
 #include <linux/spinlock.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -164,7 +165,7 @@ struct da8xx_fb_par {
        struct notifier_block   freq_transition;
 #endif
        unsigned int            lcdc_clk_rate;
-       void (*panel_power_ctrl)(int);
+       struct regulator        *lcd_supply;
        u32 pseudo_palette[16];
        struct fb_videomode     mode;
        struct lcd_ctrl_config  cfg;
@@ -1066,33 +1067,30 @@ static void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par)
 static int fb_remove(struct platform_device *dev)
 {
        struct fb_info *info = dev_get_drvdata(&dev->dev);
-
-       if (info) {
-               struct da8xx_fb_par *par = info->par;
+       struct da8xx_fb_par *par = info->par;
+       int ret;
 
 #ifdef CONFIG_CPU_FREQ
-               lcd_da8xx_cpufreq_deregister(par);
+       lcd_da8xx_cpufreq_deregister(par);
 #endif
-               if (par->panel_power_ctrl)
-                       par->panel_power_ctrl(0);
+       if (par->lcd_supply) {
+               ret = regulator_disable(par->lcd_supply);
+               if (ret)
+                       return ret;
+       }
 
-               lcd_disable_raster(DA8XX_FRAME_WAIT);
-               lcdc_write(0, LCD_RASTER_CTRL_REG);
+       lcd_disable_raster(DA8XX_FRAME_WAIT);
+       lcdc_write(0, LCD_RASTER_CTRL_REG);
 
-               /* disable DMA  */
-               lcdc_write(0, LCD_DMA_CTRL_REG);
+       /* disable DMA  */
+       lcdc_write(0, LCD_DMA_CTRL_REG);
 
-               unregister_framebuffer(info);
-               fb_dealloc_cmap(&info->cmap);
-               dma_free_coherent(par->dev, PALETTE_SIZE, par->v_palette_base,
-                                 par->p_palette_base);
-               dma_free_coherent(par->dev, par->vram_size, par->vram_virt,
-                                 par->vram_phys);
-               pm_runtime_put_sync(&dev->dev);
-               pm_runtime_disable(&dev->dev);
-               framebuffer_release(info);
+       unregister_framebuffer(info);
+       fb_dealloc_cmap(&info->cmap);
+       pm_runtime_put_sync(&dev->dev);
+       pm_runtime_disable(&dev->dev);
+       framebuffer_release(info);
 
-       }
        return 0;
 }
 
@@ -1179,15 +1177,21 @@ static int cfb_blank(int blank, struct fb_info *info)
        case FB_BLANK_UNBLANK:
                lcd_enable_raster();
 
-               if (par->panel_power_ctrl)
-                       par->panel_power_ctrl(1);
+               if (par->lcd_supply) {
+                       ret = regulator_enable(par->lcd_supply);
+                       if (ret)
+                               return ret;
+               }
                break;
        case FB_BLANK_NORMAL:
        case FB_BLANK_VSYNC_SUSPEND:
        case FB_BLANK_HSYNC_SUSPEND:
        case FB_BLANK_POWERDOWN:
-               if (par->panel_power_ctrl)
-                       par->panel_power_ctrl(0);
+               if (par->lcd_supply) {
+                       ret = regulator_disable(par->lcd_supply);
+                       if (ret)
+                               return ret;
+               }
 
                lcd_disable_raster(DA8XX_FRAME_WAIT);
                break;
@@ -1328,7 +1332,6 @@ static int fb_probe(struct platform_device *device)
 {
        struct da8xx_lcdc_platform_data *fb_pdata =
                                                dev_get_platdata(&device->dev);
-       struct resource *lcdc_regs;
        struct lcd_ctrl_config *lcd_cfg;
        struct fb_videomode *lcdc_info;
        struct fb_info *da8xx_fb_info;
@@ -1346,8 +1349,7 @@ static int fb_probe(struct platform_device *device)
        if (lcdc_info == NULL)
                return -ENODEV;
 
-       lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
-       da8xx_fb_reg_base = devm_ioremap_resource(&device->dev, lcdc_regs);
+       da8xx_fb_reg_base = devm_platform_ioremap_resource(device, 0);
        if (IS_ERR(da8xx_fb_reg_base))
                return PTR_ERR(da8xx_fb_reg_base);
 
@@ -1395,9 +1397,19 @@ static int fb_probe(struct platform_device *device)
        par->dev = &device->dev;
        par->lcdc_clk = tmp_lcdc_clk;
        par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk);
-       if (fb_pdata->panel_power_ctrl) {
-               par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
-               par->panel_power_ctrl(1);
+
+       par->lcd_supply = devm_regulator_get_optional(&device->dev, "lcd");
+       if (IS_ERR(par->lcd_supply)) {
+               if (PTR_ERR(par->lcd_supply) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+                       goto err_pm_runtime_disable;
+               }
+
+               par->lcd_supply = NULL;
+       } else {
+               ret = regulator_enable(par->lcd_supply);
+               if (ret)
+                       goto err_pm_runtime_disable;
        }
 
        fb_videomode_to_var(&da8xx_fb_var, lcdc_info);
@@ -1411,10 +1423,10 @@ static int fb_probe(struct platform_device *device)
        par->vram_size = roundup(par->vram_size/8, ulcm);
        par->vram_size = par->vram_size * LCD_NUM_BUFFERS;
 
-       par->vram_virt = dma_alloc_coherent(par->dev,
-                                           par->vram_size,
-                                           &par->vram_phys,
-                                           GFP_KERNEL | GFP_DMA);
+       par->vram_virt = dmam_alloc_coherent(par->dev,
+                                            par->vram_size,
+                                            &par->vram_phys,
+                                            GFP_KERNEL | GFP_DMA);
        if (!par->vram_virt) {
                dev_err(&device->dev,
                        "GLCD: kmalloc for frame buffer failed\n");
@@ -1432,20 +1444,20 @@ static int fb_probe(struct platform_device *device)
                da8xx_fb_fix.line_length - 1;
 
        /* allocate palette buffer */
-       par->v_palette_base = dma_alloc_coherent(par->dev, PALETTE_SIZE,
-                                                &par->p_palette_base,
-                                                GFP_KERNEL | GFP_DMA);
+       par->v_palette_base = dmam_alloc_coherent(par->dev, PALETTE_SIZE,
+                                                 &par->p_palette_base,
+                                                 GFP_KERNEL | GFP_DMA);
        if (!par->v_palette_base) {
                dev_err(&device->dev,
                        "GLCD: kmalloc for palette buffer failed\n");
                ret = -EINVAL;
-               goto err_release_fb_mem;
+               goto err_release_fb;
        }
 
        par->irq = platform_get_irq(device, 0);
        if (par->irq < 0) {
                ret = -ENOENT;
-               goto err_release_pl_mem;
+               goto err_release_fb;
        }
 
        da8xx_fb_var.grayscale =
@@ -1463,7 +1475,7 @@ static int fb_probe(struct platform_device *device)
 
        ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
        if (ret)
-               goto err_release_pl_mem;
+               goto err_release_fb;
        da8xx_fb_info->cmap.len = par->palette_sz;
 
        /* initialize var_screeninfo */
@@ -1517,14 +1529,6 @@ err_cpu_freq:
 err_dealloc_cmap:
        fb_dealloc_cmap(&da8xx_fb_info->cmap);
 
-err_release_pl_mem:
-       dma_free_coherent(par->dev, PALETTE_SIZE, par->v_palette_base,
-                         par->p_palette_base);
-
-err_release_fb_mem:
-       dma_free_coherent(par->dev, par->vram_size, par->vram_virt,
-                         par->vram_phys);
-
 err_release_fb:
        framebuffer_release(da8xx_fb_info);
 
@@ -1603,10 +1607,14 @@ static int fb_suspend(struct device *dev)
 {
        struct fb_info *info = dev_get_drvdata(dev);
        struct da8xx_fb_par *par = info->par;
+       int ret;
 
        console_lock();
-       if (par->panel_power_ctrl)
-               par->panel_power_ctrl(0);
+       if (par->lcd_supply) {
+               ret = regulator_disable(par->lcd_supply);
+               if (ret)
+                       return ret;
+       }
 
        fb_set_suspend(info, 1);
        lcd_disable_raster(DA8XX_FRAME_WAIT);
@@ -1620,6 +1628,7 @@ static int fb_resume(struct device *dev)
 {
        struct fb_info *info = dev_get_drvdata(dev);
        struct da8xx_fb_par *par = info->par;
+       int ret;
 
        console_lock();
        pm_runtime_get_sync(dev);
@@ -1627,8 +1636,11 @@ static int fb_resume(struct device *dev)
        if (par->blank == FB_BLANK_UNBLANK) {
                lcd_enable_raster();
 
-               if (par->panel_power_ctrl)
-                       par->panel_power_ctrl(1);
+               if (par->lcd_supply) {
+                       ret = regulator_enable(par->lcd_supply);
+                       if (ret)
+                               return ret;
+               }
        }
 
        fb_set_suspend(info, 0);
diff --git a/drivers/video/fbdev/nuc900fb.c b/drivers/video/fbdev/nuc900fb.c
deleted file mode 100644 (file)
index 4fd8515..0000000
+++ /dev/null
@@ -1,760 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- *
- * Copyright (c) 2009 Nuvoton technology corporation
- * All rights reserved.
- *
- *  Description:
- *    Nuvoton LCD Controller Driver
- *  Author:
- *    Wang Qiang (rurality.linux@gmail.com) 2009/12/11
- */
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/err.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
-#include <linux/wait.h>
-#include <linux/platform_device.h>
-#include <linux/clk.h>
-#include <linux/cpufreq.h>
-#include <linux/io.h>
-#include <linux/pm.h>
-#include <linux/device.h>
-
-#include <mach/map.h>
-#include <mach/regs-clock.h>
-#include <mach/regs-ldm.h>
-#include <linux/platform_data/video-nuc900fb.h>
-
-#include "nuc900fb.h"
-
-
-/*
- *  Initialize the nuc900 video (dual) buffer address
- */
-static void nuc900fb_set_lcdaddr(struct fb_info *info)
-{
-       struct nuc900fb_info *fbi = info->par;
-       void __iomem *regs = fbi->io;
-       unsigned long vbaddr1, vbaddr2;
-
-       vbaddr1  = info->fix.smem_start;
-       vbaddr2  = info->fix.smem_start;
-       vbaddr2 += info->fix.line_length * info->var.yres;
-
-       /* set frambuffer start phy addr*/
-       writel(vbaddr1, regs + REG_LCM_VA_BADDR0);
-       writel(vbaddr2, regs + REG_LCM_VA_BADDR1);
-
-       writel(fbi->regs.lcd_va_fbctrl, regs + REG_LCM_VA_FBCTRL);
-       writel(fbi->regs.lcd_va_scale, regs + REG_LCM_VA_SCALE);
-}
-
-/*
- *     calculate divider for lcd div
- */
-static unsigned int nuc900fb_calc_pixclk(struct nuc900fb_info *fbi,
-                                        unsigned long pixclk)
-{
-       unsigned long clk = fbi->clk_rate;
-       unsigned long long div;
-
-       /* pixclk is in picseconds. our clock is in Hz*/
-       /* div = (clk * pixclk)/10^12 */
-       div = (unsigned long long)clk * pixclk;
-       div >>= 12;
-       do_div(div, 625 * 625UL * 625);
-
-       dev_dbg(fbi->dev, "pixclk %ld, divisor is %lld\n", pixclk, div);
-
-       return div;
-}
-
-/*
- *     Check the video params of 'var'.
- */
-static int nuc900fb_check_var(struct fb_var_screeninfo *var,
-                              struct fb_info *info)
-{
-       struct nuc900fb_info *fbi = info->par;
-       struct nuc900fb_mach_info *mach_info = dev_get_platdata(fbi->dev);
-       struct nuc900fb_display *display = NULL;
-       struct nuc900fb_display *default_display = mach_info->displays +
-                                                  mach_info->default_display;
-       int i;
-
-       dev_dbg(fbi->dev, "check_var(var=%p, info=%p)\n", var, info);
-
-       /* validate x/y resolution */
-       /* choose default mode if possible */
-       if (var->xres == default_display->xres &&
-           var->yres == default_display->yres &&
-           var->bits_per_pixel == default_display->bpp)
-               display = default_display;
-       else
-               for (i = 0; i < mach_info->num_displays; i++)
-                       if (var->xres == mach_info->displays[i].xres &&
-                           var->yres == mach_info->displays[i].yres &&
-                           var->bits_per_pixel == mach_info->displays[i].bpp) {
-                               display = mach_info->displays + i;
-                               break;
-                       }
-
-       if (display == NULL) {
-               printk(KERN_ERR "wrong resolution or depth %dx%d at %d bit per pixel\n",
-                       var->xres, var->yres, var->bits_per_pixel);
-               return -EINVAL;
-       }
-
-       /* it should be the same size as the display */
-       var->xres_virtual       = display->xres;
-       var->yres_virtual       = display->yres;
-       var->height             = display->height;
-       var->width              = display->width;
-
-       /* copy lcd settings */
-       var->pixclock           = display->pixclock;
-       var->left_margin        = display->left_margin;
-       var->right_margin       = display->right_margin;
-       var->upper_margin       = display->upper_margin;
-       var->lower_margin       = display->lower_margin;
-       var->vsync_len          = display->vsync_len;
-       var->hsync_len          = display->hsync_len;
-
-       var->transp.offset      = 0;
-       var->transp.length      = 0;
-
-       fbi->regs.lcd_dccs = display->dccs;
-       fbi->regs.lcd_device_ctrl = display->devctl;
-       fbi->regs.lcd_va_fbctrl = display->fbctrl;
-       fbi->regs.lcd_va_scale = display->scale;
-
-       /* set R/G/B possions */
-       switch (var->bits_per_pixel) {
-       case 1:
-       case 2:
-       case 4:
-       case 8:
-       default:
-               var->red.offset         = 0;
-               var->red.length         = var->bits_per_pixel;
-               var->green              = var->red;
-               var->blue               = var->red;
-               break;
-       case 12:
-               var->red.length         = 4;
-               var->green.length       = 4;
-               var->blue.length        = 4;
-               var->red.offset         = 8;
-               var->green.offset       = 4;
-               var->blue.offset        = 0;
-               break;
-       case 16:
-               var->red.length         = 5;
-               var->green.length       = 6;
-               var->blue.length        = 5;
-               var->red.offset         = 11;
-               var->green.offset       = 5;
-               var->blue.offset        = 0;
-               break;
-       case 18:
-               var->red.length         = 6;
-               var->green.length       = 6;
-               var->blue.length        = 6;
-               var->red.offset         = 12;
-               var->green.offset       = 6;
-               var->blue.offset        = 0;
-               break;
-       case 32:
-               var->red.length         = 8;
-               var->green.length       = 8;
-               var->blue.length        = 8;
-               var->red.offset         = 16;
-               var->green.offset       = 8;
-               var->blue.offset        = 0;
-               break;
-       }
-
-       return 0;
-}
-
-/*
- *     Calculate lcd register values from var setting & save into hw
- */
-static void nuc900fb_calculate_lcd_regs(const struct fb_info *info,
-                                       struct nuc900fb_hw *regs)
-{
-       const struct fb_var_screeninfo *var = &info->var;
-       int vtt = var->height + var->upper_margin + var->lower_margin;
-       int htt = var->width + var->left_margin + var->right_margin;
-       int hsync = var->width + var->right_margin;
-       int vsync = var->height + var->lower_margin;
-
-       regs->lcd_crtc_size = LCM_CRTC_SIZE_VTTVAL(vtt) |
-                             LCM_CRTC_SIZE_HTTVAL(htt);
-       regs->lcd_crtc_dend = LCM_CRTC_DEND_VDENDVAL(var->height) |
-                             LCM_CRTC_DEND_HDENDVAL(var->width);
-       regs->lcd_crtc_hr = LCM_CRTC_HR_EVAL(var->width + 5) |
-                           LCM_CRTC_HR_SVAL(var->width + 1);
-       regs->lcd_crtc_hsync = LCM_CRTC_HSYNC_EVAL(hsync + var->hsync_len) |
-                              LCM_CRTC_HSYNC_SVAL(hsync);
-       regs->lcd_crtc_vr = LCM_CRTC_VR_EVAL(vsync + var->vsync_len) |
-                           LCM_CRTC_VR_SVAL(vsync);
-
-}
-
-/*
- *     Activate (set) the controller from the given framebuffer
- *     information
- */
-static void nuc900fb_activate_var(struct fb_info *info)
-{
-       struct nuc900fb_info *fbi = info->par;
-       void __iomem *regs = fbi->io;
-       struct fb_var_screeninfo *var = &info->var;
-       int clkdiv;
-
-       clkdiv = nuc900fb_calc_pixclk(fbi, var->pixclock) - 1;
-       if (clkdiv < 0)
-               clkdiv = 0;
-
-       nuc900fb_calculate_lcd_regs(info, &fbi->regs);
-
-       /* set the new lcd registers*/
-
-       dev_dbg(fbi->dev, "new lcd register set:\n");
-       dev_dbg(fbi->dev, "dccs       = 0x%08x\n", fbi->regs.lcd_dccs);
-       dev_dbg(fbi->dev, "dev_ctl    = 0x%08x\n", fbi->regs.lcd_device_ctrl);
-       dev_dbg(fbi->dev, "crtc_size  = 0x%08x\n", fbi->regs.lcd_crtc_size);
-       dev_dbg(fbi->dev, "crtc_dend  = 0x%08x\n", fbi->regs.lcd_crtc_dend);
-       dev_dbg(fbi->dev, "crtc_hr    = 0x%08x\n", fbi->regs.lcd_crtc_hr);
-       dev_dbg(fbi->dev, "crtc_hsync = 0x%08x\n", fbi->regs.lcd_crtc_hsync);
-       dev_dbg(fbi->dev, "crtc_vr    = 0x%08x\n", fbi->regs.lcd_crtc_vr);
-
-       writel(fbi->regs.lcd_device_ctrl, regs + REG_LCM_DEV_CTRL);
-       writel(fbi->regs.lcd_crtc_size, regs + REG_LCM_CRTC_SIZE);
-       writel(fbi->regs.lcd_crtc_dend, regs + REG_LCM_CRTC_DEND);
-       writel(fbi->regs.lcd_crtc_hr, regs + REG_LCM_CRTC_HR);
-       writel(fbi->regs.lcd_crtc_hsync, regs + REG_LCM_CRTC_HSYNC);
-       writel(fbi->regs.lcd_crtc_vr, regs + REG_LCM_CRTC_VR);
-
-       /* set lcd address pointers */
-       nuc900fb_set_lcdaddr(info);
-
-       writel(fbi->regs.lcd_dccs, regs + REG_LCM_DCCS);
-}
-
-/*
- *      Alters the hardware state.
- *
- */
-static int nuc900fb_set_par(struct fb_info *info)
-{
-       struct fb_var_screeninfo *var = &info->var;
-
-       switch (var->bits_per_pixel) {
-       case 32:
-       case 24:
-       case 18:
-       case 16:
-       case 12:
-               info->fix.visual = FB_VISUAL_TRUECOLOR;
-               break;
-       case 1:
-               info->fix.visual = FB_VISUAL_MONO01;
-               break;
-       default:
-               info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
-               break;
-       }
-
-       info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;
-
-       /* activate this new configuration */
-       nuc900fb_activate_var(info);
-       return 0;
-}
-
-static inline unsigned int chan_to_field(unsigned int chan,
-                                        struct fb_bitfield *bf)
-{
-       chan &= 0xffff;
-       chan >>= 16 - bf->length;
-       return chan << bf->offset;
-}
-
-static int nuc900fb_setcolreg(unsigned regno,
-                              unsigned red, unsigned green, unsigned blue,
-                              unsigned transp, struct fb_info *info)
-{
-       unsigned int val;
-
-       switch (info->fix.visual) {
-       case FB_VISUAL_TRUECOLOR:
-               /* true-colour, use pseuo-palette */
-               if (regno < 16) {
-                       u32 *pal = info->pseudo_palette;
-
-                       val  = chan_to_field(red, &info->var.red);
-                       val |= chan_to_field(green, &info->var.green);
-                       val |= chan_to_field(blue, &info->var.blue);
-                       pal[regno] = val;
-               }
-               break;
-
-       default:
-               return 1;   /* unknown type */
-       }
-       return 0;
-}
-
-/**
- *      nuc900fb_blank
- *
- */
-static int nuc900fb_blank(int blank_mode, struct fb_info *info)
-{
-
-       return 0;
-}
-
-static struct fb_ops nuc900fb_ops = {
-       .owner                  = THIS_MODULE,
-       .fb_check_var           = nuc900fb_check_var,
-       .fb_set_par             = nuc900fb_set_par,
-       .fb_blank               = nuc900fb_blank,
-       .fb_setcolreg           = nuc900fb_setcolreg,
-       .fb_fillrect            = cfb_fillrect,
-       .fb_copyarea            = cfb_copyarea,
-       .fb_imageblit           = cfb_imageblit,
-};
-
-
-static inline void modify_gpio(void __iomem *reg,
-                              unsigned long set, unsigned long mask)
-{
-       unsigned long tmp;
-       tmp = readl(reg) & ~mask;
-       writel(tmp | set, reg);
-}
-
-/*
- * Initialise LCD-related registers
- */
-static int nuc900fb_init_registers(struct fb_info *info)
-{
-       struct nuc900fb_info *fbi = info->par;
-       struct nuc900fb_mach_info *mach_info = dev_get_platdata(fbi->dev);
-       void __iomem *regs = fbi->io;
-
-       /*reset the display engine*/
-       writel(0, regs + REG_LCM_DCCS);
-       writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_ENG_RST,
-              regs + REG_LCM_DCCS);
-       ndelay(100);
-       writel(readl(regs + REG_LCM_DCCS) & (~LCM_DCCS_ENG_RST),
-              regs + REG_LCM_DCCS);
-       ndelay(100);
-
-       writel(0, regs + REG_LCM_DEV_CTRL);
-
-       /* config gpio output */
-       modify_gpio(W90X900_VA_GPIO + 0x54, mach_info->gpio_dir,
-                   mach_info->gpio_dir_mask);
-       modify_gpio(W90X900_VA_GPIO + 0x58, mach_info->gpio_data,
-                   mach_info->gpio_data_mask);
-
-       return 0;
-}
-
-
-/*
- *    Alloc the SDRAM region of NUC900 for the frame buffer.
- *    The buffer should be a non-cached, non-buffered, memory region
- *    to allow palette and pixel writes without flushing the cache.
- */
-static int nuc900fb_map_video_memory(struct fb_info *info)
-{
-       struct nuc900fb_info *fbi = info->par;
-       dma_addr_t map_dma;
-       unsigned long map_size = PAGE_ALIGN(info->fix.smem_len);
-
-       dev_dbg(fbi->dev, "nuc900fb_map_video_memory(fbi=%p) map_size %lu\n",
-               fbi, map_size);
-
-       info->screen_base = dma_alloc_wc(fbi->dev, map_size, &map_dma,
-                                        GFP_KERNEL);
-
-       if (!info->screen_base)
-               return -ENOMEM;
-
-       memset(info->screen_base, 0x00, map_size);
-       info->fix.smem_start = map_dma;
-
-       return 0;
-}
-
-static inline void nuc900fb_unmap_video_memory(struct fb_info *info)
-{
-       struct nuc900fb_info *fbi = info->par;
-       dma_free_wc(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
-                   info->screen_base, info->fix.smem_start);
-}
-
-static irqreturn_t nuc900fb_irqhandler(int irq, void *dev_id)
-{
-       struct nuc900fb_info *fbi = dev_id;
-       void __iomem *regs = fbi->io;
-       void __iomem *irq_base = fbi->irq_base;
-       unsigned long lcdirq = readl(regs + REG_LCM_INT_CS);
-
-       if (lcdirq & LCM_INT_CS_DISP_F_STATUS) {
-               writel(readl(irq_base) | 1<<30, irq_base);
-
-               /* wait VA_EN low */
-               if ((readl(regs + REG_LCM_DCCS) &
-                   LCM_DCCS_SINGLE) == LCM_DCCS_SINGLE)
-                       while ((readl(regs + REG_LCM_DCCS) &
-                              LCM_DCCS_VA_EN) == LCM_DCCS_VA_EN)
-                               ;
-               /* display_out-enable */
-               writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_DISP_OUT_EN,
-                       regs + REG_LCM_DCCS);
-               /* va-enable*/
-               writel(readl(regs + REG_LCM_DCCS) | LCM_DCCS_VA_EN,
-                       regs + REG_LCM_DCCS);
-       } else if (lcdirq & LCM_INT_CS_UNDERRUN_INT) {
-               writel(readl(irq_base) | LCM_INT_CS_UNDERRUN_INT, irq_base);
-       } else if (lcdirq & LCM_INT_CS_BUS_ERROR_INT) {
-               writel(readl(irq_base) | LCM_INT_CS_BUS_ERROR_INT, irq_base);
-       }
-
-       return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_CPU_FREQ
-
-static int nuc900fb_cpufreq_transition(struct notifier_block *nb,
-                                      unsigned long val, void *data)
-{
-       struct nuc900fb_info *info;
-       struct fb_info *fbinfo;
-       long delta_f;
-       info = container_of(nb, struct nuc900fb_info, freq_transition);
-       fbinfo = dev_get_drvdata(info->dev);
-
-       delta_f = info->clk_rate - clk_get_rate(info->clk);
-
-       if ((val == CPUFREQ_POSTCHANGE && delta_f > 0) ||
-          (val == CPUFREQ_PRECHANGE && delta_f < 0)) {
-               info->clk_rate = clk_get_rate(info->clk);
-               nuc900fb_activate_var(fbinfo);
-       }
-
-       return 0;
-}
-
-static inline int nuc900fb_cpufreq_register(struct nuc900fb_info *fbi)
-{
-       fbi->freq_transition.notifier_call = nuc900fb_cpufreq_transition;
-       return cpufreq_register_notifier(&fbi->freq_transition,
-                                 CPUFREQ_TRANSITION_NOTIFIER);
-}
-
-static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *fbi)
-{
-       cpufreq_unregister_notifier(&fbi->freq_transition,
-                                   CPUFREQ_TRANSITION_NOTIFIER);
-}
-#else
-static inline int nuc900fb_cpufreq_transition(struct notifier_block *nb,
-                                      unsigned long val, void *data)
-{
-       return 0;
-}
-
-static inline int nuc900fb_cpufreq_register(struct nuc900fb_info *fbi)
-{
-       return 0;
-}
-
-static inline void nuc900fb_cpufreq_deregister(struct nuc900fb_info *info)
-{
-}
-#endif
-
-static char driver_name[] = "nuc900fb";
-
-static int nuc900fb_probe(struct platform_device *pdev)
-{
-       struct nuc900fb_info *fbi;
-       struct nuc900fb_display *display;
-       struct fb_info     *fbinfo;
-       struct nuc900fb_mach_info *mach_info;
-       struct resource *res;
-       int ret;
-       int irq;
-       int i;
-       int size;
-
-       dev_dbg(&pdev->dev, "devinit\n");
-       mach_info = dev_get_platdata(&pdev->dev);
-       if (mach_info == NULL) {
-               dev_err(&pdev->dev,
-                       "no platform data for lcd, cannot attach\n");
-               return -EINVAL;
-       }
-
-       if (mach_info->default_display > mach_info->num_displays) {
-               dev_err(&pdev->dev,
-                       "default display No. is %d but only %d displays \n",
-                       mach_info->default_display, mach_info->num_displays);
-               return -EINVAL;
-       }
-
-
-       display = mach_info->displays + mach_info->default_display;
-
-       irq = platform_get_irq(pdev, 0);
-       if (irq < 0) {
-               dev_err(&pdev->dev, "no irq for device\n");
-               return -ENOENT;
-       }
-
-       fbinfo = framebuffer_alloc(sizeof(struct nuc900fb_info), &pdev->dev);
-       if (!fbinfo)
-               return -ENOMEM;
-
-       platform_set_drvdata(pdev, fbinfo);
-
-       fbi = fbinfo->par;
-       fbi->dev = &pdev->dev;
-
-#ifdef CONFIG_CPU_NUC950
-       fbi->drv_type = LCDDRV_NUC950;
-#endif
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-       size = resource_size(res);
-       fbi->mem = request_mem_region(res->start, size, pdev->name);
-       if (fbi->mem == NULL) {
-               dev_err(&pdev->dev, "failed to alloc memory region\n");
-               ret = -ENOENT;
-               goto free_fb;
-       }
-
-       fbi->io = ioremap(res->start, size);
-       if (fbi->io == NULL) {
-               dev_err(&pdev->dev, "ioremap() of lcd registers failed\n");
-               ret = -ENXIO;
-               goto release_mem_region;
-       }
-
-       fbi->irq_base = fbi->io + REG_LCM_INT_CS;
-
-
-       /* Stop the LCD */
-       writel(0, fbi->io + REG_LCM_DCCS);
-
-       /* fill the fbinfo*/
-       strcpy(fbinfo->fix.id, driver_name);
-       fbinfo->fix.type                = FB_TYPE_PACKED_PIXELS;
-       fbinfo->fix.type_aux            = 0;
-       fbinfo->fix.xpanstep            = 0;
-       fbinfo->fix.ypanstep            = 0;
-       fbinfo->fix.ywrapstep           = 0;
-       fbinfo->fix.accel               = FB_ACCEL_NONE;
-       fbinfo->var.nonstd              = 0;
-       fbinfo->var.activate            = FB_ACTIVATE_NOW;
-       fbinfo->var.accel_flags         = 0;
-       fbinfo->var.vmode               = FB_VMODE_NONINTERLACED;
-       fbinfo->fbops                   = &nuc900fb_ops;
-       fbinfo->flags                   = FBINFO_FLAG_DEFAULT;
-       fbinfo->pseudo_palette          = &fbi->pseudo_pal;
-
-       ret = request_irq(irq, nuc900fb_irqhandler, 0, pdev->name, fbi);
-       if (ret) {
-               dev_err(&pdev->dev, "cannot register irq handler %d -err %d\n",
-                       irq, ret);
-               ret = -EBUSY;
-               goto release_regs;
-       }
-
-       fbi->clk = clk_get(&pdev->dev, NULL);
-       if (IS_ERR(fbi->clk)) {
-               printk(KERN_ERR "nuc900-lcd:failed to get lcd clock source\n");
-               ret = PTR_ERR(fbi->clk);
-               goto release_irq;
-       }
-
-       clk_enable(fbi->clk);
-       dev_dbg(&pdev->dev, "got and enabled clock\n");
-
-       fbi->clk_rate = clk_get_rate(fbi->clk);
-
-       /* calutate the video buffer size */
-       for (i = 0; i < mach_info->num_displays; i++) {
-               unsigned long smem_len = mach_info->displays[i].xres;
-               smem_len *= mach_info->displays[i].yres;
-               smem_len *= mach_info->displays[i].bpp;
-               smem_len >>= 3;
-               if (fbinfo->fix.smem_len < smem_len)
-                       fbinfo->fix.smem_len = smem_len;
-       }
-
-       /* Initialize Video Memory */
-       ret = nuc900fb_map_video_memory(fbinfo);
-       if (ret) {
-               printk(KERN_ERR "Failed to allocate video RAM: %x\n", ret);
-               goto release_clock;
-       }
-
-       dev_dbg(&pdev->dev, "got video memory\n");
-
-       fbinfo->var.xres = display->xres;
-       fbinfo->var.yres = display->yres;
-       fbinfo->var.bits_per_pixel = display->bpp;
-
-       nuc900fb_init_registers(fbinfo);
-
-       nuc900fb_check_var(&fbinfo->var, fbinfo);
-
-       ret = nuc900fb_cpufreq_register(fbi);
-       if (ret < 0) {
-               dev_err(&pdev->dev, "Failed to register cpufreq\n");
-               goto free_video_memory;
-       }
-
-       ret = register_framebuffer(fbinfo);
-       if (ret) {
-               printk(KERN_ERR "failed to register framebuffer device: %d\n",
-                       ret);
-               goto free_cpufreq;
-       }
-
-       fb_info(fbinfo, "%s frame buffer device\n", fbinfo->fix.id);
-
-       return 0;
-
-free_cpufreq:
-       nuc900fb_cpufreq_deregister(fbi);
-free_video_memory:
-       nuc900fb_unmap_video_memory(fbinfo);
-release_clock:
-       clk_disable(fbi->clk);
-       clk_put(fbi->clk);
-release_irq:
-       free_irq(irq, fbi);
-release_regs:
-       iounmap(fbi->io);
-release_mem_region:
-       release_mem_region(res->start, size);
-free_fb:
-       framebuffer_release(fbinfo);
-       return ret;
-}
-
-/*
- * shutdown the lcd controller
- */
-static void nuc900fb_stop_lcd(struct fb_info *info)
-{
-       struct nuc900fb_info *fbi = info->par;
-       void __iomem *regs = fbi->io;
-
-       writel((~LCM_DCCS_DISP_INT_EN) | (~LCM_DCCS_VA_EN) | (~LCM_DCCS_OSD_EN),
-               regs + REG_LCM_DCCS);
-}
-
-/*
- *  Cleanup
- */
-static int nuc900fb_remove(struct platform_device *pdev)
-{
-       struct fb_info *fbinfo = platform_get_drvdata(pdev);
-       struct nuc900fb_info *fbi = fbinfo->par;
-       int irq;
-
-       nuc900fb_stop_lcd(fbinfo);
-       msleep(1);
-
-       unregister_framebuffer(fbinfo);
-       nuc900fb_cpufreq_deregister(fbi);
-       nuc900fb_unmap_video_memory(fbinfo);
-
-       iounmap(fbi->io);
-
-       irq = platform_get_irq(pdev, 0);
-       free_irq(irq, fbi);
-
-       release_resource(fbi->mem);
-       kfree(fbi->mem);
-
-       framebuffer_release(fbinfo);
-
-       return 0;
-}
-
-#ifdef CONFIG_PM
-
-/*
- *     suspend and resume support for the lcd controller
- */
-
-static int nuc900fb_suspend(struct platform_device *dev, pm_message_t state)
-{
-       struct fb_info     *fbinfo = platform_get_drvdata(dev);
-       struct nuc900fb_info *info = fbinfo->par;
-
-       nuc900fb_stop_lcd(fbinfo);
-       msleep(1);
-       clk_disable(info->clk);
-       return 0;
-}
-
-static int nuc900fb_resume(struct platform_device *dev)
-{
-       struct fb_info     *fbinfo = platform_get_drvdata(dev);
-       struct nuc900fb_info *fbi = fbinfo->par;
-
-       printk(KERN_INFO "nuc900fb resume\n");
-
-       clk_enable(fbi->clk);
-       msleep(1);
-
-       nuc900fb_init_registers(fbinfo);
-       nuc900fb_activate_var(fbinfo);
-
-       return 0;
-}
-
-#else
-#define nuc900fb_suspend NULL
-#define nuc900fb_resume  NULL
-#endif
-
-static struct platform_driver nuc900fb_driver = {
-       .probe          = nuc900fb_probe,
-       .remove         = nuc900fb_remove,
-       .suspend        = nuc900fb_suspend,
-       .resume         = nuc900fb_resume,
-       .driver         = {
-               .name   = "nuc900-lcd",
-       },
-};
-
-module_platform_driver(nuc900fb_driver);
-
-MODULE_DESCRIPTION("Framebuffer driver for the NUC900");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/nuc900fb.h b/drivers/video/fbdev/nuc900fb.h
deleted file mode 100644 (file)
index 055ae92..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- *
- * Copyright (c) 2009 Nuvoton technology corporation
- * All rights reserved.
- *
- *   Author:
- *        Wang Qiang(rurality.linux@gmail.com)  2009/12/16
- */
-
-#ifndef __NUC900FB_H
-#define __NUC900FB_H
-
-#include <mach/map.h>
-#include <linux/platform_data/video-nuc900fb.h>
-
-enum nuc900_lcddrv_type {
-       LCDDRV_NUC910,
-       LCDDRV_NUC930,
-       LCDDRV_NUC932,
-       LCDDRV_NUC950,
-       LCDDRV_NUC960,
-};
-
-
-#define PALETTE_BUFFER_SIZE    256
-#define PALETTE_BUFF_CLEAR     (0x80000000) /* entry is clear/invalid */
-
-struct nuc900fb_info {
-       struct device           *dev;
-       struct clk              *clk;
-
-       struct resource         *mem;
-       void __iomem            *io;
-       void __iomem            *irq_base;
-       int                     drv_type;
-       struct nuc900fb_hw      regs;
-       unsigned long           clk_rate;
-
-#ifdef CONFIG_CPU_FREQ
-       struct notifier_block   freq_transition;
-#endif
-
-       /* keep these registers in case we need to re-write palette */
-       u32                     palette_buffer[PALETTE_BUFFER_SIZE];
-       u32                     pseudo_pal[16];
-};
-
-int nuc900fb_init(void);
-
-#endif /* __NUC900FB_H */
index c8be1c4..bdc0824 100644 (file)
@@ -566,13 +566,17 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
 
 unmap_release:
        err_idx = i;
-       i = head;
+
+       if (indirect)
+               i = 0;
+       else
+               i = head;
 
        for (n = 0; n < total_sg; n++) {
                if (i == err_idx)
                        break;
                vring_unmap_one_split(vq, &desc[i]);
-               i = virtio16_to_cpu(_vq->vdev, vq->split.vring.desc[i].next);
+               i = virtio16_to_cpu(_vq->vdev, desc[i].next);
        }
 
        if (indirect)
index 8188963..a45f9e3 100644 (file)
@@ -551,7 +551,7 @@ config OMAP_WATCHDOG
 
 config PNX4008_WATCHDOG
        tristate "LPC32XX Watchdog"
-       depends on ARCH_LPC32XX
+       depends on ARCH_LPC32XX || COMPILE_TEST
        select WATCHDOG_CORE
        help
          Say Y here if to include support for the watchdog timer
index 7b446b6..e0ea133 100644 (file)
@@ -30,7 +30,6 @@
 #include <linux/of.h>
 #include <linux/delay.h>
 #include <linux/reboot.h>
-#include <mach/hardware.h>
 
 /* WatchDog Timer - Chapter 23 Page 207 */
 
index ae1df49..adcabd9 100644 (file)
@@ -386,8 +386,8 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
         */
        trace_swiotlb_bounced(dev, dev_addr, size, swiotlb_force);
 
-       map = swiotlb_tbl_map_single(dev, start_dma_addr, phys, size, dir,
-                                    attrs);
+       map = swiotlb_tbl_map_single(dev, start_dma_addr, phys,
+                                    size, size, dir, attrs);
        if (map == (phys_addr_t)DMA_MAPPING_ERROR)
                return DMA_MAPPING_ERROR;
 
@@ -397,7 +397,7 @@ static dma_addr_t xen_swiotlb_map_page(struct device *dev, struct page *page,
         * Ensure that the address returned is DMA'ble
         */
        if (unlikely(!dma_capable(dev, dev_addr, size))) {
-               swiotlb_tbl_unmap_single(dev, map, size, dir,
+               swiotlb_tbl_unmap_single(dev, map, size, size, dir,
                                attrs | DMA_ATTR_SKIP_CPU_SYNC);
                return DMA_MAPPING_ERROR;
        }
@@ -433,7 +433,7 @@ static void xen_unmap_single(struct device *hwdev, dma_addr_t dev_addr,
 
        /* NOTE: We use dev_addr here, not paddr! */
        if (is_xen_swiotlb_buffer(dev_addr))
-               swiotlb_tbl_unmap_single(hwdev, paddr, size, dir, attrs);
+               swiotlb_tbl_unmap_single(hwdev, paddr, size, size, dir, attrs);
 }
 
 static void xen_swiotlb_unmap_page(struct device *hwdev, dma_addr_t dev_addr,
index 1ff438f..eeb7528 100644 (file)
@@ -3628,6 +3628,13 @@ void wait_on_extent_buffer_writeback(struct extent_buffer *eb)
                       TASK_UNINTERRUPTIBLE);
 }
 
+static void end_extent_buffer_writeback(struct extent_buffer *eb)
+{
+       clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags);
+       smp_mb__after_atomic();
+       wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK);
+}
+
 /*
  * Lock eb pages and flush the bio if we can't the locks
  *
@@ -3699,8 +3706,11 @@ static noinline_for_stack int lock_extent_buffer_for_io(struct extent_buffer *eb
 
                if (!trylock_page(p)) {
                        if (!flush) {
-                               ret = flush_write_bio(epd);
-                               if (ret < 0) {
+                               int err;
+
+                               err = flush_write_bio(epd);
+                               if (err < 0) {
+                                       ret = err;
                                        failed_page_nr = i;
                                        goto err_unlock;
                                }
@@ -3715,16 +3725,23 @@ err_unlock:
        /* Unlock already locked pages */
        for (i = 0; i < failed_page_nr; i++)
                unlock_page(eb->pages[i]);
+       /*
+        * Clear EXTENT_BUFFER_WRITEBACK and wake up anyone waiting on it.
+        * Also set back EXTENT_BUFFER_DIRTY so future attempts to this eb can
+        * be made and undo everything done before.
+        */
+       btrfs_tree_lock(eb);
+       spin_lock(&eb->refs_lock);
+       set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags);
+       end_extent_buffer_writeback(eb);
+       spin_unlock(&eb->refs_lock);
+       percpu_counter_add_batch(&fs_info->dirty_metadata_bytes, eb->len,
+                                fs_info->dirty_metadata_batch);
+       btrfs_clear_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);
+       btrfs_tree_unlock(eb);
        return ret;
 }
 
-static void end_extent_buffer_writeback(struct extent_buffer *eb)
-{
-       clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags);
-       smp_mb__after_atomic();
-       wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK);
-}
-
 static void set_btree_ioerr(struct page *page)
 {
        struct extent_buffer *eb = (struct extent_buffer *)page->private;
index 6c8297b..1bfd7e3 100644 (file)
@@ -4985,7 +4985,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
                                                      BTRFS_I(inode),
                                                      LOG_OTHER_INODE_ALL,
                                                      0, LLONG_MAX, ctx);
-                                       iput(inode);
+                                       btrfs_add_delayed_iput(inode);
                                }
                        }
                        continue;
@@ -5000,7 +5000,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
                ret = btrfs_log_inode(trans, root, BTRFS_I(inode),
                                      LOG_OTHER_INODE, 0, LLONG_MAX, ctx);
                if (ret) {
-                       iput(inode);
+                       btrfs_add_delayed_iput(inode);
                        continue;
                }
 
@@ -5009,7 +5009,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
                key.offset = 0;
                ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
                if (ret < 0) {
-                       iput(inode);
+                       btrfs_add_delayed_iput(inode);
                        continue;
                }
 
@@ -5056,7 +5056,7 @@ static int log_conflicting_inodes(struct btrfs_trans_handle *trans,
                        }
                        path->slots[0]++;
                }
-               iput(inode);
+               btrfs_add_delayed_iput(inode);
        }
 
        return ret;
@@ -5689,7 +5689,7 @@ process_leaf:
                        }
 
                        if (btrfs_inode_in_log(BTRFS_I(di_inode), trans->transid)) {
-                               iput(di_inode);
+                               btrfs_add_delayed_iput(di_inode);
                                break;
                        }
 
@@ -5701,7 +5701,7 @@ process_leaf:
                        if (!ret &&
                            btrfs_must_commit_transaction(trans, BTRFS_I(di_inode)))
                                ret = 1;
-                       iput(di_inode);
+                       btrfs_add_delayed_iput(di_inode);
                        if (ret)
                                goto next_dir_inode;
                        if (ctx->log_new_dentries) {
@@ -5848,7 +5848,7 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
                        if (!ret && ctx && ctx->log_new_dentries)
                                ret = log_new_dir_dentries(trans, root,
                                                   BTRFS_I(dir_inode), ctx);
-                       iput(dir_inode);
+                       btrfs_add_delayed_iput(dir_inode);
                        if (ret)
                                goto out;
                }
@@ -5891,7 +5891,7 @@ static int log_new_ancestors(struct btrfs_trans_handle *trans,
                        ret = btrfs_log_inode(trans, root, BTRFS_I(inode),
                                              LOG_INODE_EXISTS,
                                              0, LLONG_MAX, ctx);
-               iput(inode);
+               btrfs_add_delayed_iput(inode);
                if (ret)
                        return ret;
 
index 4b21a90..99caf77 100644 (file)
@@ -152,5 +152,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern const struct export_operations cifs_export_ops;
 #endif /* CONFIG_CIFS_NFSD_EXPORT */
 
-#define CIFS_VERSION   "2.21"
+#define CIFS_VERSION   "2.22"
 #endif                         /* _CIFSFS_H */
index e232342..592a6ce 100644 (file)
@@ -579,6 +579,7 @@ extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
                                unsigned int *len, unsigned int *offset);
 
 void extract_unc_hostname(const char *unc, const char **h, size_t *len);
+int copy_path_name(char *dst, const char *src);
 
 #ifdef CONFIG_CIFS_DFS_UPCALL
 static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
index e2f9596..3907653 100644 (file)
@@ -942,10 +942,8 @@ PsxDelete:
                                       PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else { /* BB add path length overrun check */
-               name_len = strnlen(fileName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, fileName, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, fileName);
        }
 
        params = 6 + name_len;
@@ -1015,10 +1013,8 @@ DelFileRetry:
                                              remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {                /* BB improve check for buffer overruns BB */
-               name_len = strnlen(name, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->fileName, name, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->fileName, name);
        }
        pSMB->SearchAttributes =
            cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
@@ -1062,10 +1058,8 @@ RmDirRetry:
                                              remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {                /* BB improve check for buffer overruns BB */
-               name_len = strnlen(name, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->DirName, name, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->DirName, name);
        }
 
        pSMB->BufferFormat = 0x04;
@@ -1107,10 +1101,8 @@ MkDirRetry:
                                              remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {                /* BB improve check for buffer overruns BB */
-               name_len = strnlen(name, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->DirName, name, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->DirName, name);
        }
 
        pSMB->BufferFormat = 0x04;
@@ -1157,10 +1149,8 @@ PsxCreat:
                                       PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(name, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, name, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, name);
        }
 
        params = 6 + name_len;
@@ -1324,11 +1314,9 @@ OldOpenRetry:
                                      fileName, PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {                /* BB improve check for buffer overruns BB */
+       } else {
                count = 0;      /* no pad */
-               name_len = strnlen(fileName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->fileName, fileName, name_len);
+               name_len = copy_path_name(pSMB->fileName, fileName);
        }
        if (*pOplock & REQ_OPLOCK)
                pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
@@ -1442,11 +1430,8 @@ openRetry:
                /* BB improve check for buffer overruns BB */
                /* no pad */
                count = 0;
-               name_len = strnlen(path, PATH_MAX);
-               /* trailing null */
-               name_len++;
+               name_len = copy_path_name(req->fileName, path);
                req->NameLength = cpu_to_le16(name_len);
-               strncpy(req->fileName, path, name_len);
        }
 
        if (*oplock & REQ_OPLOCK)
@@ -2812,15 +2797,10 @@ renameRetry:
                                       remap);
                name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
                name_len2 *= 2; /* convert to bytes */
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(from_name, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->OldFileName, from_name, name_len);
-               name_len2 = strnlen(to_name, PATH_MAX);
-               name_len2++;    /* trailing null */
+       } else {
+               name_len = copy_path_name(pSMB->OldFileName, from_name);
+               name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
                pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
-               strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
-               name_len2++;    /* trailing null */
                name_len2++;    /* signature byte */
        }
 
@@ -2962,15 +2942,10 @@ copyRetry:
                                       toName, PATH_MAX, nls_codepage, remap);
                name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
                name_len2 *= 2; /* convert to bytes */
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(fromName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->OldFileName, fromName, name_len);
-               name_len2 = strnlen(toName, PATH_MAX);
-               name_len2++;    /* trailing null */
+       } else {
+               name_len = copy_path_name(pSMB->OldFileName, fromName);
                pSMB->OldFileName[name_len] = 0x04;  /* 2nd buffer format */
-               strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
-               name_len2++;    /* trailing null */
+               name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, toName);
                name_len2++;    /* signature byte */
        }
 
@@ -3021,10 +2996,8 @@ createSymLinkRetry:
                name_len++;     /* trailing null */
                name_len *= 2;
 
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(fromName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, fromName, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, fromName);
        }
        params = 6 + name_len;
        pSMB->MaxSetupCount = 0;
@@ -3044,10 +3017,8 @@ createSymLinkRetry:
                                        PATH_MAX, nls_codepage, remap);
                name_len_target++;      /* trailing null */
                name_len_target *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len_target = strnlen(toName, PATH_MAX);
-               name_len_target++;      /* trailing null */
-               strncpy(data_offset, toName, name_len_target);
+       } else {
+               name_len_target = copy_path_name(data_offset, toName);
        }
 
        pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -3109,10 +3080,8 @@ createHardLinkRetry:
                name_len++;     /* trailing null */
                name_len *= 2;
 
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(toName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, toName, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, toName);
        }
        params = 6 + name_len;
        pSMB->MaxSetupCount = 0;
@@ -3131,10 +3100,8 @@ createHardLinkRetry:
                                       PATH_MAX, nls_codepage, remap);
                name_len_target++;      /* trailing null */
                name_len_target *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len_target = strnlen(fromName, PATH_MAX);
-               name_len_target++;      /* trailing null */
-               strncpy(data_offset, fromName, name_len_target);
+       } else {
+               name_len_target = copy_path_name(data_offset, fromName);
        }
 
        pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -3213,15 +3180,10 @@ winCreateHardLinkRetry:
                                       remap);
                name_len2 += 1 /* trailing null */  + 1 /* Signature word */ ;
                name_len2 *= 2; /* convert to bytes */
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(from_name, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->OldFileName, from_name, name_len);
-               name_len2 = strnlen(to_name, PATH_MAX);
-               name_len2++;    /* trailing null */
+       } else {
+               name_len = copy_path_name(pSMB->OldFileName, from_name);
                pSMB->OldFileName[name_len] = 0x04;     /* 2nd buffer format */
-               strncpy(&pSMB->OldFileName[name_len + 1], to_name, name_len2);
-               name_len2++;    /* trailing null */
+               name_len2 = copy_path_name(pSMB->OldFileName+name_len+1, to_name);
                name_len2++;    /* signature byte */
        }
 
@@ -3271,10 +3233,8 @@ querySymLinkRetry:
                                           remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(searchName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, searchName, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, searchName);
        }
 
        params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
@@ -3691,10 +3651,8 @@ queryAclRetry:
                name_len *= 2;
                pSMB->FileName[name_len] = 0;
                pSMB->FileName[name_len+1] = 0;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(searchName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, searchName, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, searchName);
        }
 
        params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
@@ -3776,10 +3734,8 @@ setAclRetry:
                                           PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(fileName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, fileName, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, fileName);
        }
        params = 6 + name_len;
        pSMB->MaxParameterCount = cpu_to_le16(2);
@@ -4184,9 +4140,7 @@ QInfRetry:
                name_len++;     /* trailing null */
                name_len *= 2;
        } else {
-               name_len = strnlen(search_name, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, search_name, name_len);
+               name_len = copy_path_name(pSMB->FileName, search_name);
        }
        pSMB->BufferFormat = 0x04;
        name_len++; /* account for buffer type byte */
@@ -4321,10 +4275,8 @@ QPathInfoRetry:
                                       PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(search_name, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, search_name, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, search_name);
        }
 
        params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
@@ -4490,10 +4442,8 @@ UnixQPathInfoRetry:
                                       PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(searchName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, searchName, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, searchName);
        }
 
        params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
@@ -4593,17 +4543,16 @@ findFirstRetry:
                        pSMB->FileName[name_len+1] = 0;
                        name_len += 2;
                }
-       } else {        /* BB add check for overrun of SMB buf BB */
-               name_len = strnlen(searchName, PATH_MAX);
-/* BB fix here and in unicode clause above ie
-               if (name_len > buffersize-header)
-                       free buffer exit; BB */
-               strncpy(pSMB->FileName, searchName, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, searchName);
                if (msearch) {
-                       pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
-                       pSMB->FileName[name_len+1] = '*';
-                       pSMB->FileName[name_len+2] = 0;
-                       name_len += 3;
+                       if (WARN_ON_ONCE(name_len > PATH_MAX-2))
+                               name_len = PATH_MAX-2;
+                       /* overwrite nul byte */
+                       pSMB->FileName[name_len-1] = CIFS_DIR_SEP(cifs_sb);
+                       pSMB->FileName[name_len] = '*';
+                       pSMB->FileName[name_len+1] = 0;
+                       name_len += 2;
                }
        }
 
@@ -4898,10 +4847,8 @@ GetInodeNumberRetry:
                                           remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(search_name, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, search_name, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, search_name);
        }
 
        params = 2 /* level */  + 4 /* rsrvd */  + name_len /* incl null */ ;
@@ -5008,9 +4955,7 @@ getDFSRetry:
                name_len++;     /* trailing null */
                name_len *= 2;
        } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(search_name, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->RequestFileName, search_name, name_len);
+               name_len = copy_path_name(pSMB->RequestFileName, search_name);
        }
 
        if (ses->server->sign)
@@ -5663,10 +5608,8 @@ SetEOFRetry:
                                       PATH_MAX, cifs_sb->local_nls, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(file_name, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, file_name, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, file_name);
        }
        params = 6 + name_len;
        data_count = sizeof(struct file_end_of_file_info);
@@ -5959,10 +5902,8 @@ SetTimesRetry:
                                       PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(fileName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, fileName, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, fileName);
        }
 
        params = 6 + name_len;
@@ -6040,10 +5981,8 @@ SetAttrLgcyRetry:
                                       PATH_MAX, nls_codepage);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(fileName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->fileName, fileName, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->fileName, fileName);
        }
        pSMB->attr = cpu_to_le16(dos_attrs);
        pSMB->BufferFormat = 0x04;
@@ -6203,10 +6142,8 @@ setPermsRetry:
                                       PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(file_name, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, file_name, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, file_name);
        }
 
        params = 6 + name_len;
@@ -6298,10 +6235,8 @@ QAllEAsRetry:
                                       PATH_MAX, nls_codepage, remap);
                list_len++;     /* trailing null */
                list_len *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               list_len = strnlen(searchName, PATH_MAX);
-               list_len++;     /* trailing null */
-               strncpy(pSMB->FileName, searchName, list_len);
+       } else {
+               list_len = copy_path_name(pSMB->FileName, searchName);
        }
 
        params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
@@ -6480,10 +6415,8 @@ SetEARetry:
                                       PATH_MAX, nls_codepage, remap);
                name_len++;     /* trailing null */
                name_len *= 2;
-       } else {        /* BB improve the check for buffer overruns BB */
-               name_len = strnlen(fileName, PATH_MAX);
-               name_len++;     /* trailing null */
-               strncpy(pSMB->FileName, fileName, name_len);
+       } else {
+               name_len = copy_path_name(pSMB->FileName, fileName);
        }
 
        params = 6 + name_len;
index 1795e80..5299eff 100644 (file)
@@ -2981,6 +2981,7 @@ static int
 cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
 {
        int rc = 0;
+       int is_domain = 0;
        const char *delim, *payload;
        char *desc;
        ssize_t len;
@@ -3028,6 +3029,7 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
                        rc = PTR_ERR(key);
                        goto out_err;
                }
+               is_domain = 1;
        }
 
        down_read(&key->sem);
@@ -3085,6 +3087,26 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
                goto out_key_put;
        }
 
+       /*
+        * If we have a domain key then we must set the domainName in the
+        * for the request.
+        */
+       if (is_domain && ses->domainName) {
+               vol->domainname = kstrndup(ses->domainName,
+                                          strlen(ses->domainName),
+                                          GFP_KERNEL);
+               if (!vol->domainname) {
+                       cifs_dbg(FYI, "Unable to allocate %zd bytes for "
+                                "domain\n", len);
+                       rc = -ENOMEM;
+                       kfree(vol->username);
+                       vol->username = NULL;
+                       kzfree(vol->password);
+                       vol->password = NULL;
+                       goto out_key_put;
+               }
+       }
+
 out_key_put:
        up_read(&key->sem);
        key_put(key);
@@ -4209,16 +4231,19 @@ build_unc_path_to_root(const struct smb_vol *vol,
                strlen(vol->prepath) + 1 : 0;
        unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1);
 
+       if (unc_len > MAX_TREE_SIZE)
+               return ERR_PTR(-EINVAL);
+
        full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL);
        if (full_path == NULL)
                return ERR_PTR(-ENOMEM);
 
-       strncpy(full_path, vol->UNC, unc_len);
+       memcpy(full_path, vol->UNC, unc_len);
        pos = full_path + unc_len;
 
        if (pplen) {
                *pos = CIFS_DIR_SEP(cifs_sb);
-               strncpy(pos + 1, vol->prepath, pplen);
+               memcpy(pos + 1, vol->prepath, pplen);
                pos += pplen;
        }
 
index f26a48d..be424e8 100644 (file)
@@ -69,11 +69,10 @@ cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
                return full_path;
 
        if (dfsplen)
-               strncpy(full_path, tcon->treeName, dfsplen);
+               memcpy(full_path, tcon->treeName, dfsplen);
        full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb);
-       strncpy(full_path + dfsplen + 1, vol->prepath, pplen);
+       memcpy(full_path + dfsplen + 1, vol->prepath, pplen);
        convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
-       full_path[dfsplen + pplen] = 0; /* add trailing null */
        return full_path;
 }
 
index f383877..5ad83bd 100644 (file)
@@ -1011,3 +1011,25 @@ void extract_unc_hostname(const char *unc, const char **h, size_t *len)
        *h = unc;
        *len = end - unc;
 }
+
+/**
+ * copy_path_name - copy src path to dst, possibly truncating
+ *
+ * returns number of bytes written (including trailing nul)
+ */
+int copy_path_name(char *dst, const char *src)
+{
+       int name_len;
+
+       /*
+        * PATH_MAX includes nul, so if strlen(src) >= PATH_MAX it
+        * will truncate and strlen(dst) will be PATH_MAX-1
+        */
+       name_len = strscpy(dst, src, PATH_MAX);
+       if (WARN_ON_ONCE(name_len < 0))
+               name_len = PATH_MAX-1;
+
+       /* we count the trailing nul */
+       name_len++;
+       return name_len;
+}
index dcd49ad..4c764ff 100644 (file)
@@ -159,13 +159,16 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
                                 const struct nls_table *nls_cp)
 {
        char *bcc_ptr = *pbcc_area;
+       int len;
 
        /* copy user */
        /* BB what about null user mounts - check that we do this BB */
        /* copy user */
        if (ses->user_name != NULL) {
-               strncpy(bcc_ptr, ses->user_name, CIFS_MAX_USERNAME_LEN);
-               bcc_ptr += strnlen(ses->user_name, CIFS_MAX_USERNAME_LEN);
+               len = strscpy(bcc_ptr, ses->user_name, CIFS_MAX_USERNAME_LEN);
+               if (WARN_ON_ONCE(len < 0))
+                       len = CIFS_MAX_USERNAME_LEN - 1;
+               bcc_ptr += len;
        }
        /* else null user mount */
        *bcc_ptr = 0;
@@ -173,8 +176,10 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
 
        /* copy domain */
        if (ses->domainName != NULL) {
-               strncpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
-               bcc_ptr += strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
+               len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
+               if (WARN_ON_ONCE(len < 0))
+                       len = CIFS_MAX_DOMAINNAME_LEN - 1;
+               bcc_ptr += len;
        } /* else we will send a null domain name
             so the server will default to its own domain */
        *bcc_ptr = 0;
@@ -242,9 +247,10 @@ static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
 
        kfree(ses->serverOS);
 
-       ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
+       ses->serverOS = kmalloc(len + 1, GFP_KERNEL);
        if (ses->serverOS) {
-               strncpy(ses->serverOS, bcc_ptr, len);
+               memcpy(ses->serverOS, bcc_ptr, len);
+               ses->serverOS[len] = 0;
                if (strncmp(ses->serverOS, "OS/2", 4) == 0)
                        cifs_dbg(FYI, "OS/2 server\n");
        }
@@ -258,9 +264,11 @@ static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
 
        kfree(ses->serverNOS);
 
-       ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
-       if (ses->serverNOS)
-               strncpy(ses->serverNOS, bcc_ptr, len);
+       ses->serverNOS = kmalloc(len + 1, GFP_KERNEL);
+       if (ses->serverNOS) {
+               memcpy(ses->serverNOS, bcc_ptr, len);
+               ses->serverNOS[len] = 0;
+       }
 
        bcc_ptr += len + 1;
        bleft -= len + 1;
index f752d83..520f181 100644 (file)
 #include <linux/list.h>
 #include <linux/spinlock.h>
 
+struct configfs_fragment {
+       atomic_t frag_count;
+       struct rw_semaphore frag_sem;
+       bool frag_dead;
+};
+
+void put_fragment(struct configfs_fragment *);
+struct configfs_fragment *get_fragment(struct configfs_fragment *);
+
 struct configfs_dirent {
        atomic_t                s_count;
        int                     s_dependent_count;
@@ -34,6 +43,7 @@ struct configfs_dirent {
 #ifdef CONFIG_LOCKDEP
        int                     s_depth;
 #endif
+       struct configfs_fragment *s_frag;
 };
 
 #define CONFIGFS_ROOT          0x0001
@@ -61,8 +71,8 @@ extern int configfs_create(struct dentry *, umode_t mode, void (*init)(struct in
 extern int configfs_create_file(struct config_item *, const struct configfs_attribute *);
 extern int configfs_create_bin_file(struct config_item *,
                                    const struct configfs_bin_attribute *);
-extern int configfs_make_dirent(struct configfs_dirent *,
-                               struct dentry *, void *, umode_t, int);
+extern int configfs_make_dirent(struct configfs_dirent *, struct dentry *,
+                               void *, umode_t, int, struct configfs_fragment *);
 extern int configfs_dirent_is_ready(struct configfs_dirent *);
 
 extern void configfs_hash_and_remove(struct dentry * dir, const char * name);
@@ -137,6 +147,7 @@ static inline void release_configfs_dirent(struct configfs_dirent * sd)
 {
        if (!(sd->s_type & CONFIGFS_ROOT)) {
                kfree(sd->s_iattr);
+               put_fragment(sd->s_frag);
                kmem_cache_free(configfs_dir_cachep, sd);
        }
 }
index 9211291..79fc25a 100644 (file)
@@ -151,11 +151,38 @@ configfs_adjust_dir_dirent_depth_after_populate(struct configfs_dirent *sd)
 
 #endif /* CONFIG_LOCKDEP */
 
+static struct configfs_fragment *new_fragment(void)
+{
+       struct configfs_fragment *p;
+
+       p = kmalloc(sizeof(struct configfs_fragment), GFP_KERNEL);
+       if (p) {
+               atomic_set(&p->frag_count, 1);
+               init_rwsem(&p->frag_sem);
+               p->frag_dead = false;
+       }
+       return p;
+}
+
+void put_fragment(struct configfs_fragment *frag)
+{
+       if (frag && atomic_dec_and_test(&frag->frag_count))
+               kfree(frag);
+}
+
+struct configfs_fragment *get_fragment(struct configfs_fragment *frag)
+{
+       if (likely(frag))
+               atomic_inc(&frag->frag_count);
+       return frag;
+}
+
 /*
  * Allocates a new configfs_dirent and links it to the parent configfs_dirent
  */
 static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent *parent_sd,
-                                                  void *element, int type)
+                                                  void *element, int type,
+                                                  struct configfs_fragment *frag)
 {
        struct configfs_dirent * sd;
 
@@ -175,6 +202,7 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent *paren
                kmem_cache_free(configfs_dir_cachep, sd);
                return ERR_PTR(-ENOENT);
        }
+       sd->s_frag = get_fragment(frag);
        list_add(&sd->s_sibling, &parent_sd->s_children);
        spin_unlock(&configfs_dirent_lock);
 
@@ -209,11 +237,11 @@ static int configfs_dirent_exists(struct configfs_dirent *parent_sd,
 
 int configfs_make_dirent(struct configfs_dirent * parent_sd,
                         struct dentry * dentry, void * element,
-                        umode_t mode, int type)
+                        umode_t mode, int type, struct configfs_fragment *frag)
 {
        struct configfs_dirent * sd;
 
-       sd = configfs_new_dirent(parent_sd, element, type);
+       sd = configfs_new_dirent(parent_sd, element, type, frag);
        if (IS_ERR(sd))
                return PTR_ERR(sd);
 
@@ -260,7 +288,8 @@ static void init_symlink(struct inode * inode)
  *     until it is validated by configfs_dir_set_ready()
  */
 
-static int configfs_create_dir(struct config_item *item, struct dentry *dentry)
+static int configfs_create_dir(struct config_item *item, struct dentry *dentry,
+                               struct configfs_fragment *frag)
 {
        int error;
        umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO;
@@ -273,7 +302,8 @@ static int configfs_create_dir(struct config_item *item, struct dentry *dentry)
                return error;
 
        error = configfs_make_dirent(p->d_fsdata, dentry, item, mode,
-                                    CONFIGFS_DIR | CONFIGFS_USET_CREATING);
+                                    CONFIGFS_DIR | CONFIGFS_USET_CREATING,
+                                    frag);
        if (unlikely(error))
                return error;
 
@@ -338,9 +368,10 @@ int configfs_create_link(struct configfs_symlink *sl,
 {
        int err = 0;
        umode_t mode = S_IFLNK | S_IRWXUGO;
+       struct configfs_dirent *p = parent->d_fsdata;
 
-       err = configfs_make_dirent(parent->d_fsdata, dentry, sl, mode,
-                                  CONFIGFS_ITEM_LINK);
+       err = configfs_make_dirent(p, dentry, sl, mode,
+                                  CONFIGFS_ITEM_LINK, p->s_frag);
        if (!err) {
                err = configfs_create(dentry, mode, init_symlink);
                if (err) {
@@ -599,7 +630,8 @@ static int populate_attrs(struct config_item *item)
 
 static int configfs_attach_group(struct config_item *parent_item,
                                 struct config_item *item,
-                                struct dentry *dentry);
+                                struct dentry *dentry,
+                                struct configfs_fragment *frag);
 static void configfs_detach_group(struct config_item *item);
 
 static void detach_groups(struct config_group *group)
@@ -647,7 +679,8 @@ static void detach_groups(struct config_group *group)
  * try using vfs_mkdir.  Just a thought.
  */
 static int create_default_group(struct config_group *parent_group,
-                               struct config_group *group)
+                               struct config_group *group,
+                               struct configfs_fragment *frag)
 {
        int ret;
        struct configfs_dirent *sd;
@@ -663,7 +696,7 @@ static int create_default_group(struct config_group *parent_group,
                d_add(child, NULL);
 
                ret = configfs_attach_group(&parent_group->cg_item,
-                                           &group->cg_item, child);
+                                           &group->cg_item, child, frag);
                if (!ret) {
                        sd = child->d_fsdata;
                        sd->s_type |= CONFIGFS_USET_DEFAULT;
@@ -677,13 +710,14 @@ static int create_default_group(struct config_group *parent_group,
        return ret;
 }
 
-static int populate_groups(struct config_group *group)
+static int populate_groups(struct config_group *group,
+                          struct configfs_fragment *frag)
 {
        struct config_group *new_group;
        int ret = 0;
 
        list_for_each_entry(new_group, &group->default_groups, group_entry) {
-               ret = create_default_group(group, new_group);
+               ret = create_default_group(group, new_group, frag);
                if (ret) {
                        detach_groups(group);
                        break;
@@ -797,11 +831,12 @@ static void link_group(struct config_group *parent_group, struct config_group *g
  */
 static int configfs_attach_item(struct config_item *parent_item,
                                struct config_item *item,
-                               struct dentry *dentry)
+                               struct dentry *dentry,
+                               struct configfs_fragment *frag)
 {
        int ret;
 
-       ret = configfs_create_dir(item, dentry);
+       ret = configfs_create_dir(item, dentry, frag);
        if (!ret) {
                ret = populate_attrs(item);
                if (ret) {
@@ -831,12 +866,13 @@ static void configfs_detach_item(struct config_item *item)
 
 static int configfs_attach_group(struct config_item *parent_item,
                                 struct config_item *item,
-                                struct dentry *dentry)
+                                struct dentry *dentry,
+                                struct configfs_fragment *frag)
 {
        int ret;
        struct configfs_dirent *sd;
 
-       ret = configfs_attach_item(parent_item, item, dentry);
+       ret = configfs_attach_item(parent_item, item, dentry, frag);
        if (!ret) {
                sd = dentry->d_fsdata;
                sd->s_type |= CONFIGFS_USET_DIR;
@@ -852,7 +888,7 @@ static int configfs_attach_group(struct config_item *parent_item,
                 */
                inode_lock_nested(d_inode(dentry), I_MUTEX_CHILD);
                configfs_adjust_dir_dirent_depth_before_populate(sd);
-               ret = populate_groups(to_config_group(item));
+               ret = populate_groups(to_config_group(item), frag);
                if (ret) {
                        configfs_detach_item(item);
                        d_inode(dentry)->i_flags |= S_DEAD;
@@ -1247,6 +1283,7 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
        struct configfs_dirent *sd;
        const struct config_item_type *type;
        struct module *subsys_owner = NULL, *new_item_owner = NULL;
+       struct configfs_fragment *frag;
        char *name;
 
        sd = dentry->d_parent->d_fsdata;
@@ -1265,6 +1302,12 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
                goto out;
        }
 
+       frag = new_fragment();
+       if (!frag) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
        /* Get a working ref for the duration of this function */
        parent_item = configfs_get_config_item(dentry->d_parent);
        type = parent_item->ci_type;
@@ -1367,9 +1410,9 @@ static int configfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode
        spin_unlock(&configfs_dirent_lock);
 
        if (group)
-               ret = configfs_attach_group(parent_item, item, dentry);
+               ret = configfs_attach_group(parent_item, item, dentry, frag);
        else
-               ret = configfs_attach_item(parent_item, item, dentry);
+               ret = configfs_attach_item(parent_item, item, dentry, frag);
 
        spin_lock(&configfs_dirent_lock);
        sd->s_type &= ~CONFIGFS_USET_IN_MKDIR;
@@ -1406,6 +1449,7 @@ out_put:
         * reference.
         */
        config_item_put(parent_item);
+       put_fragment(frag);
 
 out:
        return ret;
@@ -1417,6 +1461,7 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
        struct config_item *item;
        struct configfs_subsystem *subsys;
        struct configfs_dirent *sd;
+       struct configfs_fragment *frag;
        struct module *subsys_owner = NULL, *dead_item_owner = NULL;
        int ret;
 
@@ -1474,6 +1519,16 @@ static int configfs_rmdir(struct inode *dir, struct dentry *dentry)
                }
        } while (ret == -EAGAIN);
 
+       frag = sd->s_frag;
+       if (down_write_killable(&frag->frag_sem)) {
+               spin_lock(&configfs_dirent_lock);
+               configfs_detach_rollback(dentry);
+               spin_unlock(&configfs_dirent_lock);
+               return -EINTR;
+       }
+       frag->frag_dead = true;
+       up_write(&frag->frag_sem);
+
        /* Get a working ref for the duration of this function */
        item = configfs_get_config_item(dentry);
 
@@ -1574,7 +1629,7 @@ static int configfs_dir_open(struct inode *inode, struct file *file)
         */
        err = -ENOENT;
        if (configfs_dirent_is_ready(parent_sd)) {
-               file->private_data = configfs_new_dirent(parent_sd, NULL, 0);
+               file->private_data = configfs_new_dirent(parent_sd, NULL, 0, NULL);
                if (IS_ERR(file->private_data))
                        err = PTR_ERR(file->private_data);
                else
@@ -1732,8 +1787,13 @@ int configfs_register_group(struct config_group *parent_group,
 {
        struct configfs_subsystem *subsys = parent_group->cg_subsys;
        struct dentry *parent;
+       struct configfs_fragment *frag;
        int ret;
 
+       frag = new_fragment();
+       if (!frag)
+               return -ENOMEM;
+
        mutex_lock(&subsys->su_mutex);
        link_group(parent_group, group);
        mutex_unlock(&subsys->su_mutex);
@@ -1741,7 +1801,7 @@ int configfs_register_group(struct config_group *parent_group,
        parent = parent_group->cg_item.ci_dentry;
 
        inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
-       ret = create_default_group(parent_group, group);
+       ret = create_default_group(parent_group, group, frag);
        if (ret)
                goto err_out;
 
@@ -1749,12 +1809,14 @@ int configfs_register_group(struct config_group *parent_group,
        configfs_dir_set_ready(group->cg_item.ci_dentry->d_fsdata);
        spin_unlock(&configfs_dirent_lock);
        inode_unlock(d_inode(parent));
+       put_fragment(frag);
        return 0;
 err_out:
        inode_unlock(d_inode(parent));
        mutex_lock(&subsys->su_mutex);
        unlink_group(group);
        mutex_unlock(&subsys->su_mutex);
+       put_fragment(frag);
        return ret;
 }
 EXPORT_SYMBOL(configfs_register_group);
@@ -1770,16 +1832,12 @@ void configfs_unregister_group(struct config_group *group)
        struct configfs_subsystem *subsys = group->cg_subsys;
        struct dentry *dentry = group->cg_item.ci_dentry;
        struct dentry *parent = group->cg_item.ci_parent->ci_dentry;
+       struct configfs_dirent *sd = dentry->d_fsdata;
+       struct configfs_fragment *frag = sd->s_frag;
 
-       mutex_lock(&subsys->su_mutex);
-       if (!group->cg_item.ci_parent->ci_group) {
-               /*
-                * The parent has already been unlinked and detached
-                * due to a rmdir.
-                */
-               goto unlink_group;
-       }
-       mutex_unlock(&subsys->su_mutex);
+       down_write(&frag->frag_sem);
+       frag->frag_dead = true;
+       up_write(&frag->frag_sem);
 
        inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
        spin_lock(&configfs_dirent_lock);
@@ -1796,7 +1854,6 @@ void configfs_unregister_group(struct config_group *group)
        dput(dentry);
 
        mutex_lock(&subsys->su_mutex);
-unlink_group:
        unlink_group(group);
        mutex_unlock(&subsys->su_mutex);
 }
@@ -1853,10 +1910,17 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
        struct dentry *dentry;
        struct dentry *root;
        struct configfs_dirent *sd;
+       struct configfs_fragment *frag;
+
+       frag = new_fragment();
+       if (!frag)
+               return -ENOMEM;
 
        root = configfs_pin_fs();
-       if (IS_ERR(root))
+       if (IS_ERR(root)) {
+               put_fragment(frag);
                return PTR_ERR(root);
+       }
 
        if (!group->cg_item.ci_name)
                group->cg_item.ci_name = group->cg_item.ci_namebuf;
@@ -1872,7 +1936,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
                d_add(dentry, NULL);
 
                err = configfs_attach_group(sd->s_element, &group->cg_item,
-                                           dentry);
+                                           dentry, frag);
                if (err) {
                        BUG_ON(d_inode(dentry));
                        d_drop(dentry);
@@ -1890,6 +1954,7 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys)
                unlink_group(group);
                configfs_release_fs();
        }
+       put_fragment(frag);
 
        return err;
 }
@@ -1899,12 +1964,18 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
        struct config_group *group = &subsys->su_group;
        struct dentry *dentry = group->cg_item.ci_dentry;
        struct dentry *root = dentry->d_sb->s_root;
+       struct configfs_dirent *sd = dentry->d_fsdata;
+       struct configfs_fragment *frag = sd->s_frag;
 
        if (dentry->d_parent != root) {
                pr_err("Tried to unregister non-subsystem!\n");
                return;
        }
 
+       down_write(&frag->frag_sem);
+       frag->frag_dead = true;
+       up_write(&frag->frag_sem);
+
        inode_lock_nested(d_inode(root),
                          I_MUTEX_PARENT);
        inode_lock_nested(d_inode(dentry), I_MUTEX_CHILD);
index 61e4db4..fb65b70 100644 (file)
@@ -39,40 +39,44 @@ struct configfs_buffer {
        bool                    write_in_progress;
        char                    *bin_buffer;
        int                     bin_buffer_size;
+       int                     cb_max_size;
+       struct config_item      *item;
+       struct module           *owner;
+       union {
+               struct configfs_attribute       *attr;
+               struct configfs_bin_attribute   *bin_attr;
+       };
 };
 
+static inline struct configfs_fragment *to_frag(struct file *file)
+{
+       struct configfs_dirent *sd = file->f_path.dentry->d_fsdata;
 
-/**
- *     fill_read_buffer - allocate and fill buffer from item.
- *     @dentry:        dentry pointer.
- *     @buffer:        data buffer for file.
- *
- *     Allocate @buffer->page, if it hasn't been already, then call the
- *     config_item's show() method to fill the buffer with this attribute's
- *     data.
- *     This is called only once, on the file's first read.
- */
-static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buffer)
+       return sd->s_frag;
+}
+
+static int fill_read_buffer(struct file *file, struct configfs_buffer *buffer)
 {
-       struct configfs_attribute * attr = to_attr(dentry);
-       struct config_item * item = to_item(dentry->d_parent);
-       int ret = 0;
-       ssize_t count;
+       struct configfs_fragment *frag = to_frag(file);
+       ssize_t count = -ENOENT;
 
        if (!buffer->page)
                buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
        if (!buffer->page)
                return -ENOMEM;
 
-       count = attr->show(item, buffer->page);
-
-       BUG_ON(count > (ssize_t)SIMPLE_ATTR_SIZE);
-       if (count >= 0) {
-               buffer->needs_read_fill = 0;
-               buffer->count = count;
-       } else
-               ret = count;
-       return ret;
+       down_read(&frag->frag_sem);
+       if (!frag->frag_dead)
+               count = buffer->attr->show(buffer->item, buffer->page);
+       up_read(&frag->frag_sem);
+
+       if (count < 0)
+               return count;
+       if (WARN_ON_ONCE(count > (ssize_t)SIMPLE_ATTR_SIZE))
+               return -EIO;
+       buffer->needs_read_fill = 0;
+       buffer->count = count;
+       return 0;
 }
 
 /**
@@ -97,12 +101,13 @@ static int fill_read_buffer(struct dentry * dentry, struct configfs_buffer * buf
 static ssize_t
 configfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
-       struct configfs_buffer * buffer = file->private_data;
+       struct configfs_buffer *buffer = file->private_data;
        ssize_t retval = 0;
 
        mutex_lock(&buffer->mutex);
        if (buffer->needs_read_fill) {
-               if ((retval = fill_read_buffer(file->f_path.dentry,buffer)))
+               retval = fill_read_buffer(file, buffer);
+               if (retval)
                        goto out;
        }
        pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
@@ -138,10 +143,8 @@ static ssize_t
 configfs_read_bin_file(struct file *file, char __user *buf,
                       size_t count, loff_t *ppos)
 {
+       struct configfs_fragment *frag = to_frag(file);
        struct configfs_buffer *buffer = file->private_data;
-       struct dentry *dentry = file->f_path.dentry;
-       struct config_item *item = to_item(dentry->d_parent);
-       struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry);
        ssize_t retval = 0;
        ssize_t len = min_t(size_t, count, PAGE_SIZE);
 
@@ -156,14 +159,19 @@ configfs_read_bin_file(struct file *file, char __user *buf,
 
        if (buffer->needs_read_fill) {
                /* perform first read with buf == NULL to get extent */
-               len = bin_attr->read(item, NULL, 0);
+               down_read(&frag->frag_sem);
+               if (!frag->frag_dead)
+                       len = buffer->bin_attr->read(buffer->item, NULL, 0);
+               else
+                       len = -ENOENT;
+               up_read(&frag->frag_sem);
                if (len <= 0) {
                        retval = len;
                        goto out;
                }
 
                /* do not exceed the maximum value */
-               if (bin_attr->cb_max_size && len > bin_attr->cb_max_size) {
+               if (buffer->cb_max_size && len > buffer->cb_max_size) {
                        retval = -EFBIG;
                        goto out;
                }
@@ -176,7 +184,13 @@ configfs_read_bin_file(struct file *file, char __user *buf,
                buffer->bin_buffer_size = len;
 
                /* perform second read to fill buffer */
-               len = bin_attr->read(item, buffer->bin_buffer, len);
+               down_read(&frag->frag_sem);
+               if (!frag->frag_dead)
+                       len = buffer->bin_attr->read(buffer->item,
+                                                    buffer->bin_buffer, len);
+               else
+                       len = -ENOENT;
+               up_read(&frag->frag_sem);
                if (len < 0) {
                        retval = len;
                        vfree(buffer->bin_buffer);
@@ -226,25 +240,17 @@ fill_write_buffer(struct configfs_buffer * buffer, const char __user * buf, size
        return error ? -EFAULT : count;
 }
 
-
-/**
- *     flush_write_buffer - push buffer to config_item.
- *     @dentry:        dentry to the attribute
- *     @buffer:        data buffer for file.
- *     @count:         number of bytes
- *
- *     Get the correct pointers for the config_item and the attribute we're
- *     dealing with, then call the store() method for the attribute,
- *     passing the buffer that we acquired in fill_write_buffer().
- */
-
 static int
-flush_write_buffer(struct dentry * dentry, struct configfs_buffer * buffer, size_t count)
+flush_write_buffer(struct file *file, struct configfs_buffer *buffer, size_t count)
 {
-       struct configfs_attribute * attr = to_attr(dentry);
-       struct config_item * item = to_item(dentry->d_parent);
-
-       return attr->store(item, buffer->page, count);
+       struct configfs_fragment *frag = to_frag(file);
+       int res = -ENOENT;
+
+       down_read(&frag->frag_sem);
+       if (!frag->frag_dead)
+               res = buffer->attr->store(buffer->item, buffer->page, count);
+       up_read(&frag->frag_sem);
+       return res;
 }
 
 
@@ -268,13 +274,13 @@ flush_write_buffer(struct dentry * dentry, struct configfs_buffer * buffer, size
 static ssize_t
 configfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 {
-       struct configfs_buffer * buffer = file->private_data;
+       struct configfs_buffer *buffer = file->private_data;
        ssize_t len;
 
        mutex_lock(&buffer->mutex);
        len = fill_write_buffer(buffer, buf, count);
        if (len > 0)
-               len = flush_write_buffer(file->f_path.dentry, buffer, len);
+               len = flush_write_buffer(file, buffer, len);
        if (len > 0)
                *ppos += len;
        mutex_unlock(&buffer->mutex);
@@ -299,8 +305,6 @@ configfs_write_bin_file(struct file *file, const char __user *buf,
                        size_t count, loff_t *ppos)
 {
        struct configfs_buffer *buffer = file->private_data;
-       struct dentry *dentry = file->f_path.dentry;
-       struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry);
        void *tbuf = NULL;
        ssize_t len;
 
@@ -316,8 +320,8 @@ configfs_write_bin_file(struct file *file, const char __user *buf,
        /* buffer grows? */
        if (*ppos + count > buffer->bin_buffer_size) {
 
-               if (bin_attr->cb_max_size &&
-                       *ppos + count > bin_attr->cb_max_size) {
+               if (buffer->cb_max_size &&
+                       *ppos + count > buffer->cb_max_size) {
                        len = -EFBIG;
                        goto out;
                }
@@ -349,31 +353,51 @@ out:
        return len;
 }
 
-static int check_perm(struct inode * inode, struct file * file, int type)
+static int __configfs_open_file(struct inode *inode, struct file *file, int type)
 {
-       struct config_item *item = configfs_get_config_item(file->f_path.dentry->d_parent);
-       struct configfs_attribute * attr = to_attr(file->f_path.dentry);
-       struct configfs_bin_attribute *bin_attr = NULL;
-       struct configfs_buffer * buffer;
-       struct configfs_item_operations * ops = NULL;
-       int error = 0;
+       struct dentry *dentry = file->f_path.dentry;
+       struct configfs_fragment *frag = to_frag(file);
+       struct configfs_attribute *attr;
+       struct configfs_buffer *buffer;
+       int error;
 
-       if (!item || !attr)
-               goto Einval;
+       error = -ENOMEM;
+       buffer = kzalloc(sizeof(struct configfs_buffer), GFP_KERNEL);
+       if (!buffer)
+               goto out;
 
-       if (type & CONFIGFS_ITEM_BIN_ATTR)
-               bin_attr = to_bin_attr(file->f_path.dentry);
+       error = -ENOENT;
+       down_read(&frag->frag_sem);
+       if (unlikely(frag->frag_dead))
+               goto out_free_buffer;
 
-       /* Grab the module reference for this attribute if we have one */
-       if (!try_module_get(attr->ca_owner)) {
-               error = -ENODEV;
-               goto Done;
+       error = -EINVAL;
+       buffer->item = to_item(dentry->d_parent);
+       if (!buffer->item)
+               goto out_free_buffer;
+
+       attr = to_attr(dentry);
+       if (!attr)
+               goto out_put_item;
+
+       if (type & CONFIGFS_ITEM_BIN_ATTR) {
+               buffer->bin_attr = to_bin_attr(dentry);
+               buffer->cb_max_size = buffer->bin_attr->cb_max_size;
+       } else {
+               buffer->attr = attr;
        }
 
-       if (item->ci_type)
-               ops = item->ci_type->ct_item_ops;
-       else
-               goto Eaccess;
+       buffer->owner = attr->ca_owner;
+       /* Grab the module reference for this attribute if we have one */
+       error = -ENODEV;
+       if (!try_module_get(buffer->owner))
+               goto out_put_item;
+
+       error = -EACCES;
+       if (!buffer->item->ci_type)
+               goto out_put_module;
+
+       buffer->ops = buffer->item->ci_type->ct_item_ops;
 
        /* File needs write support.
         * The inode's perms must say it's ok,
@@ -381,13 +405,11 @@ static int check_perm(struct inode * inode, struct file * file, int type)
         */
        if (file->f_mode & FMODE_WRITE) {
                if (!(inode->i_mode & S_IWUGO))
-                       goto Eaccess;
-
+                       goto out_put_module;
                if ((type & CONFIGFS_ITEM_ATTR) && !attr->store)
-                       goto Eaccess;
-
-               if ((type & CONFIGFS_ITEM_BIN_ATTR) && !bin_attr->write)
-                       goto Eaccess;
+                       goto out_put_module;
+               if ((type & CONFIGFS_ITEM_BIN_ATTR) && !buffer->bin_attr->write)
+                       goto out_put_module;
        }
 
        /* File needs read support.
@@ -396,92 +418,72 @@ static int check_perm(struct inode * inode, struct file * file, int type)
         */
        if (file->f_mode & FMODE_READ) {
                if (!(inode->i_mode & S_IRUGO))
-                       goto Eaccess;
-
+                       goto out_put_module;
                if ((type & CONFIGFS_ITEM_ATTR) && !attr->show)
-                       goto Eaccess;
-
-               if ((type & CONFIGFS_ITEM_BIN_ATTR) && !bin_attr->read)
-                       goto Eaccess;
+                       goto out_put_module;
+               if ((type & CONFIGFS_ITEM_BIN_ATTR) && !buffer->bin_attr->read)
+                       goto out_put_module;
        }
 
-       /* No error? Great, allocate a buffer for the file, and store it
-        * it in file->private_data for easy access.
-        */
-       buffer = kzalloc(sizeof(struct configfs_buffer),GFP_KERNEL);
-       if (!buffer) {
-               error = -ENOMEM;
-               goto Enomem;
-       }
        mutex_init(&buffer->mutex);
        buffer->needs_read_fill = 1;
        buffer->read_in_progress = false;
        buffer->write_in_progress = false;
-       buffer->ops = ops;
        file->private_data = buffer;
-       goto Done;
+       up_read(&frag->frag_sem);
+       return 0;
 
- Einval:
-       error = -EINVAL;
-       goto Done;
- Eaccess:
-       error = -EACCES;
- Enomem:
-       module_put(attr->ca_owner);
- Done:
-       if (error && item)
-               config_item_put(item);
+out_put_module:
+       module_put(buffer->owner);
+out_put_item:
+       config_item_put(buffer->item);
+out_free_buffer:
+       up_read(&frag->frag_sem);
+       kfree(buffer);
+out:
        return error;
 }
 
 static int configfs_release(struct inode *inode, struct file *filp)
 {
-       struct config_item * item = to_item(filp->f_path.dentry->d_parent);
-       struct configfs_attribute * attr = to_attr(filp->f_path.dentry);
-       struct module * owner = attr->ca_owner;
-       struct configfs_buffer * buffer = filp->private_data;
-
-       if (item)
-               config_item_put(item);
-       /* After this point, attr should not be accessed. */
-       module_put(owner);
-
-       if (buffer) {
-               if (buffer->page)
-                       free_page((unsigned long)buffer->page);
-               mutex_destroy(&buffer->mutex);
-               kfree(buffer);
-       }
+       struct configfs_buffer *buffer = filp->private_data;
+
+       module_put(buffer->owner);
+       if (buffer->page)
+               free_page((unsigned long)buffer->page);
+       mutex_destroy(&buffer->mutex);
+       kfree(buffer);
        return 0;
 }
 
 static int configfs_open_file(struct inode *inode, struct file *filp)
 {
-       return check_perm(inode, filp, CONFIGFS_ITEM_ATTR);
+       return __configfs_open_file(inode, filp, CONFIGFS_ITEM_ATTR);
 }
 
 static int configfs_open_bin_file(struct inode *inode, struct file *filp)
 {
-       return check_perm(inode, filp, CONFIGFS_ITEM_BIN_ATTR);
+       return __configfs_open_file(inode, filp, CONFIGFS_ITEM_BIN_ATTR);
 }
 
-static int configfs_release_bin_file(struct inode *inode, struct file *filp)
+static int configfs_release_bin_file(struct inode *inode, struct file *file)
 {
-       struct configfs_buffer *buffer = filp->private_data;
-       struct dentry *dentry = filp->f_path.dentry;
-       struct config_item *item = to_item(dentry->d_parent);
-       struct configfs_bin_attribute *bin_attr = to_bin_attr(dentry);
-       ssize_t len = 0;
-       int ret;
+       struct configfs_buffer *buffer = file->private_data;
 
        buffer->read_in_progress = false;
 
        if (buffer->write_in_progress) {
+               struct configfs_fragment *frag = to_frag(file);
                buffer->write_in_progress = false;
 
-               len = bin_attr->write(item, buffer->bin_buffer,
-                               buffer->bin_buffer_size);
-
+               down_read(&frag->frag_sem);
+               if (!frag->frag_dead) {
+                       /* result of ->release() is ignored */
+                       buffer->bin_attr->write(buffer->item,
+                                       buffer->bin_buffer,
+                                       buffer->bin_buffer_size);
+               }
+               up_read(&frag->frag_sem);
                /* vfree on NULL is safe */
                vfree(buffer->bin_buffer);
                buffer->bin_buffer = NULL;
@@ -489,10 +491,8 @@ static int configfs_release_bin_file(struct inode *inode, struct file *filp)
                buffer->needs_read_fill = 1;
        }
 
-       ret = configfs_release(inode, filp);
-       if (len < 0)
-               return len;
-       return ret;
+       configfs_release(inode, file);
+       return 0;
 }
 
 
@@ -527,7 +527,7 @@ int configfs_create_file(struct config_item * item, const struct configfs_attrib
 
        inode_lock_nested(d_inode(dir), I_MUTEX_NORMAL);
        error = configfs_make_dirent(parent_sd, NULL, (void *) attr, mode,
-                                    CONFIGFS_ITEM_ATTR);
+                                    CONFIGFS_ITEM_ATTR, parent_sd->s_frag);
        inode_unlock(d_inode(dir));
 
        return error;
@@ -549,7 +549,7 @@ int configfs_create_bin_file(struct config_item *item,
 
        inode_lock_nested(dir->d_inode, I_MUTEX_NORMAL);
        error = configfs_make_dirent(parent_sd, NULL, (void *) bin_attr, mode,
-                                    CONFIGFS_ITEM_BIN_ATTR);
+                                    CONFIGFS_ITEM_BIN_ATTR, parent_sd->s_frag);
        inode_unlock(dir->d_inode);
 
        return error;
index 420fe3d..006b7a2 100644 (file)
@@ -4586,7 +4586,6 @@ static int __ext4_get_inode_loc(struct inode *inode,
        struct buffer_head      *bh;
        struct super_block      *sb = inode->i_sb;
        ext4_fsblk_t            block;
-       struct blk_plug         plug;
        int                     inodes_per_block, inode_offset;
 
        iloc->bh = NULL;
@@ -4675,7 +4674,6 @@ make_io:
                 * If we need to do any I/O, try to pre-readahead extra
                 * blocks from the inode table.
                 */
-               blk_start_plug(&plug);
                if (EXT4_SB(sb)->s_inode_readahead_blks) {
                        ext4_fsblk_t b, end, table;
                        unsigned num;
@@ -4706,7 +4704,6 @@ make_io:
                get_bh(bh);
                bh->b_end_io = end_buffer_read_sync;
                submit_bh(REQ_OP_READ, REQ_META | REQ_PRIO, bh);
-               blk_finish_plug(&plug);
                wait_on_buffer(bh);
                if (!buffer_uptodate(bh)) {
                        EXT4_ERROR_INODE_BLOCK(inode, block,
index 8d50109..0adfd88 100644 (file)
@@ -1487,7 +1487,7 @@ static int nfs_finish_open(struct nfs_open_context *ctx,
        if (S_ISREG(file->f_path.dentry->d_inode->i_mode))
                nfs_file_set_open_context(file, ctx);
        else
-               err = -ESTALE;
+               err = -EOPENSTALE;
 out:
        return err;
 }
index 0cb4424..222d711 100644 (file)
@@ -401,15 +401,21 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr)
        unsigned long bytes = 0;
        struct nfs_direct_req *dreq = hdr->dreq;
 
-       if (test_bit(NFS_IOHDR_REDO, &hdr->flags))
-               goto out_put;
-
        spin_lock(&dreq->lock);
-       if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && (hdr->good_bytes == 0))
+       if (test_bit(NFS_IOHDR_ERROR, &hdr->flags))
                dreq->error = hdr->error;
-       else
+
+       if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) {
+               spin_unlock(&dreq->lock);
+               goto out_put;
+       }
+
+       if (hdr->good_bytes != 0)
                nfs_direct_good_bytes(dreq, hdr);
 
+       if (test_bit(NFS_IOHDR_EOF, &hdr->flags))
+               dreq->error = 0;
+
        spin_unlock(&dreq->lock);
 
        while (!list_empty(&hdr->pages)) {
@@ -782,16 +788,19 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr)
        bool request_commit = false;
        struct nfs_page *req = nfs_list_entry(hdr->pages.next);
 
-       if (test_bit(NFS_IOHDR_REDO, &hdr->flags))
-               goto out_put;
-
        nfs_init_cinfo_from_dreq(&cinfo, dreq);
 
        spin_lock(&dreq->lock);
 
        if (test_bit(NFS_IOHDR_ERROR, &hdr->flags))
                dreq->error = hdr->error;
-       if (dreq->error == 0) {
+
+       if (test_bit(NFS_IOHDR_REDO, &hdr->flags)) {
+               spin_unlock(&dreq->lock);
+               goto out_put;
+       }
+
+       if (hdr->good_bytes != 0) {
                nfs_direct_good_bytes(dreq, hdr);
                if (nfs_write_need_commit(hdr)) {
                        if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES)
index b04e20d..5657b7f 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <linux/nfs_fs.h>
+#include <linux/nfs_mount.h>
 #include <linux/nfs_page.h>
 #include <linux/module.h>
 #include <linux/sched/mm.h>
@@ -928,7 +929,9 @@ retry:
        pgm = &pgio->pg_mirrors[0];
        pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].rsize;
 
-       pgio->pg_maxretrans = io_maxretrans;
+       if (NFS_SERVER(pgio->pg_inode)->flags &
+                       (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR))
+               pgio->pg_maxretrans = io_maxretrans;
        return;
 out_nolseg:
        if (pgio->pg_error < 0)
@@ -940,6 +943,7 @@ out_mds:
                        pgio->pg_lseg);
        pnfs_put_lseg(pgio->pg_lseg);
        pgio->pg_lseg = NULL;
+       pgio->pg_maxretrans = 0;
        nfs_pageio_reset_read_mds(pgio);
 }
 
@@ -1000,7 +1004,9 @@ retry:
                pgm->pg_bsize = mirror->mirror_ds->ds_versions[0].wsize;
        }
 
-       pgio->pg_maxretrans = io_maxretrans;
+       if (NFS_SERVER(pgio->pg_inode)->flags &
+                       (NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR))
+               pgio->pg_maxretrans = io_maxretrans;
        return;
 
 out_mds:
@@ -1010,6 +1016,7 @@ out_mds:
                        pgio->pg_lseg);
        pnfs_put_lseg(pgio->pg_lseg);
        pgio->pg_lseg = NULL;
+       pgio->pg_maxretrans = 0;
        nfs_pageio_reset_write_mds(pgio);
 }
 
@@ -1148,8 +1155,6 @@ static int ff_layout_async_handle_error_v4(struct rpc_task *task,
                break;
        case -NFS4ERR_RETRY_UNCACHED_REP:
                break;
-       case -EAGAIN:
-               return -NFS4ERR_RESET_TO_PNFS;
        /* Invalidate Layout errors */
        case -NFS4ERR_PNFS_NO_LAYOUT:
        case -ESTALE:           /* mapped NFS4ERR_STALE */
@@ -1210,7 +1215,6 @@ static int ff_layout_async_handle_error_v3(struct rpc_task *task,
        case -EBADHANDLE:
        case -ELOOP:
        case -ENOSPC:
-       case -EAGAIN:
                break;
        case -EJUKEBOX:
                nfs_inc_stats(lseg->pls_layout->plh_inode, NFSIOS_DELAY);
@@ -1445,16 +1449,6 @@ static void ff_layout_read_prepare_v4(struct rpc_task *task, void *data)
        ff_layout_read_prepare_common(task, hdr);
 }
 
-static void
-ff_layout_io_prepare_transmit(struct rpc_task *task,
-               void *data)
-{
-       struct nfs_pgio_header *hdr = data;
-
-       if (!pnfs_is_valid_lseg(hdr->lseg))
-               rpc_exit(task, -EAGAIN);
-}
-
 static void ff_layout_read_call_done(struct rpc_task *task, void *data)
 {
        struct nfs_pgio_header *hdr = data;
@@ -1740,7 +1734,6 @@ static void ff_layout_commit_release(void *data)
 
 static const struct rpc_call_ops ff_layout_read_call_ops_v3 = {
        .rpc_call_prepare = ff_layout_read_prepare_v3,
-       .rpc_call_prepare_transmit = ff_layout_io_prepare_transmit,
        .rpc_call_done = ff_layout_read_call_done,
        .rpc_count_stats = ff_layout_read_count_stats,
        .rpc_release = ff_layout_read_release,
@@ -1748,7 +1741,6 @@ static const struct rpc_call_ops ff_layout_read_call_ops_v3 = {
 
 static const struct rpc_call_ops ff_layout_read_call_ops_v4 = {
        .rpc_call_prepare = ff_layout_read_prepare_v4,
-       .rpc_call_prepare_transmit = ff_layout_io_prepare_transmit,
        .rpc_call_done = ff_layout_read_call_done,
        .rpc_count_stats = ff_layout_read_count_stats,
        .rpc_release = ff_layout_read_release,
@@ -1756,7 +1748,6 @@ static const struct rpc_call_ops ff_layout_read_call_ops_v4 = {
 
 static const struct rpc_call_ops ff_layout_write_call_ops_v3 = {
        .rpc_call_prepare = ff_layout_write_prepare_v3,
-       .rpc_call_prepare_transmit = ff_layout_io_prepare_transmit,
        .rpc_call_done = ff_layout_write_call_done,
        .rpc_count_stats = ff_layout_write_count_stats,
        .rpc_release = ff_layout_write_release,
@@ -1764,7 +1755,6 @@ static const struct rpc_call_ops ff_layout_write_call_ops_v3 = {
 
 static const struct rpc_call_ops ff_layout_write_call_ops_v4 = {
        .rpc_call_prepare = ff_layout_write_prepare_v4,
-       .rpc_call_prepare_transmit = ff_layout_io_prepare_transmit,
        .rpc_call_done = ff_layout_write_call_done,
        .rpc_count_stats = ff_layout_write_count_stats,
        .rpc_release = ff_layout_write_release,
index 8a17582..2a03bfe 100644 (file)
@@ -1403,12 +1403,22 @@ static int nfs_check_inode_attributes(struct inode *inode, struct nfs_fattr *fat
        if (NFS_PROTO(inode)->have_delegation(inode, FMODE_READ))
                return 0;
 
+       if (!(fattr->valid & NFS_ATTR_FATTR_FILEID)) {
+               /* Only a mounted-on-fileid? Just exit */
+               if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
+                       return 0;
        /* Has the inode gone and changed behind our back? */
-       if ((fattr->valid & NFS_ATTR_FATTR_FILEID) && nfsi->fileid != fattr->fileid)
+       } else if (nfsi->fileid != fattr->fileid) {
+               /* Is this perhaps the mounted-on fileid? */
+               if ((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) &&
+                   nfsi->fileid == fattr->mounted_on_fileid)
+                       return 0;
                return -ESTALE;
+       }
        if ((fattr->valid & NFS_ATTR_FATTR_TYPE) && (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT))
                return -ESTALE;
 
+
        if (!nfs_file_has_buffered_writers(nfsi)) {
                /* Verify a few of the more important attributes */
                if ((fattr->valid & NFS_ATTR_FATTR_CHANGE) != 0 && !inode_eq_iversion_raw(inode, fattr->change_attr))
@@ -1768,18 +1778,6 @@ int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fa
 EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc);
 
 
-static inline bool nfs_fileid_valid(struct nfs_inode *nfsi,
-                                   struct nfs_fattr *fattr)
-{
-       bool ret1 = true, ret2 = true;
-
-       if (fattr->valid & NFS_ATTR_FATTR_FILEID)
-               ret1 = (nfsi->fileid == fattr->fileid);
-       if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
-               ret2 = (nfsi->fileid == fattr->mounted_on_fileid);
-       return ret1 || ret2;
-}
-
 /*
  * Many nfs protocol calls return the new file attributes after
  * an operation.  Here we update the inode to reflect the state
@@ -1810,7 +1808,16 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                        nfs_display_fhandle_hash(NFS_FH(inode)),
                        atomic_read(&inode->i_count), fattr->valid);
 
-       if (!nfs_fileid_valid(nfsi, fattr)) {
+       if (!(fattr->valid & NFS_ATTR_FATTR_FILEID)) {
+               /* Only a mounted-on-fileid? Just exit */
+               if (fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID)
+                       return 0;
+       /* Has the inode gone and changed behind our back? */
+       } else if (nfsi->fileid != fattr->fileid) {
+               /* Is this perhaps the mounted-on fileid? */
+               if ((fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) &&
+                   nfsi->fileid == fattr->mounted_on_fileid)
+                       return 0;
                printk(KERN_ERR "NFS: server %s error: fileid changed\n"
                        "fsid %s: expected fileid 0x%Lx, got 0x%Lx\n",
                        NFS_SERVER(inode)->nfs_client->cl_hostname,
index a2346a2..e64f810 100644 (file)
@@ -775,3 +775,13 @@ static inline bool nfs_error_is_fatal(int err)
        }
 }
 
+static inline bool nfs_error_is_fatal_on_server(int err)
+{
+       switch (err) {
+       case 0:
+       case -ERESTARTSYS:
+       case -EINTR:
+               return false;
+       }
+       return nfs_error_is_fatal(err);
+}
index 96db471..339663d 100644 (file)
@@ -73,13 +73,13 @@ nfs4_file_open(struct inode *inode, struct file *filp)
        if (IS_ERR(inode)) {
                err = PTR_ERR(inode);
                switch (err) {
-               case -EPERM:
-               case -EACCES:
-               case -EDQUOT:
-               case -ENOSPC:
-               case -EROFS:
-                       goto out_put_ctx;
                default:
+                       goto out_put_ctx;
+               case -ENOENT:
+               case -ESTALE:
+               case -EISDIR:
+               case -ENOTDIR:
+               case -ELOOP:
                        goto out_drop;
                }
        }
index ed4e1b0..20b3717 100644 (file)
@@ -590,7 +590,7 @@ static void nfs_pgio_rpcsetup(struct nfs_pgio_header *hdr,
        }
 
        hdr->res.fattr   = &hdr->fattr;
-       hdr->res.count   = count;
+       hdr->res.count   = 0;
        hdr->res.eof     = 0;
        hdr->res.verf    = &hdr->verf;
        nfs_fattr_init(&hdr->fattr);
@@ -1251,20 +1251,23 @@ static void nfs_pageio_complete_mirror(struct nfs_pageio_descriptor *desc,
 int nfs_pageio_resend(struct nfs_pageio_descriptor *desc,
                      struct nfs_pgio_header *hdr)
 {
-       LIST_HEAD(failed);
+       LIST_HEAD(pages);
 
        desc->pg_io_completion = hdr->io_completion;
        desc->pg_dreq = hdr->dreq;
-       while (!list_empty(&hdr->pages)) {
-               struct nfs_page *req = nfs_list_entry(hdr->pages.next);
+       list_splice_init(&hdr->pages, &pages);
+       while (!list_empty(&pages)) {
+               struct nfs_page *req = nfs_list_entry(pages.next);
 
                if (!nfs_pageio_add_request(desc, req))
-                       nfs_list_move_request(req, &failed);
+                       break;
        }
        nfs_pageio_complete(desc);
-       if (!list_empty(&failed)) {
-               list_move(&failed, &hdr->pages);
-               return desc->pg_error < 0 ? desc->pg_error : -EIO;
+       if (!list_empty(&pages)) {
+               int err = desc->pg_error < 0 ? desc->pg_error : -EIO;
+               hdr->completion_ops->error_cleanup(&pages, err);
+               nfs_set_pgio_error(hdr, err, hdr->io_start);
+               return err;
        }
        return 0;
 }
index c0046c3..82af480 100644 (file)
@@ -627,11 +627,16 @@ static int _nfs4_pnfs_v3_ds_connect(struct nfs_server *mds_srv,
                        /* Add this address as an alias */
                        rpc_clnt_add_xprt(clp->cl_rpcclient, &xprt_args,
                                        rpc_clnt_test_and_add_xprt, NULL);
-               } else
-                       clp = get_v3_ds_connect(mds_srv,
-                                       (struct sockaddr *)&da->da_addr,
-                                       da->da_addrlen, IPPROTO_TCP,
-                                       timeo, retrans);
+                       continue;
+               }
+               clp = get_v3_ds_connect(mds_srv,
+                               (struct sockaddr *)&da->da_addr,
+                               da->da_addrlen, IPPROTO_TCP,
+                               timeo, retrans);
+               if (IS_ERR(clp))
+                       continue;
+               clp->cl_rpcclient->cl_softerr = 0;
+               clp->cl_rpcclient->cl_softrtry = 0;
        }
 
        if (IS_ERR(clp)) {
index 5552fa8..0f7288b 100644 (file)
@@ -594,7 +594,8 @@ static int nfs_read_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
                /* Emulate the eof flag, which isn't normally needed in NFSv2
                 * as it is guaranteed to always return the file attributes
                 */
-               if (hdr->args.offset + hdr->res.count >= hdr->res.fattr->size)
+               if ((hdr->res.count == 0 && hdr->args.count > 0) ||
+                   hdr->args.offset + hdr->res.count >= hdr->res.fattr->size)
                        hdr->res.eof = 1;
        }
        return 0;
@@ -615,8 +616,10 @@ static int nfs_proc_pgio_rpc_prepare(struct rpc_task *task,
 
 static int nfs_write_done(struct rpc_task *task, struct nfs_pgio_header *hdr)
 {
-       if (task->tk_status >= 0)
+       if (task->tk_status >= 0) {
+               hdr->res.count = hdr->args.count;
                nfs_writeback_update_inode(hdr);
+       }
        return 0;
 }
 
index c19841c..cfe0b58 100644 (file)
@@ -91,19 +91,25 @@ void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio)
 }
 EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds);
 
-static void nfs_readpage_release(struct nfs_page *req)
+static void nfs_readpage_release(struct nfs_page *req, int error)
 {
        struct inode *inode = d_inode(nfs_req_openctx(req)->dentry);
+       struct page *page = req->wb_page;
 
        dprintk("NFS: read done (%s/%llu %d@%lld)\n", inode->i_sb->s_id,
                (unsigned long long)NFS_FILEID(inode), req->wb_bytes,
                (long long)req_offset(req));
 
+       if (nfs_error_is_fatal_on_server(error) && error != -ETIMEDOUT)
+               SetPageError(page);
        if (nfs_page_group_sync_on_bit(req, PG_UNLOCKPAGE)) {
-               if (PageUptodate(req->wb_page))
-                       nfs_readpage_to_fscache(inode, req->wb_page, 0);
+               struct address_space *mapping = page_file_mapping(page);
 
-               unlock_page(req->wb_page);
+               if (PageUptodate(page))
+                       nfs_readpage_to_fscache(inode, page, 0);
+               else if (!PageError(page) && !PagePrivate(page))
+                       generic_error_remove_page(mapping, page);
+               unlock_page(page);
        }
        nfs_release_request(req);
 }
@@ -131,7 +137,7 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
                             &nfs_async_read_completion_ops);
        if (!nfs_pageio_add_request(&pgio, new)) {
                nfs_list_remove_request(new);
-               nfs_readpage_release(new);
+               nfs_readpage_release(new, pgio.pg_error);
        }
        nfs_pageio_complete(&pgio);
 
@@ -153,6 +159,7 @@ static void nfs_page_group_set_uptodate(struct nfs_page *req)
 static void nfs_read_completion(struct nfs_pgio_header *hdr)
 {
        unsigned long bytes = 0;
+       int error;
 
        if (test_bit(NFS_IOHDR_REDO, &hdr->flags))
                goto out;
@@ -179,14 +186,19 @@ static void nfs_read_completion(struct nfs_pgio_header *hdr)
                                zero_user_segment(page, start, end);
                        }
                }
+               error = 0;
                bytes += req->wb_bytes;
                if (test_bit(NFS_IOHDR_ERROR, &hdr->flags)) {
                        if (bytes <= hdr->good_bytes)
                                nfs_page_group_set_uptodate(req);
+                       else {
+                               error = hdr->error;
+                               xchg(&nfs_req_openctx(req)->error, error);
+                       }
                } else
                        nfs_page_group_set_uptodate(req);
                nfs_list_remove_request(req);
-               nfs_readpage_release(req);
+               nfs_readpage_release(req, error);
        }
 out:
        hdr->release(hdr);
@@ -213,7 +225,7 @@ nfs_async_read_error(struct list_head *head, int error)
        while (!list_empty(head)) {
                req = nfs_list_entry(head->next);
                nfs_list_remove_request(req);
-               nfs_readpage_release(req);
+               nfs_readpage_release(req, error);
        }
 }
 
@@ -337,8 +349,13 @@ int nfs_readpage(struct file *file, struct page *page)
                        goto out;
        }
 
+       xchg(&ctx->error, 0);
        error = nfs_readpage_async(ctx, inode, page);
-
+       if (!error) {
+               error = wait_on_page_locked_killable(page);
+               if (!PageUptodate(page) && !error)
+                       error = xchg(&ctx->error, 0);
+       }
 out:
        put_nfs_open_context(ctx);
        return error;
@@ -372,8 +389,8 @@ readpage_async_filler(void *data, struct page *page)
                zero_user_segment(page, len, PAGE_SIZE);
        if (!nfs_pageio_add_request(desc->pgio, new)) {
                nfs_list_remove_request(new);
-               nfs_readpage_release(new);
                error = desc->pgio->pg_error;
+               nfs_readpage_release(new, error);
                goto out;
        }
        return 0;
index 92d9cad..85ca495 100644 (file)
@@ -57,6 +57,7 @@ static const struct rpc_call_ops nfs_commit_ops;
 static const struct nfs_pgio_completion_ops nfs_async_write_completion_ops;
 static const struct nfs_commit_completion_ops nfs_commit_completion_ops;
 static const struct nfs_rw_ops nfs_rw_write_ops;
+static void nfs_inode_remove_request(struct nfs_page *req);
 static void nfs_clear_request_commit(struct nfs_page *req);
 static void nfs_init_cinfo_from_inode(struct nfs_commit_info *cinfo,
                                      struct inode *inode);
@@ -591,23 +592,13 @@ release_request:
 
 static void nfs_write_error(struct nfs_page *req, int error)
 {
+       nfs_set_pageerror(page_file_mapping(req->wb_page));
        nfs_mapping_set_error(req->wb_page, error);
+       nfs_inode_remove_request(req);
        nfs_end_page_writeback(req);
        nfs_release_request(req);
 }
 
-static bool
-nfs_error_is_fatal_on_server(int err)
-{
-       switch (err) {
-       case 0:
-       case -ERESTARTSYS:
-       case -EINTR:
-               return false;
-       }
-       return nfs_error_is_fatal(err);
-}
-
 /*
  * Find an associated nfs write request, and prepare to flush it out
  * May return an error if the user signalled nfs_wait_on_request().
@@ -615,7 +606,6 @@ nfs_error_is_fatal_on_server(int err)
 static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
                                struct page *page)
 {
-       struct address_space *mapping;
        struct nfs_page *req;
        int ret = 0;
 
@@ -630,12 +620,11 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
        WARN_ON_ONCE(test_bit(PG_CLEAN, &req->wb_flags));
 
        /* If there is a fatal error that covers this write, just exit */
-       ret = 0;
-       mapping = page_file_mapping(page);
-       if (test_bit(AS_ENOSPC, &mapping->flags) ||
-           test_bit(AS_EIO, &mapping->flags))
+       ret = pgio->pg_error;
+       if (nfs_error_is_fatal_on_server(ret))
                goto out_launder;
 
+       ret = 0;
        if (!nfs_pageio_add_request(pgio, req)) {
                ret = pgio->pg_error;
                /*
@@ -647,6 +636,7 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
                } else
                        ret = -EAGAIN;
                nfs_redirty_request(req);
+               pgio->pg_error = 0;
        } else
                nfs_add_stats(page_file_mapping(page)->host,
                                NFSIOS_WRITEPAGES, 1);
@@ -666,7 +656,7 @@ static int nfs_do_writepage(struct page *page, struct writeback_control *wbc,
        ret = nfs_page_async_flush(pgio, page);
        if (ret == -EAGAIN) {
                redirty_page_for_writepage(wbc, page);
-               ret = 0;
+               ret = AOP_WRITEPAGE_ACTIVATE;
        }
        return ret;
 }
@@ -685,10 +675,11 @@ static int nfs_writepage_locked(struct page *page,
        nfs_pageio_init_write(&pgio, inode, 0,
                                false, &nfs_async_write_completion_ops);
        err = nfs_do_writepage(page, wbc, &pgio);
+       pgio.pg_error = 0;
        nfs_pageio_complete(&pgio);
        if (err < 0)
                return err;
-       if (pgio.pg_error < 0)
+       if (nfs_error_is_fatal(pgio.pg_error))
                return pgio.pg_error;
        return 0;
 }
@@ -698,7 +689,8 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
        int ret;
 
        ret = nfs_writepage_locked(page, wbc);
-       unlock_page(page);
+       if (ret != AOP_WRITEPAGE_ACTIVATE)
+               unlock_page(page);
        return ret;
 }
 
@@ -707,7 +699,8 @@ static int nfs_writepages_callback(struct page *page, struct writeback_control *
        int ret;
 
        ret = nfs_do_writepage(page, wbc, data);
-       unlock_page(page);
+       if (ret != AOP_WRITEPAGE_ACTIVATE)
+               unlock_page(page);
        return ret;
 }
 
@@ -733,13 +726,14 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
                                &nfs_async_write_completion_ops);
        pgio.pg_io_completion = ioc;
        err = write_cache_pages(mapping, wbc, nfs_writepages_callback, &pgio);
+       pgio.pg_error = 0;
        nfs_pageio_complete(&pgio);
        nfs_io_completion_put(ioc);
 
        if (err < 0)
                goto out_err;
        err = pgio.pg_error;
-       if (err < 0)
+       if (nfs_error_is_fatal(err))
                goto out_err;
        return 0;
 out_err:
index c38f0d4..4d5a03a 100644 (file)
@@ -550,7 +550,6 @@ header-test-                        += linux/platform_data/sky81452-backlight.h
 header-test-                   += linux/platform_data/spi-davinci.h
 header-test-                   += linux/platform_data/spi-ep93xx.h
 header-test-                   += linux/platform_data/spi-mt65xx.h
-header-test-                   += linux/platform_data/spi-nuc900.h
 header-test-                   += linux/platform_data/st_sensors_pdata.h
 header-test-                   += linux/platform_data/ti-sysc.h
 header-test-                   += linux/platform_data/timer-ixp4xx.h
@@ -569,7 +568,6 @@ header-test-                        += linux/platform_data/usb3503.h
 header-test-                   += linux/platform_data/ux500_wdt.h
 header-test-                   += linux/platform_data/video-clcd-versatile.h
 header-test-                   += linux/platform_data/video-imxfb.h
-header-test-                   += linux/platform_data/video-nuc900fb.h
 header-test-                   += linux/platform_data/video-pxafb.h
 header-test-                   += linux/platform_data/video_s3c.h
 header-test-                   += linux/platform_data/voltage-omap.h
index 95a159a..80ca610 100644 (file)
@@ -16,6 +16,8 @@ struct error_injection_entry {
        int             etype;
 };
 
+struct pt_regs;
+
 #ifdef CONFIG_FUNCTION_ERROR_INJECTION
 /*
  * Whitelist ganerating macro. Specify functions which can be
@@ -28,8 +30,12 @@ static struct error_injection_entry __used                           \
                .addr = (unsigned long)fname,                           \
                .etype = EI_ETYPE_##_etype,                             \
        };
+
+void override_function_with_return(struct pt_regs *regs);
 #else
 #define ALLOW_ERROR_INJECTION(fname, _etype)
+
+static inline void override_function_with_return(struct pt_regs *regs) { }
 #endif
 #endif
 
diff --git a/include/dt-bindings/bus/moxtet.h b/include/dt-bindings/bus/moxtet.h
new file mode 100644 (file)
index 0000000..dc93454
--- /dev/null
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Constant for device tree bindings for Turris Mox module configuration bus
+ *
+ * Copyright (C) 2019 Marek Behun <marek.behun@nic.cz>
+ */
+
+#ifndef _DT_BINDINGS_BUS_MOXTET_H
+#define _DT_BINDINGS_BUS_MOXTET_H
+
+#define MOXTET_IRQ_PCI         0
+#define MOXTET_IRQ_USB3                4
+#define MOXTET_IRQ_PERIDOT(n)  (8 + (n))
+#define MOXTET_IRQ_TOPAZ       12
+
+#endif /* _DT_BINDINGS_BUS_MOXTET_H */
index b6b127e..0837c1a 100644 (file)
 #define CLKID_VDEC_HEVC                                207
 #define CLKID_VDEC_HEVCF                       210
 #define CLKID_TS                               212
+#define CLKID_CPUB_CLK                         224
+#define CLKID_GP1_PLL                          243
+#define CLKID_DSU_CLK                          252
+#define CLKID_CPU1_CLK                         253
+#define CLKID_CPU2_CLK                         254
+#define CLKID_CPU3_CLK                         255
 
 #endif /* __G12A_CLKC_H */
index 4236818..673a8c6 100644 (file)
 #define IMX_ADMA_LPCG_PWM_IPG_CLK                      38
 #define IMX_ADMA_LPCG_LCD_PIX_CLK                      39
 #define IMX_ADMA_LPCG_LCD_APB_CLK                      40
+#define IMX_ADMA_LPCG_DSP_ADB_CLK                      41
+#define IMX_ADMA_LPCG_DSP_IPG_CLK                      42
+#define IMX_ADMA_LPCG_DSP_CORE_CLK                     43
+#define IMX_ADMA_LPCG_OCRAM_IPG_CLK                    44
 
-#define IMX_ADMA_LPCG_CLK_END                          41
+#define IMX_ADMA_LPCG_CLK_END                          45
 
 #endif /* __DT_BINDINGS_CLOCK_IMX_H */
diff --git a/include/dt-bindings/clock/imx8mn-clock.h b/include/dt-bindings/clock/imx8mn-clock.h
new file mode 100644 (file)
index 0000000..5255b1c
--- /dev/null
@@ -0,0 +1,215 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2018-2019 NXP
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX8MN_H
+#define __DT_BINDINGS_CLOCK_IMX8MN_H
+
+#define IMX8MN_CLK_DUMMY                       0
+#define IMX8MN_CLK_32K                         1
+#define IMX8MN_CLK_24M                         2
+#define IMX8MN_OSC_HDMI_CLK                    3
+#define IMX8MN_CLK_EXT1                                4
+#define IMX8MN_CLK_EXT2                                5
+#define IMX8MN_CLK_EXT3                                6
+#define IMX8MN_CLK_EXT4                                7
+#define IMX8MN_AUDIO_PLL1_REF_SEL              8
+#define IMX8MN_AUDIO_PLL2_REF_SEL              9
+#define IMX8MN_VIDEO_PLL1_REF_SEL              10
+#define IMX8MN_DRAM_PLL_REF_SEL                        11
+#define IMX8MN_GPU_PLL_REF_SEL                 12
+#define IMX8MN_VPU_PLL_REF_SEL                 13
+#define IMX8MN_ARM_PLL_REF_SEL                 14
+#define IMX8MN_SYS_PLL1_REF_SEL                        15
+#define IMX8MN_SYS_PLL2_REF_SEL                        16
+#define IMX8MN_SYS_PLL3_REF_SEL                        17
+#define IMX8MN_AUDIO_PLL1                      18
+#define IMX8MN_AUDIO_PLL2                      19
+#define IMX8MN_VIDEO_PLL1                      20
+#define IMX8MN_DRAM_PLL                                21
+#define IMX8MN_GPU_PLL                         22
+#define IMX8MN_VPU_PLL                         23
+#define IMX8MN_ARM_PLL                         24
+#define IMX8MN_SYS_PLL1                                25
+#define IMX8MN_SYS_PLL2                                26
+#define IMX8MN_SYS_PLL3                                27
+#define IMX8MN_AUDIO_PLL1_BYPASS               28
+#define IMX8MN_AUDIO_PLL2_BYPASS               29
+#define IMX8MN_VIDEO_PLL1_BYPASS               30
+#define IMX8MN_DRAM_PLL_BYPASS                 31
+#define IMX8MN_GPU_PLL_BYPASS                  32
+#define IMX8MN_VPU_PLL_BYPASS                  33
+#define IMX8MN_ARM_PLL_BYPASS                  34
+#define IMX8MN_SYS_PLL1_BYPASS                 35
+#define IMX8MN_SYS_PLL2_BYPASS                 36
+#define IMX8MN_SYS_PLL3_BYPASS                 37
+#define IMX8MN_AUDIO_PLL1_OUT                  38
+#define IMX8MN_AUDIO_PLL2_OUT                  39
+#define IMX8MN_VIDEO_PLL1_OUT                  40
+#define IMX8MN_DRAM_PLL_OUT                    41
+#define IMX8MN_GPU_PLL_OUT                     42
+#define IMX8MN_VPU_PLL_OUT                     43
+#define IMX8MN_ARM_PLL_OUT                     44
+#define IMX8MN_SYS_PLL1_OUT                    45
+#define IMX8MN_SYS_PLL2_OUT                    46
+#define IMX8MN_SYS_PLL3_OUT                    47
+#define IMX8MN_SYS_PLL1_40M                    48
+#define IMX8MN_SYS_PLL1_80M                    49
+#define IMX8MN_SYS_PLL1_100M                   50
+#define IMX8MN_SYS_PLL1_133M                   51
+#define IMX8MN_SYS_PLL1_160M                   52
+#define IMX8MN_SYS_PLL1_200M                   53
+#define IMX8MN_SYS_PLL1_266M                   54
+#define IMX8MN_SYS_PLL1_400M                   55
+#define IMX8MN_SYS_PLL1_800M                   56
+#define IMX8MN_SYS_PLL2_50M                    57
+#define IMX8MN_SYS_PLL2_100M                   58
+#define IMX8MN_SYS_PLL2_125M                   59
+#define IMX8MN_SYS_PLL2_166M                   60
+#define IMX8MN_SYS_PLL2_200M                   61
+#define IMX8MN_SYS_PLL2_250M                   62
+#define IMX8MN_SYS_PLL2_333M                   63
+#define IMX8MN_SYS_PLL2_500M                   64
+#define IMX8MN_SYS_PLL2_1000M                  65
+
+/* CORE CLOCK ROOT */
+#define IMX8MN_CLK_A53_SRC                     66
+#define IMX8MN_CLK_GPU_CORE_SRC                        67
+#define IMX8MN_CLK_GPU_SHADER_SRC              68
+#define IMX8MN_CLK_A53_CG                      69
+#define IMX8MN_CLK_GPU_CORE_CG                 70
+#define IMX8MN_CLK_GPU_SHADER_CG               71
+#define IMX8MN_CLK_A53_DIV                     72
+#define IMX8MN_CLK_GPU_CORE_DIV                        73
+#define IMX8MN_CLK_GPU_SHADER_DIV              74
+
+/* BUS CLOCK ROOT */
+#define IMX8MN_CLK_MAIN_AXI                    75
+#define IMX8MN_CLK_ENET_AXI                    76
+#define IMX8MN_CLK_NAND_USDHC_BUS              77
+#define IMX8MN_CLK_DISP_AXI                    78
+#define IMX8MN_CLK_DISP_APB                    79
+#define IMX8MN_CLK_USB_BUS                     80
+#define IMX8MN_CLK_GPU_AXI                     81
+#define IMX8MN_CLK_GPU_AHB                     82
+#define IMX8MN_CLK_NOC                         83
+#define IMX8MN_CLK_AHB                         84
+#define IMX8MN_CLK_AUDIO_AHB                   85
+
+/* IPG CLOCK ROOT */
+#define IMX8MN_CLK_IPG_ROOT                    86
+#define IMX8MN_CLK_IPG_AUDIO_ROOT              87
+
+/* IP */
+#define IMX8MN_CLK_DRAM_CORE                   88
+#define IMX8MN_CLK_DRAM_ALT                    89
+#define IMX8MN_CLK_DRAM_APB                    90
+#define IMX8MN_CLK_DRAM_ALT_ROOT               91
+#define IMX8MN_CLK_DISP_PIXEL                  92
+#define IMX8MN_CLK_SAI2                                93
+#define IMX8MN_CLK_SAI3                                94
+#define IMX8MN_CLK_SAI5                                95
+#define IMX8MN_CLK_SAI6                                96
+#define IMX8MN_CLK_SPDIF1                      97
+#define IMX8MN_CLK_ENET_REF                    98
+#define IMX8MN_CLK_ENET_TIMER                  99
+#define IMX8MN_CLK_ENET_PHY_REF                        100
+#define IMX8MN_CLK_NAND                                101
+#define IMX8MN_CLK_QSPI                                102
+#define IMX8MN_CLK_USDHC1                      103
+#define IMX8MN_CLK_USDHC2                      104
+#define IMX8MN_CLK_I2C1                                105
+#define IMX8MN_CLK_I2C2                                106
+#define IMX8MN_CLK_I2C3                                107
+#define IMX8MN_CLK_I2C4                                118
+#define IMX8MN_CLK_UART1                       119
+#define IMX8MN_CLK_UART2                       110
+#define IMX8MN_CLK_UART3                       111
+#define IMX8MN_CLK_UART4                       112
+#define IMX8MN_CLK_USB_CORE_REF                        113
+#define IMX8MN_CLK_USB_PHY_REF                 114
+#define IMX8MN_CLK_ECSPI1                      115
+#define IMX8MN_CLK_ECSPI2                      116
+#define IMX8MN_CLK_PWM1                                117
+#define IMX8MN_CLK_PWM2                                118
+#define IMX8MN_CLK_PWM3                                119
+#define IMX8MN_CLK_PWM4                                120
+#define IMX8MN_CLK_WDOG                                121
+#define IMX8MN_CLK_WRCLK                       122
+#define IMX8MN_CLK_CLKO1                       123
+#define IMX8MN_CLK_CLKO2                       124
+#define IMX8MN_CLK_DSI_CORE                    125
+#define IMX8MN_CLK_DSI_PHY_REF                 126
+#define IMX8MN_CLK_DSI_DBI                     127
+#define IMX8MN_CLK_USDHC3                      128
+#define IMX8MN_CLK_CAMERA_PIXEL                        129
+#define IMX8MN_CLK_CSI1_PHY_REF                        130
+#define IMX8MN_CLK_CSI2_PHY_REF                        131
+#define IMX8MN_CLK_CSI2_ESC                    132
+#define IMX8MN_CLK_ECSPI3                      133
+#define IMX8MN_CLK_PDM                         134
+#define IMX8MN_CLK_SAI7                                135
+
+#define IMX8MN_CLK_ECSPI1_ROOT                 136
+#define IMX8MN_CLK_ECSPI2_ROOT                 137
+#define IMX8MN_CLK_ECSPI3_ROOT                 138
+#define IMX8MN_CLK_ENET1_ROOT                  139
+#define IMX8MN_CLK_GPIO1_ROOT                  140
+#define IMX8MN_CLK_GPIO2_ROOT                  141
+#define IMX8MN_CLK_GPIO3_ROOT                  142
+#define IMX8MN_CLK_GPIO4_ROOT                  143
+#define IMX8MN_CLK_GPIO5_ROOT                  144
+#define IMX8MN_CLK_I2C1_ROOT                   145
+#define IMX8MN_CLK_I2C2_ROOT                   146
+#define IMX8MN_CLK_I2C3_ROOT                   147
+#define IMX8MN_CLK_I2C4_ROOT                   148
+#define IMX8MN_CLK_MU_ROOT                     149
+#define IMX8MN_CLK_OCOTP_ROOT                  150
+#define IMX8MN_CLK_PWM1_ROOT                   151
+#define IMX8MN_CLK_PWM2_ROOT                   152
+#define IMX8MN_CLK_PWM3_ROOT                   153
+#define IMX8MN_CLK_PWM4_ROOT                   154
+#define IMX8MN_CLK_QSPI_ROOT                   155
+#define IMX8MN_CLK_NAND_ROOT                   156
+#define IMX8MN_CLK_SAI2_ROOT                   157
+#define IMX8MN_CLK_SAI2_IPG                    158
+#define IMX8MN_CLK_SAI3_ROOT                   159
+#define IMX8MN_CLK_SAI3_IPG                    160
+#define IMX8MN_CLK_SAI5_ROOT                   161
+#define IMX8MN_CLK_SAI5_IPG                    162
+#define IMX8MN_CLK_SAI6_ROOT                   163
+#define IMX8MN_CLK_SAI6_IPG                    164
+#define IMX8MN_CLK_SAI7_ROOT                   165
+#define IMX8MN_CLK_SAI7_IPG                    166
+#define IMX8MN_CLK_SDMA1_ROOT                  167
+#define IMX8MN_CLK_SDMA2_ROOT                  168
+#define IMX8MN_CLK_UART1_ROOT                  169
+#define IMX8MN_CLK_UART2_ROOT                  170
+#define IMX8MN_CLK_UART3_ROOT                  171
+#define IMX8MN_CLK_UART4_ROOT                  172
+#define IMX8MN_CLK_USB1_CTRL_ROOT              173
+#define IMX8MN_CLK_USDHC1_ROOT                 174
+#define IMX8MN_CLK_USDHC2_ROOT                 175
+#define IMX8MN_CLK_WDOG1_ROOT                  176
+#define IMX8MN_CLK_WDOG2_ROOT                  177
+#define IMX8MN_CLK_WDOG3_ROOT                  178
+#define IMX8MN_CLK_GPU_BUS_ROOT                        179
+#define IMX8MN_CLK_ASRC_ROOT                   180
+#define IMX8MN_CLK_GPU3D_ROOT                  181
+#define IMX8MN_CLK_PDM_ROOT                    182
+#define IMX8MN_CLK_PDM_IPG                     183
+#define IMX8MN_CLK_DISP_AXI_ROOT               184
+#define IMX8MN_CLK_DISP_APB_ROOT               185
+#define IMX8MN_CLK_DISP_PIXEL_ROOT             186
+#define IMX8MN_CLK_CAMERA_PIXEL_ROOT           187
+#define IMX8MN_CLK_USDHC3_ROOT                 188
+#define IMX8MN_CLK_SDMA3_ROOT                  189
+#define IMX8MN_CLK_TMU_ROOT                    190
+#define IMX8MN_CLK_ARM                         191
+#define IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK  192
+#define IMX8MN_CLK_GPU_CORE_ROOT               193
+
+#define IMX8MN_CLK_END                         194
+
+#endif
diff --git a/include/dt-bindings/memory/mt8183-larb-port.h b/include/dt-bindings/memory/mt8183-larb-port.h
new file mode 100644 (file)
index 0000000..2c579f3
--- /dev/null
@@ -0,0 +1,130 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Yong Wu <yong.wu@mediatek.com>
+ */
+#ifndef __DTS_IOMMU_PORT_MT8183_H
+#define __DTS_IOMMU_PORT_MT8183_H
+
+#define MTK_M4U_ID(larb, port)         (((larb) << 5) | (port))
+
+#define M4U_LARB0_ID                   0
+#define M4U_LARB1_ID                   1
+#define M4U_LARB2_ID                   2
+#define M4U_LARB3_ID                   3
+#define M4U_LARB4_ID                   4
+#define M4U_LARB5_ID                   5
+#define M4U_LARB6_ID                   6
+#define M4U_LARB7_ID                   7
+
+/* larb0 */
+#define        M4U_PORT_DISP_OVL0              MTK_M4U_ID(M4U_LARB0_ID, 0)
+#define        M4U_PORT_DISP_2L_OVL0_LARB0     MTK_M4U_ID(M4U_LARB0_ID, 1)
+#define        M4U_PORT_DISP_2L_OVL1_LARB0     MTK_M4U_ID(M4U_LARB0_ID, 2)
+#define        M4U_PORT_DISP_RDMA0             MTK_M4U_ID(M4U_LARB0_ID, 3)
+#define        M4U_PORT_DISP_RDMA1             MTK_M4U_ID(M4U_LARB0_ID, 4)
+#define        M4U_PORT_DISP_WDMA0             MTK_M4U_ID(M4U_LARB0_ID, 5)
+#define        M4U_PORT_MDP_RDMA0              MTK_M4U_ID(M4U_LARB0_ID, 6)
+#define        M4U_PORT_MDP_WROT0              MTK_M4U_ID(M4U_LARB0_ID, 7)
+#define        M4U_PORT_MDP_WDMA0              MTK_M4U_ID(M4U_LARB0_ID, 8)
+#define        M4U_PORT_DISP_FAKE0             MTK_M4U_ID(M4U_LARB0_ID, 9)
+
+/* larb1 */
+#define        M4U_PORT_HW_VDEC_MC_EXT         MTK_M4U_ID(M4U_LARB1_ID, 0)
+#define        M4U_PORT_HW_VDEC_PP_EXT         MTK_M4U_ID(M4U_LARB1_ID, 1)
+#define        M4U_PORT_HW_VDEC_VLD_EXT        MTK_M4U_ID(M4U_LARB1_ID, 2)
+#define        M4U_PORT_HW_VDEC_AVC_MV_EXT     MTK_M4U_ID(M4U_LARB1_ID, 3)
+#define        M4U_PORT_HW_VDEC_PRED_RD_EXT    MTK_M4U_ID(M4U_LARB1_ID, 4)
+#define        M4U_PORT_HW_VDEC_PRED_WR_EXT    MTK_M4U_ID(M4U_LARB1_ID, 5)
+#define        M4U_PORT_HW_VDEC_PPWRAP_EXT     MTK_M4U_ID(M4U_LARB1_ID, 6)
+
+/* larb2 VPU0 */
+#define        M4U_PORT_IMG_IPUO               MTK_M4U_ID(M4U_LARB2_ID, 0)
+#define        M4U_PORT_IMG_IPU3O              MTK_M4U_ID(M4U_LARB2_ID, 1)
+#define        M4U_PORT_IMG_IPUI               MTK_M4U_ID(M4U_LARB2_ID, 2)
+
+/* larb3 VPU1 */
+#define        M4U_PORT_CAM_IPUO               MTK_M4U_ID(M4U_LARB3_ID, 0)
+#define        M4U_PORT_CAM_IPU2O              MTK_M4U_ID(M4U_LARB3_ID, 1)
+#define        M4U_PORT_CAM_IPU3O              MTK_M4U_ID(M4U_LARB3_ID, 2)
+#define        M4U_PORT_CAM_IPUI               MTK_M4U_ID(M4U_LARB3_ID, 3)
+#define        M4U_PORT_CAM_IPU2I              MTK_M4U_ID(M4U_LARB3_ID, 4)
+
+/* larb4 */
+#define        M4U_PORT_VENC_RCPU              MTK_M4U_ID(M4U_LARB4_ID, 0)
+#define        M4U_PORT_VENC_REC               MTK_M4U_ID(M4U_LARB4_ID, 1)
+#define        M4U_PORT_VENC_BSDMA             MTK_M4U_ID(M4U_LARB4_ID, 2)
+#define        M4U_PORT_VENC_SV_COMV           MTK_M4U_ID(M4U_LARB4_ID, 3)
+#define        M4U_PORT_VENC_RD_COMV           MTK_M4U_ID(M4U_LARB4_ID, 4)
+#define        M4U_PORT_JPGENC_RDMA            MTK_M4U_ID(M4U_LARB4_ID, 5)
+#define        M4U_PORT_JPGENC_BSDMA           MTK_M4U_ID(M4U_LARB4_ID, 6)
+#define        M4U_PORT_VENC_CUR_LUMA          MTK_M4U_ID(M4U_LARB4_ID, 7)
+#define        M4U_PORT_VENC_CUR_CHROMA        MTK_M4U_ID(M4U_LARB4_ID, 8)
+#define        M4U_PORT_VENC_REF_LUMA          MTK_M4U_ID(M4U_LARB4_ID, 9)
+#define        M4U_PORT_VENC_REF_CHROMA        MTK_M4U_ID(M4U_LARB4_ID, 10)
+
+/* larb5 */
+#define        M4U_PORT_CAM_IMGI               MTK_M4U_ID(M4U_LARB5_ID, 0)
+#define        M4U_PORT_CAM_IMG2O              MTK_M4U_ID(M4U_LARB5_ID, 1)
+#define        M4U_PORT_CAM_IMG3O              MTK_M4U_ID(M4U_LARB5_ID, 2)
+#define        M4U_PORT_CAM_VIPI               MTK_M4U_ID(M4U_LARB5_ID, 3)
+#define        M4U_PORT_CAM_LCEI               MTK_M4U_ID(M4U_LARB5_ID, 4)
+#define        M4U_PORT_CAM_SMXI               MTK_M4U_ID(M4U_LARB5_ID, 5)
+#define        M4U_PORT_CAM_SMXO               MTK_M4U_ID(M4U_LARB5_ID, 6)
+#define        M4U_PORT_CAM_WPE0_RDMA1         MTK_M4U_ID(M4U_LARB5_ID, 7)
+#define        M4U_PORT_CAM_WPE0_RDMA0         MTK_M4U_ID(M4U_LARB5_ID, 8)
+#define        M4U_PORT_CAM_WPE0_WDMA          MTK_M4U_ID(M4U_LARB5_ID, 9)
+#define        M4U_PORT_CAM_FDVT_RP            MTK_M4U_ID(M4U_LARB5_ID, 10)
+#define        M4U_PORT_CAM_FDVT_WR            MTK_M4U_ID(M4U_LARB5_ID, 11)
+#define        M4U_PORT_CAM_FDVT_RB            MTK_M4U_ID(M4U_LARB5_ID, 12)
+#define        M4U_PORT_CAM_WPE1_RDMA0         MTK_M4U_ID(M4U_LARB5_ID, 13)
+#define        M4U_PORT_CAM_WPE1_RDMA1         MTK_M4U_ID(M4U_LARB5_ID, 14)
+#define        M4U_PORT_CAM_WPE1_WDMA          MTK_M4U_ID(M4U_LARB5_ID, 15)
+#define        M4U_PORT_CAM_DPE_RDMA           MTK_M4U_ID(M4U_LARB5_ID, 16)
+#define        M4U_PORT_CAM_DPE_WDMA           MTK_M4U_ID(M4U_LARB5_ID, 17)
+#define        M4U_PORT_CAM_MFB_RDMA0          MTK_M4U_ID(M4U_LARB5_ID, 18)
+#define        M4U_PORT_CAM_MFB_RDMA1          MTK_M4U_ID(M4U_LARB5_ID, 19)
+#define        M4U_PORT_CAM_MFB_WDMA           MTK_M4U_ID(M4U_LARB5_ID, 20)
+#define        M4U_PORT_CAM_RSC_RDMA0          MTK_M4U_ID(M4U_LARB5_ID, 21)
+#define        M4U_PORT_CAM_RSC_WDMA           MTK_M4U_ID(M4U_LARB5_ID, 22)
+#define        M4U_PORT_CAM_OWE_RDMA           MTK_M4U_ID(M4U_LARB5_ID, 23)
+#define        M4U_PORT_CAM_OWE_WDMA           MTK_M4U_ID(M4U_LARB5_ID, 24)
+
+/* larb6 */
+#define        M4U_PORT_CAM_IMGO               MTK_M4U_ID(M4U_LARB6_ID, 0)
+#define        M4U_PORT_CAM_RRZO               MTK_M4U_ID(M4U_LARB6_ID, 1)
+#define        M4U_PORT_CAM_AAO                MTK_M4U_ID(M4U_LARB6_ID, 2)
+#define        M4U_PORT_CAM_AFO                MTK_M4U_ID(M4U_LARB6_ID, 3)
+#define        M4U_PORT_CAM_LSCI0              MTK_M4U_ID(M4U_LARB6_ID, 4)
+#define        M4U_PORT_CAM_LSCI1              MTK_M4U_ID(M4U_LARB6_ID, 5)
+#define        M4U_PORT_CAM_PDO                MTK_M4U_ID(M4U_LARB6_ID, 6)
+#define        M4U_PORT_CAM_BPCI               MTK_M4U_ID(M4U_LARB6_ID, 7)
+#define        M4U_PORT_CAM_LCSO               MTK_M4U_ID(M4U_LARB6_ID, 8)
+#define        M4U_PORT_CAM_CAM_RSSO_A         MTK_M4U_ID(M4U_LARB6_ID, 9)
+#define        M4U_PORT_CAM_UFEO               MTK_M4U_ID(M4U_LARB6_ID, 10)
+#define        M4U_PORT_CAM_SOCO               MTK_M4U_ID(M4U_LARB6_ID, 11)
+#define        M4U_PORT_CAM_SOC1               MTK_M4U_ID(M4U_LARB6_ID, 12)
+#define        M4U_PORT_CAM_SOC2               MTK_M4U_ID(M4U_LARB6_ID, 13)
+#define        M4U_PORT_CAM_CCUI               MTK_M4U_ID(M4U_LARB6_ID, 14)
+#define        M4U_PORT_CAM_CCUO               MTK_M4U_ID(M4U_LARB6_ID, 15)
+#define        M4U_PORT_CAM_RAWI_A             MTK_M4U_ID(M4U_LARB6_ID, 16)
+#define        M4U_PORT_CAM_CCUG               MTK_M4U_ID(M4U_LARB6_ID, 17)
+#define        M4U_PORT_CAM_PSO                MTK_M4U_ID(M4U_LARB6_ID, 18)
+#define        M4U_PORT_CAM_AFO_1              MTK_M4U_ID(M4U_LARB6_ID, 19)
+#define        M4U_PORT_CAM_LSCI_2             MTK_M4U_ID(M4U_LARB6_ID, 20)
+#define        M4U_PORT_CAM_PDI                MTK_M4U_ID(M4U_LARB6_ID, 21)
+#define        M4U_PORT_CAM_FLKO               MTK_M4U_ID(M4U_LARB6_ID, 22)
+#define        M4U_PORT_CAM_LMVO               MTK_M4U_ID(M4U_LARB6_ID, 23)
+#define        M4U_PORT_CAM_UFGO               MTK_M4U_ID(M4U_LARB6_ID, 24)
+#define        M4U_PORT_CAM_SPARE              MTK_M4U_ID(M4U_LARB6_ID, 25)
+#define        M4U_PORT_CAM_SPARE_2            MTK_M4U_ID(M4U_LARB6_ID, 26)
+#define        M4U_PORT_CAM_SPARE_3            MTK_M4U_ID(M4U_LARB6_ID, 27)
+#define        M4U_PORT_CAM_SPARE_4            MTK_M4U_ID(M4U_LARB6_ID, 28)
+#define        M4U_PORT_CAM_SPARE_5            MTK_M4U_ID(M4U_LARB6_ID, 29)
+#define        M4U_PORT_CAM_SPARE_6            MTK_M4U_ID(M4U_LARB6_ID, 30)
+
+/* CCU */
+#define        M4U_PORT_CCU0                   MTK_M4U_ID(M4U_LARB7_ID, 0)
+#define        M4U_PORT_CCU1                   MTK_M4U_ID(M4U_LARB7_ID, 1)
+
+#endif
diff --git a/include/dt-bindings/power/meson-g12a-power.h b/include/dt-bindings/power/meson-g12a-power.h
new file mode 100644 (file)
index 0000000..bb5e67a
--- /dev/null
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#ifndef _DT_BINDINGS_MESON_G12A_POWER_H
+#define _DT_BINDINGS_MESON_G12A_POWER_H
+
+#define PWRC_G12A_VPU_ID               0
+#define PWRC_G12A_ETH_ID               1
+
+#endif
diff --git a/include/dt-bindings/power/meson-sm1-power.h b/include/dt-bindings/power/meson-sm1-power.h
new file mode 100644 (file)
index 0000000..a020ab0
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#ifndef _DT_BINDINGS_MESON_SM1_POWER_H
+#define _DT_BINDINGS_MESON_SM1_POWER_H
+
+#define PWRC_SM1_VPU_ID                0
+#define PWRC_SM1_NNA_ID                1
+#define PWRC_SM1_USB_ID                2
+#define PWRC_SM1_PCIE_ID       3
+#define PWRC_SM1_GE2D_ID       4
+#define PWRC_SM1_AUDIO_ID      5
+#define PWRC_SM1_ETH_ID                6
+
+#endif
diff --git a/include/dt-bindings/regulator/active-semi,8865-regulator.h b/include/dt-bindings/regulator/active-semi,8865-regulator.h
new file mode 100644 (file)
index 0000000..15473db
--- /dev/null
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Device Tree binding constants for the ACT8865 PMIC regulators
+ */
+
+#ifndef _DT_BINDINGS_REGULATOR_ACT8865_H
+#define _DT_BINDINGS_REGULATOR_ACT8865_H
+
+/*
+ * These constants should be used to specify regulator modes in device tree for
+ * ACT8865 regulators as follows:
+ * ACT8865_REGULATOR_MODE_FIXED:       It is specific to DCDC regulators and it
+ *                                     specifies the usage of fixed-frequency
+ *                                     PWM.
+ *
+ * ACT8865_REGULATOR_MODE_NORMAL:      It is specific to LDO regulators and it
+ *                                     specifies the usage of normal mode.
+ *
+ * ACT8865_REGULATOR_MODE_LOWPOWER:    For DCDC and LDO regulators; it specify
+ *                                     the usage of proprietary power-saving
+ *                                     mode.
+ */
+
+#define ACT8865_REGULATOR_MODE_FIXED           1
+#define ACT8865_REGULATOR_MODE_NORMAL          2
+#define ACT8865_REGULATOR_MODE_LOWPOWER        3
+
+#endif
diff --git a/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h b/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h
new file mode 100644 (file)
index 0000000..14b78da
--- /dev/null
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ *
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_MESON_G12A_AUDIO_RESET_H
+#define _DT_BINDINGS_AMLOGIC_MESON_G12A_AUDIO_RESET_H
+
+#define AUD_RESET_PDM          0
+#define AUD_RESET_TDMIN_A      1
+#define AUD_RESET_TDMIN_B      2
+#define AUD_RESET_TDMIN_C      3
+#define AUD_RESET_TDMIN_LB     4
+#define AUD_RESET_LOOPBACK     5
+#define AUD_RESET_TODDR_A      6
+#define AUD_RESET_TODDR_B      7
+#define AUD_RESET_TODDR_C      8
+#define AUD_RESET_FRDDR_A      9
+#define AUD_RESET_FRDDR_B      10
+#define AUD_RESET_FRDDR_C      11
+#define AUD_RESET_TDMOUT_A     12
+#define AUD_RESET_TDMOUT_B     13
+#define AUD_RESET_TDMOUT_C     14
+#define AUD_RESET_SPDIFOUT     15
+#define AUD_RESET_SPDIFOUT_B   16
+#define AUD_RESET_SPDIFIN      17
+#define AUD_RESET_EQDRC                18
+#define AUD_RESET_RESAMPLE     19
+#define AUD_RESET_DDRARB       20
+#define AUD_RESET_POWDET       21
+#define AUD_RESET_TORAM                22
+#define AUD_RESET_TOACODEC     23
+#define AUD_RESET_TOHDMITX     24
+#define AUD_RESET_CLKTREE      25
+
+#endif
index 524d607..ea50586 100644 (file)
@@ -1,56 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
  * Copyright (c) 2016 BayLibre, SAS.
  * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- * The full GNU General Public License is included in this distribution
- * in the file called COPYING.
- *
- * BSD LICENSE
- *
- * Copyright (c) 2016 BayLibre, SAS.
- * Author: Neil Armstrong <narmstrong@baylibre.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 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.
  */
 #ifndef _DT_BINDINGS_AMLOGIC_MESON_GXBB_RESET_H
 #define _DT_BINDINGS_AMLOGIC_MESON_GXBB_RESET_H
index 614aff2..c614438 100644 (file)
@@ -1,56 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
 /*
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- * redistributing this file, you may do so under either license.
- *
- * GPL LICENSE SUMMARY
- *
  * Copyright (c) 2016 BayLibre, SAS.
  * Author: Neil Armstrong <narmstrong@baylibre.com>
- *
- * 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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- * The full GNU General Public License is included in this distribution
- * in the file called COPYING.
- *
- * BSD LICENSE
- *
- * Copyright (c) 2016 BayLibre, SAS.
- * Author: Neil Armstrong <narmstrong@baylibre.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 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.
  */
 #ifndef _DT_BINDINGS_AMLOGIC_MESON8B_RESET_H
 #define _DT_BINDINGS_AMLOGIC_MESON8B_RESET_H
index 57c5924..9a30108 100644 (file)
 #define IMX8MQ_RESET_OTG2_PHY_RESET            20
 #define IMX8MQ_RESET_MIPI_DSI_RESET_BYTE_N     21
 #define IMX8MQ_RESET_MIPI_DSI_RESET_N          22
-#define IMX8MQ_RESET_MIPI_DIS_DPI_RESET_N      23
-#define IMX8MQ_RESET_MIPI_DIS_ESC_RESET_N      24
-#define IMX8MQ_RESET_MIPI_DIS_PCLK_RESET_N     25
+#define IMX8MQ_RESET_MIPI_DSI_DPI_RESET_N      23
+#define IMX8MQ_RESET_MIPI_DSI_ESC_RESET_N      24
+#define IMX8MQ_RESET_MIPI_DSI_PCLK_RESET_N     25
 #define IMX8MQ_RESET_PCIEPHY                   26
 #define IMX8MQ_RESET_PCIEPHY_PERST             27
 #define IMX8MQ_RESET_PCIE_CTRL_APPS_EN         28
 #define IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF    29
-#define IMX8MQ_RESET_HDMI_PHY_APB_RESET                30
+#define IMX8MQ_RESET_HDMI_PHY_APB_RESET                30      /* i.MX8MM does NOT support */
 #define IMX8MQ_RESET_DISP_RESET                        31
 #define IMX8MQ_RESET_GPU_RESET                 32
 #define IMX8MQ_RESET_VPU_RESET                 33
-#define IMX8MQ_RESET_PCIEPHY2                  34
-#define IMX8MQ_RESET_PCIEPHY2_PERST            35
-#define IMX8MQ_RESET_PCIE2_CTRL_APPS_EN                36
-#define IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF   37
-#define IMX8MQ_RESET_MIPI_CSI1_CORE_RESET      38
-#define IMX8MQ_RESET_MIPI_CSI1_PHY_REF_RESET   39
-#define IMX8MQ_RESET_MIPI_CSI1_ESC_RESET       40
-#define IMX8MQ_RESET_MIPI_CSI2_CORE_RESET      41
-#define IMX8MQ_RESET_MIPI_CSI2_PHY_REF_RESET   42
-#define IMX8MQ_RESET_MIPI_CSI2_ESC_RESET       43
+#define IMX8MQ_RESET_PCIEPHY2                  34      /* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_PCIEPHY2_PERST            35      /* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_PCIE2_CTRL_APPS_EN                36      /* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF   37      /* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_MIPI_CSI1_CORE_RESET      38      /* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_MIPI_CSI1_PHY_REF_RESET   39      /* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_MIPI_CSI1_ESC_RESET       40      /* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_MIPI_CSI2_CORE_RESET      41      /* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_MIPI_CSI2_PHY_REF_RESET   42      /* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_MIPI_CSI2_ESC_RESET       43      /* i.MX8MM does NOT support */
 #define IMX8MQ_RESET_DDRC1_PRST                        44
 #define IMX8MQ_RESET_DDRC1_CORE_RESET          45
 #define IMX8MQ_RESET_DDRC1_PHY_RESET           46
-#define IMX8MQ_RESET_DDRC2_PRST                        47
-#define IMX8MQ_RESET_DDRC2_CORE_RESET          48
-#define IMX8MQ_RESET_DDRC2_PHY_RESET           49
+#define IMX8MQ_RESET_DDRC2_PRST                        47      /* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_DDRC2_CORE_RESET          48      /* i.MX8MM does NOT support */
+#define IMX8MQ_RESET_DDRC2_PHY_RESET           49      /* i.MX8MM does NOT support */
 
 #define IMX8MQ_RESET_NUM                       50
 
diff --git a/include/dt-bindings/reset/mt7629-resets.h b/include/dt-bindings/reset/mt7629-resets.h
new file mode 100644 (file)
index 0000000..6bb8573
--- /dev/null
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2019 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT7629
+#define _DT_BINDINGS_RESET_CONTROLLER_MT7629
+
+/* INFRACFG resets */
+#define MT7629_INFRA_EMI_MPU_RST               0
+#define MT7629_INFRA_UART5_RST                 2
+#define MT7629_INFRA_CIRQ_EINT_RST             3
+#define MT7629_INFRA_APXGPT_RST                        4
+#define MT7629_INFRA_SCPSYS_RST                        5
+#define MT7629_INFRA_KP_RST                    6
+#define MT7629_INFRA_SPI1_RST                  7
+#define MT7629_INFRA_SPI4_RST                  8
+#define MT7629_INFRA_SYSTIMER_RST              9
+#define MT7629_INFRA_IRRX_RST                  10
+#define MT7629_INFRA_AO_BUS_RST                        16
+#define MT7629_INFRA_EMI_RST                   32
+#define MT7629_INFRA_APMIXED_RST               35
+#define MT7629_INFRA_MIPI_RST                  36
+#define MT7629_INFRA_TRNG_RST                  37
+#define MT7629_INFRA_SYSCIRQ_RST               38
+#define MT7629_INFRA_MIPI_CSI_RST              39
+#define MT7629_INFRA_GCE_FAXI_RST              40
+#define MT7629_INFRA_I2C_SRAM_RST              41
+#define MT7629_INFRA_IOMMU_RST                 47
+
+/* PERICFG resets */
+#define MT7629_PERI_UART0_SW_RST               0
+#define MT7629_PERI_UART1_SW_RST               1
+#define MT7629_PERI_UART2_SW_RST               2
+#define MT7629_PERI_BTIF_SW_RST                        6
+#define MT7629_PERI_PWN_SW_RST                 8
+#define MT7629_PERI_DMA_SW_RST                 11
+#define MT7629_PERI_NFI_SW_RST                 14
+#define MT7629_PERI_I2C0_SW_RST                        22
+#define MT7629_PERI_SPI0_SW_RST                        33
+#define MT7629_PERI_SPI1_SW_RST                        34
+#define MT7629_PERI_FLASHIF_SW_RST             36
+
+/* PCIe Subsystem resets */
+#define MT7629_PCIE1_CORE_RST                  19
+#define MT7629_PCIE1_MMIO_RST                  20
+#define MT7629_PCIE1_HRST                      21
+#define MT7629_PCIE1_USER_RST                  22
+#define MT7629_PCIE1_PIPE_RST                  23
+#define MT7629_PCIE0_CORE_RST                  27
+#define MT7629_PCIE0_MMIO_RST                  28
+#define MT7629_PCIE0_HRST                      29
+#define MT7629_PCIE0_USER_RST                  30
+#define MT7629_PCIE0_PIPE_RST                  31
+
+/* SSUSB Subsystem resets */
+#define MT7629_SSUSB_PHY_PWR_RST               3
+#define MT7629_SSUSB_MAC_PWR_RST               4
+
+/* ETH Subsystem resets */
+#define MT7629_ETHSYS_SYS_RST                  0
+#define MT7629_ETHSYS_MCM_RST                  2
+#define MT7629_ETHSYS_HSDMA_RST                        5
+#define MT7629_ETHSYS_FE_RST                   6
+#define MT7629_ETHSYS_ESW_RST                  16
+#define MT7629_ETHSYS_GMAC_RST                 23
+#define MT7629_ETHSYS_EPHY_RST                 24
+#define MT7629_ETHSYS_CRYPTO_RST               29
+#define MT7629_ETHSYS_PPE_RST                  31
+
+#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT7629 */
diff --git a/include/dt-bindings/soc/ti,sci_pm_domain.h b/include/dt-bindings/soc/ti,sci_pm_domain.h
new file mode 100644 (file)
index 0000000..8f2a736
--- /dev/null
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __DT_BINDINGS_TI_SCI_PM_DOMAIN_H
+#define __DT_BINDINGS_TI_SCI_PM_DOMAIN_H
+
+#define TI_SCI_PD_EXCLUSIVE    1
+#define TI_SCI_PD_SHARED       0
+
+#endif /* __DT_BINDINGS_TI_SCI_PM_DOMAIN_H */
index 9426b9a..0fecacc 100644 (file)
@@ -994,62 +994,11 @@ void __acpi_handle_debug(struct _ddebug *descriptor, acpi_handle handle, const c
 #endif
 #endif
 
-struct acpi_gpio_params {
-       unsigned int crs_entry_index;
-       unsigned int line_index;
-       bool active_low;
-};
-
-struct acpi_gpio_mapping {
-       const char *name;
-       const struct acpi_gpio_params *data;
-       unsigned int size;
-
-/* Ignore IoRestriction field */
-#define ACPI_GPIO_QUIRK_NO_IO_RESTRICTION      BIT(0)
-/*
- * When ACPI GPIO mapping table is in use the index parameter inside it
- * refers to the GPIO resource in _CRS method. That index has no
- * distinction of actual type of the resource. When consumer wants to
- * get GpioIo type explicitly, this quirk may be used.
- */
-#define ACPI_GPIO_QUIRK_ONLY_GPIOIO            BIT(1)
-
-       unsigned int quirks;
-};
-
 #if defined(CONFIG_ACPI) && defined(CONFIG_GPIOLIB)
-int acpi_dev_add_driver_gpios(struct acpi_device *adev,
-                             const struct acpi_gpio_mapping *gpios);
-
-static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev)
-{
-       if (adev)
-               adev->driver_gpios = NULL;
-}
-
-int devm_acpi_dev_add_driver_gpios(struct device *dev,
-                                  const struct acpi_gpio_mapping *gpios);
-void devm_acpi_dev_remove_driver_gpios(struct device *dev);
-
 bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
                                struct acpi_resource_gpio **agpio);
 int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index);
 #else
-static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev,
-                             const struct acpi_gpio_mapping *gpios)
-{
-       return -ENXIO;
-}
-static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev) {}
-
-static inline int devm_acpi_dev_add_driver_gpios(struct device *dev,
-                             const struct acpi_gpio_mapping *gpios)
-{
-       return -ENXIO;
-}
-static inline void devm_acpi_dev_remove_driver_gpios(struct device *dev) {}
-
 static inline bool acpi_gpio_get_irq_resource(struct acpi_resource *ares,
                                              struct acpi_resource_gpio **agpio)
 {
@@ -1302,11 +1251,16 @@ static inline int lpit_read_residency_count_address(u64 *address)
 #endif
 
 #ifdef CONFIG_ACPI_PPTT
+int acpi_pptt_cpu_is_thread(unsigned int cpu);
 int find_acpi_cpu_topology(unsigned int cpu, int level);
 int find_acpi_cpu_topology_package(unsigned int cpu);
 int find_acpi_cpu_topology_hetero_id(unsigned int cpu);
 int find_acpi_cpu_cache_topology(unsigned int cpu, int level);
 #else
+static inline int acpi_pptt_cpu_is_thread(unsigned int cpu)
+{
+       return -EINVAL;
+}
 static inline int find_acpi_cpu_topology(unsigned int cpu, int level)
 {
        return -EINVAL;
index 4a4d006..21e950e 100644 (file)
@@ -184,6 +184,9 @@ extern int amd_iommu_register_ga_log_notifier(int (*notifier)(u32));
 extern int
 amd_iommu_update_ga(int cpu, bool is_run, void *data);
 
+extern int amd_iommu_activate_guest_mode(void *data);
+extern int amd_iommu_deactivate_guest_mode(void *data);
+
 #else /* defined(CONFIG_AMD_IOMMU) && defined(CONFIG_IRQ_REMAP) */
 
 static inline int
@@ -198,6 +201,15 @@ amd_iommu_update_ga(int cpu, bool is_run, void *data)
        return 0;
 }
 
+static inline int amd_iommu_activate_guest_mode(void *data)
+{
+       return 0;
+}
+
+static inline int amd_iommu_deactivate_guest_mode(void *data)
+{
+       return 0;
+}
 #endif /* defined(CONFIG_AMD_IOMMU) && defined(CONFIG_IRQ_REMAP) */
 
 #endif /* _ASM_X86_AMD_IOMMU_H */
index 1cfe05e..42f2b51 100644 (file)
@@ -33,4 +33,30 @@ unsigned long topology_get_freq_scale(int cpu)
        return per_cpu(freq_scale, cpu);
 }
 
+struct cpu_topology {
+       int thread_id;
+       int core_id;
+       int package_id;
+       int llc_id;
+       cpumask_t thread_sibling;
+       cpumask_t core_sibling;
+       cpumask_t llc_sibling;
+};
+
+#ifdef CONFIG_GENERIC_ARCH_TOPOLOGY
+extern struct cpu_topology cpu_topology[NR_CPUS];
+
+#define topology_physical_package_id(cpu)      (cpu_topology[cpu].package_id)
+#define topology_core_id(cpu)          (cpu_topology[cpu].core_id)
+#define topology_core_cpumask(cpu)     (&cpu_topology[cpu].core_sibling)
+#define topology_sibling_cpumask(cpu)  (&cpu_topology[cpu].thread_sibling)
+#define topology_llc_cpumask(cpu)      (&cpu_topology[cpu].llc_sibling)
+void init_cpu_topology(void);
+void store_cpu_topology(unsigned int cpuid);
+const struct cpumask *cpu_coregroup_mask(int cpu);
+void update_siblings_masks(unsigned int cpu);
+void remove_cpu_topology(unsigned int cpuid);
+void reset_cpu_topology(void);
+#endif
+
 #endif /* _LINUX_ARCH_TOPOLOGY_H_ */
index feff3fe..1b1fa15 100644 (file)
@@ -311,6 +311,7 @@ enum req_flag_bits {
        __REQ_RAHEAD,           /* read ahead, can fail anytime */
        __REQ_BACKGROUND,       /* background IO */
        __REQ_NOWAIT,           /* Don't wait if request will block */
+       __REQ_NOWAIT_INLINE,    /* Return would-block error inline */
        /*
         * When a shared kthread needs to issue a bio for a cgroup, doing
         * so synchronously can lead to priority inversions as the kthread
@@ -345,6 +346,7 @@ enum req_flag_bits {
 #define REQ_RAHEAD             (1ULL << __REQ_RAHEAD)
 #define REQ_BACKGROUND         (1ULL << __REQ_BACKGROUND)
 #define REQ_NOWAIT             (1ULL << __REQ_NOWAIT)
+#define REQ_NOWAIT_INLINE      (1ULL << __REQ_NOWAIT_INLINE)
 #define REQ_CGROUP_PUNT                (1ULL << __REQ_CGROUP_PUNT)
 
 #define REQ_NOUNMAP            (1ULL << __REQ_NOUNMAP)
@@ -418,12 +420,13 @@ static inline int op_stat_group(unsigned int op)
 
 typedef unsigned int blk_qc_t;
 #define BLK_QC_T_NONE          -1U
+#define BLK_QC_T_EAGAIN                -2U
 #define BLK_QC_T_SHIFT         16
 #define BLK_QC_T_INTERNAL      (1U << 31)
 
 static inline bool blk_qc_t_valid(blk_qc_t cookie)
 {
-       return cookie != BLK_QC_T_NONE;
+       return cookie != BLK_QC_T_NONE && cookie != BLK_QC_T_EAGAIN;
 }
 
 static inline unsigned int blk_qc_t_to_queue_num(blk_qc_t cookie)
index 2ae7604..dce5521 100644 (file)
@@ -817,6 +817,7 @@ unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
 struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
 struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
                                          unsigned int index);
+int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *new_parent);
 unsigned int __clk_get_enable_count(struct clk *clk);
 unsigned long clk_hw_get_rate(const struct clk_hw *hw);
 unsigned long __clk_get_flags(struct clk *clk);
index f0fd563..5e88e7e 100644 (file)
@@ -24,7 +24,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
                        long ______r;                                   \
                        static struct ftrace_likely_data                \
                                __aligned(4)                            \
-                               __section("_ftrace_annotated_branch")   \
+                               __section(_ftrace_annotated_branch)     \
                                ______f = {                             \
                                .data.func = __func__,                  \
                                .data.file = __FILE__,                  \
@@ -60,7 +60,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
 #define __trace_if_value(cond) ({                      \
        static struct ftrace_branch_data                \
                __aligned(4)                            \
-               __section("_ftrace_branch")             \
+               __section(_ftrace_branch)               \
                __if_trace = {                          \
                        .func = __func__,               \
                        .file = __FILE__,               \
@@ -118,7 +118,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
        ".popsection\n\t"
 
 /* Annotate a C jump table to allow objtool to follow the code flow */
-#define __annotate_jump_table __section(".rodata..c_jump_table")
+#define __annotate_jump_table __section(.rodata..c_jump_table)
 
 #else
 #define annotate_reachable()
@@ -298,7 +298,7 @@ unsigned long read_word_at_a_time(const void *addr)
  * visible to the compiler.
  */
 #define __ADDRESSABLE(sym) \
-       static void * __section(".discard.addressable") __used \
+       static void * __section(.discard.addressable) __used \
                __PASTE(__addressable_##sym, __LINE__) = (void *)&sym;
 
 /**
index bb9a0db..12ae4b8 100644 (file)
@@ -256,7 +256,10 @@ static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
 {return 0;}
 #endif
 
-#define __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, is_retention) \
+#define __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter,                  \
+                               idx,                                    \
+                               state,                                  \
+                               is_retention)                           \
 ({                                                                     \
        int __ret = 0;                                                  \
                                                                        \
@@ -268,7 +271,7 @@ static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
        if (!is_retention)                                              \
                __ret =  cpu_pm_enter();                                \
        if (!__ret) {                                                   \
-               __ret = low_level_idle_enter(idx);                      \
+               __ret = low_level_idle_enter(state);                    \
                if (!is_retention)                                      \
                        cpu_pm_exit();                                  \
        }                                                               \
@@ -277,9 +280,15 @@ static inline int cpuidle_register_governor(struct cpuidle_governor *gov)
 })
 
 #define CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx)       \
-       __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, 0)
+       __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, idx, 0)
 
 #define CPU_PM_CPU_IDLE_ENTER_RETENTION(low_level_idle_enter, idx)     \
-       __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, 1)
+       __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, idx, 1)
+
+#define CPU_PM_CPU_IDLE_ENTER_PARAM(low_level_idle_enter, idx, state)  \
+       __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, state, 0)
+
+#define CPU_PM_CPU_IDLE_ENTER_RETENTION_PARAM(low_level_idle_enter, idx, state)        \
+       __CPU_PM_CPU_IDLE_ENTER(low_level_idle_enter, idx, state, 1)
 
 #endif /* _LINUX_CPUIDLE_H */
index 342dabd..c19483b 100644 (file)
@@ -440,7 +440,7 @@ struct dimm_info {
        char label[EDAC_MC_LABEL_LEN + 1];      /* DIMM label on motherboard */
 
        /* Memory location data */
-       unsigned location[EDAC_MAX_LAYERS];
+       unsigned int location[EDAC_MAX_LAYERS];
 
        struct mem_ctl_info *mci;       /* the parent */
 
@@ -451,7 +451,7 @@ struct dimm_info {
 
        u32 nr_pages;                   /* number of pages on this dimm */
 
-       unsigned csrow, cschannel;      /* Points to the old API data */
+       unsigned int csrow, cschannel;  /* Points to the old API data */
 
        u16 smbios_handle;              /* Handle for SMBIOS type 17 */
 };
@@ -597,7 +597,7 @@ struct mem_ctl_info {
                                           unsigned long page);
        int mc_idx;
        struct csrow_info **csrows;
-       unsigned nr_csrows, num_cschannel;
+       unsigned int nr_csrows, num_cschannel;
 
        /*
         * Memory Controller hierarchy
@@ -608,14 +608,14 @@ struct mem_ctl_info {
         * of the recent drivers enumerate memories per DIMM, instead.
         * When the memory controller is per rank, csbased is true.
         */
-       unsigned n_layers;
+       unsigned int n_layers;
        struct edac_mc_layer *layers;
        bool csbased;
 
        /*
         * DIMM info. Will eventually remove the entire csrows_info some day
         */
-       unsigned tot_dimms;
+       unsigned int tot_dimms;
        struct dimm_info **dimms;
 
        /*
index 280c61e..635a95c 100644 (file)
@@ -2,16 +2,16 @@
 #ifndef _LINUX_ERROR_INJECTION_H
 #define _LINUX_ERROR_INJECTION_H
 
-#ifdef CONFIG_FUNCTION_ERROR_INJECTION
+#include <linux/compiler.h>
+#include <asm-generic/error-injection.h>
 
-#include <asm/error-injection.h>
+#ifdef CONFIG_FUNCTION_ERROR_INJECTION
 
 extern bool within_error_injection_list(unsigned long addr);
 extern int get_injectable_error_type(unsigned long addr);
 
 #else /* !CONFIG_FUNCTION_ERROR_INJECTION */
 
-#include <asm-generic/error-injection.h>
 static inline bool within_error_injection_list(unsigned long addr)
 {
        return false;
diff --git a/include/linux/firmware/imx/dsp.h b/include/linux/firmware/imx/dsp.h
new file mode 100644 (file)
index 0000000..7562099
--- /dev/null
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2019 NXP
+ *
+ * Header file for the DSP IPC implementation
+ */
+
+#ifndef _IMX_DSP_IPC_H
+#define _IMX_DSP_IPC_H
+
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/mailbox_client.h>
+
+#define DSP_MU_CHAN_NUM                4
+
+struct imx_dsp_chan {
+       struct imx_dsp_ipc *ipc;
+       struct mbox_client cl;
+       struct mbox_chan *ch;
+       char *name;
+       int idx;
+};
+
+struct imx_dsp_ops {
+       void (*handle_reply)(struct imx_dsp_ipc *ipc);
+       void (*handle_request)(struct imx_dsp_ipc *ipc);
+};
+
+struct imx_dsp_ipc {
+       /* Host <-> DSP communication uses 2 txdb and 2 rxdb channels */
+       struct imx_dsp_chan chans[DSP_MU_CHAN_NUM];
+       struct device *dev;
+       struct imx_dsp_ops *ops;
+       void *private_data;
+};
+
+static inline void imx_dsp_set_data(struct imx_dsp_ipc *ipc, void *data)
+{
+       if (!ipc)
+               return;
+
+       ipc->private_data = data;
+}
+
+static inline void *imx_dsp_get_data(struct imx_dsp_ipc *ipc)
+{
+       if (!ipc)
+               return NULL;
+
+       return ipc->private_data;
+}
+
+#if IS_ENABLED(CONFIG_IMX_DSP)
+
+int imx_dsp_ring_doorbell(struct imx_dsp_ipc *dsp, unsigned int chan_idx);
+
+#else
+
+static inline int imx_dsp_ring_doorbell(struct imx_dsp_ipc *ipc,
+                                       unsigned int chan_idx)
+{
+       return -ENOTSUPP;
+}
+
+#endif
+#endif /* _IMX_DSP_IPC_H */
index f757a58..2157717 100644 (file)
@@ -221,19 +221,6 @@ static inline int gpio_to_irq(unsigned gpio)
        return -EINVAL;
 }
 
-static inline int gpiochip_lock_as_irq(struct gpio_chip *chip,
-                                      unsigned int offset)
-{
-       WARN_ON(1);
-       return -EINVAL;
-}
-
-static inline void gpiochip_unlock_as_irq(struct gpio_chip *chip,
-                                         unsigned int offset)
-{
-       WARN_ON(1);
-}
-
 static inline int irq_to_gpio(unsigned irq)
 {
        /* irq can never have been returned from gpio_to_irq() */
index a7f08fb..b70af92 100644 (file)
@@ -170,18 +170,8 @@ struct gpio_desc *gpio_to_desc(unsigned gpio);
 int desc_to_gpio(const struct gpio_desc *desc);
 
 /* Child properties interface */
-struct device_node;
 struct fwnode_handle;
 
-struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
-                                        const char *propname, int index,
-                                        enum gpiod_flags dflags,
-                                        const char *label);
-struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev,
-                                             struct device_node *node,
-                                             const char *propname, int index,
-                                             enum gpiod_flags dflags,
-                                             const char *label);
 struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
                                         const char *propname, int index,
                                         enum gpiod_flags dflags,
@@ -530,29 +520,9 @@ static inline int desc_to_gpio(const struct gpio_desc *desc)
 }
 
 /* Child properties interface */
-struct device_node;
 struct fwnode_handle;
 
 static inline
-struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
-                                        const char *propname, int index,
-                                        enum gpiod_flags dflags,
-                                        const char *label)
-{
-       return ERR_PTR(-ENOSYS);
-}
-
-static inline
-struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev,
-                                             struct device_node *node,
-                                             const char *propname, int index,
-                                             enum gpiod_flags dflags,
-                                             const char *label)
-{
-       return ERR_PTR(-ENOSYS);
-}
-
-static inline
 struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
                                         const char *propname, int index,
                                         enum gpiod_flags dflags,
@@ -584,6 +554,111 @@ struct gpio_desc *devm_fwnode_get_gpiod_from_child(struct device *dev,
                                                      flags, label);
 }
 
+#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_OF_GPIO)
+struct device_node;
+
+struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
+                                        const char *propname, int index,
+                                        enum gpiod_flags dflags,
+                                        const char *label);
+
+#else  /* CONFIG_GPIOLIB && CONFIG_OF_GPIO */
+
+struct device_node;
+
+static inline
+struct gpio_desc *gpiod_get_from_of_node(struct device_node *node,
+                                        const char *propname, int index,
+                                        enum gpiod_flags dflags,
+                                        const char *label)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+#endif /* CONFIG_GPIOLIB && CONFIG_OF_GPIO */
+
+#ifdef CONFIG_GPIOLIB
+struct device_node;
+
+struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev,
+                                             struct device_node *node,
+                                             const char *propname, int index,
+                                             enum gpiod_flags dflags,
+                                             const char *label);
+
+#else  /* CONFIG_GPIOLIB */
+
+struct device_node;
+
+static inline
+struct gpio_desc *devm_gpiod_get_from_of_node(struct device *dev,
+                                             struct device_node *node,
+                                             const char *propname, int index,
+                                             enum gpiod_flags dflags,
+                                             const char *label)
+{
+       return ERR_PTR(-ENOSYS);
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+struct acpi_gpio_params {
+       unsigned int crs_entry_index;
+       unsigned int line_index;
+       bool active_low;
+};
+
+struct acpi_gpio_mapping {
+       const char *name;
+       const struct acpi_gpio_params *data;
+       unsigned int size;
+
+/* Ignore IoRestriction field */
+#define ACPI_GPIO_QUIRK_NO_IO_RESTRICTION      BIT(0)
+/*
+ * When ACPI GPIO mapping table is in use the index parameter inside it
+ * refers to the GPIO resource in _CRS method. That index has no
+ * distinction of actual type of the resource. When consumer wants to
+ * get GpioIo type explicitly, this quirk may be used.
+ */
+#define ACPI_GPIO_QUIRK_ONLY_GPIOIO            BIT(1)
+
+       unsigned int quirks;
+};
+
+#if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_ACPI)
+
+struct acpi_device;
+
+int acpi_dev_add_driver_gpios(struct acpi_device *adev,
+                             const struct acpi_gpio_mapping *gpios);
+void acpi_dev_remove_driver_gpios(struct acpi_device *adev);
+
+int devm_acpi_dev_add_driver_gpios(struct device *dev,
+                                  const struct acpi_gpio_mapping *gpios);
+void devm_acpi_dev_remove_driver_gpios(struct device *dev);
+
+#else  /* CONFIG_GPIOLIB && CONFIG_ACPI */
+
+struct acpi_device;
+
+static inline int acpi_dev_add_driver_gpios(struct acpi_device *adev,
+                             const struct acpi_gpio_mapping *gpios)
+{
+       return -ENXIO;
+}
+static inline void acpi_dev_remove_driver_gpios(struct acpi_device *adev) {}
+
+static inline int devm_acpi_dev_add_driver_gpios(struct device *dev,
+                             const struct acpi_gpio_mapping *gpios)
+{
+       return -ENXIO;
+}
+static inline void devm_acpi_dev_remove_driver_gpios(struct device *dev) {}
+
+#endif /* CONFIG_GPIOLIB && CONFIG_ACPI */
+
+
 #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS)
 
 int gpiod_export(struct gpio_desc *desc, bool direction_may_change);
index 6a0e420..f8245d6 100644 (file)
@@ -20,9 +20,8 @@ struct module;
 enum gpiod_flags;
 enum gpio_lookup_flags;
 
-#ifdef CONFIG_GPIOLIB
+struct gpio_chip;
 
-#ifdef CONFIG_GPIOLIB_IRQCHIP
 /**
  * struct gpio_irq_chip - GPIO interrupt controller
  */
@@ -49,6 +48,84 @@ struct gpio_irq_chip {
         */
        const struct irq_domain_ops *domain_ops;
 
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+       /**
+        * @fwnode:
+        *
+        * Firmware node corresponding to this gpiochip/irqchip, necessary
+        * for hierarchical irqdomain support.
+        */
+       struct fwnode_handle *fwnode;
+
+       /**
+        * @parent_domain:
+        *
+        * If non-NULL, will be set as the parent of this GPIO interrupt
+        * controller's IRQ domain to establish a hierarchical interrupt
+        * domain. The presence of this will activate the hierarchical
+        * interrupt support.
+        */
+       struct irq_domain *parent_domain;
+
+       /**
+        * @child_to_parent_hwirq:
+        *
+        * This callback translates a child hardware IRQ offset to a parent
+        * hardware IRQ offset on a hierarchical interrupt chip. The child
+        * hardware IRQs correspond to the GPIO index 0..ngpio-1 (see the
+        * ngpio field of struct gpio_chip) and the corresponding parent
+        * hardware IRQ and type (such as IRQ_TYPE_*) shall be returned by
+        * the driver. The driver can calculate this from an offset or using
+        * a lookup table or whatever method is best for this chip. Return
+        * 0 on successful translation in the driver.
+        *
+        * If some ranges of hardware IRQs do not have a corresponding parent
+        * HWIRQ, return -EINVAL, but also make sure to fill in @valid_mask and
+        * @need_valid_mask to make these GPIO lines unavailable for
+        * translation.
+        */
+       int (*child_to_parent_hwirq)(struct gpio_chip *chip,
+                                    unsigned int child_hwirq,
+                                    unsigned int child_type,
+                                    unsigned int *parent_hwirq,
+                                    unsigned int *parent_type);
+
+       /**
+        * @populate_parent_fwspec:
+        *
+        * This optional callback populates the &struct irq_fwspec for the
+        * parent's IRQ domain. If this is not specified, then
+        * &gpiochip_populate_parent_fwspec_twocell will be used. A four-cell
+        * variant named &gpiochip_populate_parent_fwspec_fourcell is also
+        * available.
+        */
+       void (*populate_parent_fwspec)(struct gpio_chip *chip,
+                                      struct irq_fwspec *fwspec,
+                                      unsigned int parent_hwirq,
+                                      unsigned int parent_type);
+
+       /**
+        * @child_offset_to_irq:
+        *
+        * This optional callback is used to translate the child's GPIO line
+        * offset on the GPIO chip to an IRQ number for the GPIO to_irq()
+        * callback. If this is not specified, then a default callback will be
+        * provided that returns the line offset.
+        */
+       unsigned int (*child_offset_to_irq)(struct gpio_chip *chip,
+                                           unsigned int pin);
+
+       /**
+        * @child_irq_domain_ops:
+        *
+        * The IRQ domain operations that will be used for this GPIO IRQ
+        * chip. If no operations are provided, then default callbacks will
+        * be populated to setup the IRQ hierarchy. Some drivers need to
+        * supply their own translate function.
+        */
+       struct irq_domain_ops child_irq_domain_ops;
+#endif
+
        /**
         * @handler:
         *
@@ -125,11 +202,17 @@ struct gpio_irq_chip {
        bool threaded;
 
        /**
-        * @need_valid_mask:
-        *
-        * If set core allocates @valid_mask with all bits set to one.
+        * @init_valid_mask: optional routine to initialize @valid_mask, to be
+        * used if not all GPIO lines are valid interrupts. Sometimes some
+        * lines just cannot fire interrupts, and this routine, when defined,
+        * is passed a bitmap in "valid_mask" and it will have ngpios
+        * bits from 0..(ngpios-1) set to "1" as in valid. The callback can
+        * then directly set some bits to "0" if they cannot be used for
+        * interrupts.
         */
-       bool need_valid_mask;
+       void (*init_valid_mask)(struct gpio_chip *chip,
+                               unsigned long *valid_mask,
+                               unsigned int ngpios);
 
        /**
         * @valid_mask:
@@ -161,7 +244,6 @@ struct gpio_irq_chip {
         */
        void            (*irq_disable)(struct irq_data *data);
 };
-#endif /* CONFIG_GPIOLIB_IRQCHIP */
 
 /**
  * struct gpio_chip - abstract a GPIO controller
@@ -282,7 +364,9 @@ struct gpio_chip {
        void                    (*dbg_show)(struct seq_file *s,
                                                struct gpio_chip *chip);
 
-       int                     (*init_valid_mask)(struct gpio_chip *chip);
+       int                     (*init_valid_mask)(struct gpio_chip *chip,
+                                                  unsigned long *valid_mask,
+                                                  unsigned int ngpios);
 
        int                     base;
        u16                     ngpio;
@@ -321,15 +405,6 @@ struct gpio_chip {
 #endif /* CONFIG_GPIOLIB_IRQCHIP */
 
        /**
-        * @need_valid_mask:
-        *
-        * If set core allocates @valid_mask with all its values initialized
-        * with init_valid_mask() or set to one if init_valid_mask() is not
-        * defined
-        */
-       bool need_valid_mask;
-
-       /**
         * @valid_mask:
         *
         * If not %NULL holds bitmask of GPIOs which are valid to be used
@@ -421,9 +496,6 @@ extern int devm_gpiochip_add_data(struct device *dev, struct gpio_chip *chip,
 extern struct gpio_chip *gpiochip_find(void *data,
                              int (*match)(struct gpio_chip *chip, void *data));
 
-/* lock/unlock as IRQ */
-int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset);
-void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset);
 bool gpiochip_line_is_irq(struct gpio_chip *chip, unsigned int offset);
 int gpiochip_reqres_irq(struct gpio_chip *chip, unsigned int offset);
 void gpiochip_relres_irq(struct gpio_chip *chip, unsigned int offset);
@@ -441,15 +513,40 @@ bool gpiochip_line_is_valid(const struct gpio_chip *chip, unsigned int offset);
 /* get driver data */
 void *gpiochip_get_data(struct gpio_chip *chip);
 
-struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc);
-
 struct bgpio_pdata {
        const char *label;
        int base;
        int ngpio;
 };
 
-#if IS_ENABLED(CONFIG_GPIO_GENERIC)
+#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
+
+void gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
+                                            struct irq_fwspec *fwspec,
+                                            unsigned int parent_hwirq,
+                                            unsigned int parent_type);
+void gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
+                                             struct irq_fwspec *fwspec,
+                                             unsigned int parent_hwirq,
+                                             unsigned int parent_type);
+
+#else
+
+static inline void gpiochip_populate_parent_fwspec_twocell(struct gpio_chip *chip,
+                                                   struct irq_fwspec *fwspec,
+                                                   unsigned int parent_hwirq,
+                                                   unsigned int parent_type)
+{
+}
+
+static inline void gpiochip_populate_parent_fwspec_fourcell(struct gpio_chip *chip,
+                                                    struct irq_fwspec *fwspec,
+                                                    unsigned int parent_hwirq,
+                                                    unsigned int parent_type)
+{
+}
+
+#endif /* CONFIG_IRQ_DOMAIN_HIERARCHY */
 
 int bgpio_init(struct gpio_chip *gc, struct device *dev,
               unsigned long sz, void __iomem *dat, void __iomem *set,
@@ -463,10 +560,6 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev,
 #define BGPIOF_READ_OUTPUT_REG_SET     BIT(4) /* reg_set stores output value */
 #define BGPIOF_NO_OUTPUT               BIT(5) /* only input */
 
-#endif /* CONFIG_GPIO_GENERIC */
-
-#ifdef CONFIG_GPIOLIB_IRQCHIP
-
 int gpiochip_irq_map(struct irq_domain *d, unsigned int irq,
                     irq_hw_number_t hwirq);
 void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq);
@@ -555,15 +648,11 @@ static inline int gpiochip_irqchip_add_nested(struct gpio_chip *gpiochip,
 }
 #endif /* CONFIG_LOCKDEP */
 
-#endif /* CONFIG_GPIOLIB_IRQCHIP */
-
 int gpiochip_generic_request(struct gpio_chip *chip, unsigned offset);
 void gpiochip_generic_free(struct gpio_chip *chip, unsigned offset);
 int gpiochip_generic_config(struct gpio_chip *chip, unsigned offset,
                            unsigned long config);
 
-#ifdef CONFIG_PINCTRL
-
 /**
  * struct gpio_pin_range - pin range controlled by a gpio chip
  * @node: list for maintaining set of pin ranges, used internally
@@ -576,6 +665,8 @@ struct gpio_pin_range {
        struct pinctrl_gpio_range range;
 };
 
+#ifdef CONFIG_PINCTRL
+
 int gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
                           unsigned int gpio_offset, unsigned int pin_offset,
                           unsigned int npins);
@@ -586,8 +677,6 @@ void gpiochip_remove_pin_ranges(struct gpio_chip *chip);
 
 #else /* ! CONFIG_PINCTRL */
 
-struct pinctrl_dev;
-
 static inline int
 gpiochip_add_pin_range(struct gpio_chip *chip, const char *pinctl_name,
                       unsigned int gpio_offset, unsigned int pin_offset,
@@ -619,6 +708,15 @@ void gpiochip_free_own_desc(struct gpio_desc *desc);
 void devprop_gpiochip_set_names(struct gpio_chip *chip,
                                const struct fwnode_handle *fwnode);
 
+#ifdef CONFIG_GPIOLIB
+
+/* lock/unlock as IRQ */
+int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset);
+void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset);
+
+
+struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc);
+
 #else /* CONFIG_GPIOLIB */
 
 static inline struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc)
@@ -628,6 +726,18 @@ static inline struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc)
        return ERR_PTR(-ENODEV);
 }
 
+static inline int gpiochip_lock_as_irq(struct gpio_chip *chip,
+                                      unsigned int offset)
+{
+       WARN_ON(1);
+       return -EINVAL;
+}
+
+static inline void gpiochip_unlock_as_irq(struct gpio_chip *chip,
+                                         unsigned int offset)
+{
+       WARN_ON(1);
+}
 #endif /* CONFIG_GPIOLIB */
 
-#endif
+#endif /* __LINUX_GPIO_DRIVER_H */
index 5ecb055..de102e4 100644 (file)
@@ -188,6 +188,10 @@ static inline struct i3c_driver *drv_to_i3cdrv(struct device_driver *drv)
 struct device *i3cdev_to_dev(struct i3c_device *i3cdev);
 struct i3c_device *dev_to_i3cdev(struct device *dev);
 
+const struct i3c_device_id *
+i3c_device_match_id(struct i3c_device *i3cdev,
+                   const struct i3c_device_id *id_table);
+
 static inline void i3cdev_set_drvdata(struct i3c_device *i3cdev,
                                      void *data)
 {
index 1f08fa8..9cb39d9 100644 (file)
@@ -71,6 +71,9 @@ struct i2c_dev_boardinfo {
  * @common: common part of the I2C device descriptor
  * @boardinfo: pointer to the boardinfo attached to this I2C device
  * @dev: I2C device object registered to the I2C framework
+ * @addr: I2C device address
+ * @lvr: LVR (Legacy Virtual Register) needed by the I3C core to know about
+ *      the I2C device limitations
  *
  * Each I2C device connected on the bus will have an i2c_dev_desc.
  * This object is created by the core and later attached to the controller
@@ -84,6 +87,8 @@ struct i2c_dev_desc {
        struct i3c_i2c_dev_desc common;
        const struct i2c_dev_boardinfo *boardinfo;
        struct i2c_client *dev;
+       u16 addr;
+       u8 lvr;
 };
 
 /**
index ceabb01..1ecb6b4 100644 (file)
@@ -48,7 +48,7 @@ static const struct acpi_device_id elan_acpi_id[] = {
        { "ELAN0618", 0 },
        { "ELAN0619", 0 },
        { "ELAN061A", 0 },
-       { "ELAN061B", 0 },
+/*     { "ELAN061B", 0 }, not working on the Lenovo Legion Y7000 */
        { "ELAN061C", 0 },
        { "ELAN061D", 0 },
        { "ELAN061E", 0 },
index f2ae8a0..ed11ef5 100644 (file)
 #define dma_frcd_type(d) ((d >> 30) & 1)
 #define dma_frcd_fault_reason(c) (c & 0xff)
 #define dma_frcd_source_id(c) (c & 0xffff)
+#define dma_frcd_pasid_value(c) (((c) >> 8) & 0xfffff)
+#define dma_frcd_pasid_present(c) (((c) >> 31) & 1)
 /* low 64 bit */
 #define dma_frcd_page_addr(d) (d & (((u64)-1) << PAGE_SHIFT))
 
@@ -346,7 +348,6 @@ enum {
 #define QI_PC_PASID_SEL                (QI_PC_TYPE | QI_PC_GRAN(1))
 
 #define QI_EIOTLB_ADDR(addr)   ((u64)(addr) & VTD_PAGE_MASK)
-#define QI_EIOTLB_GL(gl)       (((u64)gl) << 7)
 #define QI_EIOTLB_IH(ih)       (((u64)ih) << 6)
 #define QI_EIOTLB_AM(am)       (((u64)am))
 #define QI_EIOTLB_PASID(pasid)         (((u64)pasid) << 32)
@@ -378,8 +379,6 @@ enum {
 #define QI_RESP_INVALID                0x1
 #define QI_RESP_FAILURE                0xf
 
-#define QI_GRAN_ALL_ALL                        0
-#define QI_GRAN_NONG_ALL               1
 #define QI_GRAN_NONG_PASID             2
 #define QI_GRAN_PSI_PASID              3
 
index b5a450a..ec7a134 100644 (file)
@@ -1,7 +1,9 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef __IO_PGTABLE_H
 #define __IO_PGTABLE_H
+
 #include <linux/bitops.h>
+#include <linux/iommu.h>
 
 /*
  * Public API for use by IOMMU drivers
@@ -17,22 +19,31 @@ enum io_pgtable_fmt {
 };
 
 /**
- * struct iommu_gather_ops - IOMMU callbacks for TLB and page table management.
+ * struct iommu_flush_ops - IOMMU callbacks for TLB and page table management.
  *
- * @tlb_flush_all: Synchronously invalidate the entire TLB context.
- * @tlb_add_flush: Queue up a TLB invalidation for a virtual address range.
- * @tlb_sync:      Ensure any queued TLB invalidation has taken effect, and
- *                 any corresponding page table updates are visible to the
- *                 IOMMU.
+ * @tlb_flush_all:  Synchronously invalidate the entire TLB context.
+ * @tlb_flush_walk: Synchronously invalidate all intermediate TLB state
+ *                  (sometimes referred to as the "walk cache") for a virtual
+ *                  address range.
+ * @tlb_flush_leaf: Synchronously invalidate all leaf TLB state for a virtual
+ *                  address range.
+ * @tlb_add_page:   Optional callback to queue up leaf TLB invalidation for a
+ *                  single page.  IOMMUs that cannot batch TLB invalidation
+ *                  operations efficiently will typically issue them here, but
+ *                  others may decide to update the iommu_iotlb_gather structure
+ *                  and defer the invalidation until iommu_tlb_sync() instead.
  *
  * Note that these can all be called in atomic context and must therefore
  * not block.
  */
-struct iommu_gather_ops {
+struct iommu_flush_ops {
        void (*tlb_flush_all)(void *cookie);
-       void (*tlb_add_flush)(unsigned long iova, size_t size, size_t granule,
-                             bool leaf, void *cookie);
-       void (*tlb_sync)(void *cookie);
+       void (*tlb_flush_walk)(unsigned long iova, size_t size, size_t granule,
+                              void *cookie);
+       void (*tlb_flush_leaf)(unsigned long iova, size_t size, size_t granule,
+                              void *cookie);
+       void (*tlb_add_page)(struct iommu_iotlb_gather *gather,
+                            unsigned long iova, size_t granule, void *cookie);
 };
 
 /**
@@ -65,10 +76,9 @@ struct io_pgtable_cfg {
         *      (unmapped) entries but the hardware might do so anyway, perform
         *      TLB maintenance when mapping as well as when unmapping.
         *
-        * IO_PGTABLE_QUIRK_ARM_MTK_4GB: (ARM v7s format) Set bit 9 in all
-        *      PTEs, for Mediatek IOMMUs which treat it as a 33rd address bit
-        *      when the SoC is in "4GB mode" and they can only access the high
-        *      remap of DRAM (0x1_00000000 to 0x1_ffffffff).
+        * IO_PGTABLE_QUIRK_ARM_MTK_EXT: (ARM v7s format) MediaTek IOMMUs extend
+        *      to support up to 34 bits PA where the bit32 and bit33 are
+        *      encoded in the bit9 and bit4 of the PTE respectively.
         *
         * IO_PGTABLE_QUIRK_NON_STRICT: Skip issuing synchronous leaf TLBIs
         *      on unmap, for DMA domains using the flush queue mechanism for
@@ -77,14 +87,14 @@ struct io_pgtable_cfg {
        #define IO_PGTABLE_QUIRK_ARM_NS         BIT(0)
        #define IO_PGTABLE_QUIRK_NO_PERMS       BIT(1)
        #define IO_PGTABLE_QUIRK_TLBI_ON_MAP    BIT(2)
-       #define IO_PGTABLE_QUIRK_ARM_MTK_4GB    BIT(3)
+       #define IO_PGTABLE_QUIRK_ARM_MTK_EXT    BIT(3)
        #define IO_PGTABLE_QUIRK_NON_STRICT     BIT(4)
        unsigned long                   quirks;
        unsigned long                   pgsize_bitmap;
        unsigned int                    ias;
        unsigned int                    oas;
        bool                            coherent_walk;
-       const struct iommu_gather_ops   *tlb;
+       const struct iommu_flush_ops    *tlb;
        struct device                   *iommu_dev;
 
        /* Low-level data specific to the table format */
@@ -128,7 +138,7 @@ struct io_pgtable_ops {
        int (*map)(struct io_pgtable_ops *ops, unsigned long iova,
                   phys_addr_t paddr, size_t size, int prot);
        size_t (*unmap)(struct io_pgtable_ops *ops, unsigned long iova,
-                       size_t size);
+                       size_t size, struct iommu_iotlb_gather *gather);
        phys_addr_t (*iova_to_phys)(struct io_pgtable_ops *ops,
                                    unsigned long iova);
 };
@@ -184,15 +194,27 @@ static inline void io_pgtable_tlb_flush_all(struct io_pgtable *iop)
        iop->cfg.tlb->tlb_flush_all(iop->cookie);
 }
 
-static inline void io_pgtable_tlb_add_flush(struct io_pgtable *iop,
-               unsigned long iova, size_t size, size_t granule, bool leaf)
+static inline void
+io_pgtable_tlb_flush_walk(struct io_pgtable *iop, unsigned long iova,
+                         size_t size, size_t granule)
+{
+       iop->cfg.tlb->tlb_flush_walk(iova, size, granule, iop->cookie);
+}
+
+static inline void
+io_pgtable_tlb_flush_leaf(struct io_pgtable *iop, unsigned long iova,
+                         size_t size, size_t granule)
 {
-       iop->cfg.tlb->tlb_add_flush(iova, size, granule, leaf, iop->cookie);
+       iop->cfg.tlb->tlb_flush_leaf(iova, size, granule, iop->cookie);
 }
 
-static inline void io_pgtable_tlb_sync(struct io_pgtable *iop)
+static inline void
+io_pgtable_tlb_add_page(struct io_pgtable *iop,
+                       struct iommu_iotlb_gather * gather, unsigned long iova,
+                       size_t granule)
 {
-       iop->cfg.tlb->tlb_sync(iop->cookie);
+       if (iop->cfg.tlb->tlb_add_page)
+               iop->cfg.tlb->tlb_add_page(gather, iova, granule, iop->cookie);
 }
 
 /**
diff --git a/include/linux/ioc4.h b/include/linux/ioc4.h
deleted file mode 100644 (file)
index 51e2b9f..0000000
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 2005 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#ifndef _LINUX_IOC4_H
-#define _LINUX_IOC4_H
-
-#include <linux/interrupt.h>
-
-/***************
- * Definitions *
- ***************/
-
-/* Miscellaneous values inherent to hardware */
-
-#define IOC4_EXTINT_COUNT_DIVISOR 520  /* PCI clocks per COUNT tick */
-
-/***********************************
- * Structures needed by subdrivers *
- ***********************************/
-
-/* This structure fully describes the IOC4 miscellaneous registers which
- * appear at bar[0]+0x00000 through bar[0]+0x0005c.  The corresponding
- * PCI resource is managed by the main IOC4 driver because it contains
- * registers of interest to many different IOC4 subdrivers.
- */
-struct ioc4_misc_regs {
-       /* Miscellaneous IOC4 registers */
-       union ioc4_pci_err_addr_l {
-               uint32_t raw;
-               struct {
-                       uint32_t valid:1;       /* Address captured */
-                       uint32_t master_id:4;   /* Unit causing error
-                                                * 0/1: Serial port 0 TX/RX
-                                                * 2/3: Serial port 1 TX/RX
-                                                * 4/5: Serial port 2 TX/RX
-                                                * 6/7: Serial port 3 TX/RX
-                                                * 8: ATA/ATAPI
-                                                * 9-15: Undefined
-                                                */
-                       uint32_t mul_err:1;     /* Multiple errors occurred */
-                       uint32_t addr:26;       /* Bits 31-6 of error addr */
-               } fields;
-       } pci_err_addr_l;
-       uint32_t pci_err_addr_h;        /* Bits 63-32 of error addr */
-       union ioc4_sio_int {
-               uint32_t raw;
-               struct {
-                       uint8_t tx_mt:1;        /* TX ring buffer empty */
-                       uint8_t rx_full:1;      /* RX ring buffer full */
-                       uint8_t rx_high:1;      /* RX high-water exceeded */
-                       uint8_t rx_timer:1;     /* RX timer has triggered */
-                       uint8_t delta_dcd:1;    /* DELTA_DCD seen */
-                       uint8_t delta_cts:1;    /* DELTA_CTS seen */
-                       uint8_t intr_pass:1;    /* Interrupt pass-through */
-                       uint8_t tx_explicit:1;  /* TX, MCW, or delay complete */
-               } fields[4];
-       } sio_ir;               /* Serial interrupt state */
-       union ioc4_other_int {
-               uint32_t raw;
-               struct {
-                       uint32_t ata_int:1;     /* ATA port passthru */
-                       uint32_t ata_memerr:1;  /* ATA halted by mem error */
-                       uint32_t memerr:4;      /* Serial halted by mem err */
-                       uint32_t kbd_int:1;     /* kbd/mouse intr asserted */
-                       uint32_t reserved:16;   /* zero */
-                       uint32_t rt_int:1;      /* INT_OUT section latch */
-                       uint32_t gen_int:8;     /* Intr. from generic pins */
-               } fields;
-       } other_ir;             /* Other interrupt state */
-       union ioc4_sio_int sio_ies;     /* Serial interrupt enable set */
-       union ioc4_other_int other_ies; /* Other interrupt enable set */
-       union ioc4_sio_int sio_iec;     /* Serial interrupt enable clear */
-       union ioc4_other_int other_iec; /* Other interrupt enable clear */
-       union ioc4_sio_cr {
-               uint32_t raw;
-               struct {
-                       uint32_t cmd_pulse:4;   /* Bytebus strobe width */
-                       uint32_t arb_diag:3;    /* PCI bus requester */
-                       uint32_t sio_diag_idle:1;       /* Active ser req? */
-                       uint32_t ata_diag_idle:1;       /* Active ATA req? */
-                       uint32_t ata_diag_active:1;     /* ATA req is winner */
-                       uint32_t reserved:22;   /* zero */
-               } fields;
-       } sio_cr;
-       uint32_t unused1;
-       union ioc4_int_out {
-               uint32_t raw;
-               struct {
-                       uint32_t count:16;      /* Period control */
-                       uint32_t mode:3;        /* Output signal shape */
-                       uint32_t reserved:11;   /* zero */
-                       uint32_t diag:1;        /* Timebase control */
-                       uint32_t int_out:1;     /* Current value */
-               } fields;
-       } int_out;              /* External interrupt output control */
-       uint32_t unused2;
-       union ioc4_gpcr {
-               uint32_t raw;
-               struct {
-                       uint32_t dir:8; /* Pin direction */
-                       uint32_t edge:8;        /* Edge/level mode */
-                       uint32_t reserved1:4;   /* zero */
-                       uint32_t int_out_en:1;  /* INT_OUT enable */
-                       uint32_t reserved2:11;  /* zero */
-               } fields;
-       } gpcr_s;               /* Generic PIO control set */
-       union ioc4_gpcr gpcr_c; /* Generic PIO control clear */
-       union ioc4_gpdr {
-               uint32_t raw;
-               struct {
-                       uint32_t gen_pin:8;     /* State of pins */
-                       uint32_t reserved:24;
-               } fields;
-       } gpdr;                 /* Generic PIO data */
-       uint32_t unused3;
-       union ioc4_gppr {
-               uint32_t raw;
-               struct {
-                       uint32_t gen_pin:1;     /* Single pin state */
-                       uint32_t reserved:31;
-               } fields;
-       } gppr[8];              /* Generic PIO pins */
-};
-
-/* Masks for GPCR DIR pins */
-#define IOC4_GPCR_DIR_0 0x01   /* External interrupt output */
-#define IOC4_GPCR_DIR_1 0x02   /* External interrupt input */
-#define IOC4_GPCR_DIR_2 0x04
-#define IOC4_GPCR_DIR_3 0x08   /* Keyboard/mouse presence */
-#define IOC4_GPCR_DIR_4 0x10   /* Ser. port 0 xcvr select (0=232, 1=422) */
-#define IOC4_GPCR_DIR_5 0x20   /* Ser. port 1 xcvr select (0=232, 1=422) */
-#define IOC4_GPCR_DIR_6 0x40   /* Ser. port 2 xcvr select (0=232, 1=422) */
-#define IOC4_GPCR_DIR_7 0x80   /* Ser. port 3 xcvr select (0=232, 1=422) */
-
-/* Masks for GPCR EDGE pins */
-#define IOC4_GPCR_EDGE_0 0x01
-#define IOC4_GPCR_EDGE_1 0x02  /* External interrupt input */
-#define IOC4_GPCR_EDGE_2 0x04
-#define IOC4_GPCR_EDGE_3 0x08
-#define IOC4_GPCR_EDGE_4 0x10
-#define IOC4_GPCR_EDGE_5 0x20
-#define IOC4_GPCR_EDGE_6 0x40
-#define IOC4_GPCR_EDGE_7 0x80
-
-#define IOC4_VARIANT_IO9       0x0900
-#define IOC4_VARIANT_PCI_RT    0x0901
-#define IOC4_VARIANT_IO10      0x1000
-
-/* One of these per IOC4 */
-struct ioc4_driver_data {
-       struct list_head idd_list;
-       unsigned long idd_bar0;
-       struct pci_dev *idd_pdev;
-       const struct pci_device_id *idd_pci_id;
-       struct ioc4_misc_regs __iomem *idd_misc_regs;
-       unsigned long count_period;
-       void *idd_serial_data;
-       unsigned int idd_variant;
-};
-
-/* One per submodule */
-struct ioc4_submodule {
-       struct list_head is_list;
-       char *is_name;
-       struct module *is_owner;
-       int (*is_probe) (struct ioc4_driver_data *);
-       int (*is_remove) (struct ioc4_driver_data *);
-};
-
-#define IOC4_NUM_CARDS         8       /* max cards per partition */
-
-/**********************************
- * Functions needed by submodules *
- **********************************/
-
-extern int ioc4_register_submodule(struct ioc4_submodule *);
-extern void ioc4_unregister_submodule(struct ioc4_submodule *);
-
-#endif                         /* _LINUX_IOC4_H */
index fdc355c..29bac53 100644 (file)
@@ -192,6 +192,23 @@ struct iommu_sva_ops {
 #ifdef CONFIG_IOMMU_API
 
 /**
+ * struct iommu_iotlb_gather - Range information for a pending IOTLB flush
+ *
+ * @start: IOVA representing the start of the range to be flushed
+ * @end: IOVA representing the end of the range to be flushed (exclusive)
+ * @pgsize: The interval at which to perform the flush
+ *
+ * This structure is intended to be updated by multiple calls to the
+ * ->unmap() function in struct iommu_ops before eventually being passed
+ * into ->iotlb_sync().
+ */
+struct iommu_iotlb_gather {
+       unsigned long           start;
+       unsigned long           end;
+       size_t                  pgsize;
+};
+
+/**
  * struct iommu_ops - iommu ops and capabilities
  * @capable: check capability
  * @domain_alloc: allocate iommu domain
@@ -201,7 +218,6 @@ struct iommu_sva_ops {
  * @map: map a physically contiguous memory region to an iommu domain
  * @unmap: unmap a physically contiguous memory region from an iommu domain
  * @flush_iotlb_all: Synchronously flush all hardware TLBs for this domain
- * @iotlb_range_add: Add a given iova range to the flush queue for this domain
  * @iotlb_sync_map: Sync mappings created recently using @map to the hardware
  * @iotlb_sync: Flush all queued ranges from the hardware TLBs and empty flush
  *            queue
@@ -242,12 +258,11 @@ struct iommu_ops {
        int (*map)(struct iommu_domain *domain, unsigned long iova,
                   phys_addr_t paddr, size_t size, int prot);
        size_t (*unmap)(struct iommu_domain *domain, unsigned long iova,
-                    size_t size);
+                    size_t size, struct iommu_iotlb_gather *iotlb_gather);
        void (*flush_iotlb_all)(struct iommu_domain *domain);
-       void (*iotlb_range_add)(struct iommu_domain *domain,
-                               unsigned long iova, size_t size);
        void (*iotlb_sync_map)(struct iommu_domain *domain);
-       void (*iotlb_sync)(struct iommu_domain *domain);
+       void (*iotlb_sync)(struct iommu_domain *domain,
+                          struct iommu_iotlb_gather *iotlb_gather);
        phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova);
        int (*add_device)(struct device *dev);
        void (*remove_device)(struct device *dev);
@@ -378,6 +393,13 @@ static inline struct iommu_device *dev_to_iommu_device(struct device *dev)
        return (struct iommu_device *)dev_get_drvdata(dev);
 }
 
+static inline void iommu_iotlb_gather_init(struct iommu_iotlb_gather *gather)
+{
+       *gather = (struct iommu_iotlb_gather) {
+               .start  = ULONG_MAX,
+       };
+}
+
 #define IOMMU_GROUP_NOTIFY_ADD_DEVICE          1 /* Device added */
 #define IOMMU_GROUP_NOTIFY_DEL_DEVICE          2 /* Pre Device removed */
 #define IOMMU_GROUP_NOTIFY_BIND_DRIVER         3 /* Pre Driver bind */
@@ -402,7 +424,8 @@ extern int iommu_map(struct iommu_domain *domain, unsigned long iova,
 extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,
                          size_t size);
 extern size_t iommu_unmap_fast(struct iommu_domain *domain,
-                              unsigned long iova, size_t size);
+                              unsigned long iova, size_t size,
+                              struct iommu_iotlb_gather *iotlb_gather);
 extern size_t iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
                           struct scatterlist *sg,unsigned int nents, int prot);
 extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain, dma_addr_t iova);
@@ -413,6 +436,9 @@ extern void iommu_get_resv_regions(struct device *dev, struct list_head *list);
 extern void iommu_put_resv_regions(struct device *dev, struct list_head *list);
 extern int iommu_request_dm_for_dev(struct device *dev);
 extern int iommu_request_dma_domain_for_dev(struct device *dev);
+extern void iommu_set_default_passthrough(bool cmd_line);
+extern void iommu_set_default_translated(bool cmd_line);
+extern bool iommu_default_passthrough(void);
 extern struct iommu_resv_region *
 iommu_alloc_resv_region(phys_addr_t start, size_t length, int prot,
                        enum iommu_resv_type type);
@@ -476,17 +502,38 @@ static inline void iommu_flush_tlb_all(struct iommu_domain *domain)
                domain->ops->flush_iotlb_all(domain);
 }
 
-static inline void iommu_tlb_range_add(struct iommu_domain *domain,
-                                      unsigned long iova, size_t size)
+static inline void iommu_tlb_sync(struct iommu_domain *domain,
+                                 struct iommu_iotlb_gather *iotlb_gather)
 {
-       if (domain->ops->iotlb_range_add)
-               domain->ops->iotlb_range_add(domain, iova, size);
+       if (domain->ops->iotlb_sync)
+               domain->ops->iotlb_sync(domain, iotlb_gather);
+
+       iommu_iotlb_gather_init(iotlb_gather);
 }
 
-static inline void iommu_tlb_sync(struct iommu_domain *domain)
+static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain,
+                                              struct iommu_iotlb_gather *gather,
+                                              unsigned long iova, size_t size)
 {
-       if (domain->ops->iotlb_sync)
-               domain->ops->iotlb_sync(domain);
+       unsigned long start = iova, end = start + size;
+
+       /*
+        * If the new page is disjoint from the current range or is mapped at
+        * a different granularity, then sync the TLB so that the gather
+        * structure can be rewritten.
+        */
+       if (gather->pgsize != size ||
+           end < gather->start || start > gather->end) {
+               if (gather->pgsize)
+                       iommu_tlb_sync(domain, gather);
+               gather->pgsize = size;
+       }
+
+       if (gather->end < end)
+               gather->end = end;
+
+       if (gather->start > start)
+               gather->start = start;
 }
 
 /* PCI device grouping function */
@@ -567,6 +614,7 @@ struct iommu_group {};
 struct iommu_fwspec {};
 struct iommu_device {};
 struct iommu_fault_param {};
+struct iommu_iotlb_gather {};
 
 static inline bool iommu_present(struct bus_type *bus)
 {
@@ -621,7 +669,8 @@ static inline size_t iommu_unmap(struct iommu_domain *domain,
 }
 
 static inline size_t iommu_unmap_fast(struct iommu_domain *domain,
-                                     unsigned long iova, int gfp_order)
+                                     unsigned long iova, int gfp_order,
+                                     struct iommu_iotlb_gather *iotlb_gather)
 {
        return 0;
 }
@@ -637,12 +686,8 @@ static inline void iommu_flush_tlb_all(struct iommu_domain *domain)
 {
 }
 
-static inline void iommu_tlb_range_add(struct iommu_domain *domain,
-                                      unsigned long iova, size_t size)
-{
-}
-
-static inline void iommu_tlb_sync(struct iommu_domain *domain)
+static inline void iommu_tlb_sync(struct iommu_domain *domain,
+                                 struct iommu_iotlb_gather *iotlb_gather)
 {
 }
 
@@ -694,6 +739,19 @@ static inline int iommu_request_dma_domain_for_dev(struct device *dev)
        return -ENODEV;
 }
 
+static inline void iommu_set_default_passthrough(bool cmd_line)
+{
+}
+
+static inline void iommu_set_default_translated(bool cmd_line)
+{
+}
+
+static inline bool iommu_default_passthrough(void)
+{
+       return true;
+}
+
 static inline int iommu_attach_group(struct iommu_domain *domain,
                                     struct iommu_group *group)
 {
@@ -827,6 +885,16 @@ static inline struct iommu_device *dev_to_iommu_device(struct device *dev)
        return NULL;
 }
 
+static inline void iommu_iotlb_gather_init(struct iommu_iotlb_gather *gather)
+{
+}
+
+static inline void iommu_iotlb_gather_add_page(struct iommu_domain *domain,
+                                              struct iommu_iotlb_gather *gather,
+                                              unsigned long iova, size_t size)
+{
+}
+
 static inline void iommu_device_unregister(struct iommu_device *iommu)
 {
 }
index b9b1bc5..f0b8092 100644 (file)
@@ -216,6 +216,29 @@ extern int crash_prepare_elf64_headers(struct crash_mem *mem, int kernel_map,
                                       void **addr, unsigned long *sz);
 #endif /* CONFIG_KEXEC_FILE */
 
+#ifdef CONFIG_KEXEC_ELF
+struct kexec_elf_info {
+       /*
+        * Where the ELF binary contents are kept.
+        * Memory managed by the user of the struct.
+        */
+       const char *buffer;
+
+       const struct elfhdr *ehdr;
+       const struct elf_phdr *proghdrs;
+};
+
+int kexec_build_elf_info(const char *buf, size_t len, struct elfhdr *ehdr,
+                              struct kexec_elf_info *elf_info);
+
+int kexec_elf_load(struct kimage *image, struct elfhdr *ehdr,
+                        struct kexec_elf_info *elf_info,
+                        struct kexec_buf *kbuf,
+                        unsigned long *lowest_load_addr);
+
+void kexec_free_elf_info(struct kexec_elf_info *elf_info);
+int kexec_elf_probe(const char *buf, unsigned long len);
+#endif
 struct kimage {
        kimage_entry_t head;
        kimage_entry_t *entry;
index cbd9d84..88e1e63 100644 (file)
@@ -117,6 +117,7 @@ struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode);
 unsigned long logic_pio_trans_hwaddr(struct fwnode_handle *fwnode,
                        resource_size_t hw_addr, resource_size_t size);
 int logic_pio_register_range(struct logic_pio_hwaddr *newrange);
+void logic_pio_unregister_range(struct logic_pio_hwaddr *range);
 resource_size_t logic_pio_to_hwaddr(unsigned long pio);
 unsigned long logic_pio_trans_cpuaddr(resource_size_t hw_addr);
 
index d77d717..3f38c30 100644 (file)
@@ -215,8 +215,9 @@ enum node_stat_item {
        NR_INACTIVE_FILE,       /*  "     "     "   "       "         */
        NR_ACTIVE_FILE,         /*  "     "     "   "       "         */
        NR_UNEVICTABLE,         /*  "     "     "   "       "         */
-       NR_SLAB_RECLAIMABLE,
-       NR_SLAB_UNRECLAIMABLE,
+       NR_SLAB_RECLAIMABLE,    /* Please do not reorder this item */
+       NR_SLAB_UNRECLAIMABLE,  /* and this one without looking at
+                                * memcg_flush_percpu_vmstats() first. */
        NR_ISOLATED_ANON,       /* Temporary isolated pages from anon lru */
        NR_ISOLATED_FILE,       /* Temporary isolated pages from file lru */
        WORKINGSET_NODES,
diff --git a/include/linux/moxtet.h b/include/linux/moxtet.h
new file mode 100644 (file)
index 0000000..490db68
--- /dev/null
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Turris Mox module configuration bus driver
+ *
+ * Copyright (C) 2019 Marek Behun <marek.behun@nic.cz>
+ */
+
+#ifndef __LINUX_MOXTET_H
+#define __LINUX_MOXTET_H
+
+#include <linux/device.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/mutex.h>
+
+#define TURRIS_MOX_MAX_MODULES 10
+
+enum turris_mox_cpu_module_id {
+       TURRIS_MOX_CPU_ID_EMMC  = 0x00,
+       TURRIS_MOX_CPU_ID_SD    = 0x10,
+};
+
+enum turris_mox_module_id {
+       TURRIS_MOX_MODULE_FIRST         = 0x01,
+
+       TURRIS_MOX_MODULE_SFP           = 0x01,
+       TURRIS_MOX_MODULE_PCI           = 0x02,
+       TURRIS_MOX_MODULE_TOPAZ         = 0x03,
+       TURRIS_MOX_MODULE_PERIDOT       = 0x04,
+       TURRIS_MOX_MODULE_USB3          = 0x05,
+       TURRIS_MOX_MODULE_PCI_BRIDGE    = 0x06,
+
+       TURRIS_MOX_MODULE_LAST          = 0x06,
+};
+
+#define MOXTET_NIRQS   16
+
+extern struct bus_type moxtet_type;
+
+struct moxtet {
+       struct device                   *dev;
+       struct mutex                    lock;
+       u8                              modules[TURRIS_MOX_MAX_MODULES];
+       int                             count;
+       u8                              tx[TURRIS_MOX_MAX_MODULES];
+       int                             dev_irq;
+       struct {
+               struct irq_domain       *domain;
+               struct irq_chip         chip;
+               unsigned long           masked, exists;
+               struct moxtet_irqpos {
+                                       u8 idx;
+                                       u8 bit;
+               } position[MOXTET_NIRQS];
+       } irq;
+#ifdef CONFIG_DEBUG_FS
+       struct dentry                   *debugfs_root;
+#endif
+};
+
+struct moxtet_driver {
+       const enum turris_mox_module_id *id_table;
+       struct device_driver            driver;
+};
+
+static inline struct moxtet_driver *
+to_moxtet_driver(struct device_driver *drv)
+{
+       if (!drv)
+               return NULL;
+       return container_of(drv, struct moxtet_driver, driver);
+}
+
+extern int __moxtet_register_driver(struct module *owner,
+                                   struct moxtet_driver *mdrv);
+
+static inline void moxtet_unregister_driver(struct moxtet_driver *mdrv)
+{
+       if (mdrv)
+               driver_unregister(&mdrv->driver);
+}
+
+#define moxtet_register_driver(driver) \
+       __moxtet_register_driver(THIS_MODULE, driver)
+
+#define module_moxtet_driver(__moxtet_driver) \
+       module_driver(__moxtet_driver, moxtet_register_driver, \
+                       moxtet_unregister_driver)
+
+struct moxtet_device {
+       struct device                   dev;
+       struct moxtet                   *moxtet;
+       enum turris_mox_module_id       id;
+       unsigned int                    idx;
+};
+
+extern int moxtet_device_read(struct device *dev);
+extern int moxtet_device_write(struct device *dev, u8 val);
+extern int moxtet_device_written(struct device *dev);
+
+static inline struct moxtet_device *
+to_moxtet_device(struct device *dev)
+{
+       if (!dev)
+               return NULL;
+       return container_of(dev, struct moxtet_device, dev);
+}
+
+#endif /* __LINUX_MOXTET_H */
index 7a6871a..74c6f92 100644 (file)
@@ -4,6 +4,9 @@
  * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
  */
 
+#ifndef _NF_CONNTRACK_H323_TYPES_H
+#define _NF_CONNTRACK_H323_TYPES_H
+
 typedef struct TransportAddress_ipAddress {    /* SEQUENCE */
        int options;            /* No use */
        unsigned int ip;
@@ -931,3 +934,5 @@ typedef struct RasMessage { /* CHOICE */
                InfoRequestResponse infoRequestResponse;
        };
 } RasMessage;
+
+#endif /* _NF_CONNTRACK_H323_TYPES_H */
index f9737de..1696739 100644 (file)
@@ -61,10 +61,6 @@ static inline int of_mm_gpiochip_add(struct device_node *np,
 }
 extern void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc);
 
-extern int of_gpio_simple_xlate(struct gpio_chip *gc,
-                               const struct of_phandle_args *gpiospec,
-                               u32 *flags);
-
 #else /* CONFIG_OF_GPIO */
 
 /* Drivers may not strictly depend on the GPIO support, so let them link. */
@@ -77,13 +73,6 @@ static inline int of_get_named_gpio_flags(struct device_node *np,
        return -ENOSYS;
 }
 
-static inline int of_gpio_simple_xlate(struct gpio_chip *gc,
-                                      const struct of_phandle_args *gpiospec,
-                                      u32 *flags)
-{
-       return -ENOSYS;
-}
-
 #endif /* CONFIG_OF_GPIO */
 
 /**
index 153bf25..2c32ca0 100644 (file)
 #ifndef _OMAP_IOMMU_H_
 #define _OMAP_IOMMU_H_
 
+struct iommu_domain;
+
 #ifdef CONFIG_OMAP_IOMMU
 extern void omap_iommu_save_ctx(struct device *dev);
 extern void omap_iommu_restore_ctx(struct device *dev);
+
+int omap_iommu_domain_deactivate(struct iommu_domain *domain);
+int omap_iommu_domain_activate(struct iommu_domain *domain);
 #else
 static inline void omap_iommu_save_ctx(struct device *dev) {}
 static inline void omap_iommu_restore_ctx(struct device *dev) {}
+
+static inline int omap_iommu_domain_deactivate(struct iommu_domain *domain)
+{
+       return -ENODEV;
+}
+
+static inline int omap_iommu_domain_activate(struct iommu_domain *domain)
+{
+       return -ENODEV;
+}
 #endif
 
 #endif
index c842735..24486f4 100644 (file)
 #define PCI_DEVICE_ID_AMD_17H_DF_F3    0x1463
 #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 0x15eb
 #define PCI_DEVICE_ID_AMD_17H_M30H_DF_F3 0x1493
+#define PCI_DEVICE_ID_AMD_17H_M70H_DF_F3 0x1443
 #define PCI_DEVICE_ID_AMD_CNB17H_F3    0x1703
 #define PCI_DEVICE_ID_AMD_LANCE                0x2000
 #define PCI_DEVICE_ID_AMD_LANCE_HOME   0x2001
 #define PCI_VENDOR_ID_SGI              0x10a9
 #define PCI_DEVICE_ID_SGI_IOC3         0x0003
 #define PCI_DEVICE_ID_SGI_LITHIUM      0x1002
-#define PCI_DEVICE_ID_SGI_IOC4         0x100a
 
 #define PCI_VENDOR_ID_WINBOND          0x10ad
 #define PCI_DEVICE_ID_WINBOND_82C105   0x0105
index 462b90b..2fb9c8f 100644 (file)
@@ -1107,6 +1107,7 @@ int genphy_c45_an_disable_aneg(struct phy_device *phydev);
 int genphy_c45_read_mdix(struct phy_device *phydev);
 int genphy_c45_pma_read_abilities(struct phy_device *phydev);
 int genphy_c45_read_status(struct phy_device *phydev);
+int genphy_c45_config_aneg(struct phy_device *phydev);
 
 /* The gen10g_* functions are the old Clause 45 stub */
 int gen10g_config_aneg(struct phy_device *phydev);
index 1e5d86e..52bc8e4 100644 (file)
@@ -11,6 +11,7 @@ struct fixed_phy_status {
 };
 
 struct device_node;
+struct gpio_desc;
 
 #if IS_ENABLED(CONFIG_FIXED_PHY)
 extern int fixed_phy_change_carrier(struct net_device *dev, bool new_carrier);
index 2a83e43..9645b11 100644 (file)
@@ -72,6 +72,10 @@ extern struct pid init_struct_pid;
 
 extern const struct file_operations pidfd_fops;
 
+struct file;
+
+extern struct pid *pidfd_pid(const struct file *file);
+
 static inline struct pid *get_pid(struct pid *pid)
 {
        if (pid)
similarity index 98%
rename from arch/arm/include/asm/hardware/iop_adma.h
rename to include/linux/platform_data/dma-iop32x.h
index bcedbab..ac83cff 100644 (file)
 #endif
 #define iop_paranoia(x) BUG_ON(IOP_PARANOIA && (x))
 
+#define DMA0_ID 0
+#define DMA1_ID 1
+#define AAU_ID 2
+
 /**
  * struct iop_adma_device - internal representation of an ADMA device
  * @pdev: Platform device
index 9a3e780..eaefba0 100644 (file)
@@ -50,7 +50,4 @@ struct htc_egpio_platform_data {
        int                   num_chips;
 };
 
-/* Determine the wakeup irq, to be called during early resume */
-extern int htc_egpio_get_wakeup_irq(struct device *dev);
-
 #endif
index 44d913a..8474a02 100644 (file)
@@ -13,4 +13,8 @@ struct iommu_platform_data {
        const char *reset_name;
        int (*assert_reset)(struct platform_device *pdev, const char *name);
        int (*deassert_reset)(struct platform_device *pdev, const char *name);
+       int (*device_enable)(struct platform_device *pdev);
+       int (*device_idle)(struct platform_device *pdev);
+       int (*set_pwrdm_constraint)(struct platform_device *pdev, bool request,
+                                   u8 *pwrst);
 };
diff --git a/include/linux/platform_data/spi-nuc900.h b/include/linux/platform_data/spi-nuc900.h
deleted file mode 100644 (file)
index ca35108..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (c) 2009 Nuvoton technology corporation.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- */
-
-#ifndef __SPI_NUC900_H
-#define __SPI_NUC900_H
-
-extern void mfp_set_groupg(struct device *dev, const char *subname);
-
-struct nuc900_spi_info {
-       unsigned int num_cs;
-       unsigned int lsb;
-       unsigned int txneg;
-       unsigned int rxneg;
-       unsigned int divider;
-       unsigned int sleep;
-       unsigned int txnum;
-       unsigned int txbitlen;
-       int bus_num;
-};
-
-struct nuc900_spi_chip {
-       unsigned char bits_per_word;
-};
-
-#endif /* __SPI_NUC900_H */
diff --git a/include/linux/platform_data/video-nuc900fb.h b/include/linux/platform_data/video-nuc900fb.h
deleted file mode 100644 (file)
index 3da5044..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/* linux/include/asm/arch-nuc900/fb.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
- *
- * Changelog:
- *
- *   2008/08/26     vincen.zswan modify this file for LCD.
- */
-
-#ifndef __ASM_ARM_FB_H
-#define __ASM_ARM_FB_H
-
-
-
-/* LCD Controller Hardware Desc */
-struct nuc900fb_hw {
-       unsigned int lcd_dccs;
-       unsigned int lcd_device_ctrl;
-       unsigned int lcd_mpulcd_cmd;
-       unsigned int lcd_int_cs;
-       unsigned int lcd_crtc_size;
-       unsigned int lcd_crtc_dend;
-       unsigned int lcd_crtc_hr;
-       unsigned int lcd_crtc_hsync;
-       unsigned int lcd_crtc_vr;
-       unsigned int lcd_va_baddr0;
-       unsigned int lcd_va_baddr1;
-       unsigned int lcd_va_fbctrl;
-       unsigned int lcd_va_scale;
-       unsigned int lcd_va_test;
-       unsigned int lcd_va_win;
-       unsigned int lcd_va_stuff;
-};
-
-/* LCD Display Description */
-struct nuc900fb_display {
-       /* LCD Image type */
-       unsigned type;
-
-       /* LCD Screen Size */
-       unsigned short width;
-       unsigned short height;
-
-       /* LCD Screen Info */
-       unsigned short xres;
-       unsigned short yres;
-       unsigned short bpp;
-
-       unsigned long pixclock;
-       unsigned short left_margin;
-       unsigned short right_margin;
-       unsigned short hsync_len;
-       unsigned short upper_margin;
-       unsigned short lower_margin;
-       unsigned short vsync_len;
-
-       /* hardware special register value */
-       unsigned int dccs;
-       unsigned int devctl;
-       unsigned int fbctrl;
-       unsigned int scale;
-};
-
-struct nuc900fb_mach_info {
-       struct nuc900fb_display *displays;
-       unsigned num_displays;
-       unsigned default_display;
-       /* GPIO Setting  Info */
-       unsigned gpio_dir;
-       unsigned gpio_dir_mask;
-       unsigned gpio_data;
-       unsigned gpio_data_mask;
-};
-
-extern void __init nuc900_fb_set_platdata(struct nuc900fb_mach_info *);
-
-#endif /* __ASM_ARM_FB_H */
index a8a1561..e2bacc6 100644 (file)
@@ -15,8 +15,8 @@
 
 bool psci_tos_resident_on(int cpu);
 
-int psci_cpu_init_idle(unsigned int cpu);
-int psci_cpu_suspend_enter(unsigned long index);
+int psci_cpu_suspend_enter(u32 state);
+bool psci_power_state_is_valid(u32 state);
 
 enum psci_conduit {
        PSCI_CONDUIT_NONE,
index 3f12cc7..2d5eff5 100644 (file)
@@ -49,8 +49,9 @@ extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
 extern int qcom_scm_pas_auth_and_reset(u32 peripheral);
 extern int qcom_scm_pas_shutdown(u32 peripheral);
 extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
-                              unsigned int *src, struct qcom_scm_vmperm *newvm,
-                              int dest_cnt);
+                              unsigned int *src,
+                              const struct qcom_scm_vmperm *newvm,
+                              unsigned int dest_cnt);
 extern void qcom_scm_cpu_power_down(u32 flags);
 extern u32 qcom_scm_get_version(void);
 extern int qcom_scm_set_remote_state(u32 state, u32 id);
@@ -87,8 +88,8 @@ qcom_scm_pas_auth_and_reset(u32 peripheral) { return -ENODEV; }
 static inline int qcom_scm_pas_shutdown(u32 peripheral) { return -ENODEV; }
 static inline int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
                                      unsigned int *src,
-                                     struct qcom_scm_vmperm *newvm,
-                                     int dest_cnt) { return -ENODEV; }
+                                     const struct qcom_scm_vmperm *newvm,
+                                     unsigned int dest_cnt) { return -ENODEV; }
 static inline void qcom_scm_cpu_power_down(u32 flags) {}
 static inline u32 qcom_scm_get_version(void) { return 0; }
 static inline u32
index 1f7dced..f189c92 100644 (file)
@@ -19,6 +19,7 @@ struct random_ready_callback {
 };
 
 extern void add_device_randomness(const void *, unsigned int);
+extern void add_bootloader_randomness(const void *, unsigned int);
 
 #if defined(LATENT_ENTROPY_PLUGIN) && !defined(__CHECKER__)
 static inline void add_latent_entropy(void)
index 8159834..337a463 100644 (file)
@@ -281,6 +281,12 @@ void devm_regulator_unregister_notifier(struct regulator *regulator,
 void *regulator_get_drvdata(struct regulator *regulator);
 void regulator_set_drvdata(struct regulator *regulator, void *data);
 
+/* misc helpers */
+
+void regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
+                                    const char *const *supply_names,
+                                    unsigned int num_supplies);
+
 #else
 
 /*
@@ -580,6 +586,13 @@ static inline int regulator_list_voltage(struct regulator *regulator, unsigned s
        return -EINVAL;
 }
 
+static inline void
+regulator_bulk_set_supply_names(struct regulator_bulk_data *consumers,
+                               const char *const *supply_names,
+                               unsigned int num_supplies)
+{
+}
+
 #endif
 
 static inline int regulator_set_voltage_triplet(struct regulator *regulator,
diff --git a/include/linux/regulator/mt6358-regulator.h b/include/linux/regulator/mt6358-regulator.h
new file mode 100644 (file)
index 0000000..1cc3049
--- /dev/null
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef __LINUX_REGULATOR_MT6358_H
+#define __LINUX_REGULATOR_MT6358_H
+
+enum {
+       MT6358_ID_VDRAM1 = 0,
+       MT6358_ID_VCORE,
+       MT6358_ID_VPA,
+       MT6358_ID_VPROC11,
+       MT6358_ID_VPROC12,
+       MT6358_ID_VGPU,
+       MT6358_ID_VS2,
+       MT6358_ID_VMODEM,
+       MT6358_ID_VS1,
+       MT6358_ID_VDRAM2 = 9,
+       MT6358_ID_VSIM1,
+       MT6358_ID_VIBR,
+       MT6358_ID_VRF12,
+       MT6358_ID_VIO18,
+       MT6358_ID_VUSB,
+       MT6358_ID_VCAMIO,
+       MT6358_ID_VCAMD,
+       MT6358_ID_VCN18,
+       MT6358_ID_VFE28,
+       MT6358_ID_VSRAM_PROC11,
+       MT6358_ID_VCN28,
+       MT6358_ID_VSRAM_OTHERS,
+       MT6358_ID_VSRAM_GPU,
+       MT6358_ID_VXO22,
+       MT6358_ID_VEFUSE,
+       MT6358_ID_VAUX18,
+       MT6358_ID_VMCH,
+       MT6358_ID_VBIF28,
+       MT6358_ID_VSRAM_PROC12,
+       MT6358_ID_VCAMA1,
+       MT6358_ID_VEMC,
+       MT6358_ID_VIO28,
+       MT6358_ID_VA12,
+       MT6358_ID_VRF18,
+       MT6358_ID_VCN33_BT,
+       MT6358_ID_VCN33_WIFI,
+       MT6358_ID_VCAMA2,
+       MT6358_ID_VMC,
+       MT6358_ID_VLDO28,
+       MT6358_ID_VAUD28,
+       MT6358_ID_VSIM2,
+       MT6358_ID_RG_MAX,
+};
+
+#define MT6358_MAX_REGULATOR   MT6358_ID_RG_MAX
+
+#endif /* __LINUX_REGULATOR_MT6358_H */
index 9ff2e93..881fea4 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0
+/* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * SCMI Message Protocol driver header
  *
@@ -71,7 +71,7 @@ struct scmi_clk_ops {
        int (*rate_get)(const struct scmi_handle *handle, u32 clk_id,
                        u64 *rate);
        int (*rate_set)(const struct scmi_handle *handle, u32 clk_id,
-                       u32 config, u64 rate);
+                       u64 rate);
        int (*enable)(const struct scmi_handle *handle, u32 clk_id);
        int (*disable)(const struct scmi_handle *handle, u32 clk_id);
 };
@@ -145,6 +145,8 @@ struct scmi_sensor_info {
        u32 id;
        u8 type;
        s8 scale;
+       u8 num_trip_points;
+       bool async;
        char name[SCMI_MAX_STR_SIZE];
 };
 
@@ -167,9 +169,9 @@ enum scmi_sensor_class {
  *
  * @count_get: get the count of sensors provided by SCMI
  * @info_get: get the information of the specified sensor
- * @configuration_set: control notifications on cross-over events for
+ * @trip_point_notify: control notifications on cross-over events for
  *     the trip-points
- * @trip_point_set: selects and configures a trip-point of interest
+ * @trip_point_config: selects and configures a trip-point of interest
  * @reading_get: gets the current value of the sensor
  */
 struct scmi_sensor_ops {
@@ -177,12 +179,32 @@ struct scmi_sensor_ops {
 
        const struct scmi_sensor_info *(*info_get)
                (const struct scmi_handle *handle, u32 sensor_id);
-       int (*configuration_set)(const struct scmi_handle *handle,
-                                u32 sensor_id);
-       int (*trip_point_set)(const struct scmi_handle *handle, u32 sensor_id,
-                             u8 trip_id, u64 trip_value);
+       int (*trip_point_notify)(const struct scmi_handle *handle,
+                                u32 sensor_id, bool enable);
+       int (*trip_point_config)(const struct scmi_handle *handle,
+                                u32 sensor_id, u8 trip_id, u64 trip_value);
        int (*reading_get)(const struct scmi_handle *handle, u32 sensor_id,
-                          bool async, u64 *value);
+                          u64 *value);
+};
+
+/**
+ * struct scmi_reset_ops - represents the various operations provided
+ *     by SCMI Reset Protocol
+ *
+ * @num_domains_get: get the count of reset domains provided by SCMI
+ * @name_get: gets the name of a reset domain
+ * @latency_get: gets the reset latency for the specified reset domain
+ * @reset: resets the specified reset domain
+ * @assert: explicitly assert reset signal of the specified reset domain
+ * @deassert: explicitly deassert reset signal of the specified reset domain
+ */
+struct scmi_reset_ops {
+       int (*num_domains_get)(const struct scmi_handle *handle);
+       char *(*name_get)(const struct scmi_handle *handle, u32 domain);
+       int (*latency_get)(const struct scmi_handle *handle, u32 domain);
+       int (*reset)(const struct scmi_handle *handle, u32 domain);
+       int (*assert)(const struct scmi_handle *handle, u32 domain);
+       int (*deassert)(const struct scmi_handle *handle, u32 domain);
 };
 
 /**
@@ -194,6 +216,7 @@ struct scmi_sensor_ops {
  * @perf_ops: pointer to set of performance protocol operations
  * @clk_ops: pointer to set of clock protocol operations
  * @sensor_ops: pointer to set of sensor protocol operations
+ * @reset_ops: pointer to set of reset protocol operations
  * @perf_priv: pointer to private data structure specific to performance
  *     protocol(for internal use only)
  * @clk_priv: pointer to private data structure specific to clock
@@ -202,6 +225,8 @@ struct scmi_sensor_ops {
  *     protocol(for internal use only)
  * @sensor_priv: pointer to private data structure specific to sensors
  *     protocol(for internal use only)
+ * @reset_priv: pointer to private data structure specific to reset
+ *     protocol(for internal use only)
  */
 struct scmi_handle {
        struct device *dev;
@@ -210,11 +235,13 @@ struct scmi_handle {
        struct scmi_clk_ops *clk_ops;
        struct scmi_power_ops *power_ops;
        struct scmi_sensor_ops *sensor_ops;
+       struct scmi_reset_ops *reset_ops;
        /* for protocol internal use */
        void *perf_priv;
        void *clk_priv;
        void *power_priv;
        void *sensor_priv;
+       void *reset_priv;
 };
 
 enum scmi_std_protocol {
@@ -224,6 +251,7 @@ enum scmi_std_protocol {
        SCMI_PROTOCOL_PERF = 0x13,
        SCMI_PROTOCOL_CLOCK = 0x14,
        SCMI_PROTOCOL_SENSOR = 0x15,
+       SCMI_PROTOCOL_RESET = 0x16,
 };
 
 struct scmi_device {
index 54ade13..f3ae45d 100644 (file)
@@ -63,26 +63,26 @@ void cmdq_pkt_destroy(struct cmdq_pkt *pkt);
 /**
  * cmdq_pkt_write() - append write command to the CMDQ packet
  * @pkt:       the CMDQ packet
- * @value:     the specified target register value
  * @subsys:    the CMDQ sub system code
  * @offset:    register offset from CMDQ sub system
+ * @value:     the specified target register value
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_write(struct cmdq_pkt *pkt, u32 value, u32 subsys, u32 offset);
+int cmdq_pkt_write(struct cmdq_pkt *pkt, u8 subsys, u16 offset, u32 value);
 
 /**
  * cmdq_pkt_write_mask() - append write command with mask to the CMDQ packet
  * @pkt:       the CMDQ packet
- * @value:     the specified target register value
  * @subsys:    the CMDQ sub system code
  * @offset:    register offset from CMDQ sub system
+ * @value:     the specified target register value
  * @mask:      the specified target register mask
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
-                       u32 subsys, u32 offset, u32 mask);
+int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u8 subsys,
+                       u16 offset, u32 value, u32 mask);
 
 /**
  * cmdq_pkt_wfe() - append wait for event command to the CMDQ packet
@@ -91,7 +91,7 @@ int cmdq_pkt_write_mask(struct cmdq_pkt *pkt, u32 value,
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event);
+int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u16 event);
 
 /**
  * cmdq_pkt_clear_event() - append clear event command to the CMDQ packet
@@ -100,7 +100,7 @@ int cmdq_pkt_wfe(struct cmdq_pkt *pkt, u32 event);
  *
  * Return: 0 for success; else the error code is returned
  */
-int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u32 event);
+int cmdq_pkt_clear_event(struct cmdq_pkt *pkt, u16 event);
 
 /**
  * cmdq_pkt_flush_async() - trigger CMDQ to asynchronously execute the CMDQ
diff --git a/include/linux/soc/nxp/lpc32xx-misc.h b/include/linux/soc/nxp/lpc32xx-misc.h
new file mode 100644 (file)
index 0000000..699c6f1
--- /dev/null
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Author: Kevin Wells <kevin.wells@nxp.com>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ */
+
+#ifndef __SOC_LPC32XX_MISC_H
+#define __SOC_LPC32XX_MISC_H
+
+#include <linux/types.h>
+#include <linux/phy.h>
+
+#ifdef CONFIG_ARCH_LPC32XX
+extern u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr);
+extern void lpc32xx_set_phy_interface_mode(phy_interface_t mode);
+extern void lpc32xx_loopback_set(resource_size_t mapbase, int state);
+#else
+static inline u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr)
+{
+       *mapbase = NULL;
+       *dmaaddr = 0;
+       return 0;
+}
+static inline void lpc32xx_set_phy_interface_mode(phy_interface_t mode)
+{
+}
+static inline void lpc32xx_loopback_set(resource_size_t mapbase, int state)
+{
+}
+#endif
+
+#endif  /* __SOC_LPC32XX_MISC_H */
diff --git a/include/linux/soc/samsung/exynos-chipid.h b/include/linux/soc/samsung/exynos-chipid.h
new file mode 100644 (file)
index 0000000..8bca676
--- /dev/null
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ *           http://www.samsung.com/
+ *
+ * Exynos - CHIPID support
+ */
+#ifndef __LINUX_SOC_EXYNOS_CHIPID_H
+#define __LINUX_SOC_EXYNOS_CHIPID_H
+
+#define EXYNOS_CHIPID_REG_PRO_ID       0x00
+#define EXYNOS_SUBREV_MASK             (0xf << 4)
+#define EXYNOS_MAINREV_MASK            (0xf << 0)
+#define EXYNOS_REV_MASK                        (EXYNOS_SUBREV_MASK | \
+                                        EXYNOS_MAINREV_MASK)
+#define EXYNOS_MASK                    0xfffff000
+
+#define EXYNOS_CHIPID_REG_PKG_ID       0x04
+/* Bit field definitions for EXYNOS_CHIPID_REG_PKG_ID register */
+#define EXYNOS5422_IDS_OFFSET          24
+#define EXYNOS5422_IDS_MASK            0xff
+#define EXYNOS5422_USESG_OFFSET        3
+#define EXYNOS5422_USESG_MASK          0x01
+#define EXYNOS5422_SG_OFFSET           0
+#define EXYNOS5422_SG_MASK             0x07
+#define EXYNOS5422_TABLE_OFFSET        8
+#define EXYNOS5422_TABLE_MASK          0x03
+#define EXYNOS5422_SG_A_OFFSET         17
+#define EXYNOS5422_SG_A_MASK           0x0f
+#define EXYNOS5422_SG_B_OFFSET         21
+#define EXYNOS5422_SG_B_MASK           0x03
+#define EXYNOS5422_SG_BSIGN_OFFSET     23
+#define EXYNOS5422_SG_BSIGN_MASK       0x01
+#define EXYNOS5422_BIN2_OFFSET         12
+#define EXYNOS5422_BIN2_MASK           0x01
+
+#define EXYNOS_CHIPID_REG_LOT_ID       0x14
+
+#define EXYNOS_CHIPID_REG_AUX_INFO     0x1c
+/* Bit field definitions for EXYNOS_CHIPID_REG_AUX_INFO register */
+#define EXYNOS5422_TMCB_OFFSET         0
+#define EXYNOS5422_TMCB_MASK           0x7f
+#define EXYNOS5422_ARM_UP_OFFSET       8
+#define EXYNOS5422_ARM_UP_MASK         0x03
+#define EXYNOS5422_ARM_DN_OFFSET       10
+#define EXYNOS5422_ARM_DN_MASK         0x03
+#define EXYNOS5422_KFC_UP_OFFSET       12
+#define EXYNOS5422_KFC_UP_MASK         0x03
+#define EXYNOS5422_KFC_DN_OFFSET       14
+#define EXYNOS5422_KFC_DN_MASK         0x03
+
+#endif /*__LINUX_SOC_EXYNOS_CHIPID_H */
index 6c610e1..9531ec8 100644 (file)
@@ -97,7 +97,10 @@ struct ti_sci_core_ops {
  */
 struct ti_sci_dev_ops {
        int (*get_device)(const struct ti_sci_handle *handle, u32 id);
+       int (*get_device_exclusive)(const struct ti_sci_handle *handle, u32 id);
        int (*idle_device)(const struct ti_sci_handle *handle, u32 id);
+       int (*idle_device_exclusive)(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,
index baa3ecd..27536b9 100644 (file)
@@ -98,7 +98,6 @@ typedef void                  (*rpc_action)(struct rpc_task *);
 
 struct rpc_call_ops {
        void (*rpc_call_prepare)(struct rpc_task *, void *);
-       void (*rpc_call_prepare_transmit)(struct rpc_task *, void *);
        void (*rpc_call_done)(struct rpc_task *, void *);
        void (*rpc_count_stats)(struct rpc_task *, void *);
        void (*rpc_release)(void *);
index 361f62b..cde3dc1 100644 (file)
@@ -46,13 +46,17 @@ enum dma_sync_target {
 
 extern phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
                                          dma_addr_t tbl_dma_addr,
-                                         phys_addr_t phys, size_t size,
+                                         phys_addr_t phys,
+                                         size_t mapping_size,
+                                         size_t alloc_size,
                                          enum dma_data_direction dir,
                                          unsigned long attrs);
 
 extern void swiotlb_tbl_unmap_single(struct device *hwdev,
                                     phys_addr_t tlb_addr,
-                                    size_t size, enum dma_data_direction dir,
+                                    size_t mapping_size,
+                                    size_t alloc_size,
+                                    enum dma_data_direction dir,
                                     unsigned long attrs);
 
 extern void swiotlb_tbl_sync_single(struct device *hwdev,
index b7c70c3..48ceea8 100644 (file)
@@ -12,6 +12,7 @@ struct soc_device_attribute {
        const char *machine;
        const char *family;
        const char *revision;
+       const char *serial_number;
        const char *soc_id;
        const void *data;
 };
index 88145da..f7c561c 100644 (file)
@@ -1402,4 +1402,23 @@ static inline unsigned int ksys_personality(unsigned int personality)
        return old;
 }
 
+/* for __ARCH_WANT_SYS_IPC */
+long ksys_semtimedop(int semid, struct sembuf __user *tsops,
+                    unsigned int nsops,
+                    const struct __kernel_timespec __user *timeout);
+long ksys_semget(key_t key, int nsems, int semflg);
+long ksys_old_semctl(int semid, int semnum, int cmd, unsigned long arg);
+long ksys_msgget(key_t key, int msgflg);
+long ksys_old_msgctl(int msqid, int cmd, struct msqid_ds __user *buf);
+long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
+                long msgtyp, int msgflg);
+long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz,
+                int msgflg);
+long ksys_shmget(key_t key, size_t size, int shmflg);
+long ksys_shmdt(char __user *shmaddr);
+long ksys_old_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
+long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems,
+                           unsigned int nsops,
+                           const struct old_timespec32 __user *timeout);
+
 #endif
index 47a3e3c..2a19d19 100644 (file)
@@ -27,6 +27,7 @@
 #ifndef _LINUX_TOPOLOGY_H
 #define _LINUX_TOPOLOGY_H
 
+#include <linux/arch_topology.h>
 #include <linux/cpumask.h>
 #include <linux/bitops.h>
 #include <linux/mmzone.h>
index 5150436..30a8cdc 100644 (file)
@@ -548,6 +548,7 @@ extern int trace_event_get_offsets(struct trace_event_call *call);
 
 #define is_signed_type(type)   (((type)(-1)) < (type)1)
 
+int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set);
 int trace_set_clr_event(const char *system, const char *event, int set);
 
 /*
diff --git a/include/linux/usb/samsung_usb_phy.h b/include/linux/usb/samsung_usb_phy.h
deleted file mode 100644 (file)
index dc00717..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2012 Samsung Electronics Co.Ltd
- *             http://www.samsung.com/
- *
- * Defines phy types for samsung usb phy controllers - HOST or DEIVCE.
- *
- * 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.
- */
-
-enum samsung_usb_phy_type {
-       USB_PHY_TYPE_DEVICE,
-       USB_PHY_TYPE_HOST,
-};
index f37d128..adcc6a9 100644 (file)
@@ -308,6 +308,7 @@ do {                                                                             \
                                                                             \
   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):                          \
     R##_e = X##_e;                                                          \
+         /* Fall through */                                                 \
   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL):                           \
   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):                              \
   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):                                     \
@@ -318,6 +319,7 @@ do {                                                                             \
                                                                             \
   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL):                          \
     R##_e = Y##_e;                                                          \
+         /* Fall through */                                                 \
   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN):                           \
   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):                              \
   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):                                     \
@@ -415,6 +417,7 @@ do {                                                        \
   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF):         \
   case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO):                \
     R##_s = X##_s;                                     \
+       /* Fall through */                              \
                                                        \
   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF):         \
   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):      \
@@ -428,6 +431,7 @@ do {                                                        \
   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN):         \
   case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN):                \
     R##_s = Y##_s;                                     \
+       /* Fall through */                              \
                                                        \
   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF):      \
   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):     \
@@ -493,6 +497,7 @@ do {                                                        \
                                                        \
   case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO):     \
     FP_SET_EXCEPTION(FP_EX_DIVZERO);                   \
+         /* Fall through */                            \
   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO):                \
   case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL):      \
     R##_c = FP_CLS_INF;                                        \
index c61a1bf..3a1a729 100644 (file)
@@ -15,6 +15,7 @@
 struct tcf_idrinfo {
        struct mutex    lock;
        struct idr      action_idr;
+       struct net      *net;
 };
 
 struct tc_action_ops;
@@ -108,7 +109,7 @@ struct tc_action_net {
 };
 
 static inline
-int tc_action_net_init(struct tc_action_net *tn,
+int tc_action_net_init(struct net *net, struct tc_action_net *tn,
                       const struct tc_action_ops *ops)
 {
        int err = 0;
@@ -117,6 +118,7 @@ int tc_action_net_init(struct tc_action_net *tn,
        if (!tn->idrinfo)
                return -ENOMEM;
        tn->ops = ops;
+       tn->idrinfo->net = net;
        mutex_init(&tn->idrinfo->lock);
        idr_init(&tn->idrinfo->action_idr);
        return err;
index becdad5..3f62b34 100644 (file)
@@ -206,7 +206,7 @@ static inline int ipv6_mc_may_pull(struct sk_buff *skb,
                                   unsigned int len)
 {
        if (skb_transport_offset(skb) + ipv6_transport_len(skb) < len)
-               return -EINVAL;
+               return 0;
 
        return pskb_may_pull(skb, len);
 }
index 4c81846..ab1ca9e 100644 (file)
@@ -513,7 +513,7 @@ int ip_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
                          struct netlink_callback *cb);
 
 int fib_nexthop_info(struct sk_buff *skb, const struct fib_nh_common *nh,
-                    unsigned char *flags, bool skip_oif);
+                    u8 rt_family, unsigned char *flags, bool skip_oif);
 int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nh,
-                   int nh_weight);
+                   int nh_weight, u8 rt_family);
 #endif  /* _NET_FIB_H */
index cb668bc..ab40d7a 100644 (file)
@@ -52,7 +52,7 @@ struct bpf_prog;
 #define NETDEV_HASHENTRIES (1 << NETDEV_HASHBITS)
 
 struct net {
-       refcount_t              passive;        /* To decided when the network
+       refcount_t              passive;        /* To decide when the network
                                                 * namespace should be freed.
                                                 */
        refcount_t              count;          /* To decided when the network
index 25f1f9a..331ebbc 100644 (file)
@@ -141,12 +141,6 @@ static inline unsigned int nexthop_num_path(const struct nexthop *nh)
 
                nh_grp = rcu_dereference_rtnl(nh->nh_grp);
                rc = nh_grp->num_nh;
-       } else {
-               const struct nh_info *nhi;
-
-               nhi = rcu_dereference_rtnl(nh->nh_info);
-               if (nhi->reject_nh)
-                       rc = 0;
        }
 
        return rc;
@@ -167,7 +161,8 @@ struct nexthop *nexthop_mpath_select(const struct nexthop *nh, int nhsel)
 }
 
 static inline
-int nexthop_mpath_fill_node(struct sk_buff *skb, struct nexthop *nh)
+int nexthop_mpath_fill_node(struct sk_buff *skb, struct nexthop *nh,
+                           u8 rt_family)
 {
        struct nh_group *nhg = rtnl_dereference(nh->nh_grp);
        int i;
@@ -178,7 +173,7 @@ int nexthop_mpath_fill_node(struct sk_buff *skb, struct nexthop *nh)
                struct fib_nh_common *nhc = &nhi->fib_nhc;
                int weight = nhg->nh_entries[i].weight;
 
-               if (fib_add_nexthop(skb, nhc, weight) < 0)
+               if (fib_add_nexthop(skb, nhc, weight, rt_family) < 0)
                        return -EMSGSIZE;
        }
 
index 37a4df2..6b578ce 100644 (file)
@@ -11,6 +11,7 @@ struct psample_group {
        u32 group_num;
        u32 refcount;
        u32 seq;
+       struct rcu_head rcu;
 };
 
 struct psample_group *psample_group_get(struct net *net, u32 group_num);
index 630a049..dfce19c 100644 (file)
@@ -233,7 +233,7 @@ void rt_del_uncached_list(struct rtable *rt);
 
 int fib_dump_info_fnhe(struct sk_buff *skb, struct netlink_callback *cb,
                       u32 table_id, struct fib_info *fi,
-                      int *fa_index, int fa_start);
+                      int *fa_index, int fa_start, unsigned int flags);
 
 static inline void ip_rt_put(struct rtable *rt)
 {
index b22db30..aa08a7a 100644 (file)
@@ -983,7 +983,6 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
 void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
 
 struct xfrm_if_parms {
-       char name[IFNAMSIZ];    /* name of XFRM device */
        int link;               /* ifindex of underlying L2 interface */
        u32 if_id;              /* interface identifyer */
 };
@@ -991,7 +990,6 @@ struct xfrm_if_parms {
 struct xfrm_if {
        struct xfrm_if __rcu *next;     /* next interface in list */
        struct net_device *dev;         /* virtual device associated with interface */
-       struct net_device *phydev;      /* physical device */
        struct net *net;                /* netns for packet i/o */
        struct xfrm_if_parms p;         /* interface parms */
 
index 50f49e0..d1a93c7 100644 (file)
@@ -46,7 +46,9 @@ struct mcip_cmd {
 #define CMD_IDU_ENABLE                 0x71
 #define CMD_IDU_DISABLE                        0x72
 #define CMD_IDU_SET_MODE               0x74
+#define CMD_IDU_READ_MODE              0x75
 #define CMD_IDU_SET_DEST               0x76
+#define CMD_IDU_ACK_CIRQ               0x79
 #define CMD_IDU_SET_MASK               0x7C
 
 #define IDU_M_TRIG_LEVEL               0x0
@@ -119,4 +121,13 @@ static inline void __mcip_cmd_data(unsigned int cmd, unsigned int param,
        __mcip_cmd(cmd, param);
 }
 
+/*
+ * Read MCIP register
+ */
+static inline unsigned int __mcip_cmd_read(unsigned int cmd, unsigned int param)
+{
+       __mcip_cmd(cmd, param);
+       return read_aux_reg(ARC_REG_MCIP_READBACK);
+}
+
 #endif
index 79b74ce..5a34b87 100644 (file)
@@ -20,11 +20,6 @@ struct mtk_smi_larb_iommu {
        unsigned int   mmu;
 };
 
-struct mtk_smi_iommu {
-       unsigned int larb_nr;
-       struct mtk_smi_larb_iommu larb_imu[MTK_LARB_NR_MAX];
-};
-
 /*
  * mtk_smi_larb_get: Enable the power domain and clocks for this local arbiter.
  *                   It also initialize some basic setting(like iommu).
diff --git a/include/trace/events/intel_iommu.h b/include/trace/events/intel_iommu.h
new file mode 100644 (file)
index 0000000..54e61d4
--- /dev/null
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Intel IOMMU trace support
+ *
+ * Copyright (C) 2019 Intel Corporation
+ *
+ * Author: Lu Baolu <baolu.lu@linux.intel.com>
+ */
+#ifdef CONFIG_INTEL_IOMMU
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM intel_iommu
+
+#if !defined(_TRACE_INTEL_IOMMU_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_INTEL_IOMMU_H
+
+#include <linux/tracepoint.h>
+#include <linux/intel-iommu.h>
+
+DECLARE_EVENT_CLASS(dma_map,
+       TP_PROTO(struct device *dev, dma_addr_t dev_addr, phys_addr_t phys_addr,
+                size_t size),
+
+       TP_ARGS(dev, dev_addr, phys_addr, size),
+
+       TP_STRUCT__entry(
+               __string(dev_name, dev_name(dev))
+               __field(dma_addr_t, dev_addr)
+               __field(phys_addr_t, phys_addr)
+               __field(size_t, size)
+       ),
+
+       TP_fast_assign(
+               __assign_str(dev_name, dev_name(dev));
+               __entry->dev_addr = dev_addr;
+               __entry->phys_addr = phys_addr;
+               __entry->size = size;
+       ),
+
+       TP_printk("dev=%s dev_addr=0x%llx phys_addr=0x%llx size=%zu",
+                 __get_str(dev_name),
+                 (unsigned long long)__entry->dev_addr,
+                 (unsigned long long)__entry->phys_addr,
+                 __entry->size)
+);
+
+DEFINE_EVENT(dma_map, map_single,
+       TP_PROTO(struct device *dev, dma_addr_t dev_addr, phys_addr_t phys_addr,
+                size_t size),
+       TP_ARGS(dev, dev_addr, phys_addr, size)
+);
+
+DEFINE_EVENT(dma_map, map_sg,
+       TP_PROTO(struct device *dev, dma_addr_t dev_addr, phys_addr_t phys_addr,
+                size_t size),
+       TP_ARGS(dev, dev_addr, phys_addr, size)
+);
+
+DEFINE_EVENT(dma_map, bounce_map_single,
+       TP_PROTO(struct device *dev, dma_addr_t dev_addr, phys_addr_t phys_addr,
+                size_t size),
+       TP_ARGS(dev, dev_addr, phys_addr, size)
+);
+
+DECLARE_EVENT_CLASS(dma_unmap,
+       TP_PROTO(struct device *dev, dma_addr_t dev_addr, size_t size),
+
+       TP_ARGS(dev, dev_addr, size),
+
+       TP_STRUCT__entry(
+               __string(dev_name, dev_name(dev))
+               __field(dma_addr_t, dev_addr)
+               __field(size_t, size)
+       ),
+
+       TP_fast_assign(
+               __assign_str(dev_name, dev_name(dev));
+               __entry->dev_addr = dev_addr;
+               __entry->size = size;
+       ),
+
+       TP_printk("dev=%s dev_addr=0x%llx size=%zu",
+                 __get_str(dev_name),
+                 (unsigned long long)__entry->dev_addr,
+                 __entry->size)
+);
+
+DEFINE_EVENT(dma_unmap, unmap_single,
+       TP_PROTO(struct device *dev, dma_addr_t dev_addr, size_t size),
+       TP_ARGS(dev, dev_addr, size)
+);
+
+DEFINE_EVENT(dma_unmap, unmap_sg,
+       TP_PROTO(struct device *dev, dma_addr_t dev_addr, size_t size),
+       TP_ARGS(dev, dev_addr, size)
+);
+
+DEFINE_EVENT(dma_unmap, bounce_unmap_single,
+       TP_PROTO(struct device *dev, dma_addr_t dev_addr, size_t size),
+       TP_ARGS(dev, dev_addr, size)
+);
+
+#endif /* _TRACE_INTEL_IOMMU_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
+#endif /* CONFIG_INTEL_IOMMU */
index fa06b52..a13a62d 100644 (file)
 #define __RXRPC_DECLARE_TRACE_ENUMS_ONCE_ONLY
 
 enum rxrpc_skb_trace {
-       rxrpc_skb_rx_cleaned,
-       rxrpc_skb_rx_freed,
-       rxrpc_skb_rx_got,
-       rxrpc_skb_rx_lost,
-       rxrpc_skb_rx_purged,
-       rxrpc_skb_rx_received,
-       rxrpc_skb_rx_rotated,
-       rxrpc_skb_rx_seen,
-       rxrpc_skb_tx_cleaned,
-       rxrpc_skb_tx_freed,
-       rxrpc_skb_tx_got,
-       rxrpc_skb_tx_new,
-       rxrpc_skb_tx_rotated,
-       rxrpc_skb_tx_seen,
+       rxrpc_skb_cleaned,
+       rxrpc_skb_freed,
+       rxrpc_skb_got,
+       rxrpc_skb_lost,
+       rxrpc_skb_new,
+       rxrpc_skb_purged,
+       rxrpc_skb_received,
+       rxrpc_skb_rotated,
+       rxrpc_skb_seen,
+       rxrpc_skb_unshared,
+       rxrpc_skb_unshared_nomem,
 };
 
 enum rxrpc_local_trace {
@@ -228,20 +225,17 @@ enum rxrpc_tx_point {
  * Declare tracing information enums and their string mappings for display.
  */
 #define rxrpc_skb_traces \
-       EM(rxrpc_skb_rx_cleaned,                "Rx CLN") \
-       EM(rxrpc_skb_rx_freed,                  "Rx FRE") \
-       EM(rxrpc_skb_rx_got,                    "Rx GOT") \
-       EM(rxrpc_skb_rx_lost,                   "Rx *L*") \
-       EM(rxrpc_skb_rx_purged,                 "Rx PUR") \
-       EM(rxrpc_skb_rx_received,               "Rx RCV") \
-       EM(rxrpc_skb_rx_rotated,                "Rx ROT") \
-       EM(rxrpc_skb_rx_seen,                   "Rx SEE") \
-       EM(rxrpc_skb_tx_cleaned,                "Tx CLN") \
-       EM(rxrpc_skb_tx_freed,                  "Tx FRE") \
-       EM(rxrpc_skb_tx_got,                    "Tx GOT") \
-       EM(rxrpc_skb_tx_new,                    "Tx NEW") \
-       EM(rxrpc_skb_tx_rotated,                "Tx ROT") \
-       E_(rxrpc_skb_tx_seen,                   "Tx SEE")
+       EM(rxrpc_skb_cleaned,                   "CLN") \
+       EM(rxrpc_skb_freed,                     "FRE") \
+       EM(rxrpc_skb_got,                       "GOT") \
+       EM(rxrpc_skb_lost,                      "*L*") \
+       EM(rxrpc_skb_new,                       "NEW") \
+       EM(rxrpc_skb_purged,                    "PUR") \
+       EM(rxrpc_skb_received,                  "RCV") \
+       EM(rxrpc_skb_rotated,                   "ROT") \
+       EM(rxrpc_skb_seen,                      "SEE") \
+       EM(rxrpc_skb_unshared,                  "UNS") \
+       E_(rxrpc_skb_unshared_nomem,            "US0")
 
 #define rxrpc_local_traces \
        EM(rxrpc_local_got,                     "GOT") \
@@ -643,13 +637,14 @@ TRACE_EVENT(rxrpc_call,
 
 TRACE_EVENT(rxrpc_skb,
            TP_PROTO(struct sk_buff *skb, enum rxrpc_skb_trace op,
-                    int usage, int mod_count, const void *where),
+                    int usage, int mod_count, u8 flags,    const void *where),
 
-           TP_ARGS(skb, op, usage, mod_count, where),
+           TP_ARGS(skb, op, usage, mod_count, flags, where),
 
            TP_STRUCT__entry(
                    __field(struct sk_buff *,           skb             )
                    __field(enum rxrpc_skb_trace,       op              )
+                   __field(u8,                         flags           )
                    __field(int,                        usage           )
                    __field(int,                        mod_count       )
                    __field(const void *,               where           )
@@ -657,14 +652,16 @@ TRACE_EVENT(rxrpc_skb,
 
            TP_fast_assign(
                    __entry->skb = skb;
+                   __entry->flags = flags;
                    __entry->op = op;
                    __entry->usage = usage;
                    __entry->mod_count = mod_count;
                    __entry->where = where;
                           ),
 
-           TP_printk("s=%p %s u=%d m=%d p=%pSR",
+           TP_printk("s=%p %cx %s u=%d m=%d p=%pSR",
                      __entry->skb,
+                     __entry->flags & RXRPC_SKB_TX_BUFFER ? 'T' : 'R',
                      __print_symbolic(__entry->op, rxrpc_skb_traces),
                      __entry->usage,
                      __entry->mod_count,
index 1be0e79..1fc8faa 100644 (file)
@@ -569,7 +569,7 @@ __SYSCALL(__NR_semget, sys_semget)
 __SC_COMP(__NR_semctl, sys_semctl, compat_sys_semctl)
 #if defined(__ARCH_WANT_TIME32_SYSCALLS) || __BITS_PER_LONG != 32
 #define __NR_semtimedop 192
-__SC_COMP(__NR_semtimedop, sys_semtimedop, sys_semtimedop_time32)
+__SC_3264(__NR_semtimedop, sys_semtimedop_time32, sys_semtimedop)
 #endif
 #define __NR_semop 193
 __SYSCALL(__NR_semop, sys_semop)
index 4941628..5ec88e7 100644 (file)
@@ -16,6 +16,7 @@
 #define CAPI_MSG_BASELEN               8
 #define CAPI_DATA_B3_REQ_LEN           (CAPI_MSG_BASELEN+4+4+2+2+2)
 #define CAPI_DATA_B3_RESP_LEN          (CAPI_MSG_BASELEN+4+2)
+#define CAPI_DISCONNECT_B3_RESP_LEN    (CAPI_MSG_BASELEN+4)
 
 /*----- CAPI commands -----*/
 #define CAPI_ALERT                 0x01
index 6d11286..05669c8 100644 (file)
@@ -31,6 +31,7 @@
 #define KEXEC_ARCH_DEFAULT ( 0 << 16)
 #define KEXEC_ARCH_386     ( 3 << 16)
 #define KEXEC_ARCH_68K     ( 4 << 16)
+#define KEXEC_ARCH_PARISC  (15 << 16)
 #define KEXEC_ARCH_X86_64  (62 << 16)
 #define KEXEC_ARCH_PPC     (20 << 16)
 #define KEXEC_ARCH_PPC64   (21 << 16)
index 5c8a4d7..b5123ab 100644 (file)
@@ -11,4 +11,9 @@ struct xt_nfacct_match_info {
        struct nf_acct  *nfacct;
 };
 
+struct xt_nfacct_match_info_v1 {
+       char            name[NFACCT_NAME_MAX];
+       struct nf_acct  *nfacct __attribute__((aligned(8)));
+};
+
 #endif /* _XT_NFACCT_MATCH_H */
index 094bb03..2e927b3 100644 (file)
@@ -229,4 +229,9 @@ struct prctl_mm_map {
 # define PR_PAC_APDBKEY                        (1UL << 3)
 # define PR_PAC_APGAKEY                        (1UL << 4)
 
+/* Tagged user address controls for arm64 */
+#define PR_SET_TAGGED_ADDR_CTRL                55
+#define PR_GET_TAGGED_ADDR_CTRL                56
+# define PR_TAGGED_ADDR_ENABLE         (1UL << 0)
+
 #endif /* _LINUX_PRCTL_H */
index fd6b5f6..cba368e 100644 (file)
@@ -250,6 +250,7 @@ struct rds_info_rdma_connection {
        __u32           rdma_mr_max;
        __u32           rdma_mr_size;
        __u8            tos;
+       __u8            sl;
        __u32           cache_allocs;
 };
 
@@ -265,6 +266,7 @@ struct rds6_info_rdma_connection {
        __u32           rdma_mr_max;
        __u32           rdma_mr_size;
        __u8            tos;
+       __u8            sl;
        __u32           cache_allocs;
 };
 
index ac49a22..85b809f 100644 (file)
@@ -17,6 +17,7 @@
 #define P_ALL          0
 #define P_PID          1
 #define P_PGID         2
+#define P_PIDFD                3
 
 
 #endif /* _UAPI_LINUX_WAIT_H */
index efed3c3..1d19ae6 100644 (file)
@@ -32,7 +32,6 @@ struct da8xx_lcdc_platform_data {
        const char manu_name[10];
        void *controller_data;
        const char type[25];
-       void (*panel_power_ctrl)(int);
 };
 
 struct lcd_ctrl_config {
index bd7d650..d96127e 100644 (file)
@@ -30,6 +30,9 @@ config CC_CAN_LINK
 config CC_HAS_ASM_GOTO
        def_bool $(success,$(srctree)/scripts/gcc-goto.sh $(CC))
 
+config TOOLS_SUPPORT_RELR
+       def_bool $(success,env "CC=$(CC)" "LD=$(LD)" "NM=$(NM)" "OBJCOPY=$(OBJCOPY)" $(srctree)/scripts/tools-support-relr.sh)
+
 config CC_HAS_WARN_MAYBE_UNINITIALIZED
        def_bool $(cc-option,-Wmaybe-uninitialized)
        help
index 0fcf8e7..5766c61 100644 (file)
@@ -276,29 +276,7 @@ static inline int compat_ipc_parse_version(int *cmd)
        *cmd &= ~IPC_64;
        return version;
 }
-#endif
 
-/* for __ARCH_WANT_SYS_IPC */
-long ksys_semtimedop(int semid, struct sembuf __user *tsops,
-                    unsigned int nsops,
-                    const struct __kernel_timespec __user *timeout);
-long ksys_semget(key_t key, int nsems, int semflg);
-long ksys_old_semctl(int semid, int semnum, int cmd, unsigned long arg);
-long ksys_msgget(key_t key, int msgflg);
-long ksys_old_msgctl(int msqid, int cmd, struct msqid_ds __user *buf);
-long ksys_msgrcv(int msqid, struct msgbuf __user *msgp, size_t msgsz,
-                long msgtyp, int msgflg);
-long ksys_msgsnd(int msqid, struct msgbuf __user *msgp, size_t msgsz,
-                int msgflg);
-long ksys_shmget(key_t key, size_t size, int shmflg);
-long ksys_shmdt(char __user *shmaddr);
-long ksys_old_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
-
-/* for CONFIG_ARCH_WANT_OLD_COMPAT_IPC */
-long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems,
-                           unsigned int nsops,
-                           const struct old_timespec32 __user *timeout);
-#ifdef CONFIG_COMPAT
 long compat_ksys_old_semctl(int semid, int semnum, int cmd, int arg);
 long compat_ksys_old_msgctl(int msqid, int cmd, void __user *uptr);
 long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz,
@@ -306,6 +284,7 @@ long compat_ksys_msgrcv(int msqid, compat_uptr_t msgp, compat_ssize_t msgsz,
 long compat_ksys_msgsnd(int msqid, compat_uptr_t msgp,
                       compat_ssize_t msgsz, int msgflg);
 long compat_ksys_old_shmctl(int shmid, int cmd, void __user *uptr);
-#endif /* CONFIG_COMPAT */
+
+#endif
 
 #endif
index ef0d95a..48c5376 100644 (file)
@@ -64,6 +64,7 @@ obj-$(CONFIG_CRASH_CORE) += crash_core.o
 obj-$(CONFIG_KEXEC_CORE) += kexec_core.o
 obj-$(CONFIG_KEXEC) += kexec.o
 obj-$(CONFIG_KEXEC_FILE) += kexec_file.o
+obj-$(CONFIG_KEXEC_ELF) += kexec_elf.o
 obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o
 obj-$(CONFIG_COMPAT) += compat.o
 obj-$(CONFIG_CGROUPS) += cgroup/
index 8191a7d..66088a9 100644 (file)
@@ -890,7 +890,8 @@ int bpf_jit_get_func_addr(const struct bpf_prog *prog,
 
 static int bpf_jit_blind_insn(const struct bpf_insn *from,
                              const struct bpf_insn *aux,
-                             struct bpf_insn *to_buff)
+                             struct bpf_insn *to_buff,
+                             bool emit_zext)
 {
        struct bpf_insn *to = to_buff;
        u32 imm_rnd = get_random_int();
@@ -1005,6 +1006,8 @@ static int bpf_jit_blind_insn(const struct bpf_insn *from,
        case 0: /* Part 2 of BPF_LD | BPF_IMM | BPF_DW. */
                *to++ = BPF_ALU32_IMM(BPF_MOV, BPF_REG_AX, imm_rnd ^ aux[0].imm);
                *to++ = BPF_ALU32_IMM(BPF_XOR, BPF_REG_AX, imm_rnd);
+               if (emit_zext)
+                       *to++ = BPF_ZEXT_REG(BPF_REG_AX);
                *to++ = BPF_ALU64_REG(BPF_OR,  aux[0].dst_reg, BPF_REG_AX);
                break;
 
@@ -1088,7 +1091,8 @@ struct bpf_prog *bpf_jit_blind_constants(struct bpf_prog *prog)
                    insn[1].code == 0)
                        memcpy(aux, insn, sizeof(aux));
 
-               rewritten = bpf_jit_blind_insn(insn, aux, insn_buff);
+               rewritten = bpf_jit_blind_insn(insn, aux, insn_buff,
+                                               clone->aux->verifier_zext);
                if (!rewritten)
                        continue;
 
index 5d141f1..272071e 100644 (file)
@@ -1707,20 +1707,26 @@ static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr)
        if (err)
                goto free_used_maps;
 
-       err = bpf_prog_new_fd(prog);
-       if (err < 0) {
-               /* failed to allocate fd.
-                * bpf_prog_put() is needed because the above
-                * bpf_prog_alloc_id() has published the prog
-                * to the userspace and the userspace may
-                * have refcnt-ed it through BPF_PROG_GET_FD_BY_ID.
-                */
-               bpf_prog_put(prog);
-               return err;
-       }
-
+       /* Upon success of bpf_prog_alloc_id(), the BPF prog is
+        * effectively publicly exposed. However, retrieving via
+        * bpf_prog_get_fd_by_id() will take another reference,
+        * therefore it cannot be gone underneath us.
+        *
+        * Only for the time /after/ successful bpf_prog_new_fd()
+        * and before returning to userspace, we might just hold
+        * one reference and any parallel close on that fd could
+        * rip everything out. Hence, below notifications must
+        * happen before bpf_prog_new_fd().
+        *
+        * Also, any failure handling from this point onwards must
+        * be using bpf_prog_put() given the program is exposed.
+        */
        bpf_prog_kallsyms_add(prog);
        perf_event_bpf_event(prog, PERF_BPF_EVENT_PROG_LOAD, 0);
+
+       err = bpf_prog_new_fd(prog);
+       if (err < 0)
+               bpf_prog_put(prog);
        return err;
 
 free_used_maps:
index c84d83f..c36a719 100644 (file)
@@ -985,9 +985,6 @@ static void __mark_reg_unbounded(struct bpf_reg_state *reg)
        reg->smax_value = S64_MAX;
        reg->umin_value = 0;
        reg->umax_value = U64_MAX;
-
-       /* constant backtracking is enabled for root only for now */
-       reg->precise = capable(CAP_SYS_ADMIN) ? false : true;
 }
 
 /* Mark a register as having a completely unknown (scalar) value. */
@@ -1014,7 +1011,11 @@ static void mark_reg_unknown(struct bpf_verifier_env *env,
                        __mark_reg_not_init(regs + regno);
                return;
        }
-       __mark_reg_unknown(regs + regno);
+       regs += regno;
+       __mark_reg_unknown(regs);
+       /* constant backtracking is enabled for root without bpf2bpf calls */
+       regs->precise = env->subprog_cnt > 1 || !env->allow_ptr_leaks ?
+                       true : false;
 }
 
 static void __mark_reg_not_init(struct bpf_reg_state *reg)
@@ -1771,16 +1772,21 @@ static int __mark_chain_precision(struct bpf_verifier_env *env, int regno,
                bitmap_from_u64(mask, stack_mask);
                for_each_set_bit(i, mask, 64) {
                        if (i >= func->allocated_stack / BPF_REG_SIZE) {
-                               /* This can happen if backtracking
-                                * is propagating stack precision where
-                                * caller has larger stack frame
-                                * than callee, but backtrack_insn() should
-                                * have returned -ENOTSUPP.
+                               /* the sequence of instructions:
+                                * 2: (bf) r3 = r10
+                                * 3: (7b) *(u64 *)(r3 -8) = r0
+                                * 4: (79) r4 = *(u64 *)(r10 -8)
+                                * doesn't contain jmps. It's backtracked
+                                * as a single block.
+                                * During backtracking insn 3 is not recognized as
+                                * stack access, so at the end of backtracking
+                                * stack slot fp-8 is still marked in stack_mask.
+                                * However the parent state may not have accessed
+                                * fp-8 and it's "unallocated" stack space.
+                                * In such case fallback to conservative.
                                 */
-                               verbose(env, "BUG spi %d stack_size %d\n",
-                                       i, func->allocated_stack);
-                               WARN_ONCE(1, "verifier backtracking bug");
-                               return -EFAULT;
+                               mark_all_scalars_precise(env, st);
+                               return 0;
                        }
 
                        if (func->stack[i].slot_type[0] != STACK_SPILL) {
index 753afbc..8be1da1 100644 (file)
@@ -5255,8 +5255,16 @@ static struct cgroup *cgroup_create(struct cgroup *parent)
         * if the parent has to be frozen, the child has too.
         */
        cgrp->freezer.e_freeze = parent->freezer.e_freeze;
-       if (cgrp->freezer.e_freeze)
+       if (cgrp->freezer.e_freeze) {
+               /*
+                * Set the CGRP_FREEZE flag, so when a process will be
+                * attached to the child cgroup, it will become frozen.
+                * At this point the new cgroup is unpopulated, so we can
+                * consider it frozen immediately.
+                */
+               set_bit(CGRP_FREEZE, &cgrp->flags);
                set_bit(CGRP_FROZEN, &cgrp->flags);
+       }
 
        spin_lock_irq(&css_set_lock);
        for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) {
index 706113c..8402b29 100644 (file)
@@ -305,7 +305,7 @@ void dma_direct_unmap_page(struct device *dev, dma_addr_t addr,
                dma_direct_sync_single_for_cpu(dev, addr, size, dir);
 
        if (unlikely(is_swiotlb_buffer(phys)))
-               swiotlb_tbl_unmap_single(dev, phys, size, dir, attrs);
+               swiotlb_tbl_unmap_single(dev, phys, size, size, dir, attrs);
 }
 EXPORT_SYMBOL(dma_direct_unmap_page);
 
index 9de2322..796a44f 100644 (file)
@@ -444,7 +444,9 @@ static void swiotlb_bounce(phys_addr_t orig_addr, phys_addr_t tlb_addr,
 
 phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
                                   dma_addr_t tbl_dma_addr,
-                                  phys_addr_t orig_addr, size_t size,
+                                  phys_addr_t orig_addr,
+                                  size_t mapping_size,
+                                  size_t alloc_size,
                                   enum dma_data_direction dir,
                                   unsigned long attrs)
 {
@@ -464,6 +466,12 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
                pr_warn_once("%s is active and system is using DMA bounce buffers\n",
                             sme_active() ? "SME" : "SEV");
 
+       if (mapping_size > alloc_size) {
+               dev_warn_once(hwdev, "Invalid sizes (mapping: %zd bytes, alloc: %zd bytes)",
+                             mapping_size, alloc_size);
+               return (phys_addr_t)DMA_MAPPING_ERROR;
+       }
+
        mask = dma_get_seg_boundary(hwdev);
 
        tbl_dma_addr &= mask;
@@ -471,8 +479,8 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
        offset_slots = ALIGN(tbl_dma_addr, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
 
        /*
-        * Carefully handle integer overflow which can occur when mask == ~0UL.
-        */
+        * Carefully handle integer overflow which can occur when mask == ~0UL.
+        */
        max_slots = mask + 1
                    ? ALIGN(mask + 1, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT
                    : 1UL << (BITS_PER_LONG - IO_TLB_SHIFT);
@@ -481,8 +489,8 @@ phys_addr_t swiotlb_tbl_map_single(struct device *hwdev,
         * For mappings greater than or equal to a page, we limit the stride
         * (and hence alignment) to a page size.
         */
-       nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
-       if (size >= PAGE_SIZE)
+       nslots = ALIGN(alloc_size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
+       if (alloc_size >= PAGE_SIZE)
                stride = (1 << (PAGE_SHIFT - IO_TLB_SHIFT));
        else
                stride = 1;
@@ -547,7 +555,7 @@ not_found:
        spin_unlock_irqrestore(&io_tlb_lock, flags);
        if (!(attrs & DMA_ATTR_NO_WARN) && printk_ratelimit())
                dev_warn(hwdev, "swiotlb buffer is full (sz: %zd bytes), total %lu (slots), used %lu (slots)\n",
-                        size, io_tlb_nslabs, tmp_io_tlb_used);
+                        alloc_size, io_tlb_nslabs, tmp_io_tlb_used);
        return (phys_addr_t)DMA_MAPPING_ERROR;
 found:
        io_tlb_used += nslots;
@@ -562,7 +570,7 @@ found:
                io_tlb_orig_addr[index+i] = orig_addr + (i << IO_TLB_SHIFT);
        if (!(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
            (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL))
-               swiotlb_bounce(orig_addr, tlb_addr, size, DMA_TO_DEVICE);
+               swiotlb_bounce(orig_addr, tlb_addr, mapping_size, DMA_TO_DEVICE);
 
        return tlb_addr;
 }
@@ -571,11 +579,11 @@ found:
  * tlb_addr is the physical address of the bounce buffer to unmap.
  */
 void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr,
-                             size_t size, enum dma_data_direction dir,
-                             unsigned long attrs)
+                             size_t mapping_size, size_t alloc_size,
+                             enum dma_data_direction dir, unsigned long attrs)
 {
        unsigned long flags;
-       int i, count, nslots = ALIGN(size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
+       int i, count, nslots = ALIGN(alloc_size, 1 << IO_TLB_SHIFT) >> IO_TLB_SHIFT;
        int index = (tlb_addr - io_tlb_start) >> IO_TLB_SHIFT;
        phys_addr_t orig_addr = io_tlb_orig_addr[index];
 
@@ -585,7 +593,7 @@ void swiotlb_tbl_unmap_single(struct device *hwdev, phys_addr_t tlb_addr,
        if (orig_addr != INVALID_PHYS_ADDR &&
            !(attrs & DMA_ATTR_SKIP_CPU_SYNC) &&
            ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)))
-               swiotlb_bounce(orig_addr, tlb_addr, size, DMA_FROM_DEVICE);
+               swiotlb_bounce(orig_addr, tlb_addr, mapping_size, DMA_FROM_DEVICE);
 
        /*
         * Return the buffer to the free list by setting the corresponding
@@ -665,14 +673,14 @@ bool swiotlb_map(struct device *dev, phys_addr_t *phys, dma_addr_t *dma_addr,
 
        /* Oh well, have to allocate and map a bounce buffer. */
        *phys = swiotlb_tbl_map_single(dev, __phys_to_dma(dev, io_tlb_start),
-                       *phys, size, dir, attrs);
+                       *phys, size, size, dir, attrs);
        if (*phys == (phys_addr_t)DMA_MAPPING_ERROR)
                return false;
 
        /* Ensure that the address returned is DMA'ble */
        *dma_addr = __phys_to_dma(dev, *phys);
        if (unlikely(!dma_capable(dev, *dma_addr, size))) {
-               swiotlb_tbl_unmap_single(dev, *phys, size, dir,
+               swiotlb_tbl_unmap_single(dev, *phys, size, size, dir,
                        attrs | DMA_ATTR_SKIP_CPU_SYNC);
                return false;
        }
index c5cd852..3cc8416 100644 (file)
@@ -413,7 +413,7 @@ static int hw_breakpoint_parse(struct perf_event *bp,
 
 int register_perf_hw_breakpoint(struct perf_event *bp)
 {
-       struct arch_hw_breakpoint hw;
+       struct arch_hw_breakpoint hw = { };
        int err;
 
        err = reserve_bp_slot(bp);
@@ -461,7 +461,7 @@ int
 modify_user_hw_breakpoint_check(struct perf_event *bp, struct perf_event_attr *attr,
                                bool check)
 {
-       struct arch_hw_breakpoint hw;
+       struct arch_hw_breakpoint hw = { };
        int err;
 
        err = hw_breakpoint_parse(bp, attr, &hw);
index 5b4a5dc..22ab6a4 100644 (file)
@@ -1554,6 +1554,23 @@ end:
        return retval;
 }
 
+static struct pid *pidfd_get_pid(unsigned int fd)
+{
+       struct fd f;
+       struct pid *pid;
+
+       f = fdget(fd);
+       if (!f.file)
+               return ERR_PTR(-EBADF);
+
+       pid = pidfd_pid(f.file);
+       if (!IS_ERR(pid))
+               get_pid(pid);
+
+       fdput(f);
+       return pid;
+}
+
 static long kernel_waitid(int which, pid_t upid, struct waitid_info *infop,
                          int options, struct rusage *ru)
 {
@@ -1576,19 +1593,32 @@ static long kernel_waitid(int which, pid_t upid, struct waitid_info *infop,
                type = PIDTYPE_PID;
                if (upid <= 0)
                        return -EINVAL;
+
+               pid = find_get_pid(upid);
                break;
        case P_PGID:
                type = PIDTYPE_PGID;
-               if (upid <= 0)
+               if (upid < 0)
+                       return -EINVAL;
+
+               if (upid)
+                       pid = find_get_pid(upid);
+               else
+                       pid = get_task_pid(current, PIDTYPE_PGID);
+               break;
+       case P_PIDFD:
+               type = PIDTYPE_PID;
+               if (upid < 0)
                        return -EINVAL;
+
+               pid = pidfd_get_pid(upid);
+               if (IS_ERR(pid))
+                       return PTR_ERR(pid);
                break;
        default:
                return -EINVAL;
        }
 
-       if (type < PIDTYPE_MAX)
-               pid = find_get_pid(upid);
-
        wo.wo_type      = type;
        wo.wo_pid       = pid;
        wo.wo_flags     = options;
index 2852d0e..1d1cd06 100644 (file)
@@ -768,6 +768,7 @@ static void set_max_threads(unsigned int max_threads_suggested)
 int arch_task_struct_size __read_mostly;
 #endif
 
+#ifndef CONFIG_ARCH_TASK_STRUCT_ALLOCATOR
 static void task_struct_whitelist(unsigned long *offset, unsigned long *size)
 {
        /* Fetch thread_struct whitelist for the architecture. */
@@ -782,6 +783,7 @@ static void task_struct_whitelist(unsigned long *offset, unsigned long *size)
        else
                *offset += offsetof(struct task_struct, thread);
 }
+#endif /* CONFIG_ARCH_TASK_STRUCT_ALLOCATOR */
 
 void __init fork_init(void)
 {
@@ -1690,6 +1692,14 @@ static inline void rcu_copy_process(struct task_struct *p)
 #endif /* #ifdef CONFIG_TASKS_RCU */
 }
 
+struct pid *pidfd_pid(const struct file *file)
+{
+       if (file->f_op == &pidfd_fops)
+               return file->private_data;
+
+       return ERR_PTR(-EBADF);
+}
+
 static int pidfd_release(struct inode *inode, struct file *file)
 {
        struct pid *pid = file->private_data;
@@ -2338,6 +2348,8 @@ struct mm_struct *copy_init_mm(void)
  *
  * It copies the process, and if successful kick-starts
  * it and waits for it to finish using the VM if required.
+ *
+ * args->exit_signal is expected to be checked for sanity by the caller.
  */
 long _do_fork(struct kernel_clone_args *args)
 {
@@ -2562,6 +2574,14 @@ noinline static int copy_clone_args_from_user(struct kernel_clone_args *kargs,
        if (copy_from_user(&args, uargs, size))
                return -EFAULT;
 
+       /*
+        * Verify that higher 32bits of exit_signal are unset and that
+        * it is a valid signal
+        */
+       if (unlikely((args.exit_signal & ~((u64)CSIGNAL)) ||
+                    !valid_signal(args.exit_signal)))
+               return -EINVAL;
+
        *kargs = (struct kernel_clone_args){
                .flags          = args.flags,
                .pidfd          = u64_to_user_ptr(args.pidfd),
index da9addb..cfc4f08 100644 (file)
@@ -100,10 +100,6 @@ static int irq_affinity_hint_proc_show(struct seq_file *m, void *v)
        return 0;
 }
 
-#ifndef is_affinity_mask_valid
-#define is_affinity_mask_valid(val) 1
-#endif
-
 int no_irq_affinity;
 static int irq_affinity_proc_show(struct seq_file *m, void *v)
 {
@@ -136,11 +132,6 @@ static ssize_t write_irq_affinity(int type, struct file *file,
        if (err)
                goto free_cpumask;
 
-       if (!is_affinity_mask_valid(new_value)) {
-               err = -EINVAL;
-               goto free_cpumask;
-       }
-
        /*
         * Do not allow disabling IRQs completely - it's a too easy
         * way to make the system unusable accidentally :-) At least
@@ -232,11 +223,6 @@ static ssize_t default_affinity_write(struct file *file,
        if (err)
                goto out;
 
-       if (!is_affinity_mask_valid(new_value)) {
-               err = -EINVAL;
-               goto out;
-       }
-
        /*
         * Do not allow disabling IRQs completely - it's a too easy
         * way to make the system unusable accidentally :-) At least
index 95414ad..98c04ca 100644 (file)
@@ -36,6 +36,8 @@ static void resend_irqs(unsigned long arg)
                irq = find_first_bit(irqs_resend, nr_irqs);
                clear_bit(irq, irqs_resend);
                desc = irq_to_desc(irq);
+               if (!desc)
+                       continue;
                local_irq_disable();
                desc->handle_irq(desc);
                local_irq_enable();
index df30084..cdb3ffa 100644 (file)
@@ -407,7 +407,9 @@ static bool jump_label_can_update(struct jump_entry *entry, bool init)
                return false;
 
        if (!kernel_text_address(jump_entry_code(entry))) {
-               WARN_ONCE(1, "can't patch jump_label at %pS", (void *)jump_entry_code(entry));
+               WARN_ONCE(!jump_entry_is_init(entry),
+                         "can't patch jump_label at %pS",
+                         (void *)jump_entry_code(entry));
                return false;
        }
 
index 95a260f..136ce04 100644 (file)
@@ -263,8 +263,10 @@ int kallsyms_lookup_size_offset(unsigned long addr, unsigned long *symbolsize,
 {
        char namebuf[KSYM_NAME_LEN];
 
-       if (is_ksym_addr(addr))
-               return !!get_symbol_pos(addr, symbolsize, offset);
+       if (is_ksym_addr(addr)) {
+               get_symbol_pos(addr, symbolsize, offset);
+               return 1;
+       }
        return !!module_address_lookup(addr, symbolsize, offset, NULL, namebuf) ||
               !!__bpf_address_lookup(addr, symbolsize, offset, namebuf);
 }
diff --git a/kernel/kexec_elf.c b/kernel/kexec_elf.c
new file mode 100644 (file)
index 0000000..d368963
--- /dev/null
@@ -0,0 +1,430 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Load ELF vmlinux file for the kexec_file_load syscall.
+ *
+ * Copyright (C) 2004  Adam Litke (agl@us.ibm.com)
+ * Copyright (C) 2004  IBM Corp.
+ * Copyright (C) 2005  R Sharada (sharada@in.ibm.com)
+ * Copyright (C) 2006  Mohan Kumar M (mohan@in.ibm.com)
+ * Copyright (C) 2016  IBM Corporation
+ *
+ * Based on kexec-tools' kexec-elf-exec.c and kexec-elf-ppc64.c.
+ * Heavily modified for the kernel by
+ * Thiago Jung Bauermann <bauerman@linux.vnet.ibm.com>.
+ */
+
+#define pr_fmt(fmt)    "kexec_elf: " fmt
+
+#include <linux/elf.h>
+#include <linux/kexec.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+static inline bool elf_is_elf_file(const struct elfhdr *ehdr)
+{
+       return memcmp(ehdr->e_ident, ELFMAG, SELFMAG) == 0;
+}
+
+static uint64_t elf64_to_cpu(const struct elfhdr *ehdr, uint64_t value)
+{
+       if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
+               value = le64_to_cpu(value);
+       else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
+               value = be64_to_cpu(value);
+
+       return value;
+}
+
+static uint32_t elf32_to_cpu(const struct elfhdr *ehdr, uint32_t value)
+{
+       if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
+               value = le32_to_cpu(value);
+       else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
+               value = be32_to_cpu(value);
+
+       return value;
+}
+
+static uint16_t elf16_to_cpu(const struct elfhdr *ehdr, uint16_t value)
+{
+       if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB)
+               value = le16_to_cpu(value);
+       else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
+               value = be16_to_cpu(value);
+
+       return value;
+}
+
+/**
+ * elf_is_ehdr_sane - check that it is safe to use the ELF header
+ * @buf_len:   size of the buffer in which the ELF file is loaded.
+ */
+static bool elf_is_ehdr_sane(const struct elfhdr *ehdr, size_t buf_len)
+{
+       if (ehdr->e_phnum > 0 && ehdr->e_phentsize != sizeof(struct elf_phdr)) {
+               pr_debug("Bad program header size.\n");
+               return false;
+       } else if (ehdr->e_shnum > 0 &&
+                  ehdr->e_shentsize != sizeof(struct elf_shdr)) {
+               pr_debug("Bad section header size.\n");
+               return false;
+       } else if (ehdr->e_ident[EI_VERSION] != EV_CURRENT ||
+                  ehdr->e_version != EV_CURRENT) {
+               pr_debug("Unknown ELF version.\n");
+               return false;
+       }
+
+       if (ehdr->e_phoff > 0 && ehdr->e_phnum > 0) {
+               size_t phdr_size;
+
+               /*
+                * e_phnum is at most 65535 so calculating the size of the
+                * program header cannot overflow.
+                */
+               phdr_size = sizeof(struct elf_phdr) * ehdr->e_phnum;
+
+               /* Sanity check the program header table location. */
+               if (ehdr->e_phoff + phdr_size < ehdr->e_phoff) {
+                       pr_debug("Program headers at invalid location.\n");
+                       return false;
+               } else if (ehdr->e_phoff + phdr_size > buf_len) {
+                       pr_debug("Program headers truncated.\n");
+                       return false;
+               }
+       }
+
+       if (ehdr->e_shoff > 0 && ehdr->e_shnum > 0) {
+               size_t shdr_size;
+
+               /*
+                * e_shnum is at most 65536 so calculating
+                * the size of the section header cannot overflow.
+                */
+               shdr_size = sizeof(struct elf_shdr) * ehdr->e_shnum;
+
+               /* Sanity check the section header table location. */
+               if (ehdr->e_shoff + shdr_size < ehdr->e_shoff) {
+                       pr_debug("Section headers at invalid location.\n");
+                       return false;
+               } else if (ehdr->e_shoff + shdr_size > buf_len) {
+                       pr_debug("Section headers truncated.\n");
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+static int elf_read_ehdr(const char *buf, size_t len, struct elfhdr *ehdr)
+{
+       struct elfhdr *buf_ehdr;
+
+       if (len < sizeof(*buf_ehdr)) {
+               pr_debug("Buffer is too small to hold ELF header.\n");
+               return -ENOEXEC;
+       }
+
+       memset(ehdr, 0, sizeof(*ehdr));
+       memcpy(ehdr->e_ident, buf, sizeof(ehdr->e_ident));
+       if (!elf_is_elf_file(ehdr)) {
+               pr_debug("No ELF header magic.\n");
+               return -ENOEXEC;
+       }
+
+       if (ehdr->e_ident[EI_CLASS] != ELF_CLASS) {
+               pr_debug("Not a supported ELF class.\n");
+               return -ENOEXEC;
+       } else  if (ehdr->e_ident[EI_DATA] != ELFDATA2LSB &&
+               ehdr->e_ident[EI_DATA] != ELFDATA2MSB) {
+               pr_debug("Not a supported ELF data format.\n");
+               return -ENOEXEC;
+       }
+
+       buf_ehdr = (struct elfhdr *) buf;
+       if (elf16_to_cpu(ehdr, buf_ehdr->e_ehsize) != sizeof(*buf_ehdr)) {
+               pr_debug("Bad ELF header size.\n");
+               return -ENOEXEC;
+       }
+
+       ehdr->e_type      = elf16_to_cpu(ehdr, buf_ehdr->e_type);
+       ehdr->e_machine   = elf16_to_cpu(ehdr, buf_ehdr->e_machine);
+       ehdr->e_version   = elf32_to_cpu(ehdr, buf_ehdr->e_version);
+       ehdr->e_flags     = elf32_to_cpu(ehdr, buf_ehdr->e_flags);
+       ehdr->e_phentsize = elf16_to_cpu(ehdr, buf_ehdr->e_phentsize);
+       ehdr->e_phnum     = elf16_to_cpu(ehdr, buf_ehdr->e_phnum);
+       ehdr->e_shentsize = elf16_to_cpu(ehdr, buf_ehdr->e_shentsize);
+       ehdr->e_shnum     = elf16_to_cpu(ehdr, buf_ehdr->e_shnum);
+       ehdr->e_shstrndx  = elf16_to_cpu(ehdr, buf_ehdr->e_shstrndx);
+
+       switch (ehdr->e_ident[EI_CLASS]) {
+       case ELFCLASS64:
+               ehdr->e_entry = elf64_to_cpu(ehdr, buf_ehdr->e_entry);
+               ehdr->e_phoff = elf64_to_cpu(ehdr, buf_ehdr->e_phoff);
+               ehdr->e_shoff = elf64_to_cpu(ehdr, buf_ehdr->e_shoff);
+               break;
+
+       case ELFCLASS32:
+               ehdr->e_entry = elf32_to_cpu(ehdr, buf_ehdr->e_entry);
+               ehdr->e_phoff = elf32_to_cpu(ehdr, buf_ehdr->e_phoff);
+               ehdr->e_shoff = elf32_to_cpu(ehdr, buf_ehdr->e_shoff);
+               break;
+
+       default:
+               pr_debug("Unknown ELF class.\n");
+               return -EINVAL;
+       }
+
+       return elf_is_ehdr_sane(ehdr, len) ? 0 : -ENOEXEC;
+}
+
+/**
+ * elf_is_phdr_sane - check that it is safe to use the program header
+ * @buf_len:   size of the buffer in which the ELF file is loaded.
+ */
+static bool elf_is_phdr_sane(const struct elf_phdr *phdr, size_t buf_len)
+{
+
+       if (phdr->p_offset + phdr->p_filesz < phdr->p_offset) {
+               pr_debug("ELF segment location wraps around.\n");
+               return false;
+       } else if (phdr->p_offset + phdr->p_filesz > buf_len) {
+               pr_debug("ELF segment not in file.\n");
+               return false;
+       } else if (phdr->p_paddr + phdr->p_memsz < phdr->p_paddr) {
+               pr_debug("ELF segment address wraps around.\n");
+               return false;
+       }
+
+       return true;
+}
+
+static int elf_read_phdr(const char *buf, size_t len,
+                        struct kexec_elf_info *elf_info,
+                        int idx)
+{
+       /* Override the const in proghdrs, we are the ones doing the loading. */
+       struct elf_phdr *phdr = (struct elf_phdr *) &elf_info->proghdrs[idx];
+       const struct elfhdr *ehdr = elf_info->ehdr;
+       const char *pbuf;
+       struct elf_phdr *buf_phdr;
+
+       pbuf = buf + elf_info->ehdr->e_phoff + (idx * sizeof(*buf_phdr));
+       buf_phdr = (struct elf_phdr *) pbuf;
+
+       phdr->p_type   = elf32_to_cpu(elf_info->ehdr, buf_phdr->p_type);
+       phdr->p_flags  = elf32_to_cpu(elf_info->ehdr, buf_phdr->p_flags);
+
+       switch (ehdr->e_ident[EI_CLASS]) {
+       case ELFCLASS64:
+               phdr->p_offset = elf64_to_cpu(ehdr, buf_phdr->p_offset);
+               phdr->p_paddr  = elf64_to_cpu(ehdr, buf_phdr->p_paddr);
+               phdr->p_vaddr  = elf64_to_cpu(ehdr, buf_phdr->p_vaddr);
+               phdr->p_filesz = elf64_to_cpu(ehdr, buf_phdr->p_filesz);
+               phdr->p_memsz  = elf64_to_cpu(ehdr, buf_phdr->p_memsz);
+               phdr->p_align  = elf64_to_cpu(ehdr, buf_phdr->p_align);
+               break;
+
+       case ELFCLASS32:
+               phdr->p_offset = elf32_to_cpu(ehdr, buf_phdr->p_offset);
+               phdr->p_paddr  = elf32_to_cpu(ehdr, buf_phdr->p_paddr);
+               phdr->p_vaddr  = elf32_to_cpu(ehdr, buf_phdr->p_vaddr);
+               phdr->p_filesz = elf32_to_cpu(ehdr, buf_phdr->p_filesz);
+               phdr->p_memsz  = elf32_to_cpu(ehdr, buf_phdr->p_memsz);
+               phdr->p_align  = elf32_to_cpu(ehdr, buf_phdr->p_align);
+               break;
+
+       default:
+               pr_debug("Unknown ELF class.\n");
+               return -EINVAL;
+       }
+
+       return elf_is_phdr_sane(phdr, len) ? 0 : -ENOEXEC;
+}
+
+/**
+ * elf_read_phdrs - read the program headers from the buffer
+ *
+ * This function assumes that the program header table was checked for sanity.
+ * Use elf_is_ehdr_sane() if it wasn't.
+ */
+static int elf_read_phdrs(const char *buf, size_t len,
+                         struct kexec_elf_info *elf_info)
+{
+       size_t phdr_size, i;
+       const struct elfhdr *ehdr = elf_info->ehdr;
+
+       /*
+        * e_phnum is at most 65535 so calculating the size of the
+        * program header cannot overflow.
+        */
+       phdr_size = sizeof(struct elf_phdr) * ehdr->e_phnum;
+
+       elf_info->proghdrs = kzalloc(phdr_size, GFP_KERNEL);
+       if (!elf_info->proghdrs)
+               return -ENOMEM;
+
+       for (i = 0; i < ehdr->e_phnum; i++) {
+               int ret;
+
+               ret = elf_read_phdr(buf, len, elf_info, i);
+               if (ret) {
+                       kfree(elf_info->proghdrs);
+                       elf_info->proghdrs = NULL;
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+/**
+ * elf_read_from_buffer - read ELF file and sets up ELF header and ELF info
+ * @buf:       Buffer to read ELF file from.
+ * @len:       Size of @buf.
+ * @ehdr:      Pointer to existing struct which will be populated.
+ * @elf_info:  Pointer to existing struct which will be populated.
+ *
+ * This function allows reading ELF files with different byte order than
+ * the kernel, byte-swapping the fields as needed.
+ *
+ * Return:
+ * On success returns 0, and the caller should call
+ * kexec_free_elf_info(elf_info) to free the memory allocated for the section
+ * and program headers.
+ */
+static int elf_read_from_buffer(const char *buf, size_t len,
+                               struct elfhdr *ehdr,
+                               struct kexec_elf_info *elf_info)
+{
+       int ret;
+
+       ret = elf_read_ehdr(buf, len, ehdr);
+       if (ret)
+               return ret;
+
+       elf_info->buffer = buf;
+       elf_info->ehdr = ehdr;
+       if (ehdr->e_phoff > 0 && ehdr->e_phnum > 0) {
+               ret = elf_read_phdrs(buf, len, elf_info);
+               if (ret)
+                       return ret;
+       }
+       return 0;
+}
+
+/**
+ * kexec_free_elf_info - free memory allocated by elf_read_from_buffer
+ */
+void kexec_free_elf_info(struct kexec_elf_info *elf_info)
+{
+       kfree(elf_info->proghdrs);
+       memset(elf_info, 0, sizeof(*elf_info));
+}
+/**
+ * kexec_build_elf_info - read ELF executable and check that we can use it
+ */
+int kexec_build_elf_info(const char *buf, size_t len, struct elfhdr *ehdr,
+                              struct kexec_elf_info *elf_info)
+{
+       int i;
+       int ret;
+
+       ret = elf_read_from_buffer(buf, len, ehdr, elf_info);
+       if (ret)
+               return ret;
+
+       /* Big endian vmlinux has type ET_DYN. */
+       if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
+               pr_err("Not an ELF executable.\n");
+               goto error;
+       } else if (!elf_info->proghdrs) {
+               pr_err("No ELF program header.\n");
+               goto error;
+       }
+
+       for (i = 0; i < ehdr->e_phnum; i++) {
+               /*
+                * Kexec does not support loading interpreters.
+                * In addition this check keeps us from attempting
+                * to kexec ordinay executables.
+                */
+               if (elf_info->proghdrs[i].p_type == PT_INTERP) {
+                       pr_err("Requires an ELF interpreter.\n");
+                       goto error;
+               }
+       }
+
+       return 0;
+error:
+       kexec_free_elf_info(elf_info);
+       return -ENOEXEC;
+}
+
+
+int kexec_elf_probe(const char *buf, unsigned long len)
+{
+       struct elfhdr ehdr;
+       struct kexec_elf_info elf_info;
+       int ret;
+
+       ret = kexec_build_elf_info(buf, len, &ehdr, &elf_info);
+       if (ret)
+               return ret;
+
+       kexec_free_elf_info(&elf_info);
+
+       return elf_check_arch(&ehdr) ? 0 : -ENOEXEC;
+}
+
+/**
+ * kexec_elf_load - load ELF executable image
+ * @lowest_load_addr:  On return, will be the address where the first PT_LOAD
+ *                     section will be loaded in memory.
+ *
+ * Return:
+ * 0 on success, negative value on failure.
+ */
+int kexec_elf_load(struct kimage *image, struct elfhdr *ehdr,
+                        struct kexec_elf_info *elf_info,
+                        struct kexec_buf *kbuf,
+                        unsigned long *lowest_load_addr)
+{
+       unsigned long lowest_addr = UINT_MAX;
+       int ret;
+       size_t i;
+
+       /* Read in the PT_LOAD segments. */
+       for (i = 0; i < ehdr->e_phnum; i++) {
+               unsigned long load_addr;
+               size_t size;
+               const struct elf_phdr *phdr;
+
+               phdr = &elf_info->proghdrs[i];
+               if (phdr->p_type != PT_LOAD)
+                       continue;
+
+               size = phdr->p_filesz;
+               if (size > phdr->p_memsz)
+                       size = phdr->p_memsz;
+
+               kbuf->buffer = (void *) elf_info->buffer + phdr->p_offset;
+               kbuf->bufsz = size;
+               kbuf->memsz = phdr->p_memsz;
+               kbuf->buf_align = phdr->p_align;
+               kbuf->buf_min = phdr->p_paddr;
+               kbuf->mem = KEXEC_BUF_MEM_UNKNOWN;
+               ret = kexec_add_buffer(kbuf);
+               if (ret)
+                       goto out;
+               load_addr = kbuf->mem;
+
+               if (load_addr < lowest_addr)
+                       lowest_addr = load_addr;
+       }
+
+       *lowest_load_addr = lowest_addr;
+       ret = 0;
+ out:
+       return ret;
+}
index 010d578..df9f1fe 100644 (file)
@@ -5105,37 +5105,40 @@ out_unlock:
        return retval;
 }
 
-static int sched_read_attr(struct sched_attr __user *uattr,
-                          struct sched_attr *attr,
-                          unsigned int usize)
+/*
+ * Copy the kernel size attribute structure (which might be larger
+ * than what user-space knows about) to user-space.
+ *
+ * Note that all cases are valid: user-space buffer can be larger or
+ * smaller than the kernel-space buffer. The usual case is that both
+ * have the same size.
+ */
+static int
+sched_attr_copy_to_user(struct sched_attr __user *uattr,
+                       struct sched_attr *kattr,
+                       unsigned int usize)
 {
-       int ret;
+       unsigned int ksize = sizeof(*kattr);
 
        if (!access_ok(uattr, usize))
                return -EFAULT;
 
        /*
-        * If we're handed a smaller struct than we know of,
-        * ensure all the unknown bits are 0 - i.e. old
-        * user-space does not get uncomplete information.
+        * sched_getattr() ABI forwards and backwards compatibility:
+        *
+        * If usize == ksize then we just copy everything to user-space and all is good.
+        *
+        * If usize < ksize then we only copy as much as user-space has space for,
+        * this keeps ABI compatibility as well. We skip the rest.
+        *
+        * If usize > ksize then user-space is using a newer version of the ABI,
+        * which part the kernel doesn't know about. Just ignore it - tooling can
+        * detect the kernel's knowledge of attributes from the attr->size value
+        * which is set to ksize in this case.
         */
-       if (usize < sizeof(*attr)) {
-               unsigned char *addr;
-               unsigned char *end;
+       kattr->size = min(usize, ksize);
 
-               addr = (void *)attr + usize;
-               end  = (void *)attr + sizeof(*attr);
-
-               for (; addr < end; addr++) {
-                       if (*addr)
-                               return -EFBIG;
-               }
-
-               attr->size = usize;
-       }
-
-       ret = copy_to_user(uattr, attr, attr->size);
-       if (ret)
+       if (copy_to_user(uattr, kattr, kattr->size))
                return -EFAULT;
 
        return 0;
@@ -5145,20 +5148,18 @@ static int sched_read_attr(struct sched_attr __user *uattr,
  * sys_sched_getattr - similar to sched_getparam, but with sched_attr
  * @pid: the pid in question.
  * @uattr: structure containing the extended parameters.
- * @size: sizeof(attr) for fwd/bwd comp.
+ * @usize: sizeof(attr) that user-space knows about, for forwards and backwards compatibility.
  * @flags: for future extension.
  */
 SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,
-               unsigned int, size, unsigned int, flags)
+               unsigned int, usize, unsigned int, flags)
 {
-       struct sched_attr attr = {
-               .size = sizeof(struct sched_attr),
-       };
+       struct sched_attr kattr = { };
        struct task_struct *p;
        int retval;
 
-       if (!uattr || pid < 0 || size > PAGE_SIZE ||
-           size < SCHED_ATTR_SIZE_VER0 || flags)
+       if (!uattr || pid < 0 || usize > PAGE_SIZE ||
+           usize < SCHED_ATTR_SIZE_VER0 || flags)
                return -EINVAL;
 
        rcu_read_lock();
@@ -5171,25 +5172,24 @@ SYSCALL_DEFINE4(sched_getattr, pid_t, pid, struct sched_attr __user *, uattr,
        if (retval)
                goto out_unlock;
 
-       attr.sched_policy = p->policy;
+       kattr.sched_policy = p->policy;
        if (p->sched_reset_on_fork)
-               attr.sched_flags |= SCHED_FLAG_RESET_ON_FORK;
+               kattr.sched_flags |= SCHED_FLAG_RESET_ON_FORK;
        if (task_has_dl_policy(p))
-               __getparam_dl(p, &attr);
+               __getparam_dl(p, &kattr);
        else if (task_has_rt_policy(p))
-               attr.sched_priority = p->rt_priority;
+               kattr.sched_priority = p->rt_priority;
        else
-               attr.sched_nice = task_nice(p);
+               kattr.sched_nice = task_nice(p);
 
 #ifdef CONFIG_UCLAMP_TASK
-       attr.sched_util_min = p->uclamp_req[UCLAMP_MIN].value;
-       attr.sched_util_max = p->uclamp_req[UCLAMP_MAX].value;
+       kattr.sched_util_min = p->uclamp_req[UCLAMP_MIN].value;
+       kattr.sched_util_max = p->uclamp_req[UCLAMP_MAX].value;
 #endif
 
        rcu_read_unlock();
 
-       retval = sched_read_attr(uattr, &attr, size);
-       return retval;
+       return sched_attr_copy_to_user(uattr, &kattr, usize);
 
 out_unlock:
        rcu_read_unlock();
index bc9cfea..500f5db 100644 (file)
@@ -4470,6 +4470,8 @@ static void __account_cfs_rq_runtime(struct cfs_rq *cfs_rq, u64 delta_exec)
        if (likely(cfs_rq->runtime_remaining > 0))
                return;
 
+       if (cfs_rq->throttled)
+               return;
        /*
         * if we're unable to extend our runtime we resched so that the active
         * hierarchy can be throttled
@@ -4673,6 +4675,9 @@ static u64 distribute_cfs_runtime(struct cfs_bandwidth *cfs_b,
                if (!cfs_rq_throttled(cfs_rq))
                        goto next;
 
+               /* By the above check, this should never be true */
+               SCHED_WARN_ON(cfs_rq->runtime_remaining > 0);
+
                runtime = -cfs_rq->runtime_remaining + 1;
                if (runtime > remaining)
                        runtime = remaining;
index 534fec2..c4da1ef 100644 (file)
@@ -3678,8 +3678,11 @@ static int copy_siginfo_from_user_any(kernel_siginfo_t *kinfo, siginfo_t *info)
 
 static struct pid *pidfd_to_pid(const struct file *file)
 {
-       if (file->f_op == &pidfd_fops)
-               return file->private_data;
+       struct pid *pid;
+
+       pid = pidfd_pid(file);
+       if (!IS_ERR(pid))
+               return pid;
 
        return tgid_pidfd_to_pid(file);
 }
index 2969304..ec48396 100644 (file)
 #ifndef PAC_RESET_KEYS
 # define PAC_RESET_KEYS(a, b)  (-EINVAL)
 #endif
+#ifndef SET_TAGGED_ADDR_CTRL
+# define SET_TAGGED_ADDR_CTRL(a)       (-EINVAL)
+#endif
+#ifndef GET_TAGGED_ADDR_CTRL
+# define GET_TAGGED_ADDR_CTRL()                (-EINVAL)
+#endif
 
 /*
  * this is where the system-wide overflow UID and GID are defined, for
@@ -2492,6 +2498,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
                        return -EINVAL;
                error = PAC_RESET_KEYS(me, arg2);
                break;
+       case PR_SET_TAGGED_ADDR_CTRL:
+               if (arg3 || arg4 || arg5)
+                       return -EINVAL;
+               error = SET_TAGGED_ADDR_CTRL(arg2);
+               break;
+       case PR_GET_TAGGED_ADDR_CTRL:
+               if (arg2 || arg3 || arg4 || arg5)
+                       return -EINVAL;
+               error = GET_TAGGED_ADDR_CTRL();
+               break;
        default:
                error = -EINVAL;
                break;
index eca3450..f9821a3 100644 (file)
@@ -3095,6 +3095,14 @@ t_probe_next(struct seq_file *m, loff_t *pos)
                hnd = &iter->probe_entry->hlist;
 
        hash = iter->probe->ops.func_hash->filter_hash;
+
+       /*
+        * A probe being registered may temporarily have an empty hash
+        * and it's at the end of the func_probes list.
+        */
+       if (!hash || hash == EMPTY_HASH)
+               return NULL;
+
        size = 1 << hash->size_bits;
 
  retry:
@@ -4320,12 +4328,21 @@ register_ftrace_function_probe(char *glob, struct trace_array *tr,
 
        mutex_unlock(&ftrace_lock);
 
+       /*
+        * Note, there's a small window here that the func_hash->filter_hash
+        * may be NULL or empty. Need to be carefule when reading the loop.
+        */
        mutex_lock(&probe->ops.func_hash->regex_lock);
 
        orig_hash = &probe->ops.func_hash->filter_hash;
        old_hash = *orig_hash;
        hash = alloc_and_copy_ftrace_hash(FTRACE_HASH_DEFAULT_BITS, old_hash);
 
+       if (!hash) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
        ret = ftrace_match_records(hash, glob, strlen(glob));
 
        /* Nothing found? */
index 525a97f..563e80f 100644 (file)
@@ -1567,9 +1567,9 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
 
 /**
  * update_max_tr_single - only copy one trace over, and reset the rest
- * @tr - tracer
- * @tsk - task with the latency
- * @cpu - the cpu of the buffer to copy.
+ * @tr: tracer
+ * @tsk: task with the latency
+ * @cpu: the cpu of the buffer to copy.
  *
  * Flip the trace of a single CPU buffer between the @tr and the max_tr.
  */
@@ -1767,7 +1767,7 @@ static void __init apply_trace_boot_options(void);
 
 /**
  * register_tracer - register a tracer with the ftrace system.
- * @type - the plugin for the tracer
+ * @type: the plugin for the tracer
  *
  * Register a new plugin tracer.
  */
@@ -2230,9 +2230,9 @@ static bool tracing_record_taskinfo_skip(int flags)
 /**
  * tracing_record_taskinfo - record the task info of a task
  *
- * @task  - task to record
- * @flags - TRACE_RECORD_CMDLINE for recording comm
- *        - TRACE_RECORD_TGID for recording tgid
+ * @task task to record
+ * @flags: TRACE_RECORD_CMDLINE for recording comm
+ *         TRACE_RECORD_TGID for recording tgid
  */
 void tracing_record_taskinfo(struct task_struct *task, int flags)
 {
@@ -2258,10 +2258,10 @@ void tracing_record_taskinfo(struct task_struct *task, int flags)
 /**
  * tracing_record_taskinfo_sched_switch - record task info for sched_switch
  *
- * @prev - previous task during sched_switch
- * @next - next task during sched_switch
- * @flags - TRACE_RECORD_CMDLINE for recording comm
- *          TRACE_RECORD_TGID for recording tgid
+ * @prev: previous task during sched_switch
+ * @next: next task during sched_switch
+ * @flags: TRACE_RECORD_CMDLINE for recording comm
+ *         TRACE_RECORD_TGID for recording tgid
  */
 void tracing_record_taskinfo_sched_switch(struct task_struct *prev,
                                          struct task_struct *next, int flags)
@@ -3072,7 +3072,9 @@ static void trace_printk_start_stop_comm(int enabled)
 
 /**
  * trace_vbprintk - write binary msg to tracing buffer
- *
+ * @ip:    The address of the caller
+ * @fmt:   The string format to write to the buffer
+ * @args:  Arguments for @fmt
  */
 int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
 {
index c7506bc..6489308 100644 (file)
@@ -787,7 +787,7 @@ static int __ftrace_set_clr_event(struct trace_array *tr, const char *match,
        return ret;
 }
 
-static int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set)
+int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set)
 {
        char *event = NULL, *sub = NULL, *match;
        int ret;
index dbef0d1..fb6bfbc 100644 (file)
@@ -895,7 +895,8 @@ void trace_probe_cleanup(struct trace_probe *tp)
        for (i = 0; i < tp->nr_args; i++)
                traceprobe_free_probe_arg(&tp->args[i]);
 
-       kfree(call->class->system);
+       if (call->class)
+               kfree(call->class->system);
        kfree(call->name);
        kfree(call->print_fmt);
 }
index f33d66f..4e6b1c3 100644 (file)
@@ -631,6 +631,9 @@ config SBITMAP
 config PARMAN
        tristate "parman" if COMPILE_TEST
 
+config OBJAGG
+       tristate "objagg" if COMPILE_TEST
+
 config STRING_SELFTEST
        tristate "Test string functions"
 
@@ -653,6 +656,3 @@ config GENERIC_LIB_CMPDI2
 
 config GENERIC_LIB_UCMPDI2
        bool
-
-config OBJAGG
-       tristate "objagg" if COMPILE_TEST
index 117ad0e..70dab9a 100644 (file)
@@ -68,7 +68,8 @@ int __kfifo_init(struct __kfifo *fifo, void *buffer,
 {
        size /= esize;
 
-       size = roundup_pow_of_two(size);
+       if (!is_power_of_2(size))
+               size = rounddown_pow_of_two(size);
 
        fifo->in = 0;
        fifo->out = 0;
index feea48f..9050275 100644 (file)
@@ -35,7 +35,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
        struct logic_pio_hwaddr *range;
        resource_size_t start;
        resource_size_t end;
-       resource_size_t mmio_sz = 0;
+       resource_size_t mmio_end = 0;
        resource_size_t iio_sz = MMIO_UPPER_LIMIT;
        int ret = 0;
 
@@ -46,7 +46,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
        end = new_range->hw_start + new_range->size;
 
        mutex_lock(&io_range_mutex);
-       list_for_each_entry_rcu(range, &io_range_list, list) {
+       list_for_each_entry(range, &io_range_list, list) {
                if (range->fwnode == new_range->fwnode) {
                        /* range already there */
                        goto end_register;
@@ -56,7 +56,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
                        /* for MMIO ranges we need to check for overlap */
                        if (start >= range->hw_start + range->size ||
                            end < range->hw_start) {
-                               mmio_sz += range->size;
+                               mmio_end = range->io_start + range->size;
                        } else {
                                ret = -EFAULT;
                                goto end_register;
@@ -69,16 +69,16 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
 
        /* range not registered yet, check for available space */
        if (new_range->flags == LOGIC_PIO_CPU_MMIO) {
-               if (mmio_sz + new_range->size - 1 > MMIO_UPPER_LIMIT) {
+               if (mmio_end + new_range->size - 1 > MMIO_UPPER_LIMIT) {
                        /* if it's too big check if 64K space can be reserved */
-                       if (mmio_sz + SZ_64K - 1 > MMIO_UPPER_LIMIT) {
+                       if (mmio_end + SZ_64K - 1 > MMIO_UPPER_LIMIT) {
                                ret = -E2BIG;
                                goto end_register;
                        }
                        new_range->size = SZ_64K;
                        pr_warn("Requested IO range too big, new size set to 64K\n");
                }
-               new_range->io_start = mmio_sz;
+               new_range->io_start = mmio_end;
        } else if (new_range->flags == LOGIC_PIO_INDIRECT) {
                if (iio_sz + new_range->size - 1 > IO_SPACE_LIMIT) {
                        ret = -E2BIG;
@@ -99,6 +99,20 @@ end_register:
 }
 
 /**
+ * logic_pio_unregister_range - unregister a logical PIO range for a host
+ * @range: pointer to the IO range which has been already registered.
+ *
+ * Unregister a previously-registered IO range node.
+ */
+void logic_pio_unregister_range(struct logic_pio_hwaddr *range)
+{
+       mutex_lock(&io_range_mutex);
+       list_del_rcu(&range->list);
+       mutex_unlock(&io_range_mutex);
+       synchronize_rcu();
+}
+
+/**
  * find_io_range_by_fwnode - find logical PIO range for given FW node
  * @fwnode: FW node handle associated with logical PIO range
  *
@@ -108,26 +122,38 @@ end_register:
  */
 struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode)
 {
-       struct logic_pio_hwaddr *range;
+       struct logic_pio_hwaddr *range, *found_range = NULL;
 
+       rcu_read_lock();
        list_for_each_entry_rcu(range, &io_range_list, list) {
-               if (range->fwnode == fwnode)
-                       return range;
+               if (range->fwnode == fwnode) {
+                       found_range = range;
+                       break;
+               }
        }
-       return NULL;
+       rcu_read_unlock();
+
+       return found_range;
 }
 
 /* Return a registered range given an input PIO token */
 static struct logic_pio_hwaddr *find_io_range(unsigned long pio)
 {
-       struct logic_pio_hwaddr *range;
+       struct logic_pio_hwaddr *range, *found_range = NULL;
 
+       rcu_read_lock();
        list_for_each_entry_rcu(range, &io_range_list, list) {
-               if (in_range(pio, range->io_start, range->size))
-                       return range;
+               if (in_range(pio, range->io_start, range->size)) {
+                       found_range = range;
+                       break;
+               }
        }
-       pr_err("PIO entry token %lx invalid\n", pio);
-       return NULL;
+       rcu_read_unlock();
+
+       if (!found_range)
+               pr_err("PIO entry token 0x%lx invalid\n", pio);
+
+       return found_range;
 }
 
 /**
@@ -180,14 +206,23 @@ unsigned long logic_pio_trans_cpuaddr(resource_size_t addr)
 {
        struct logic_pio_hwaddr *range;
 
+       rcu_read_lock();
        list_for_each_entry_rcu(range, &io_range_list, list) {
                if (range->flags != LOGIC_PIO_CPU_MMIO)
                        continue;
-               if (in_range(addr, range->hw_start, range->size))
-                       return addr - range->hw_start + range->io_start;
+               if (in_range(addr, range->hw_start, range->size)) {
+                       unsigned long cpuaddr;
+
+                       cpuaddr = addr - range->hw_start + range->io_start;
+
+                       rcu_read_unlock();
+                       return cpuaddr;
+               }
        }
-       pr_err("addr %llx not registered in io_range_list\n",
-              (unsigned long long) addr);
+       rcu_read_unlock();
+
+       pr_err("addr %pa not registered in io_range_list\n", &addr);
+
        return ~0UL;
 }
 
index 798275a..26de020 100644 (file)
@@ -124,7 +124,8 @@ EXPORT_SYMBOL_GPL(balloon_page_list_dequeue);
 struct page *balloon_page_alloc(void)
 {
        struct page *page = alloc_page(balloon_mapping_gfp_mask() |
-                                      __GFP_NOMEMALLOC | __GFP_NORETRY);
+                                      __GFP_NOMEMALLOC | __GFP_NORETRY |
+                                      __GFP_NOWARN);
        return page;
 }
 EXPORT_SYMBOL_GPL(balloon_page_alloc);
index 26e2999..9ec5e12 100644 (file)
@@ -752,15 +752,13 @@ void __mod_lruvec_state(struct lruvec *lruvec, enum node_stat_item idx,
        /* Update memcg */
        __mod_memcg_state(memcg, idx, val);
 
+       /* Update lruvec */
+       __this_cpu_add(pn->lruvec_stat_local->count[idx], val);
+
        x = val + __this_cpu_read(pn->lruvec_stat_cpu->count[idx]);
        if (unlikely(abs(x) > MEMCG_CHARGE_BATCH)) {
                struct mem_cgroup_per_node *pi;
 
-               /*
-                * Batch local counters to keep them in sync with
-                * the hierarchical ones.
-                */
-               __this_cpu_add(pn->lruvec_stat_local->count[idx], x);
                for (pi = pn; pi; pi = parent_nodeinfo(pi, pgdat->node_id))
                        atomic_long_add(x, &pi->lruvec_stat[idx]);
                x = 0;
@@ -3260,37 +3258,49 @@ static u64 mem_cgroup_read_u64(struct cgroup_subsys_state *css,
        }
 }
 
-static void memcg_flush_percpu_vmstats(struct mem_cgroup *memcg)
+static void memcg_flush_percpu_vmstats(struct mem_cgroup *memcg, bool slab_only)
 {
        unsigned long stat[MEMCG_NR_STAT];
        struct mem_cgroup *mi;
        int node, cpu, i;
+       int min_idx, max_idx;
 
-       for (i = 0; i < MEMCG_NR_STAT; i++)
+       if (slab_only) {
+               min_idx = NR_SLAB_RECLAIMABLE;
+               max_idx = NR_SLAB_UNRECLAIMABLE;
+       } else {
+               min_idx = 0;
+               max_idx = MEMCG_NR_STAT;
+       }
+
+       for (i = min_idx; i < max_idx; i++)
                stat[i] = 0;
 
        for_each_online_cpu(cpu)
-               for (i = 0; i < MEMCG_NR_STAT; i++)
-                       stat[i] += raw_cpu_read(memcg->vmstats_percpu->stat[i]);
+               for (i = min_idx; i < max_idx; i++)
+                       stat[i] += per_cpu(memcg->vmstats_percpu->stat[i], cpu);
 
        for (mi = memcg; mi; mi = parent_mem_cgroup(mi))
-               for (i = 0; i < MEMCG_NR_STAT; i++)
+               for (i = min_idx; i < max_idx; i++)
                        atomic_long_add(stat[i], &mi->vmstats[i]);
 
+       if (!slab_only)
+               max_idx = NR_VM_NODE_STAT_ITEMS;
+
        for_each_node(node) {
                struct mem_cgroup_per_node *pn = memcg->nodeinfo[node];
                struct mem_cgroup_per_node *pi;
 
-               for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
+               for (i = min_idx; i < max_idx; i++)
                        stat[i] = 0;
 
                for_each_online_cpu(cpu)
-                       for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
-                               stat[i] += raw_cpu_read(
-                                       pn->lruvec_stat_cpu->count[i]);
+                       for (i = min_idx; i < max_idx; i++)
+                               stat[i] += per_cpu(
+                                       pn->lruvec_stat_cpu->count[i], cpu);
 
                for (pi = pn; pi; pi = parent_nodeinfo(pi, node))
-                       for (i = 0; i < NR_VM_NODE_STAT_ITEMS; i++)
+                       for (i = min_idx; i < max_idx; i++)
                                atomic_long_add(stat[i], &pi->lruvec_stat[i]);
        }
 }
@@ -3306,8 +3316,8 @@ static void memcg_flush_percpu_vmevents(struct mem_cgroup *memcg)
 
        for_each_online_cpu(cpu)
                for (i = 0; i < NR_VM_EVENT_ITEMS; i++)
-                       events[i] += raw_cpu_read(
-                               memcg->vmstats_percpu->events[i]);
+                       events[i] += per_cpu(memcg->vmstats_percpu->events[i],
+                                            cpu);
 
        for (mi = memcg; mi; mi = parent_mem_cgroup(mi))
                for (i = 0; i < NR_VM_EVENT_ITEMS; i++)
@@ -3363,7 +3373,14 @@ static void memcg_offline_kmem(struct mem_cgroup *memcg)
        if (!parent)
                parent = root_mem_cgroup;
 
+       /*
+        * Deactivate and reparent kmem_caches. Then flush percpu
+        * slab statistics to have precise values at the parent and
+        * all ancestor levels. It's required to keep slab stats
+        * accurate after the reparenting of kmem_caches.
+        */
        memcg_deactivate_kmem_caches(memcg, parent);
+       memcg_flush_percpu_vmstats(memcg, true);
 
        kmemcg_id = memcg->kmemcg_id;
        BUG_ON(kmemcg_id < 0);
@@ -4740,7 +4757,7 @@ static void __mem_cgroup_free(struct mem_cgroup *memcg)
         * Flush percpu vmstats and vmevents to guarantee the value correctness
         * on parent's and all ancestor levels.
         */
-       memcg_flush_percpu_vmstats(memcg);
+       memcg_flush_percpu_vmstats(memcg, false);
        memcg_flush_percpu_vmevents(memcg);
        for_each_node(node)
                free_mem_cgroup_per_node_info(memcg, node);
index c77d1e3..a6c5d0b 100644 (file)
@@ -3220,6 +3220,7 @@ unsigned long try_to_free_pages(struct zonelist *zonelist, int order,
 
 #ifdef CONFIG_MEMCG
 
+/* Only used by soft limit reclaim. Do not reuse for anything else. */
 unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg,
                                                gfp_t gfp_mask, bool noswap,
                                                pg_data_t *pgdat,
@@ -3235,7 +3236,8 @@ unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg,
        };
        unsigned long lru_pages;
 
-       set_task_reclaim_state(current, &sc.reclaim_state);
+       WARN_ON_ONCE(!current->reclaim_state);
+
        sc.gfp_mask = (gfp_mask & GFP_RECLAIM_MASK) |
                        (GFP_HIGHUSER_MOVABLE & ~GFP_RECLAIM_MASK);
 
@@ -3253,7 +3255,6 @@ unsigned long mem_cgroup_shrink_node(struct mem_cgroup *memcg,
 
        trace_mm_vmscan_memcg_softlimit_reclaim_end(sc.nr_reclaimed);
 
-       set_task_reclaim_state(current, NULL);
        *nr_scanned = sc.nr_scanned;
 
        return sc.nr_reclaimed;
index e31cd9b..75b7962 100644 (file)
@@ -1406,6 +1406,7 @@ static bool z3fold_page_isolate(struct page *page, isolate_mode_t mode)
                                 * should freak out.
                                 */
                                WARN(1, "Z3fold is experiencing kref problems\n");
+                               z3fold_page_unlock(zhdr);
                                return false;
                        }
                        z3fold_page_unlock(zhdr);
index 08def3a..e98bb6a 100644 (file)
@@ -2412,7 +2412,9 @@ struct zs_pool *zs_create_pool(const char *name)
        if (!pool->name)
                goto err;
 
+#ifdef CONFIG_COMPACTION
        init_waitqueue_head(&pool->migration_wait);
+#endif
 
        if (create_cache(pool))
                goto err;
index 240ed70..d78938e 100644 (file)
@@ -277,17 +277,23 @@ static u8 batadv_hop_penalty(u8 tq, const struct batadv_priv *bat_priv)
  * batadv_iv_ogm_aggr_packet() - checks if there is another OGM attached
  * @buff_pos: current position in the skb
  * @packet_len: total length of the skb
- * @tvlv_len: tvlv length of the previously considered OGM
+ * @ogm_packet: potential OGM in buffer
  *
  * Return: true if there is enough space for another OGM, false otherwise.
  */
-static bool batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
-                                     __be16 tvlv_len)
+static bool
+batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
+                         const struct batadv_ogm_packet *ogm_packet)
 {
        int next_buff_pos = 0;
 
-       next_buff_pos += buff_pos + BATADV_OGM_HLEN;
-       next_buff_pos += ntohs(tvlv_len);
+       /* check if there is enough space for the header */
+       next_buff_pos += buff_pos + sizeof(*ogm_packet);
+       if (next_buff_pos > packet_len)
+               return false;
+
+       /* check if there is enough space for the optional TVLV */
+       next_buff_pos += ntohs(ogm_packet->tvlv_len);
 
        return (next_buff_pos <= packet_len) &&
               (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
@@ -315,7 +321,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
 
        /* adjust all flags and log packets */
        while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
-                                        batadv_ogm_packet->tvlv_len)) {
+                                        batadv_ogm_packet)) {
                /* we might have aggregated direct link packets with an
                 * ordinary base packet
                 */
@@ -1704,7 +1710,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
 
        /* unpack the aggregated packets and process them one by one */
        while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
-                                        ogm_packet->tvlv_len)) {
+                                        ogm_packet)) {
                batadv_iv_ogm_process(skb, ogm_offset, if_incoming);
 
                ogm_offset += BATADV_OGM_HLEN;
index fad95ef..bc06e3c 100644 (file)
@@ -631,17 +631,23 @@ batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv,
  * batadv_v_ogm_aggr_packet() - checks if there is another OGM aggregated
  * @buff_pos: current position in the skb
  * @packet_len: total length of the skb
- * @tvlv_len: tvlv length of the previously considered OGM
+ * @ogm2_packet: potential OGM2 in buffer
  *
  * Return: true if there is enough space for another OGM, false otherwise.
  */
-static bool batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
-                                    __be16 tvlv_len)
+static bool
+batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
+                        const struct batadv_ogm2_packet *ogm2_packet)
 {
        int next_buff_pos = 0;
 
-       next_buff_pos += buff_pos + BATADV_OGM2_HLEN;
-       next_buff_pos += ntohs(tvlv_len);
+       /* check if there is enough space for the header */
+       next_buff_pos += buff_pos + sizeof(*ogm2_packet);
+       if (next_buff_pos > packet_len)
+               return false;
+
+       /* check if there is enough space for the optional TVLV */
+       next_buff_pos += ntohs(ogm2_packet->tvlv_len);
 
        return (next_buff_pos <= packet_len) &&
               (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
@@ -818,7 +824,7 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb,
        ogm_packet = (struct batadv_ogm2_packet *)skb->data;
 
        while (batadv_v_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
-                                       ogm_packet->tvlv_len)) {
+                                       ogm_packet)) {
                batadv_v_ogm_process(skb, ogm_offset, if_incoming);
 
                ogm_offset += BATADV_OGM2_HLEN;
index 6f08fd1..7e052d6 100644 (file)
@@ -164,7 +164,7 @@ batadv_netlink_get_ifindex(const struct nlmsghdr *nlh, int attrtype)
 {
        struct nlattr *attr = nlmsg_find_attr(nlh, GENL_HDRLEN, attrtype);
 
-       return attr ? nla_get_u32(attr) : 0;
+       return (attr && nla_len(attr) == sizeof(u32)) ? nla_get_u32(attr) : 0;
 }
 
 /**
index cdb00c2..c1d3a30 100644 (file)
@@ -5660,11 +5660,6 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev,
                return send_conn_param_neg_reply(hdev, handle,
                                                 HCI_ERROR_UNKNOWN_CONN_ID);
 
-       if (min < hcon->le_conn_min_interval ||
-           max > hcon->le_conn_max_interval)
-               return send_conn_param_neg_reply(hdev, handle,
-                                                HCI_ERROR_INVALID_LL_PARAMS);
-
        if (hci_check_conn_params(min, max, latency, timeout))
                return send_conn_param_neg_reply(hdev, handle,
                                                 HCI_ERROR_INVALID_LL_PARAMS);
index dfc1edb..da7fdbd 100644 (file)
@@ -5305,14 +5305,7 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
 
        memset(&rsp, 0, sizeof(rsp));
 
-       if (min < hcon->le_conn_min_interval ||
-           max > hcon->le_conn_max_interval) {
-               BT_DBG("requested connection interval exceeds current bounds.");
-               err = -EINVAL;
-       } else {
-               err = hci_check_conn_params(min, max, latency, to_multiplier);
-       }
-
+       err = hci_check_conn_params(min, max, latency, to_multiplier);
        if (err)
                rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
        else
index bf6acd3..63f9c08 100644 (file)
@@ -437,7 +437,7 @@ static int nlmsg_populate_rtr_fill(struct sk_buff *skb,
        struct nlmsghdr *nlh;
        struct nlattr *nest;
 
-       nlh = nlmsg_put(skb, pid, seq, type, sizeof(*bpm), NLM_F_MULTI);
+       nlh = nlmsg_put(skb, pid, seq, type, sizeof(*bpm), 0);
        if (!nlh)
                return -EMSGSIZE;
 
index d3f9592..af78001 100644 (file)
@@ -496,6 +496,10 @@ static unsigned int br_nf_pre_routing(void *priv,
                if (!brnet->call_ip6tables &&
                    !br_opt_get(br, BROPT_NF_CALL_IP6TABLES))
                        return NF_ACCEPT;
+               if (!ipv6_mod_enabled()) {
+                       pr_warn_once("Module ipv6 is disabled, so call_ip6tables is not supported.");
+                       return NF_DROP;
+               }
 
                nf_bridge_pull_encap_header_rcsum(skb);
                return br_nf_pre_routing_ipv6(priv, skb, state);
index c8177a8..4096d8a 100644 (file)
@@ -221,7 +221,7 @@ unsigned int ebt_do_table(struct sk_buff *skb,
                        return NF_DROP;
                }
 
-               ADD_COUNTER(*(counter_base + i), 1, skb->len);
+               ADD_COUNTER(*(counter_base + i), skb->len, 1);
 
                /* these should only watch: not modify, nor tell us
                 * what to do with the packet
@@ -959,8 +959,8 @@ static void get_counters(const struct ebt_counter *oldcounters,
                        continue;
                counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
                for (i = 0; i < nentries; i++)
-                       ADD_COUNTER(counters[i], counter_base[i].pcnt,
-                                   counter_base[i].bcnt);
+                       ADD_COUNTER(counters[i], counter_base[i].bcnt,
+                                   counter_base[i].pcnt);
        }
 }
 
@@ -1280,7 +1280,7 @@ static int do_update_counters(struct net *net, const char *name,
 
        /* we add to the counters of the first cpu */
        for (i = 0; i < num_counters; i++)
-               ADD_COUNTER(t->private->counters[i], tmp[i].pcnt, tmp[i].bcnt);
+               ADD_COUNTER(t->private->counters[i], tmp[i].bcnt, tmp[i].pcnt);
 
        write_unlock_bh(&t->lock);
        ret = 0;
index 1804e86..7c9e92b 100644 (file)
@@ -53,7 +53,7 @@ static void nft_meta_bridge_get_eval(const struct nft_expr *expr,
                        goto err;
 
                br_vlan_get_proto(br_dev, &p_proto);
-               nft_reg_store16(dest, p_proto);
+               nft_reg_store16(dest, htons(p_proto));
                return;
        }
        default:
index 5d6724c..4f75df4 100644 (file)
@@ -136,8 +136,10 @@ void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
        if (key) {
                kfree(key->key);
                key->key = NULL;
-               crypto_free_sync_skcipher(key->tfm);
-               key->tfm = NULL;
+               if (key->tfm) {
+                       crypto_free_sync_skcipher(key->tfm);
+                       key->tfm = NULL;
+               }
        }
 }
 
index 0891f49..5156c0e 100644 (file)
@@ -8758,6 +8758,8 @@ int register_netdevice(struct net_device *dev)
        ret = notifier_to_errno(ret);
        if (ret) {
                rollback_registered(dev);
+               rcu_barrier();
+
                dev->reg_state = NETREG_UNREGISTERED;
        }
        /*
index 7878f91..4c6a252 100644 (file)
@@ -8757,13 +8757,13 @@ sk_reuseport_is_valid_access(int off, int size,
                return size == size_default;
 
        /* Fields that allow narrowing */
-       case offsetof(struct sk_reuseport_md, eth_protocol):
+       case bpf_ctx_range(struct sk_reuseport_md, eth_protocol):
                if (size < FIELD_SIZEOF(struct sk_buff, protocol))
                        return false;
                /* fall through */
-       case offsetof(struct sk_reuseport_md, ip_protocol):
-       case offsetof(struct sk_reuseport_md, bind_inany):
-       case offsetof(struct sk_reuseport_md, len):
+       case bpf_ctx_range(struct sk_reuseport_md, ip_protocol):
+       case bpf_ctx_range(struct sk_reuseport_md, bind_inany):
+       case bpf_ctx_range(struct sk_reuseport_md, len):
                bpf_ctx_record_field_size(info, size_default);
                return bpf_ctx_narrow_access_ok(off, size, size_default);
 
index 3e6fedb..2470b4b 100644 (file)
@@ -142,8 +142,8 @@ int skb_flow_dissector_bpf_prog_detach(const union bpf_attr *attr)
                mutex_unlock(&flow_dissector_mutex);
                return -ENOENT;
        }
-       bpf_prog_put(attached);
        RCU_INIT_POINTER(net->flow_dissector_prog, NULL);
+       bpf_prog_put(attached);
        mutex_unlock(&flow_dissector_mutex);
        return 0;
 }
index 2cf27da..849380a 100644 (file)
@@ -122,7 +122,7 @@ static void queue_process(struct work_struct *work)
                txq = netdev_get_tx_queue(dev, q_index);
                HARD_TX_LOCK(dev, txq, smp_processor_id());
                if (netif_xmit_frozen_or_stopped(txq) ||
-                   netpoll_start_xmit(skb, dev, txq) != NETDEV_TX_OK) {
+                   !dev_xmit_complete(netpoll_start_xmit(skb, dev, txq))) {
                        skb_queue_head(&npinfo->txq, skb);
                        HARD_TX_UNLOCK(dev, txq);
                        local_irq_restore(flags);
@@ -335,7 +335,7 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
 
                                HARD_TX_UNLOCK(dev, txq);
 
-                               if (status == NETDEV_TX_OK)
+                               if (dev_xmit_complete(status))
                                        break;
 
                        }
@@ -352,7 +352,7 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
 
        }
 
-       if (status != NETDEV_TX_OK) {
+       if (!dev_xmit_complete(status)) {
                skb_queue_tail(&npinfo->txq, skb);
                schedule_delayed_work(&npinfo->tx_work,0);
        }
index 0338820..982d8d1 100644 (file)
@@ -3664,6 +3664,25 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
        int pos;
        int dummy;
 
+       if (list_skb && !list_skb->head_frag && skb_headlen(list_skb) &&
+           (skb_shinfo(head_skb)->gso_type & SKB_GSO_DODGY)) {
+               /* gso_size is untrusted, and we have a frag_list with a linear
+                * non head_frag head.
+                *
+                * (we assume checking the first list_skb member suffices;
+                * i.e if either of the list_skb members have non head_frag
+                * head, then the first one has too).
+                *
+                * If head_skb's headlen does not fit requested gso_size, it
+                * means that the frag_list members do NOT terminate on exact
+                * gso_size boundaries. Hence we cannot perform skb_frag_t page
+                * sharing. Therefore we must fallback to copying the frag_list
+                * skbs; we do so by disabling SG.
+                */
+               if (mss != GSO_BY_FRAGS && mss != skb_headlen(head_skb))
+                       features &= ~NETIF_F_SG;
+       }
+
        __skb_push(head_skb, doffset);
        proto = skb_network_protocol(head_skb, &dummy);
        if (unlikely(!proto))
index 6d08553..545fac1 100644 (file)
@@ -3287,16 +3287,17 @@ static __init int net_inuse_init(void)
 
 core_initcall(net_inuse_init);
 
-static void assign_proto_idx(struct proto *prot)
+static int assign_proto_idx(struct proto *prot)
 {
        prot->inuse_idx = find_first_zero_bit(proto_inuse_idx, PROTO_INUSE_NR);
 
        if (unlikely(prot->inuse_idx == PROTO_INUSE_NR - 1)) {
                pr_err("PROTO_INUSE_NR exhausted\n");
-               return;
+               return -ENOSPC;
        }
 
        set_bit(prot->inuse_idx, proto_inuse_idx);
+       return 0;
 }
 
 static void release_proto_idx(struct proto *prot)
@@ -3305,8 +3306,9 @@ static void release_proto_idx(struct proto *prot)
                clear_bit(prot->inuse_idx, proto_inuse_idx);
 }
 #else
-static inline void assign_proto_idx(struct proto *prot)
+static inline int assign_proto_idx(struct proto *prot)
 {
+       return 0;
 }
 
 static inline void release_proto_idx(struct proto *prot)
@@ -3355,6 +3357,8 @@ static int req_prot_init(const struct proto *prot)
 
 int proto_register(struct proto *prot, int alloc_slab)
 {
+       int ret = -ENOBUFS;
+
        if (alloc_slab) {
                prot->slab = kmem_cache_create_usercopy(prot->name,
                                        prot->obj_size, 0,
@@ -3391,20 +3395,27 @@ int proto_register(struct proto *prot, int alloc_slab)
        }
 
        mutex_lock(&proto_list_mutex);
+       ret = assign_proto_idx(prot);
+       if (ret) {
+               mutex_unlock(&proto_list_mutex);
+               goto out_free_timewait_sock_slab_name;
+       }
        list_add(&prot->node, &proto_list);
-       assign_proto_idx(prot);
        mutex_unlock(&proto_list_mutex);
-       return 0;
+       return ret;
 
 out_free_timewait_sock_slab_name:
-       kfree(prot->twsk_prot->twsk_slab_name);
+       if (alloc_slab && prot->twsk_prot)
+               kfree(prot->twsk_prot->twsk_slab_name);
 out_free_request_sock_slab:
-       req_prot_cleanup(prot->rsk_prot);
+       if (alloc_slab) {
+               req_prot_cleanup(prot->rsk_prot);
 
-       kmem_cache_destroy(prot->slab);
-       prot->slab = NULL;
+               kmem_cache_destroy(prot->slab);
+               prot->slab = NULL;
+       }
 out:
-       return -ENOBUFS;
+       return ret;
 }
 EXPORT_SYMBOL(proto_register);
 
index 1330a74..50916f9 100644 (file)
@@ -656,6 +656,7 @@ static int sock_hash_update_common(struct bpf_map *map, void *key,
                                   struct sock *sk, u64 flags)
 {
        struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+       struct inet_connection_sock *icsk = inet_csk(sk);
        u32 key_size = map->key_size, hash;
        struct bpf_htab_elem *elem, *elem_new;
        struct bpf_htab_bucket *bucket;
@@ -666,6 +667,8 @@ static int sock_hash_update_common(struct bpf_map *map, void *key,
        WARN_ON_ONCE(!rcu_read_lock_held());
        if (unlikely(flags > BPF_EXIST))
                return -EINVAL;
+       if (unlikely(icsk->icsk_ulp_data))
+               return -EINVAL;
 
        link = sk_psock_init_link();
        if (!link)
index e94bb02..4f1d4aa 100644 (file)
@@ -120,7 +120,6 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
        int err = 0;
        long vm_wait = 0;
        long current_timeo = *timeo_p;
-       bool noblock = (*timeo_p ? false : true);
        DEFINE_WAIT_FUNC(wait, woken_wake_function);
 
        if (sk_stream_memory_free(sk))
@@ -133,11 +132,8 @@ int sk_stream_wait_memory(struct sock *sk, long *timeo_p)
 
                if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
                        goto do_error;
-               if (!*timeo_p) {
-                       if (noblock)
-                               set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
-                       goto do_nonblock;
-               }
+               if (!*timeo_p)
+                       goto do_eagain;
                if (signal_pending(current))
                        goto do_interrupted;
                sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);
@@ -169,7 +165,13 @@ out:
 do_error:
        err = -EPIPE;
        goto out;
-do_nonblock:
+do_eagain:
+       /* Make sure that whenever EAGAIN is returned, EPOLLOUT event can
+        * be generated later.
+        * When TCP receives ACK packets that make room, tcp_check_space()
+        * only calls tcp_new_space() if SOCK_NOSPACE is set.
+        */
+       set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
        err = -EAGAIN;
        goto out;
 do_interrupted:
index 6ebbd79..67a1bc6 100644 (file)
@@ -28,6 +28,7 @@
  *
  * RSV - VID[9]:
  *     To be used for further expansion of SWITCH_ID or for other purposes.
+ *     Must be transmitted as zero and ignored on receive.
  *
  * SWITCH_ID - VID[8:6]:
  *     Index of switch within DSA tree. Must be between 0 and
@@ -35,6 +36,7 @@
  *
  * RSV - VID[5:4]:
  *     To be used for further expansion of PORT or for other purposes.
+ *     Must be transmitted as zero and ignored on receive.
  *
  * PORT - VID[3:0]:
  *     Index of switch port. Must be between 0 and DSA_MAX_PORTS - 1.
index dacbd58..badc5cf 100644 (file)
@@ -1092,7 +1092,7 @@ static struct packet_type ieee802154_packet_type = {
 
 static int __init af_ieee802154_init(void)
 {
-       int rc = -EINVAL;
+       int rc;
 
        rc = proto_register(&ieee802154_raw_prot, 1);
        if (rc)
index 2db089e..0913a09 100644 (file)
@@ -1582,7 +1582,7 @@ failure:
 }
 
 int fib_nexthop_info(struct sk_buff *skb, const struct fib_nh_common *nhc,
-                    unsigned char *flags, bool skip_oif)
+                    u8 rt_family, unsigned char *flags, bool skip_oif)
 {
        if (nhc->nhc_flags & RTNH_F_DEAD)
                *flags |= RTNH_F_DEAD;
@@ -1613,7 +1613,7 @@ int fib_nexthop_info(struct sk_buff *skb, const struct fib_nh_common *nhc,
                /* if gateway family does not match nexthop family
                 * gateway is encoded as RTA_VIA
                 */
-               if (nhc->nhc_gw_family != nhc->nhc_family) {
+               if (rt_family != nhc->nhc_gw_family) {
                        int alen = sizeof(struct in6_addr);
                        struct nlattr *nla;
                        struct rtvia *via;
@@ -1654,7 +1654,7 @@ EXPORT_SYMBOL_GPL(fib_nexthop_info);
 
 #if IS_ENABLED(CONFIG_IP_ROUTE_MULTIPATH) || IS_ENABLED(CONFIG_IPV6)
 int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nhc,
-                   int nh_weight)
+                   int nh_weight, u8 rt_family)
 {
        const struct net_device *dev = nhc->nhc_dev;
        struct rtnexthop *rtnh;
@@ -1667,7 +1667,7 @@ int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nhc,
        rtnh->rtnh_hops = nh_weight - 1;
        rtnh->rtnh_ifindex = dev ? dev->ifindex : 0;
 
-       if (fib_nexthop_info(skb, nhc, &flags, true) < 0)
+       if (fib_nexthop_info(skb, nhc, rt_family, &flags, true) < 0)
                goto nla_put_failure;
 
        rtnh->rtnh_flags = flags;
@@ -1693,13 +1693,14 @@ static int fib_add_multipath(struct sk_buff *skb, struct fib_info *fi)
                goto nla_put_failure;
 
        if (unlikely(fi->nh)) {
-               if (nexthop_mpath_fill_node(skb, fi->nh) < 0)
+               if (nexthop_mpath_fill_node(skb, fi->nh, AF_INET) < 0)
                        goto nla_put_failure;
                goto mp_end;
        }
 
        for_nexthops(fi) {
-               if (fib_add_nexthop(skb, &nh->nh_common, nh->fib_nh_weight) < 0)
+               if (fib_add_nexthop(skb, &nh->nh_common, nh->fib_nh_weight,
+                                   AF_INET) < 0)
                        goto nla_put_failure;
 #ifdef CONFIG_IP_ROUTE_CLASSID
                if (nh->nh_tclassid &&
@@ -1775,7 +1776,7 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
                const struct fib_nh_common *nhc = fib_info_nhc(fi, 0);
                unsigned char flags = 0;
 
-               if (fib_nexthop_info(skb, nhc, &flags, false) < 0)
+               if (fib_nexthop_info(skb, nhc, AF_INET, &flags, false) < 0)
                        goto nla_put_failure;
 
                rtm->rtm_flags = flags;
index 2b2b3d2..1ab2fb6 100644 (file)
@@ -2145,7 +2145,7 @@ static int fn_trie_dump_leaf(struct key_vector *l, struct fib_table *tb,
 
                if (filter->dump_exceptions) {
                        err = fib_dump_info_fnhe(skb, cb, tb->tb_id, fi,
-                                                &i_fa, s_fa);
+                                                &i_fa, s_fa, flags);
                        if (err < 0)
                                goto stop;
                }
index 1510e95..4298aae 100644 (file)
@@ -582,7 +582,13 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,
 
        if (!rt)
                goto out;
-       net = dev_net(rt->dst.dev);
+
+       if (rt->dst.dev)
+               net = dev_net(rt->dst.dev);
+       else if (skb_in->dev)
+               net = dev_net(skb_in->dev);
+       else
+               goto out;
 
        /*
         *      Find the original header. It is expected to be valid, of course.
@@ -902,7 +908,7 @@ static bool icmp_redirect(struct sk_buff *skb)
                return false;
        }
 
-       icmp_socket_deliver(skb, icmp_hdr(skb)->un.gateway);
+       icmp_socket_deliver(skb, ntohl(icmp_hdr(skb)->un.gateway));
        return true;
 }
 
index 180f689..480d0b2 100644 (file)
@@ -1475,7 +1475,7 @@ EXPORT_SYMBOL(__ip_mc_inc_group);
 
 void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
 {
-       __ip_mc_inc_group(in_dev, addr, MCAST_EXCLUDE);
+       __ip_mc_inc_group(in_dev, addr, GFP_KERNEL);
 }
 EXPORT_SYMBOL(ip_mc_inc_group);
 
@@ -2197,7 +2197,7 @@ static int __ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr,
        iml->sflist = NULL;
        iml->sfmode = mode;
        rcu_assign_pointer(inet->mc_list, iml);
-       __ip_mc_inc_group(in_dev, addr, mode);
+       ____ip_mc_inc_group(in_dev, addr, mode, GFP_KERNEL);
        err = 0;
 done:
        return err;
index 517300d..b6a6f18 100644 (file)
@@ -2728,7 +2728,8 @@ EXPORT_SYMBOL_GPL(ip_route_output_flow);
 /* called with rcu_read_lock held */
 static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
                        struct rtable *rt, u32 table_id, struct flowi4 *fl4,
-                       struct sk_buff *skb, u32 portid, u32 seq)
+                       struct sk_buff *skb, u32 portid, u32 seq,
+                       unsigned int flags)
 {
        struct rtmsg *r;
        struct nlmsghdr *nlh;
@@ -2736,7 +2737,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
        u32 error;
        u32 metrics[RTAX_MAX];
 
-       nlh = nlmsg_put(skb, portid, seq, RTM_NEWROUTE, sizeof(*r), 0);
+       nlh = nlmsg_put(skb, portid, seq, RTM_NEWROUTE, sizeof(*r), flags);
        if (!nlh)
                return -EMSGSIZE;
 
@@ -2860,7 +2861,7 @@ nla_put_failure:
 static int fnhe_dump_bucket(struct net *net, struct sk_buff *skb,
                            struct netlink_callback *cb, u32 table_id,
                            struct fnhe_hash_bucket *bucket, int genid,
-                           int *fa_index, int fa_start)
+                           int *fa_index, int fa_start, unsigned int flags)
 {
        int i;
 
@@ -2891,7 +2892,7 @@ static int fnhe_dump_bucket(struct net *net, struct sk_buff *skb,
                        err = rt_fill_info(net, fnhe->fnhe_daddr, 0, rt,
                                           table_id, NULL, skb,
                                           NETLINK_CB(cb->skb).portid,
-                                          cb->nlh->nlmsg_seq);
+                                          cb->nlh->nlmsg_seq, flags);
                        if (err)
                                return err;
 next:
@@ -2904,7 +2905,7 @@ next:
 
 int fib_dump_info_fnhe(struct sk_buff *skb, struct netlink_callback *cb,
                       u32 table_id, struct fib_info *fi,
-                      int *fa_index, int fa_start)
+                      int *fa_index, int fa_start, unsigned int flags)
 {
        struct net *net = sock_net(cb->skb->sk);
        int nhsel, genid = fnhe_genid(net);
@@ -2922,7 +2923,8 @@ int fib_dump_info_fnhe(struct sk_buff *skb, struct netlink_callback *cb,
                err = 0;
                if (bucket)
                        err = fnhe_dump_bucket(net, skb, cb, table_id, bucket,
-                                              genid, fa_index, fa_start);
+                                              genid, fa_index, fa_start,
+                                              flags);
                rcu_read_unlock();
                if (err)
                        return err;
@@ -3183,7 +3185,8 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
                                    fl4.flowi4_tos, res.fi, 0);
        } else {
                err = rt_fill_info(net, dst, src, rt, table_id, &fl4, skb,
-                                  NETLINK_CB(in_skb).portid, nlh->nlmsg_seq);
+                                  NETLINK_CB(in_skb).portid,
+                                  nlh->nlmsg_seq, 0);
        }
        if (err < 0)
                goto errout_rcu;
index 77b485d..6108206 100644 (file)
@@ -935,6 +935,22 @@ static int tcp_send_mss(struct sock *sk, int *size_goal, int flags)
        return mss_now;
 }
 
+/* In some cases, both sendpage() and sendmsg() could have added
+ * an skb to the write queue, but failed adding payload on it.
+ * We need to remove it to consume less memory, but more
+ * importantly be able to generate EPOLLOUT for Edge Trigger epoll()
+ * users.
+ */
+static void tcp_remove_empty_skb(struct sock *sk, struct sk_buff *skb)
+{
+       if (skb && !skb->len) {
+               tcp_unlink_write_queue(skb, sk);
+               if (tcp_write_queue_empty(sk))
+                       tcp_chrono_stop(sk, TCP_CHRONO_BUSY);
+               sk_wmem_free_skb(sk, skb);
+       }
+}
+
 ssize_t do_tcp_sendpages(struct sock *sk, struct page *page, int offset,
                         size_t size, int flags)
 {
@@ -1064,6 +1080,7 @@ out:
        return copied;
 
 do_error:
+       tcp_remove_empty_skb(sk, tcp_write_queue_tail(sk));
        if (copied)
                goto out;
 out_err:
@@ -1388,18 +1405,11 @@ out_nopush:
        sock_zerocopy_put(uarg);
        return copied + copied_syn;
 
+do_error:
+       skb = tcp_write_queue_tail(sk);
 do_fault:
-       if (!skb->len) {
-               tcp_unlink_write_queue(skb, sk);
-               /* It is the one place in all of TCP, except connection
-                * reset, where we can be unlinking the send_head.
-                */
-               if (tcp_write_queue_empty(sk))
-                       tcp_chrono_stop(sk, TCP_CHRONO_BUSY);
-               sk_wmem_free_skb(sk, skb);
-       }
+       tcp_remove_empty_skb(sk, skb);
 
-do_error:
        if (copied + copied_syn)
                goto out;
 out_err:
index c21e8a2..8a1cd93 100644 (file)
@@ -266,7 +266,7 @@ static void tcp_ecn_accept_cwr(struct sock *sk, const struct sk_buff *skb)
 
 static void tcp_ecn_withdraw_cwr(struct tcp_sock *tp)
 {
-       tp->ecn_flags &= ~TCP_ECN_DEMAND_CWR;
+       tp->ecn_flags &= ~TCP_ECN_QUEUE_CWR;
 }
 
 static void __tcp_ecn_check_ce(struct sock *sk, const struct sk_buff *skb)
index 979520e..8a645f3 100644 (file)
@@ -2053,7 +2053,7 @@ static bool tcp_can_coalesce_send_queue_head(struct sock *sk, int len)
                if (len <= skb->len)
                        break;
 
-               if (unlikely(TCP_SKB_CB(skb)->eor))
+               if (unlikely(TCP_SKB_CB(skb)->eor) || tcp_has_tx_tstamp(skb))
                        return false;
 
                len -= skb->len;
@@ -2170,6 +2170,7 @@ static int tcp_mtu_probe(struct sock *sk)
                         * we need to propagate it to the new skb.
                         */
                        TCP_SKB_CB(nskb)->eor = TCP_SKB_CB(skb)->eor;
+                       tcp_skb_collapse_tstamp(nskb, skb);
                        tcp_unlink_write_queue(skb, sk);
                        sk_wmem_free_skb(sk, skb);
                } else {
index dc73888..6a576ff 100644 (file)
@@ -478,7 +478,7 @@ static struct inet6_dev *ipv6_find_idev(struct net_device *dev)
        if (!idev) {
                idev = ipv6_add_dev(dev);
                if (IS_ERR(idev))
-                       return NULL;
+                       return idev;
        }
 
        if (dev->flags&IFF_UP)
@@ -1045,7 +1045,8 @@ ipv6_add_addr(struct inet6_dev *idev, struct ifa6_config *cfg,
        int err = 0;
 
        if (addr_type == IPV6_ADDR_ANY ||
-           addr_type & IPV6_ADDR_MULTICAST ||
+           (addr_type & IPV6_ADDR_MULTICAST &&
+            !(cfg->ifa_flags & IFA_F_MCAUTOJOIN)) ||
            (!(idev->dev->flags & IFF_LOOPBACK) &&
             !netif_is_l3_master(idev->dev) &&
             addr_type & IPV6_ADDR_LOOPBACK))
@@ -2465,8 +2466,8 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
        ASSERT_RTNL();
 
        idev = ipv6_find_idev(dev);
-       if (!idev)
-               return ERR_PTR(-ENOBUFS);
+       if (IS_ERR(idev))
+               return idev;
 
        if (idev->cnf.disable_ipv6)
                return ERR_PTR(-EACCES);
@@ -3158,7 +3159,7 @@ static void init_loopback(struct net_device *dev)
        ASSERT_RTNL();
 
        idev = ipv6_find_idev(dev);
-       if (!idev) {
+       if (IS_ERR(idev)) {
                pr_debug("%s: add_dev failed\n", __func__);
                return;
        }
@@ -3373,7 +3374,7 @@ static void addrconf_sit_config(struct net_device *dev)
         */
 
        idev = ipv6_find_idev(dev);
-       if (!idev) {
+       if (IS_ERR(idev)) {
                pr_debug("%s: add_dev failed\n", __func__);
                return;
        }
@@ -3398,7 +3399,7 @@ static void addrconf_gre_config(struct net_device *dev)
        ASSERT_RTNL();
 
        idev = ipv6_find_idev(dev);
-       if (!idev) {
+       if (IS_ERR(idev)) {
                pr_debug("%s: add_dev failed\n", __func__);
                return;
        }
@@ -4772,8 +4773,8 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
                         IFA_F_MCAUTOJOIN | IFA_F_OPTIMISTIC;
 
        idev = ipv6_find_idev(dev);
-       if (!idev)
-               return -ENOBUFS;
+       if (IS_ERR(idev))
+               return PTR_ERR(idev);
 
        if (!ipv6_allow_optimistic_dad(net, idev))
                cfg.ifa_flags &= ~IFA_F_OPTIMISTIC;
index 7f3f13c..eaa4c2c 100644 (file)
@@ -787,14 +787,15 @@ static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
        if (pmc) {
                im->idev = pmc->idev;
                if (im->mca_sfmode == MCAST_INCLUDE) {
-                       im->mca_tomb = pmc->mca_tomb;
-                       im->mca_sources = pmc->mca_sources;
+                       swap(im->mca_tomb, pmc->mca_tomb);
+                       swap(im->mca_sources, pmc->mca_sources);
                        for (psf = im->mca_sources; psf; psf = psf->sf_next)
                                psf->sf_crcount = idev->mc_qrv;
                } else {
                        im->mca_crcount = idev->mc_qrv;
                }
                in6_dev_put(pmc->idev);
+               ip6_mc_clear_src(pmc);
                kfree(pmc);
        }
        spin_unlock_bh(&im->mca_lock);
index 87d2d8c..98ac32b 100644 (file)
@@ -223,7 +223,7 @@ static int __net_init ping_v6_proc_init_net(struct net *net)
        return 0;
 }
 
-static void __net_init ping_v6_proc_exit_net(struct net *net)
+static void __net_exit ping_v6_proc_exit_net(struct net *net)
 {
        remove_proc_entry("icmp6", net->proc_net);
 }
index fd059e0..546088e 100644 (file)
@@ -4388,13 +4388,14 @@ struct fib6_info *addrconf_f6i_alloc(struct net *net,
        struct fib6_config cfg = {
                .fc_table = l3mdev_fib_table(idev->dev) ? : RT6_TABLE_LOCAL,
                .fc_ifindex = idev->dev->ifindex,
-               .fc_flags = RTF_UP | RTF_ADDRCONF | RTF_NONEXTHOP,
+               .fc_flags = RTF_UP | RTF_NONEXTHOP,
                .fc_dst = *addr,
                .fc_dst_len = 128,
                .fc_protocol = RTPROT_KERNEL,
                .fc_nlinfo.nl_net = net,
                .fc_ignore_dev_down = true,
        };
+       struct fib6_info *f6i;
 
        if (anycast) {
                cfg.fc_type = RTN_ANYCAST;
@@ -4404,7 +4405,10 @@ struct fib6_info *addrconf_f6i_alloc(struct net *net,
                cfg.fc_flags |= RTF_LOCAL;
        }
 
-       return ip6_route_info_create(&cfg, gfp_flags, NULL);
+       f6i = ip6_route_info_create(&cfg, gfp_flags, NULL);
+       if (!IS_ERR(f6i))
+               f6i->dst_nocount = true;
+       return f6i;
 }
 
 /* remove deleted ip from prefsrc entries */
@@ -5325,11 +5329,11 @@ static int rt6_fill_node_nexthop(struct sk_buff *skb, struct nexthop *nh,
        if (nexthop_is_multipath(nh)) {
                struct nlattr *mp;
 
-               mp = nla_nest_start(skb, RTA_MULTIPATH);
+               mp = nla_nest_start_noflag(skb, RTA_MULTIPATH);
                if (!mp)
                        goto nla_put_failure;
 
-               if (nexthop_mpath_fill_node(skb, nh))
+               if (nexthop_mpath_fill_node(skb, nh, AF_INET6))
                        goto nla_put_failure;
 
                nla_nest_end(skb, mp);
@@ -5337,7 +5341,7 @@ static int rt6_fill_node_nexthop(struct sk_buff *skb, struct nexthop *nh,
                struct fib6_nh *fib6_nh;
 
                fib6_nh = nexthop_fib6_nh(nh);
-               if (fib_nexthop_info(skb, &fib6_nh->nh_common,
+               if (fib_nexthop_info(skb, &fib6_nh->nh_common, AF_INET6,
                                     flags, false) < 0)
                        goto nla_put_failure;
        }
@@ -5466,13 +5470,14 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
                        goto nla_put_failure;
 
                if (fib_add_nexthop(skb, &rt->fib6_nh->nh_common,
-                                   rt->fib6_nh->fib_nh_weight) < 0)
+                                   rt->fib6_nh->fib_nh_weight, AF_INET6) < 0)
                        goto nla_put_failure;
 
                list_for_each_entry_safe(sibling, next_sibling,
                                         &rt->fib6_siblings, fib6_siblings) {
                        if (fib_add_nexthop(skb, &sibling->fib6_nh->nh_common,
-                                           sibling->fib6_nh->fib_nh_weight) < 0)
+                                           sibling->fib6_nh->fib_nh_weight,
+                                           AF_INET6) < 0)
                                goto nla_put_failure;
                }
 
@@ -5489,7 +5494,7 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
 
                rtm->rtm_flags |= nh_flags;
        } else {
-               if (fib_nexthop_info(skb, &rt->fib6_nh->nh_common,
+               if (fib_nexthop_info(skb, &rt->fib6_nh->nh_common, AF_INET6,
                                     &nh_flags, false) < 0)
                        goto nla_put_failure;
 
index 4d45806..4105c97 100644 (file)
@@ -1529,7 +1529,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
        struct sta_info *sta;
        struct ieee80211_sub_if_data *sdata;
        int err;
-       int layer2_update;
 
        if (params->vlan) {
                sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
@@ -1546,6 +1545,11 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
        if (is_multicast_ether_addr(mac))
                return -EINVAL;
 
+       if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER) &&
+           sdata->vif.type == NL80211_IFTYPE_STATION &&
+           !sdata->u.mgd.associated)
+               return -EINVAL;
+
        sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
        if (!sta)
                return -ENOMEM;
@@ -1553,10 +1557,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
        if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))
                sta->sta.tdls = true;
 
-       if (sta->sta.tdls && sdata->vif.type == NL80211_IFTYPE_STATION &&
-           !sdata->u.mgd.associated)
-               return -EINVAL;
-
        err = sta_apply_parameters(local, sta, params);
        if (err) {
                sta_info_free(local, sta);
@@ -1572,18 +1572,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
            test_sta_flag(sta, WLAN_STA_ASSOC))
                rate_control_rate_init(sta);
 
-       layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
-               sdata->vif.type == NL80211_IFTYPE_AP;
-
        err = sta_info_insert_rcu(sta);
        if (err) {
                rcu_read_unlock();
                return err;
        }
 
-       if (layer2_update)
-               cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr);
-
        rcu_read_unlock();
 
        return 0;
@@ -1681,10 +1675,11 @@ static int ieee80211_change_station(struct wiphy *wiphy,
                sta->sdata = vlansdata;
                ieee80211_check_fast_xmit(sta);
 
-               if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
+               if (test_sta_flag(sta, WLAN_STA_AUTHORIZED)) {
                        ieee80211_vif_inc_num_mcast(sta->sdata);
-
-               cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr);
+                       cfg80211_send_layer2_update(sta->sdata->dev,
+                                                   sta->sta.addr);
+               }
        }
 
        err = sta_apply_parameters(local, sta, params);
index 3c1ab87..768d14c 100644 (file)
@@ -2447,11 +2447,13 @@ static void ieee80211_deliver_skb_to_local_stack(struct sk_buff *skb,
                      skb->protocol == cpu_to_be16(ETH_P_PREAUTH)) &&
                     sdata->control_port_over_nl80211)) {
                struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
-               bool noencrypt = status->flag & RX_FLAG_DECRYPTED;
+               bool noencrypt = !(status->flag & RX_FLAG_DECRYPTED);
 
                cfg80211_rx_control_port(dev, skb, noencrypt);
                dev_kfree_skb(skb);
        } else {
+               memset(skb->cb, 0, sizeof(skb->cb));
+
                /* deliver to local stack */
                if (rx->napi)
                        napi_gro_receive(rx->napi, skb);
@@ -2546,8 +2548,6 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
 
        if (skb) {
                skb->protocol = eth_type_trans(skb, dev);
-               memset(skb->cb, 0, sizeof(skb->cb));
-
                ieee80211_deliver_skb_to_local_stack(skb, rx);
        }
 
index 95eb822..5fb368c 100644 (file)
@@ -1979,6 +1979,10 @@ int sta_info_move_state(struct sta_info *sta,
                        ieee80211_check_fast_xmit(sta);
                        ieee80211_check_fast_rx(sta);
                }
+               if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
+                   sta->sdata->vif.type == NL80211_IFTYPE_AP)
+                       cfg80211_send_layer2_update(sta->sdata->dev,
+                                                   sta->sta.addr);
                break;
        default:
                break;
index d25e91d..44b6750 100644 (file)
@@ -133,12 +133,12 @@ static int mpls_xmit(struct sk_buff *skb)
        mpls_stats_inc_outucastpkts(out_dev, skb);
 
        if (rt) {
-               if (rt->rt_gw_family == AF_INET)
-                       err = neigh_xmit(NEIGH_ARP_TABLE, out_dev, &rt->rt_gw4,
-                                        skb);
-               else if (rt->rt_gw_family == AF_INET6)
+               if (rt->rt_gw_family == AF_INET6)
                        err = neigh_xmit(NEIGH_ND_TABLE, out_dev, &rt->rt_gw6,
                                         skb);
+               else
+                       err = neigh_xmit(NEIGH_ARP_TABLE, out_dev, &rt->rt_gw4,
+                                        skb);
        } else if (rt6) {
                if (ipv6_addr_v4mapped(&rt6->rt6i_gateway)) {
                        /* 6PE (RFC 4798) */
index 5c3fad8..0187e65 100644 (file)
@@ -54,7 +54,7 @@ static void ncsi_cmd_build_header(struct ncsi_pkt_hdr *h,
        checksum = ncsi_calculate_checksum((unsigned char *)h,
                                           sizeof(*h) + nca->payload);
        pchecksum = (__be32 *)((void *)h + sizeof(struct ncsi_pkt_hdr) +
-                   nca->payload);
+                   ALIGN(nca->payload, 4));
        *pchecksum = htonl(checksum);
 }
 
@@ -309,14 +309,21 @@ static struct ncsi_request *ncsi_alloc_command(struct ncsi_cmd_arg *nca)
 
 int ncsi_xmit_cmd(struct ncsi_cmd_arg *nca)
 {
+       struct ncsi_cmd_handler *nch = NULL;
        struct ncsi_request *nr;
+       unsigned char type;
        struct ethhdr *eh;
-       struct ncsi_cmd_handler *nch = NULL;
        int i, ret;
 
+       /* Use OEM generic handler for Netlink request */
+       if (nca->req_flags == NCSI_REQ_FLAG_NETLINK_DRIVEN)
+               type = NCSI_PKT_CMD_OEM;
+       else
+               type = nca->type;
+
        /* Search for the handler */
        for (i = 0; i < ARRAY_SIZE(ncsi_cmd_handlers); i++) {
-               if (ncsi_cmd_handlers[i].type == nca->type) {
+               if (ncsi_cmd_handlers[i].type == type) {
                        if (ncsi_cmd_handlers[i].handler)
                                nch = &ncsi_cmd_handlers[i];
                        else
index 7581bf9..d876bd5 100644 (file)
@@ -47,7 +47,8 @@ static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
        if (ntohs(h->code) != NCSI_PKT_RSP_C_COMPLETED ||
            ntohs(h->reason) != NCSI_PKT_RSP_R_NO_ERROR) {
                netdev_dbg(nr->ndp->ndev.dev,
-                          "NCSI: non zero response/reason code\n");
+                          "NCSI: non zero response/reason code %04xh, %04xh\n",
+                           ntohs(h->code), ntohs(h->reason));
                return -EPERM;
        }
 
@@ -55,7 +56,7 @@ static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
         * sender doesn't support checksum according to NCSI
         * specification.
         */
-       pchecksum = (__be32 *)((void *)(h + 1) + payload - 4);
+       pchecksum = (__be32 *)((void *)(h + 1) + ALIGN(payload, 4) - 4);
        if (ntohl(*pchecksum) == 0)
                return 0;
 
@@ -63,7 +64,9 @@ static int ncsi_validate_rsp_pkt(struct ncsi_request *nr,
                                           sizeof(*h) + payload - 4);
 
        if (*pchecksum != htonl(checksum)) {
-               netdev_dbg(nr->ndp->ndev.dev, "NCSI: checksum mismatched\n");
+               netdev_dbg(nr->ndp->ndev.dev,
+                          "NCSI: checksum mismatched; recd: %08x calc: %08x\n",
+                          *pchecksum, htonl(checksum));
                return -EINVAL;
        }
 
index 0ecb3e2..8d96738 100644 (file)
@@ -322,7 +322,7 @@ static int find_pattern(const char *data, size_t dlen,
                i++;
        }
 
-       pr_debug("Skipped up to `%c'!\n", skip);
+       pr_debug("Skipped up to 0x%hhx delimiter!\n", skip);
 
        *numoff = i;
        *numlen = getnum(data + i, dlen - i, cmd, term, numoff);
index 6aa01eb..e2d13cd 100644 (file)
@@ -553,10 +553,8 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
                goto nla_put_failure;
 
        if (ctnetlink_dump_status(skb, ct) < 0 ||
-           ctnetlink_dump_timeout(skb, ct) < 0 ||
            ctnetlink_dump_acct(skb, ct, type) < 0 ||
            ctnetlink_dump_timestamp(skb, ct) < 0 ||
-           ctnetlink_dump_protoinfo(skb, ct) < 0 ||
            ctnetlink_dump_helpinfo(skb, ct) < 0 ||
            ctnetlink_dump_mark(skb, ct) < 0 ||
            ctnetlink_dump_secctx(skb, ct) < 0 ||
@@ -568,6 +566,11 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
            ctnetlink_dump_ct_synproxy(skb, ct) < 0)
                goto nla_put_failure;
 
+       if (!test_bit(IPS_OFFLOAD_BIT, &ct->status) &&
+           (ctnetlink_dump_timeout(skb, ct) < 0 ||
+            ctnetlink_dump_protoinfo(skb, ct) < 0))
+               goto nla_put_failure;
+
        nlmsg_end(skb, nlh);
        return skb->len;
 
index e0d392c..0006503 100644 (file)
@@ -1037,9 +1037,14 @@ static int nf_conntrack_standalone_init_sysctl(struct net *net)
        table[NF_SYSCTL_CT_COUNT].data = &net->ct.count;
        table[NF_SYSCTL_CT_CHECKSUM].data = &net->ct.sysctl_checksum;
        table[NF_SYSCTL_CT_LOG_INVALID].data = &net->ct.sysctl_log_invalid;
+       table[NF_SYSCTL_CT_ACCT].data = &net->ct.sysctl_acct;
+       table[NF_SYSCTL_CT_HELPER].data = &net->ct.sysctl_auto_assign_helper;
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
        table[NF_SYSCTL_CT_EVENTS].data = &net->ct.sysctl_events;
 #endif
+#ifdef CONFIG_NF_CONNTRACK_TIMESTAMP
+       table[NF_SYSCTL_CT_TIMESTAMP].data = &net->ct.sysctl_tstamp;
+#endif
        table[NF_SYSCTL_CT_PROTO_TIMEOUT_GENERIC].data = &nf_generic_pernet(net)->timeout;
        table[NF_SYSCTL_CT_PROTO_TIMEOUT_ICMP].data = &nf_icmp_pernet(net)->timeout;
        table[NF_SYSCTL_CT_PROTO_TIMEOUT_ICMPV6].data = &nf_icmpv6_pernet(net)->timeout;
index 80a8f9a..a0b4bf6 100644 (file)
@@ -217,7 +217,7 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow)
                return err;
        }
 
-       flow->timeout = (u32)jiffies;
+       flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT;
        return 0;
 }
 EXPORT_SYMBOL_GPL(flow_offload_add);
index d68c801..b9e7dd6 100644 (file)
@@ -228,7 +228,6 @@ static unsigned int nf_flow_xmit_xfrm(struct sk_buff *skb,
 {
        skb_orphan(skb);
        skb_dst_set_noref(skb, dst);
-       skb->tstamp = 0;
        dst_output(state->net, state->sk, skb);
        return NF_STOLEN;
 }
@@ -284,6 +283,7 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
        flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT;
        iph = ip_hdr(skb);
        ip_decrease_ttl(iph);
+       skb->tstamp = 0;
 
        if (unlikely(dst_xfrm(&rt->dst))) {
                memset(skb->cb, 0, sizeof(struct inet_skb_parm));
@@ -512,6 +512,7 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
        flow->timeout = (u32)jiffies + NF_FLOW_TIMEOUT;
        ip6h = ipv6_hdr(skb);
        ip6h->hop_limit--;
+       skb->tstamp = 0;
 
        if (unlikely(dst_xfrm(&rt->dst))) {
                memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
index 2cf3f32..a2e726a 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables_core.h>
 #include <net/netfilter/nf_tables.h>
+#include <net/ipv6.h>
 
 #include <net/netfilter/nft_fib.h>
 
@@ -34,6 +35,8 @@ static void nft_fib_netdev_eval(const struct nft_expr *expr,
                }
                break;
        case ETH_P_IPV6:
+               if (!ipv6_mod_enabled())
+                       break;
                switch (priv->result) {
                case NFT_FIB_RESULT_OIF:
                case NFT_FIB_RESULT_OIFNAME:
index 060a4ed..01705ad 100644 (file)
@@ -149,6 +149,11 @@ static int nft_flow_offload_validate(const struct nft_ctx *ctx,
        return nft_chain_validate_hooks(ctx->chain, hook_mask);
 }
 
+static const struct nla_policy nft_flow_offload_policy[NFTA_FLOW_MAX + 1] = {
+       [NFTA_FLOW_TABLE_NAME]  = { .type = NLA_STRING,
+                                   .len = NFT_NAME_MAXLEN - 1 },
+};
+
 static int nft_flow_offload_init(const struct nft_ctx *ctx,
                                 const struct nft_expr *expr,
                                 const struct nlattr * const tb[])
@@ -207,6 +212,7 @@ static const struct nft_expr_ops nft_flow_offload_ops = {
 static struct nft_expr_type nft_flow_offload_type __read_mostly = {
        .name           = "flow_offload",
        .ops            = &nft_flow_offload_ops,
+       .policy         = nft_flow_offload_policy,
        .maxattr        = NFTA_FLOW_MAX,
        .owner          = THIS_MODULE,
 };
index d7f3776..637ce3e 100644 (file)
@@ -47,9 +47,6 @@ static void nft_socket_eval(const struct nft_expr *expr,
                return;
        }
 
-       /* So that subsequent socket matching not to require other lookups. */
-       skb->sk = sk;
-
        switch(priv->key) {
        case NFT_SOCKET_TRANSPARENT:
                nft_reg_store8(dest, inet_sk_transparent(sk));
@@ -66,6 +63,9 @@ static void nft_socket_eval(const struct nft_expr *expr,
                WARN_ON(1);
                regs->verdict.code = NFT_BREAK;
        }
+
+       if (sk != skb->sk)
+               sock_gen_put(sk);
 }
 
 static const struct nla_policy nft_socket_policy[NFTA_SOCKET_MAX + 1] = {
index d0ab1ad..5aab6df 100644 (file)
@@ -54,25 +54,39 @@ nfacct_mt_destroy(const struct xt_mtdtor_param *par)
        nfnl_acct_put(info->nfacct);
 }
 
-static struct xt_match nfacct_mt_reg __read_mostly = {
-       .name       = "nfacct",
-       .family     = NFPROTO_UNSPEC,
-       .checkentry = nfacct_mt_checkentry,
-       .match      = nfacct_mt,
-       .destroy    = nfacct_mt_destroy,
-       .matchsize  = sizeof(struct xt_nfacct_match_info),
-       .usersize   = offsetof(struct xt_nfacct_match_info, nfacct),
-       .me         = THIS_MODULE,
+static struct xt_match nfacct_mt_reg[] __read_mostly = {
+       {
+               .name       = "nfacct",
+               .revision   = 0,
+               .family     = NFPROTO_UNSPEC,
+               .checkentry = nfacct_mt_checkentry,
+               .match      = nfacct_mt,
+               .destroy    = nfacct_mt_destroy,
+               .matchsize  = sizeof(struct xt_nfacct_match_info),
+               .usersize   = offsetof(struct xt_nfacct_match_info, nfacct),
+               .me         = THIS_MODULE,
+       },
+       {
+               .name       = "nfacct",
+               .revision   = 1,
+               .family     = NFPROTO_UNSPEC,
+               .checkentry = nfacct_mt_checkentry,
+               .match      = nfacct_mt,
+               .destroy    = nfacct_mt_destroy,
+               .matchsize  = sizeof(struct xt_nfacct_match_info_v1),
+               .usersize   = offsetof(struct xt_nfacct_match_info_v1, nfacct),
+               .me         = THIS_MODULE,
+       },
 };
 
 static int __init nfacct_mt_init(void)
 {
-       return xt_register_match(&nfacct_mt_reg);
+       return xt_register_matches(nfacct_mt_reg, ARRAY_SIZE(nfacct_mt_reg));
 }
 
 static void __exit nfacct_mt_exit(void)
 {
-       xt_unregister_match(&nfacct_mt_reg);
+       xt_unregister_matches(nfacct_mt_reg, ARRAY_SIZE(nfacct_mt_reg));
 }
 
 module_init(nfacct_mt_init);
index ead7c60..b92b22c 100644 (file)
@@ -101,11 +101,9 @@ static int physdev_mt_check(const struct xt_mtchk_param *par)
        if (info->bitmask & (XT_PHYSDEV_OP_OUT | XT_PHYSDEV_OP_ISOUT) &&
            (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
             info->invert & XT_PHYSDEV_OP_BRIDGED) &&
-           par->hook_mask & ((1 << NF_INET_LOCAL_OUT) |
-           (1 << NF_INET_FORWARD) | (1 << NF_INET_POST_ROUTING))) {
+           par->hook_mask & (1 << NF_INET_LOCAL_OUT)) {
                pr_info_ratelimited("--physdev-out and --physdev-is-out only supported in the FORWARD and POSTROUTING chains with bridged traffic\n");
-               if (par->hook_mask & (1 << NF_INET_LOCAL_OUT))
-                       return -EINVAL;
+               return -EINVAL;
        }
 
        if (!brnf_probed) {
index 848c6eb..05249eb 100644 (file)
@@ -67,6 +67,7 @@ struct ovs_conntrack_info {
        struct md_mark mark;
        struct md_labels labels;
        char timeout[CTNL_TIMEOUT_NAME_MAX];
+       struct nf_ct_timeout *nf_ct_timeout;
 #if IS_ENABLED(CONFIG_NF_NAT)
        struct nf_nat_range2 range;  /* Only present for SRC NAT and DST NAT. */
 #endif
@@ -524,6 +525,11 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key,
                return -EPFNOSUPPORT;
        }
 
+       /* The key extracted from the fragment that completed this datagram
+        * likely didn't have an L4 header, so regenerate it.
+        */
+       ovs_flow_key_update_l3l4(skb, key);
+
        key->ip.frag = OVS_FRAG_TYPE_NONE;
        skb_clear_hash(skb);
        skb->ignore_df = 1;
@@ -697,6 +703,14 @@ static bool skb_nfct_cached(struct net *net,
                if (help && rcu_access_pointer(help->helper) != info->helper)
                        return false;
        }
+       if (info->nf_ct_timeout) {
+               struct nf_conn_timeout *timeout_ext;
+
+               timeout_ext = nf_ct_timeout_find(ct);
+               if (!timeout_ext || info->nf_ct_timeout !=
+                   rcu_dereference(timeout_ext->timeout))
+                       return false;
+       }
        /* Force conntrack entry direction to the current packet? */
        if (info->force && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) {
                /* Delete the conntrack entry if confirmed, else just release
@@ -1565,7 +1579,7 @@ static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
                case OVS_CT_ATTR_TIMEOUT:
                        memcpy(info->timeout, nla_data(a), nla_len(a));
                        if (!memchr(info->timeout, '\0', nla_len(a))) {
-                               OVS_NLERR(log, "Invalid conntrack helper");
+                               OVS_NLERR(log, "Invalid conntrack timeout");
                                return -EINVAL;
                        }
                        break;
@@ -1657,6 +1671,10 @@ int ovs_ct_copy_action(struct net *net, const struct nlattr *attr,
                                      ct_info.timeout))
                        pr_info_ratelimited("Failed to associated timeout "
                                            "policy `%s'\n", ct_info.timeout);
+               else
+                       ct_info.nf_ct_timeout = rcu_dereference(
+                               nf_ct_timeout_find(ct_info.ct)->timeout);
+
        }
 
        if (helper) {
index bc89e16..9d81d2c 100644 (file)
@@ -523,78 +523,15 @@ static int parse_nsh(struct sk_buff *skb, struct sw_flow_key *key)
 }
 
 /**
- * key_extract - extracts a flow key from an Ethernet frame.
+ * key_extract_l3l4 - extracts L3/L4 header information.
  * @skb: sk_buff that contains the frame, with skb->data pointing to the
- * Ethernet header
+ *       L3 header
  * @key: output flow key
  *
- * The caller must ensure that skb->len >= ETH_HLEN.
- *
- * Returns 0 if successful, otherwise a negative errno value.
- *
- * Initializes @skb header fields as follows:
- *
- *    - skb->mac_header: the L2 header.
- *
- *    - skb->network_header: just past the L2 header, or just past the
- *      VLAN header, to the first byte of the L2 payload.
- *
- *    - skb->transport_header: If key->eth.type is ETH_P_IP or ETH_P_IPV6
- *      on output, then just past the IP header, if one is present and
- *      of a correct length, otherwise the same as skb->network_header.
- *      For other key->eth.type values it is left untouched.
- *
- *    - skb->protocol: the type of the data starting at skb->network_header.
- *      Equals to key->eth.type.
  */
-static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
+static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
 {
        int error;
-       struct ethhdr *eth;
-
-       /* Flags are always used as part of stats */
-       key->tp.flags = 0;
-
-       skb_reset_mac_header(skb);
-
-       /* Link layer. */
-       clear_vlan(key);
-       if (ovs_key_mac_proto(key) == MAC_PROTO_NONE) {
-               if (unlikely(eth_type_vlan(skb->protocol)))
-                       return -EINVAL;
-
-               skb_reset_network_header(skb);
-               key->eth.type = skb->protocol;
-       } else {
-               eth = eth_hdr(skb);
-               ether_addr_copy(key->eth.src, eth->h_source);
-               ether_addr_copy(key->eth.dst, eth->h_dest);
-
-               __skb_pull(skb, 2 * ETH_ALEN);
-               /* We are going to push all headers that we pull, so no need to
-               * update skb->csum here.
-               */
-
-               if (unlikely(parse_vlan(skb, key)))
-                       return -ENOMEM;
-
-               key->eth.type = parse_ethertype(skb);
-               if (unlikely(key->eth.type == htons(0)))
-                       return -ENOMEM;
-
-               /* Multiple tagged packets need to retain TPID to satisfy
-                * skb_vlan_pop(), which will later shift the ethertype into
-                * skb->protocol.
-                */
-               if (key->eth.cvlan.tci & htons(VLAN_CFI_MASK))
-                       skb->protocol = key->eth.cvlan.tpid;
-               else
-                       skb->protocol = key->eth.type;
-
-               skb_reset_network_header(skb);
-               __skb_push(skb, skb->data - skb_mac_header(skb));
-       }
-       skb_reset_mac_len(skb);
 
        /* Network layer. */
        if (key->eth.type == htons(ETH_P_IP)) {
@@ -623,6 +560,7 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
                offset = nh->frag_off & htons(IP_OFFSET);
                if (offset) {
                        key->ip.frag = OVS_FRAG_TYPE_LATER;
+                       memset(&key->tp, 0, sizeof(key->tp));
                        return 0;
                }
                if (nh->frag_off & htons(IP_MF) ||
@@ -740,8 +678,10 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
                        return error;
                }
 
-               if (key->ip.frag == OVS_FRAG_TYPE_LATER)
+               if (key->ip.frag == OVS_FRAG_TYPE_LATER) {
+                       memset(&key->tp, 0, sizeof(key->tp));
                        return 0;
+               }
                if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
                        key->ip.frag = OVS_FRAG_TYPE_FIRST;
 
@@ -788,6 +728,92 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
        return 0;
 }
 
+/**
+ * key_extract - extracts a flow key from an Ethernet frame.
+ * @skb: sk_buff that contains the frame, with skb->data pointing to the
+ * Ethernet header
+ * @key: output flow key
+ *
+ * The caller must ensure that skb->len >= ETH_HLEN.
+ *
+ * Returns 0 if successful, otherwise a negative errno value.
+ *
+ * Initializes @skb header fields as follows:
+ *
+ *    - skb->mac_header: the L2 header.
+ *
+ *    - skb->network_header: just past the L2 header, or just past the
+ *      VLAN header, to the first byte of the L2 payload.
+ *
+ *    - skb->transport_header: If key->eth.type is ETH_P_IP or ETH_P_IPV6
+ *      on output, then just past the IP header, if one is present and
+ *      of a correct length, otherwise the same as skb->network_header.
+ *      For other key->eth.type values it is left untouched.
+ *
+ *    - skb->protocol: the type of the data starting at skb->network_header.
+ *      Equals to key->eth.type.
+ */
+static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
+{
+       struct ethhdr *eth;
+
+       /* Flags are always used as part of stats */
+       key->tp.flags = 0;
+
+       skb_reset_mac_header(skb);
+
+       /* Link layer. */
+       clear_vlan(key);
+       if (ovs_key_mac_proto(key) == MAC_PROTO_NONE) {
+               if (unlikely(eth_type_vlan(skb->protocol)))
+                       return -EINVAL;
+
+               skb_reset_network_header(skb);
+               key->eth.type = skb->protocol;
+       } else {
+               eth = eth_hdr(skb);
+               ether_addr_copy(key->eth.src, eth->h_source);
+               ether_addr_copy(key->eth.dst, eth->h_dest);
+
+               __skb_pull(skb, 2 * ETH_ALEN);
+               /* We are going to push all headers that we pull, so no need to
+                * update skb->csum here.
+                */
+
+               if (unlikely(parse_vlan(skb, key)))
+                       return -ENOMEM;
+
+               key->eth.type = parse_ethertype(skb);
+               if (unlikely(key->eth.type == htons(0)))
+                       return -ENOMEM;
+
+               /* Multiple tagged packets need to retain TPID to satisfy
+                * skb_vlan_pop(), which will later shift the ethertype into
+                * skb->protocol.
+                */
+               if (key->eth.cvlan.tci & htons(VLAN_CFI_MASK))
+                       skb->protocol = key->eth.cvlan.tpid;
+               else
+                       skb->protocol = key->eth.type;
+
+               skb_reset_network_header(skb);
+               __skb_push(skb, skb->data - skb_mac_header(skb));
+       }
+
+       skb_reset_mac_len(skb);
+
+       /* Fill out L3/L4 key info, if any */
+       return key_extract_l3l4(skb, key);
+}
+
+/* In the case of conntrack fragment handling it expects L3 headers,
+ * add a helper.
+ */
+int ovs_flow_key_update_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
+{
+       return key_extract_l3l4(skb, key);
+}
+
 int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key)
 {
        int res;
index a5506e2..b830d5f 100644 (file)
@@ -270,6 +270,7 @@ void ovs_flow_stats_clear(struct sw_flow *);
 u64 ovs_flow_used_time(unsigned long flow_jiffies);
 
 int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key);
+int ovs_flow_key_update_l3l4(struct sk_buff *skb, struct sw_flow_key *key);
 int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info,
                         struct sk_buff *skb,
                         struct sw_flow_key *key);
index 841f198..66e4b61 100644 (file)
@@ -154,7 +154,7 @@ static void psample_group_destroy(struct psample_group *group)
 {
        psample_group_notify(group, PSAMPLE_CMD_DEL_GROUP);
        list_del(&group->list);
-       kfree(group);
+       kfree_rcu(group, rcu);
 }
 
 static struct psample_group *
index ccff1e5..e35869e 100644 (file)
@@ -84,11 +84,14 @@ static ssize_t qrtr_tun_write_iter(struct kiocb *iocb, struct iov_iter *from)
        if (!kbuf)
                return -ENOMEM;
 
-       if (!copy_from_iter_full(kbuf, len, from))
+       if (!copy_from_iter_full(kbuf, len, from)) {
+               kfree(kbuf);
                return -EFAULT;
+       }
 
        ret = qrtr_endpoint_post(&tun->ep, kbuf, len);
 
+       kfree(kbuf);
        return ret < 0 ? ret : len;
 }
 
index 0f4398e..05464fd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019 Oracle and/or its affiliates. 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
@@ -239,34 +239,30 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
                goto out;
        }
 
-       sock_set_flag(sk, SOCK_RCU_FREE);
-       ret = rds_add_bound(rs, binding_addr, &port, scope_id);
-       if (ret)
-               goto out;
-
-       if (rs->rs_transport) { /* previously bound */
+       /* The transport can be set using SO_RDS_TRANSPORT option before the
+        * socket is bound.
+        */
+       if (rs->rs_transport) {
                trans = rs->rs_transport;
                if (trans->laddr_check(sock_net(sock->sk),
                                       binding_addr, scope_id) != 0) {
                        ret = -ENOPROTOOPT;
-                       rds_remove_bound(rs);
-               } else {
-                       ret = 0;
+                       goto out;
                }
-               goto out;
-       }
-       trans = rds_trans_get_preferred(sock_net(sock->sk), binding_addr,
-                                       scope_id);
-       if (!trans) {
-               ret = -EADDRNOTAVAIL;
-               rds_remove_bound(rs);
-               pr_info_ratelimited("RDS: %s could not find a transport for %pI6c, load rds_tcp or rds_rdma?\n",
-                                   __func__, binding_addr);
-               goto out;
+       } else {
+               trans = rds_trans_get_preferred(sock_net(sock->sk),
+                                               binding_addr, scope_id);
+               if (!trans) {
+                       ret = -EADDRNOTAVAIL;
+                       pr_info_ratelimited("RDS: %s could not find a transport for %pI6c, load rds_tcp or rds_rdma?\n",
+                                           __func__, binding_addr);
+                       goto out;
+               }
+               rs->rs_transport = trans;
        }
 
-       rs->rs_transport = trans;
-       ret = 0;
+       sock_set_flag(sk, SOCK_RCU_FREE);
+       ret = rds_add_bound(rs, binding_addr, &port, scope_id);
 
 out:
        release_sock(sk);
index ec05d91..45acab2 100644 (file)
@@ -291,7 +291,7 @@ static int rds_ib_conn_info_visitor(struct rds_connection *conn,
                                    void *buffer)
 {
        struct rds_info_rdma_connection *iinfo = buffer;
-       struct rds_ib_connection *ic;
+       struct rds_ib_connection *ic = conn->c_transport_data;
 
        /* We will only ever look at IB transports */
        if (conn->c_trans != &rds_ib_transport)
@@ -301,15 +301,16 @@ static int rds_ib_conn_info_visitor(struct rds_connection *conn,
 
        iinfo->src_addr = conn->c_laddr.s6_addr32[3];
        iinfo->dst_addr = conn->c_faddr.s6_addr32[3];
-       iinfo->tos = conn->c_tos;
+       if (ic) {
+               iinfo->tos = conn->c_tos;
+               iinfo->sl = ic->i_sl;
+       }
 
        memset(&iinfo->src_gid, 0, sizeof(iinfo->src_gid));
        memset(&iinfo->dst_gid, 0, sizeof(iinfo->dst_gid));
        if (rds_conn_state(conn) == RDS_CONN_UP) {
                struct rds_ib_device *rds_ibdev;
 
-               ic = conn->c_transport_data;
-
                rdma_read_gids(ic->i_cm_id, (union ib_gid *)&iinfo->src_gid,
                               (union ib_gid *)&iinfo->dst_gid);
 
@@ -329,7 +330,7 @@ static int rds6_ib_conn_info_visitor(struct rds_connection *conn,
                                     void *buffer)
 {
        struct rds6_info_rdma_connection *iinfo6 = buffer;
-       struct rds_ib_connection *ic;
+       struct rds_ib_connection *ic = conn->c_transport_data;
 
        /* We will only ever look at IB transports */
        if (conn->c_trans != &rds_ib_transport)
@@ -337,6 +338,10 @@ static int rds6_ib_conn_info_visitor(struct rds_connection *conn,
 
        iinfo6->src_addr = conn->c_laddr;
        iinfo6->dst_addr = conn->c_faddr;
+       if (ic) {
+               iinfo6->tos = conn->c_tos;
+               iinfo6->sl = ic->i_sl;
+       }
 
        memset(&iinfo6->src_gid, 0, sizeof(iinfo6->src_gid));
        memset(&iinfo6->dst_gid, 0, sizeof(iinfo6->dst_gid));
@@ -344,7 +349,6 @@ static int rds6_ib_conn_info_visitor(struct rds_connection *conn,
        if (rds_conn_state(conn) == RDS_CONN_UP) {
                struct rds_ib_device *rds_ibdev;
 
-               ic = conn->c_transport_data;
                rdma_read_gids(ic->i_cm_id, (union ib_gid *)&iinfo6->src_gid,
                               (union ib_gid *)&iinfo6->dst_gid);
                rds_ibdev = ic->rds_ibdev;
index 303c6ee..f2b558e 100644 (file)
@@ -220,6 +220,7 @@ struct rds_ib_connection {
        /* Send/Recv vectors */
        int                     i_scq_vector;
        int                     i_rcq_vector;
+       u8                      i_sl;
 };
 
 /* This assumes that atomic_t is at least 32 bits */
index fddaa09..233f136 100644 (file)
@@ -152,6 +152,9 @@ void rds_ib_cm_connect_complete(struct rds_connection *conn, struct rdma_cm_even
                  RDS_PROTOCOL_MINOR(conn->c_version),
                  ic->i_flowctl ? ", flow control" : "");
 
+       /* receive sl from the peer */
+       ic->i_sl = ic->i_cm_id->route.path_rec->sl;
+
        atomic_set(&ic->i_cq_quiesce, 0);
 
        /* Init rings and fill recv. this needs to wait until protocol
index 9986d60..5f741e5 100644 (file)
@@ -43,6 +43,9 @@ static struct rdma_cm_id *rds_rdma_listen_id;
 static struct rdma_cm_id *rds6_rdma_listen_id;
 #endif
 
+/* Per IB specification 7.7.3, service level is a 4-bit field. */
+#define TOS_TO_SL(tos)         ((tos) & 0xF)
+
 static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
                                         struct rdma_cm_event *event,
                                         bool isv6)
@@ -97,10 +100,13 @@ static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
                        struct rds_ib_connection *ibic;
 
                        ibic = conn->c_transport_data;
-                       if (ibic && ibic->i_cm_id == cm_id)
+                       if (ibic && ibic->i_cm_id == cm_id) {
+                               cm_id->route.path_rec[0].sl =
+                                       TOS_TO_SL(conn->c_tos);
                                ret = trans->cm_initiate_connect(cm_id, isv6);
-                       else
+                       } else {
                                rds_conn_drop(conn);
+                       }
                }
                break;
 
index 853de48..a42ba7f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019 Oracle and/or its affiliates. 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
@@ -811,6 +811,7 @@ void rds6_inc_info_copy(struct rds_incoming *inc,
 
        minfo6.seq = be64_to_cpu(inc->i_hdr.h_sequence);
        minfo6.len = be32_to_cpu(inc->i_hdr.h_len);
+       minfo6.tos = inc->i_conn->c_tos;
 
        if (flip) {
                minfo6.laddr = *daddr;
@@ -824,6 +825,8 @@ void rds6_inc_info_copy(struct rds_incoming *inc,
                minfo6.fport = inc->i_hdr.h_dport;
        }
 
+       minfo6.flags = 0;
+
        rds_info_copy(iter, &minfo6, sizeof(minfo6));
 }
 #endif
index 0dbbfd1..d72ddb6 100644 (file)
@@ -862,7 +862,6 @@ static void rxrpc_sock_destructor(struct sock *sk)
 static int rxrpc_release_sock(struct sock *sk)
 {
        struct rxrpc_sock *rx = rxrpc_sk(sk);
-       struct rxrpc_net *rxnet = rxrpc_net(sock_net(&rx->sk));
 
        _enter("%p{%d,%d}", sk, sk->sk_state, refcount_read(&sk->sk_refcnt));
 
@@ -898,8 +897,6 @@ static int rxrpc_release_sock(struct sock *sk)
        rxrpc_release_calls_on_socket(rx);
        flush_workqueue(rxrpc_workqueue);
        rxrpc_purge_queue(&sk->sk_receive_queue);
-       rxrpc_queue_work(&rxnet->service_conn_reaper);
-       rxrpc_queue_work(&rxnet->client_conn_reaper);
 
        rxrpc_unuse_local(rx->local);
        rx->local = NULL;
index 1453356..8051dfd 100644 (file)
@@ -185,11 +185,17 @@ struct rxrpc_host_header {
  * - max 48 bytes (struct sk_buff::cb)
  */
 struct rxrpc_skb_priv {
-       union {
-               u8              nr_jumbo;       /* Number of jumbo subpackets */
-       };
+       atomic_t        nr_ring_pins;           /* Number of rxtx ring pins */
+       u8              nr_subpackets;          /* Number of subpackets */
+       u8              rx_flags;               /* Received packet flags */
+#define RXRPC_SKB_INCL_LAST    0x01            /* - Includes last packet */
+#define RXRPC_SKB_TX_BUFFER    0x02            /* - Is transmit buffer */
        union {
                int             remain;         /* amount of space remaining for next write */
+
+               /* List of requested ACKs on subpackets */
+               unsigned long   rx_req_ack[(RXRPC_MAX_NR_JUMBO + BITS_PER_LONG - 1) /
+                                          BITS_PER_LONG];
        };
 
        struct rxrpc_host_header hdr;           /* RxRPC packet header from this packet */
@@ -613,8 +619,7 @@ struct rxrpc_call {
 #define RXRPC_TX_ANNO_LAST     0x04
 #define RXRPC_TX_ANNO_RESENT   0x08
 
-#define RXRPC_RX_ANNO_JUMBO    0x3f            /* Jumbo subpacket number + 1 if not zero */
-#define RXRPC_RX_ANNO_JLAST    0x40            /* Set if last element of a jumbo packet */
+#define RXRPC_RX_ANNO_SUBPACKET        0x3f            /* Subpacket number in jumbogram */
 #define RXRPC_RX_ANNO_VERIFIED 0x80            /* Set if verified and decrypted */
        rxrpc_seq_t             tx_hard_ack;    /* Dead slot in buffer; the first transmitted but
                                                 * not hard-ACK'd packet follows this.
@@ -905,6 +910,7 @@ void rxrpc_disconnect_client_call(struct rxrpc_call *);
 void rxrpc_put_client_conn(struct rxrpc_connection *);
 void rxrpc_discard_expired_client_conns(struct work_struct *);
 void rxrpc_destroy_all_client_connections(struct rxrpc_net *);
+void rxrpc_clean_up_local_conns(struct rxrpc_local *);
 
 /*
  * conn_event.c
@@ -1105,6 +1111,7 @@ void rxrpc_kernel_data_consumed(struct rxrpc_call *, struct sk_buff *);
 void rxrpc_packet_destructor(struct sk_buff *);
 void rxrpc_new_skb(struct sk_buff *, enum rxrpc_skb_trace);
 void rxrpc_see_skb(struct sk_buff *, enum rxrpc_skb_trace);
+void rxrpc_eaten_skb(struct sk_buff *, enum rxrpc_skb_trace);
 void rxrpc_get_skb(struct sk_buff *, enum rxrpc_skb_trace);
 void rxrpc_free_skb(struct sk_buff *, enum rxrpc_skb_trace);
 void rxrpc_purge_queue(struct sk_buff_head *);
index c767679..cedbbb3 100644 (file)
@@ -199,7 +199,7 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j)
                        continue;
 
                skb = call->rxtx_buffer[ix];
-               rxrpc_see_skb(skb, rxrpc_skb_tx_seen);
+               rxrpc_see_skb(skb, rxrpc_skb_seen);
 
                if (anno_type == RXRPC_TX_ANNO_UNACK) {
                        if (ktime_after(skb->tstamp, max_age)) {
@@ -255,18 +255,18 @@ static void rxrpc_resend(struct rxrpc_call *call, unsigned long now_j)
                        continue;
 
                skb = call->rxtx_buffer[ix];
-               rxrpc_get_skb(skb, rxrpc_skb_tx_got);
+               rxrpc_get_skb(skb, rxrpc_skb_got);
                spin_unlock_bh(&call->lock);
 
                if (rxrpc_send_data_packet(call, skb, true) < 0) {
-                       rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
+                       rxrpc_free_skb(skb, rxrpc_skb_freed);
                        return;
                }
 
                if (rxrpc_is_client_call(call))
                        rxrpc_expose_client_call(call);
 
-               rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
+               rxrpc_free_skb(skb, rxrpc_skb_freed);
                spin_lock_bh(&call->lock);
 
                /* We need to clear the retransmit state, but there are two
index 217b12b..014548c 100644 (file)
@@ -422,6 +422,19 @@ void rxrpc_get_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
 }
 
 /*
+ * Clean up the RxTx skb ring.
+ */
+static void rxrpc_cleanup_ring(struct rxrpc_call *call)
+{
+       int i;
+
+       for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) {
+               rxrpc_free_skb(call->rxtx_buffer[i], rxrpc_skb_cleaned);
+               call->rxtx_buffer[i] = NULL;
+       }
+}
+
+/*
  * Detach a call from its owning socket.
  */
 void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call)
@@ -429,7 +442,6 @@ void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call)
        const void *here = __builtin_return_address(0);
        struct rxrpc_connection *conn = call->conn;
        bool put = false;
-       int i;
 
        _enter("{%d,%d}", call->debug_id, atomic_read(&call->usage));
 
@@ -479,13 +491,7 @@ void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call)
        if (conn)
                rxrpc_disconnect_call(call);
 
-       for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++) {
-               rxrpc_free_skb(call->rxtx_buffer[i],
-                              (call->tx_phase ? rxrpc_skb_tx_cleaned :
-                               rxrpc_skb_rx_cleaned));
-               call->rxtx_buffer[i] = NULL;
-       }
-
+       rxrpc_cleanup_ring(call);
        _leave("");
 }
 
@@ -568,8 +574,6 @@ static void rxrpc_rcu_destroy_call(struct rcu_head *rcu)
  */
 void rxrpc_cleanup_call(struct rxrpc_call *call)
 {
-       int i;
-
        _net("DESTROY CALL %d", call->debug_id);
 
        memset(&call->sock_node, 0xcd, sizeof(call->sock_node));
@@ -580,13 +584,8 @@ void rxrpc_cleanup_call(struct rxrpc_call *call)
        ASSERT(test_bit(RXRPC_CALL_RELEASED, &call->flags));
        ASSERTCMP(call->conn, ==, NULL);
 
-       /* Clean up the Rx/Tx buffer */
-       for (i = 0; i < RXRPC_RXTX_BUFF_SIZE; i++)
-               rxrpc_free_skb(call->rxtx_buffer[i],
-                              (call->tx_phase ? rxrpc_skb_tx_cleaned :
-                               rxrpc_skb_rx_cleaned));
-
-       rxrpc_free_skb(call->tx_pending, rxrpc_skb_tx_cleaned);
+       rxrpc_cleanup_ring(call);
+       rxrpc_free_skb(call->tx_pending, rxrpc_skb_cleaned);
 
        call_rcu(&call->rcu, rxrpc_rcu_destroy_call);
 }
index aea82f9..3f1da1b 100644 (file)
@@ -1162,3 +1162,47 @@ void rxrpc_destroy_all_client_connections(struct rxrpc_net *rxnet)
 
        _leave("");
 }
+
+/*
+ * Clean up the client connections on a local endpoint.
+ */
+void rxrpc_clean_up_local_conns(struct rxrpc_local *local)
+{
+       struct rxrpc_connection *conn, *tmp;
+       struct rxrpc_net *rxnet = local->rxnet;
+       unsigned int nr_active;
+       LIST_HEAD(graveyard);
+
+       _enter("");
+
+       spin_lock(&rxnet->client_conn_cache_lock);
+       nr_active = rxnet->nr_active_client_conns;
+
+       list_for_each_entry_safe(conn, tmp, &rxnet->idle_client_conns,
+                                cache_link) {
+               if (conn->params.local == local) {
+                       ASSERTCMP(conn->cache_state, ==, RXRPC_CONN_CLIENT_IDLE);
+
+                       trace_rxrpc_client(conn, -1, rxrpc_client_discard);
+                       if (!test_and_clear_bit(RXRPC_CONN_EXPOSED, &conn->flags))
+                               BUG();
+                       conn->cache_state = RXRPC_CONN_CLIENT_INACTIVE;
+                       list_move(&conn->cache_link, &graveyard);
+                       nr_active--;
+               }
+       }
+
+       rxnet->nr_active_client_conns = nr_active;
+       spin_unlock(&rxnet->client_conn_cache_lock);
+       ASSERTCMP(nr_active, >=, 0);
+
+       while (!list_empty(&graveyard)) {
+               conn = list_entry(graveyard.next,
+                                 struct rxrpc_connection, cache_link);
+               list_del_init(&conn->cache_link);
+
+               rxrpc_put_connection(conn);
+       }
+
+       _leave(" [culled]");
+}
index df6624c..a1ceef4 100644 (file)
@@ -472,7 +472,7 @@ void rxrpc_process_connection(struct work_struct *work)
        /* go through the conn-level event packets, releasing the ref on this
         * connection that each one has when we've finished with it */
        while ((skb = skb_dequeue(&conn->rx_queue))) {
-               rxrpc_see_skb(skb, rxrpc_skb_rx_seen);
+               rxrpc_see_skb(skb, rxrpc_skb_seen);
                ret = rxrpc_process_event(conn, skb, &abort_code);
                switch (ret) {
                case -EPROTO:
@@ -484,7 +484,7 @@ void rxrpc_process_connection(struct work_struct *work)
                        goto requeue_and_leave;
                case -ECONNABORTED:
                default:
-                       rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+                       rxrpc_free_skb(skb, rxrpc_skb_freed);
                        break;
                }
        }
@@ -501,6 +501,6 @@ requeue_and_leave:
 protocol_error:
        if (rxrpc_abort_connection(conn, ret, abort_code) < 0)
                goto requeue_and_leave;
-       rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+       rxrpc_free_skb(skb, rxrpc_skb_freed);
        goto out;
 }
index 434ef39..ed05b69 100644 (file)
@@ -398,7 +398,7 @@ void rxrpc_service_connection_reaper(struct work_struct *work)
                if (conn->state == RXRPC_CONN_SERVICE_PREALLOC)
                        continue;
 
-               if (rxnet->live) {
+               if (rxnet->live && !conn->params.local->dead) {
                        idle_timestamp = READ_ONCE(conn->idle_timestamp);
                        expire_at = idle_timestamp + rxrpc_connection_expiry * HZ;
                        if (conn->params.local->service_closed)
index dd47d46..157be1f 100644 (file)
@@ -233,7 +233,7 @@ static bool rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to,
                ix = call->tx_hard_ack & RXRPC_RXTX_BUFF_MASK;
                skb = call->rxtx_buffer[ix];
                annotation = call->rxtx_annotations[ix];
-               rxrpc_see_skb(skb, rxrpc_skb_tx_rotated);
+               rxrpc_see_skb(skb, rxrpc_skb_rotated);
                call->rxtx_buffer[ix] = NULL;
                call->rxtx_annotations[ix] = 0;
                skb->next = list;
@@ -258,7 +258,7 @@ static bool rxrpc_rotate_tx_window(struct rxrpc_call *call, rxrpc_seq_t to,
                skb = list;
                list = skb->next;
                skb_mark_not_on_list(skb);
-               rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
+               rxrpc_free_skb(skb, rxrpc_skb_freed);
        }
 
        return rot_last;
@@ -347,7 +347,7 @@ static bool rxrpc_receiving_reply(struct rxrpc_call *call)
 }
 
 /*
- * Scan a jumbo packet to validate its structure and to work out how many
+ * Scan a data packet to validate its structure and to work out how many
  * subpackets it contains.
  *
  * A jumbo packet is a collection of consecutive packets glued together with
@@ -358,16 +358,21 @@ static bool rxrpc_receiving_reply(struct rxrpc_call *call)
  * the last are RXRPC_JUMBO_DATALEN in size.  The last subpacket may be of any
  * size.
  */
-static bool rxrpc_validate_jumbo(struct sk_buff *skb)
+static bool rxrpc_validate_data(struct sk_buff *skb)
 {
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
        unsigned int offset = sizeof(struct rxrpc_wire_header);
        unsigned int len = skb->len;
-       int nr_jumbo = 1;
        u8 flags = sp->hdr.flags;
 
-       do {
-               nr_jumbo++;
+       for (;;) {
+               if (flags & RXRPC_REQUEST_ACK)
+                       __set_bit(sp->nr_subpackets, sp->rx_req_ack);
+               sp->nr_subpackets++;
+
+               if (!(flags & RXRPC_JUMBO_PACKET))
+                       break;
+
                if (len - offset < RXRPC_JUMBO_SUBPKTLEN)
                        goto protocol_error;
                if (flags & RXRPC_LAST_PACKET)
@@ -376,9 +381,10 @@ static bool rxrpc_validate_jumbo(struct sk_buff *skb)
                if (skb_copy_bits(skb, offset, &flags, 1) < 0)
                        goto protocol_error;
                offset += sizeof(struct rxrpc_jumbo_header);
-       } while (flags & RXRPC_JUMBO_PACKET);
+       }
 
-       sp->nr_jumbo = nr_jumbo;
+       if (flags & RXRPC_LAST_PACKET)
+               sp->rx_flags |= RXRPC_SKB_INCL_LAST;
        return true;
 
 protocol_error:
@@ -399,10 +405,10 @@ protocol_error:
  * (that information is encoded in the ACK packet).
  */
 static void rxrpc_input_dup_data(struct rxrpc_call *call, rxrpc_seq_t seq,
-                                u8 annotation, bool *_jumbo_bad)
+                                bool is_jumbo, bool *_jumbo_bad)
 {
        /* Discard normal packets that are duplicates. */
-       if (annotation == 0)
+       if (is_jumbo)
                return;
 
        /* Skip jumbo subpackets that are duplicates.  When we've had three or
@@ -416,29 +422,30 @@ static void rxrpc_input_dup_data(struct rxrpc_call *call, rxrpc_seq_t seq,
 }
 
 /*
- * Process a DATA packet, adding the packet to the Rx ring.
+ * Process a DATA packet, adding the packet to the Rx ring.  The caller's
+ * packet ref must be passed on or discarded.
  */
 static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb)
 {
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
        enum rxrpc_call_state state;
-       unsigned int offset = sizeof(struct rxrpc_wire_header);
-       unsigned int ix;
+       unsigned int j;
        rxrpc_serial_t serial = sp->hdr.serial, ack_serial = 0;
-       rxrpc_seq_t seq = sp->hdr.seq, hard_ack;
-       bool immediate_ack = false, jumbo_bad = false, queued;
-       u16 len;
-       u8 ack = 0, flags, annotation = 0;
+       rxrpc_seq_t seq0 = sp->hdr.seq, hard_ack;
+       bool immediate_ack = false, jumbo_bad = false;
+       u8 ack = 0;
 
        _enter("{%u,%u},{%u,%u}",
-              call->rx_hard_ack, call->rx_top, skb->len, seq);
+              call->rx_hard_ack, call->rx_top, skb->len, seq0);
 
-       _proto("Rx DATA %%%u { #%u f=%02x }",
-              sp->hdr.serial, seq, sp->hdr.flags);
+       _proto("Rx DATA %%%u { #%u f=%02x n=%u }",
+              sp->hdr.serial, seq0, sp->hdr.flags, sp->nr_subpackets);
 
        state = READ_ONCE(call->state);
-       if (state >= RXRPC_CALL_COMPLETE)
+       if (state >= RXRPC_CALL_COMPLETE) {
+               rxrpc_free_skb(skb, rxrpc_skb_freed);
                return;
+       }
 
        if (call->state == RXRPC_CALL_SERVER_RECV_REQUEST) {
                unsigned long timo = READ_ONCE(call->next_req_timo);
@@ -463,137 +470,137 @@ static void rxrpc_input_data(struct rxrpc_call *call, struct sk_buff *skb)
            !rxrpc_receiving_reply(call))
                goto unlock;
 
-       call->ackr_prev_seq = seq;
-
+       call->ackr_prev_seq = seq0;
        hard_ack = READ_ONCE(call->rx_hard_ack);
-       if (after(seq, hard_ack + call->rx_winsize)) {
-               ack = RXRPC_ACK_EXCEEDS_WINDOW;
-               ack_serial = serial;
-               goto ack;
-       }
 
-       flags = sp->hdr.flags;
-       if (flags & RXRPC_JUMBO_PACKET) {
+       if (sp->nr_subpackets > 1) {
                if (call->nr_jumbo_bad > 3) {
                        ack = RXRPC_ACK_NOSPACE;
                        ack_serial = serial;
                        goto ack;
                }
-               annotation = 1;
        }
 
-next_subpacket:
-       queued = false;
-       ix = seq & RXRPC_RXTX_BUFF_MASK;
-       len = skb->len;
-       if (flags & RXRPC_JUMBO_PACKET)
-               len = RXRPC_JUMBO_DATALEN;
-
-       if (flags & RXRPC_LAST_PACKET) {
-               if (test_bit(RXRPC_CALL_RX_LAST, &call->flags) &&
-                   seq != call->rx_top) {
-                       rxrpc_proto_abort("LSN", call, seq);
-                       goto unlock;
-               }
-       } else {
-               if (test_bit(RXRPC_CALL_RX_LAST, &call->flags) &&
-                   after_eq(seq, call->rx_top)) {
-                       rxrpc_proto_abort("LSA", call, seq);
-                       goto unlock;
+       for (j = 0; j < sp->nr_subpackets; j++) {
+               rxrpc_serial_t serial = sp->hdr.serial + j;
+               rxrpc_seq_t seq = seq0 + j;
+               unsigned int ix = seq & RXRPC_RXTX_BUFF_MASK;
+               bool terminal = (j == sp->nr_subpackets - 1);
+               bool last = terminal && (sp->rx_flags & RXRPC_SKB_INCL_LAST);
+               u8 flags, annotation = j;
+
+               _proto("Rx DATA+%u %%%u { #%x t=%u l=%u }",
+                    j, serial, seq, terminal, last);
+
+               if (last) {
+                       if (test_bit(RXRPC_CALL_RX_LAST, &call->flags) &&
+                           seq != call->rx_top) {
+                               rxrpc_proto_abort("LSN", call, seq);
+                               goto unlock;
+                       }
+               } else {
+                       if (test_bit(RXRPC_CALL_RX_LAST, &call->flags) &&
+                           after_eq(seq, call->rx_top)) {
+                               rxrpc_proto_abort("LSA", call, seq);
+                               goto unlock;
+                       }
                }
-       }
 
-       trace_rxrpc_rx_data(call->debug_id, seq, serial, flags, annotation);
-       if (before_eq(seq, hard_ack)) {
-               ack = RXRPC_ACK_DUPLICATE;
-               ack_serial = serial;
-               goto skip;
-       }
+               flags = 0;
+               if (last)
+                       flags |= RXRPC_LAST_PACKET;
+               if (!terminal)
+                       flags |= RXRPC_JUMBO_PACKET;
+               if (test_bit(j, sp->rx_req_ack))
+                       flags |= RXRPC_REQUEST_ACK;
+               trace_rxrpc_rx_data(call->debug_id, seq, serial, flags, annotation);
 
-       if (flags & RXRPC_REQUEST_ACK && !ack) {
-               ack = RXRPC_ACK_REQUESTED;
-               ack_serial = serial;
-       }
-
-       if (call->rxtx_buffer[ix]) {
-               rxrpc_input_dup_data(call, seq, annotation, &jumbo_bad);
-               if (ack != RXRPC_ACK_DUPLICATE) {
+               if (before_eq(seq, hard_ack)) {
                        ack = RXRPC_ACK_DUPLICATE;
                        ack_serial = serial;
+                       continue;
                }
-               immediate_ack = true;
-               goto skip;
-       }
 
-       /* Queue the packet.  We use a couple of memory barriers here as need
-        * to make sure that rx_top is perceived to be set after the buffer
-        * pointer and that the buffer pointer is set after the annotation and
-        * the skb data.
-        *
-        * Barriers against rxrpc_recvmsg_data() and rxrpc_rotate_rx_window()
-        * and also rxrpc_fill_out_ack().
-        */
-       rxrpc_get_skb(skb, rxrpc_skb_rx_got);
-       call->rxtx_annotations[ix] = annotation;
-       smp_wmb();
-       call->rxtx_buffer[ix] = skb;
-       if (after(seq, call->rx_top)) {
-               smp_store_release(&call->rx_top, seq);
-       } else if (before(seq, call->rx_top)) {
-               /* Send an immediate ACK if we fill in a hole */
-               if (!ack) {
-                       ack = RXRPC_ACK_DELAY;
-                       ack_serial = serial;
+               if (call->rxtx_buffer[ix]) {
+                       rxrpc_input_dup_data(call, seq, sp->nr_subpackets > 1,
+                                            &jumbo_bad);
+                       if (ack != RXRPC_ACK_DUPLICATE) {
+                               ack = RXRPC_ACK_DUPLICATE;
+                               ack_serial = serial;
+                       }
+                       immediate_ack = true;
+                       continue;
                }
-               immediate_ack = true;
-       }
-       if (flags & RXRPC_LAST_PACKET) {
-               set_bit(RXRPC_CALL_RX_LAST, &call->flags);
-               trace_rxrpc_receive(call, rxrpc_receive_queue_last, serial, seq);
-       } else {
-               trace_rxrpc_receive(call, rxrpc_receive_queue, serial, seq);
-       }
-       queued = true;
 
-       if (after_eq(seq, call->rx_expect_next)) {
-               if (after(seq, call->rx_expect_next)) {
-                       _net("OOS %u > %u", seq, call->rx_expect_next);
-                       ack = RXRPC_ACK_OUT_OF_SEQUENCE;
-                       ack_serial = serial;
-               }
-               call->rx_expect_next = seq + 1;
-       }
-
-skip:
-       offset += len;
-       if (flags & RXRPC_JUMBO_PACKET) {
-               if (skb_copy_bits(skb, offset, &flags, 1) < 0) {
-                       rxrpc_proto_abort("XJF", call, seq);
-                       goto unlock;
-               }
-               offset += sizeof(struct rxrpc_jumbo_header);
-               seq++;
-               serial++;
-               annotation++;
-               if (flags & RXRPC_JUMBO_PACKET)
-                       annotation |= RXRPC_RX_ANNO_JLAST;
                if (after(seq, hard_ack + call->rx_winsize)) {
                        ack = RXRPC_ACK_EXCEEDS_WINDOW;
                        ack_serial = serial;
-                       if (!jumbo_bad) {
-                               call->nr_jumbo_bad++;
-                               jumbo_bad = true;
+                       if (flags & RXRPC_JUMBO_PACKET) {
+                               if (!jumbo_bad) {
+                                       call->nr_jumbo_bad++;
+                                       jumbo_bad = true;
+                               }
                        }
+
                        goto ack;
                }
 
-               _proto("Rx DATA Jumbo %%%u", serial);
-               goto next_subpacket;
-       }
+               if (flags & RXRPC_REQUEST_ACK && !ack) {
+                       ack = RXRPC_ACK_REQUESTED;
+                       ack_serial = serial;
+               }
+
+               /* Queue the packet.  We use a couple of memory barriers here as need
+                * to make sure that rx_top is perceived to be set after the buffer
+                * pointer and that the buffer pointer is set after the annotation and
+                * the skb data.
+                *
+                * Barriers against rxrpc_recvmsg_data() and rxrpc_rotate_rx_window()
+                * and also rxrpc_fill_out_ack().
+                */
+               if (!terminal)
+                       rxrpc_get_skb(skb, rxrpc_skb_got);
+               call->rxtx_annotations[ix] = annotation;
+               smp_wmb();
+               call->rxtx_buffer[ix] = skb;
+               if (after(seq, call->rx_top)) {
+                       smp_store_release(&call->rx_top, seq);
+               } else if (before(seq, call->rx_top)) {
+                       /* Send an immediate ACK if we fill in a hole */
+                       if (!ack) {
+                               ack = RXRPC_ACK_DELAY;
+                               ack_serial = serial;
+                       }
+                       immediate_ack = true;
+               }
+
+               if (terminal) {
+                       /* From this point on, we're not allowed to touch the
+                        * packet any longer as its ref now belongs to the Rx
+                        * ring.
+                        */
+                       skb = NULL;
+               }
 
-       if (queued && flags & RXRPC_LAST_PACKET && !ack) {
-               ack = RXRPC_ACK_DELAY;
-               ack_serial = serial;
+               if (last) {
+                       set_bit(RXRPC_CALL_RX_LAST, &call->flags);
+                       if (!ack) {
+                               ack = RXRPC_ACK_DELAY;
+                               ack_serial = serial;
+                       }
+                       trace_rxrpc_receive(call, rxrpc_receive_queue_last, serial, seq);
+               } else {
+                       trace_rxrpc_receive(call, rxrpc_receive_queue, serial, seq);
+               }
+
+               if (after_eq(seq, call->rx_expect_next)) {
+                       if (after(seq, call->rx_expect_next)) {
+                               _net("OOS %u > %u", seq, call->rx_expect_next);
+                               ack = RXRPC_ACK_OUT_OF_SEQUENCE;
+                               ack_serial = serial;
+                       }
+                       call->rx_expect_next = seq + 1;
+               }
        }
 
 ack:
@@ -606,13 +613,14 @@ ack:
                                  false, true,
                                  rxrpc_propose_ack_input_data);
 
-       if (sp->hdr.seq == READ_ONCE(call->rx_hard_ack) + 1) {
+       if (seq0 == READ_ONCE(call->rx_hard_ack) + 1) {
                trace_rxrpc_notify_socket(call->debug_id, serial);
                rxrpc_notify_socket(call);
        }
 
 unlock:
        spin_unlock(&call->input_lock);
+       rxrpc_free_skb(skb, rxrpc_skb_freed);
        _leave(" [queued]");
 }
 
@@ -1021,7 +1029,7 @@ static void rxrpc_input_call_packet(struct rxrpc_call *call,
        switch (sp->hdr.type) {
        case RXRPC_PACKET_TYPE_DATA:
                rxrpc_input_data(call, skb);
-               break;
+               goto no_free;
 
        case RXRPC_PACKET_TYPE_ACK:
                rxrpc_input_ack(call, skb);
@@ -1048,6 +1056,8 @@ static void rxrpc_input_call_packet(struct rxrpc_call *call,
                break;
        }
 
+       rxrpc_free_skb(skb, rxrpc_skb_freed);
+no_free:
        _leave("");
 }
 
@@ -1109,7 +1119,7 @@ static void rxrpc_post_packet_to_local(struct rxrpc_local *local,
                skb_queue_tail(&local->event_queue, skb);
                rxrpc_queue_local(local);
        } else {
-               rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+               rxrpc_free_skb(skb, rxrpc_skb_freed);
        }
 }
 
@@ -1124,7 +1134,7 @@ static void rxrpc_reject_packet(struct rxrpc_local *local, struct sk_buff *skb)
                skb_queue_tail(&local->reject_queue, skb);
                rxrpc_queue_local(local);
        } else {
-               rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+               rxrpc_free_skb(skb, rxrpc_skb_freed);
        }
 }
 
@@ -1188,7 +1198,7 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
        if (skb->tstamp == 0)
                skb->tstamp = ktime_get_real();
 
-       rxrpc_new_skb(skb, rxrpc_skb_rx_received);
+       rxrpc_new_skb(skb, rxrpc_skb_received);
 
        skb_pull(skb, sizeof(struct udphdr));
 
@@ -1205,7 +1215,7 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
                static int lose;
                if ((lose++ & 7) == 7) {
                        trace_rxrpc_rx_lose(sp);
-                       rxrpc_free_skb(skb, rxrpc_skb_rx_lost);
+                       rxrpc_free_skb(skb, rxrpc_skb_lost);
                        return 0;
                }
        }
@@ -1237,9 +1247,26 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
                if (sp->hdr.callNumber == 0 ||
                    sp->hdr.seq == 0)
                        goto bad_message;
-               if (sp->hdr.flags & RXRPC_JUMBO_PACKET &&
-                   !rxrpc_validate_jumbo(skb))
+               if (!rxrpc_validate_data(skb))
                        goto bad_message;
+
+               /* Unshare the packet so that it can be modified for in-place
+                * decryption.
+                */
+               if (sp->hdr.securityIndex != 0) {
+                       struct sk_buff *nskb = skb_unshare(skb, GFP_ATOMIC);
+                       if (!nskb) {
+                               rxrpc_eaten_skb(skb, rxrpc_skb_unshared_nomem);
+                               goto out;
+                       }
+
+                       if (nskb != skb) {
+                               rxrpc_eaten_skb(skb, rxrpc_skb_received);
+                               skb = nskb;
+                               rxrpc_new_skb(skb, rxrpc_skb_unshared);
+                               sp = rxrpc_skb(skb);
+                       }
+               }
                break;
 
        case RXRPC_PACKET_TYPE_CHALLENGE:
@@ -1373,11 +1400,14 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
                mutex_unlock(&call->user_mutex);
        }
 
+       /* Process a call packet; this either discards or passes on the ref
+        * elsewhere.
+        */
        rxrpc_input_call_packet(call, skb);
-       goto discard;
+       goto out;
 
 discard:
-       rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+       rxrpc_free_skb(skb, rxrpc_skb_freed);
 out:
        trace_rxrpc_rx_done(0, 0);
        return 0;
index e93a78f..3ce6d62 100644 (file)
@@ -90,7 +90,7 @@ void rxrpc_process_local_events(struct rxrpc_local *local)
        if (skb) {
                struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
 
-               rxrpc_see_skb(skb, rxrpc_skb_rx_seen);
+               rxrpc_see_skb(skb, rxrpc_skb_seen);
                _debug("{%d},{%u}", local->debug_id, sp->hdr.type);
 
                switch (sp->hdr.type) {
@@ -108,7 +108,7 @@ void rxrpc_process_local_events(struct rxrpc_local *local)
                        break;
                }
 
-               rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+               rxrpc_free_skb(skb, rxrpc_skb_freed);
        }
 
        _leave("");
index 72a6e12..3658726 100644 (file)
@@ -426,11 +426,14 @@ static void rxrpc_local_destroyer(struct rxrpc_local *local)
 
        _enter("%d", local->debug_id);
 
+       local->dead = true;
+
        mutex_lock(&rxnet->local_mutex);
        list_del_init(&local->link);
        mutex_unlock(&rxnet->local_mutex);
 
-       ASSERT(RB_EMPTY_ROOT(&local->client_conns));
+       rxrpc_clean_up_local_conns(local);
+       rxrpc_service_connection_reaper(&rxnet->service_conn_reaper);
        ASSERT(!local->service);
 
        if (socket) {
index 369e516..935bb60 100644 (file)
@@ -565,7 +565,7 @@ void rxrpc_reject_packets(struct rxrpc_local *local)
        memset(&whdr, 0, sizeof(whdr));
 
        while ((skb = skb_dequeue(&local->reject_queue))) {
-               rxrpc_see_skb(skb, rxrpc_skb_rx_seen);
+               rxrpc_see_skb(skb, rxrpc_skb_seen);
                sp = rxrpc_skb(skb);
 
                switch (skb->mark) {
@@ -581,7 +581,7 @@ void rxrpc_reject_packets(struct rxrpc_local *local)
                        ioc = 2;
                        break;
                default:
-                       rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+                       rxrpc_free_skb(skb, rxrpc_skb_freed);
                        continue;
                }
 
@@ -606,7 +606,7 @@ void rxrpc_reject_packets(struct rxrpc_local *local)
                                                      rxrpc_tx_point_reject);
                }
 
-               rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+               rxrpc_free_skb(skb, rxrpc_skb_freed);
        }
 
        _leave("");
index 7666ec7..c97ebdc 100644 (file)
@@ -163,11 +163,11 @@ void rxrpc_error_report(struct sock *sk)
                _leave("UDP socket errqueue empty");
                return;
        }
-       rxrpc_new_skb(skb, rxrpc_skb_rx_received);
+       rxrpc_new_skb(skb, rxrpc_skb_received);
        serr = SKB_EXT_ERR(skb);
        if (!skb->len && serr->ee.ee_origin == SO_EE_ORIGIN_TIMESTAMPING) {
                _leave("UDP empty message");
-               rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+               rxrpc_free_skb(skb, rxrpc_skb_freed);
                return;
        }
 
@@ -177,7 +177,7 @@ void rxrpc_error_report(struct sock *sk)
                peer = NULL;
        if (!peer) {
                rcu_read_unlock();
-               rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+               rxrpc_free_skb(skb, rxrpc_skb_freed);
                _leave(" [no peer]");
                return;
        }
@@ -189,7 +189,7 @@ void rxrpc_error_report(struct sock *sk)
             serr->ee.ee_code == ICMP_FRAG_NEEDED)) {
                rxrpc_adjust_mtu(peer, serr);
                rcu_read_unlock();
-               rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+               rxrpc_free_skb(skb, rxrpc_skb_freed);
                rxrpc_put_peer(peer);
                _leave(" [MTU update]");
                return;
@@ -197,7 +197,7 @@ void rxrpc_error_report(struct sock *sk)
 
        rxrpc_store_error(peer, serr);
        rcu_read_unlock();
-       rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+       rxrpc_free_skb(skb, rxrpc_skb_freed);
        rxrpc_put_peer(peer);
 
        _leave("");
index 99ce322..49bb972 100644 (file)
@@ -89,6 +89,15 @@ struct rxrpc_jumbo_header {
 #define RXRPC_JUMBO_DATALEN    1412    /* non-terminal jumbo packet data length */
 #define RXRPC_JUMBO_SUBPKTLEN  (RXRPC_JUMBO_DATALEN + sizeof(struct rxrpc_jumbo_header))
 
+/*
+ * The maximum number of subpackets that can possibly fit in a UDP packet is:
+ *
+ *     ((max_IP - IP_hdr - UDP_hdr) / RXRPC_JUMBO_SUBPKTLEN) + 1
+ *     = ((65535 - 28 - 28) / 1416) + 1
+ *     = 46 non-terminal packets and 1 terminal packet.
+ */
+#define RXRPC_MAX_NR_JUMBO     47
+
 /*****************************************************************************/
 /*
  * on-the-wire Rx ACK packet data payload
index 9a7e1bc..3b0becb 100644 (file)
@@ -177,7 +177,8 @@ static void rxrpc_rotate_rx_window(struct rxrpc_call *call)
        struct sk_buff *skb;
        rxrpc_serial_t serial;
        rxrpc_seq_t hard_ack, top;
-       u8 flags;
+       bool last = false;
+       u8 subpacket;
        int ix;
 
        _enter("%d", call->debug_id);
@@ -189,23 +190,25 @@ static void rxrpc_rotate_rx_window(struct rxrpc_call *call)
        hard_ack++;
        ix = hard_ack & RXRPC_RXTX_BUFF_MASK;
        skb = call->rxtx_buffer[ix];
-       rxrpc_see_skb(skb, rxrpc_skb_rx_rotated);
+       rxrpc_see_skb(skb, rxrpc_skb_rotated);
        sp = rxrpc_skb(skb);
-       flags = sp->hdr.flags;
-       serial = sp->hdr.serial;
-       if (call->rxtx_annotations[ix] & RXRPC_RX_ANNO_JUMBO)
-               serial += (call->rxtx_annotations[ix] & RXRPC_RX_ANNO_JUMBO) - 1;
+
+       subpacket = call->rxtx_annotations[ix] & RXRPC_RX_ANNO_SUBPACKET;
+       serial = sp->hdr.serial + subpacket;
+
+       if (subpacket == sp->nr_subpackets - 1 &&
+           sp->rx_flags & RXRPC_SKB_INCL_LAST)
+               last = true;
 
        call->rxtx_buffer[ix] = NULL;
        call->rxtx_annotations[ix] = 0;
        /* Barrier against rxrpc_input_data(). */
        smp_store_release(&call->rx_hard_ack, hard_ack);
 
-       rxrpc_free_skb(skb, rxrpc_skb_rx_freed);
+       rxrpc_free_skb(skb, rxrpc_skb_freed);
 
-       _debug("%u,%u,%02x", hard_ack, top, flags);
        trace_rxrpc_receive(call, rxrpc_receive_rotate, serial, hard_ack);
-       if (flags & RXRPC_LAST_PACKET) {
+       if (last) {
                rxrpc_end_rx_phase(call, serial);
        } else {
                /* Check to see if there's an ACK that needs sending. */
@@ -233,18 +236,19 @@ static int rxrpc_verify_packet(struct rxrpc_call *call, struct sk_buff *skb,
        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
        rxrpc_seq_t seq = sp->hdr.seq;
        u16 cksum = sp->hdr.cksum;
+       u8 subpacket = annotation & RXRPC_RX_ANNO_SUBPACKET;
 
        _enter("");
 
        /* For all but the head jumbo subpacket, the security checksum is in a
         * jumbo header immediately prior to the data.
         */
-       if ((annotation & RXRPC_RX_ANNO_JUMBO) > 1) {
+       if (subpacket > 0) {
                __be16 tmp;
                if (skb_copy_bits(skb, offset - 2, &tmp, 2) < 0)
                        BUG();
                cksum = ntohs(tmp);
-               seq += (annotation & RXRPC_RX_ANNO_JUMBO) - 1;
+               seq += subpacket;
        }
 
        return call->conn->security->verify_packet(call, skb, offset, len,
@@ -265,19 +269,18 @@ static int rxrpc_locate_data(struct rxrpc_call *call, struct sk_buff *skb,
                             u8 *_annotation,
                             unsigned int *_offset, unsigned int *_len)
 {
+       struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
        unsigned int offset = sizeof(struct rxrpc_wire_header);
        unsigned int len;
        int ret;
        u8 annotation = *_annotation;
+       u8 subpacket = annotation & RXRPC_RX_ANNO_SUBPACKET;
 
        /* Locate the subpacket */
+       offset += subpacket * RXRPC_JUMBO_SUBPKTLEN;
        len = skb->len - offset;
-       if ((annotation & RXRPC_RX_ANNO_JUMBO) > 0) {
-               offset += (((annotation & RXRPC_RX_ANNO_JUMBO) - 1) *
-                          RXRPC_JUMBO_SUBPKTLEN);
-               len = (annotation & RXRPC_RX_ANNO_JLAST) ?
-                       skb->len - offset : RXRPC_JUMBO_SUBPKTLEN;
-       }
+       if (subpacket < sp->nr_subpackets - 1)
+               len = RXRPC_JUMBO_DATALEN;
 
        if (!(annotation & RXRPC_RX_ANNO_VERIFIED)) {
                ret = rxrpc_verify_packet(call, skb, annotation, offset, len);
@@ -303,6 +306,7 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
 {
        struct rxrpc_skb_priv *sp;
        struct sk_buff *skb;
+       rxrpc_serial_t serial;
        rxrpc_seq_t hard_ack, top, seq;
        size_t remain;
        bool last;
@@ -336,12 +340,15 @@ static int rxrpc_recvmsg_data(struct socket *sock, struct rxrpc_call *call,
                        break;
                }
                smp_rmb();
-               rxrpc_see_skb(skb, rxrpc_skb_rx_seen);
+               rxrpc_see_skb(skb, rxrpc_skb_seen);
                sp = rxrpc_skb(skb);
 
-               if (!(flags & MSG_PEEK))
+               if (!(flags & MSG_PEEK)) {
+                       serial = sp->hdr.serial;
+                       serial += call->rxtx_annotations[ix] & RXRPC_RX_ANNO_SUBPACKET;
                        trace_rxrpc_receive(call, rxrpc_receive_front,
-                                           sp->hdr.serial, seq);
+                                           serial, seq);
+               }
 
                if (msg)
                        sock_recv_timestamp(msg, sock->sk, skb);
index ae8cd89..c60c520 100644 (file)
@@ -187,10 +187,8 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
        struct rxrpc_skb_priv *sp;
        struct rxrpc_crypt iv;
        struct scatterlist sg[16];
-       struct sk_buff *trailer;
        unsigned int len;
        u16 check;
-       int nsg;
        int err;
 
        sp = rxrpc_skb(skb);
@@ -214,15 +212,14 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
        crypto_skcipher_encrypt(req);
 
        /* we want to encrypt the skbuff in-place */
-       nsg = skb_cow_data(skb, 0, &trailer);
-       err = -ENOMEM;
-       if (nsg < 0 || nsg > 16)
+       err = -EMSGSIZE;
+       if (skb_shinfo(skb)->nr_frags > 16)
                goto out;
 
        len = data_size + call->conn->size_align - 1;
        len &= ~(call->conn->size_align - 1);
 
-       sg_init_table(sg, nsg);
+       sg_init_table(sg, ARRAY_SIZE(sg));
        err = skb_to_sgvec(skb, sg, 0, len);
        if (unlikely(err < 0))
                goto out;
@@ -319,11 +316,10 @@ static int rxkad_verify_packet_1(struct rxrpc_call *call, struct sk_buff *skb,
        struct rxkad_level1_hdr sechdr;
        struct rxrpc_crypt iv;
        struct scatterlist sg[16];
-       struct sk_buff *trailer;
        bool aborted;
        u32 data_size, buf;
        u16 check;
-       int nsg, ret;
+       int ret;
 
        _enter("");
 
@@ -336,11 +332,7 @@ static int rxkad_verify_packet_1(struct rxrpc_call *call, struct sk_buff *skb,
        /* Decrypt the skbuff in-place.  TODO: We really want to decrypt
         * directly into the target buffer.
         */
-       nsg = skb_cow_data(skb, 0, &trailer);
-       if (nsg < 0 || nsg > 16)
-               goto nomem;
-
-       sg_init_table(sg, nsg);
+       sg_init_table(sg, ARRAY_SIZE(sg));
        ret = skb_to_sgvec(skb, sg, offset, 8);
        if (unlikely(ret < 0))
                return ret;
@@ -388,10 +380,6 @@ protocol_error:
        if (aborted)
                rxrpc_send_abort_packet(call);
        return -EPROTO;
-
-nomem:
-       _leave(" = -ENOMEM");
-       return -ENOMEM;
 }
 
 /*
@@ -406,7 +394,6 @@ static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb,
        struct rxkad_level2_hdr sechdr;
        struct rxrpc_crypt iv;
        struct scatterlist _sg[4], *sg;
-       struct sk_buff *trailer;
        bool aborted;
        u32 data_size, buf;
        u16 check;
@@ -423,12 +410,11 @@ static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb,
        /* Decrypt the skbuff in-place.  TODO: We really want to decrypt
         * directly into the target buffer.
         */
-       nsg = skb_cow_data(skb, 0, &trailer);
-       if (nsg < 0)
-               goto nomem;
-
        sg = _sg;
-       if (unlikely(nsg > 4)) {
+       nsg = skb_shinfo(skb)->nr_frags;
+       if (nsg <= 4) {
+               nsg = 4;
+       } else {
                sg = kmalloc_array(nsg, sizeof(*sg), GFP_NOIO);
                if (!sg)
                        goto nomem;
index bae1443..6a1547b 100644 (file)
@@ -176,7 +176,7 @@ static int rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
        skb->tstamp = ktime_get_real();
 
        ix = seq & RXRPC_RXTX_BUFF_MASK;
-       rxrpc_get_skb(skb, rxrpc_skb_tx_got);
+       rxrpc_get_skb(skb, rxrpc_skb_got);
        call->rxtx_annotations[ix] = annotation;
        smp_wmb();
        call->rxtx_buffer[ix] = skb;
@@ -248,7 +248,7 @@ static int rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call,
        }
 
 out:
-       rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
+       rxrpc_free_skb(skb, rxrpc_skb_freed);
        _leave(" = %d", ret);
        return ret;
 }
@@ -289,7 +289,7 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
 
        skb = call->tx_pending;
        call->tx_pending = NULL;
-       rxrpc_see_skb(skb, rxrpc_skb_tx_seen);
+       rxrpc_see_skb(skb, rxrpc_skb_seen);
 
        copied = 0;
        do {
@@ -336,7 +336,9 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
                        if (!skb)
                                goto maybe_error;
 
-                       rxrpc_new_skb(skb, rxrpc_skb_tx_new);
+                       sp = rxrpc_skb(skb);
+                       sp->rx_flags |= RXRPC_SKB_TX_BUFFER;
+                       rxrpc_new_skb(skb, rxrpc_skb_new);
 
                        _debug("ALLOC SEND %p", skb);
 
@@ -346,7 +348,6 @@ static int rxrpc_send_data(struct rxrpc_sock *rx,
                        skb_reserve(skb, call->conn->security_size);
                        skb->len += call->conn->security_size;
 
-                       sp = rxrpc_skb(skb);
                        sp->remain = chunk;
                        if (sp->remain > skb_tailroom(skb))
                                sp->remain = skb_tailroom(skb);
@@ -439,7 +440,7 @@ out:
        return ret;
 
 call_terminated:
-       rxrpc_free_skb(skb, rxrpc_skb_tx_freed);
+       rxrpc_free_skb(skb, rxrpc_skb_freed);
        _leave(" = %d", call->error);
        return call->error;
 
index 9ad5045..0348d2b 100644 (file)
@@ -14,7 +14,8 @@
 #include <net/af_rxrpc.h>
 #include "ar-internal.h"
 
-#define select_skb_count(op) (op >= rxrpc_skb_tx_cleaned ? &rxrpc_n_tx_skbs : &rxrpc_n_rx_skbs)
+#define is_tx_skb(skb) (rxrpc_skb(skb)->rx_flags & RXRPC_SKB_TX_BUFFER)
+#define select_skb_count(skb) (is_tx_skb(skb) ? &rxrpc_n_tx_skbs : &rxrpc_n_rx_skbs)
 
 /*
  * Note the allocation or reception of a socket buffer.
@@ -22,8 +23,9 @@
 void rxrpc_new_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
 {
        const void *here = __builtin_return_address(0);
-       int n = atomic_inc_return(select_skb_count(op));
-       trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here);
+       int n = atomic_inc_return(select_skb_count(skb));
+       trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n,
+                       rxrpc_skb(skb)->rx_flags, here);
 }
 
 /*
@@ -33,8 +35,9 @@ void rxrpc_see_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
 {
        const void *here = __builtin_return_address(0);
        if (skb) {
-               int n = atomic_read(select_skb_count(op));
-               trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here);
+               int n = atomic_read(select_skb_count(skb));
+               trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n,
+                               rxrpc_skb(skb)->rx_flags, here);
        }
 }
 
@@ -44,12 +47,23 @@ void rxrpc_see_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
 void rxrpc_get_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
 {
        const void *here = __builtin_return_address(0);
-       int n = atomic_inc_return(select_skb_count(op));
-       trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here);
+       int n = atomic_inc_return(select_skb_count(skb));
+       trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n,
+                       rxrpc_skb(skb)->rx_flags, here);
        skb_get(skb);
 }
 
 /*
+ * Note the dropping of a ref on a socket buffer by the core.
+ */
+void rxrpc_eaten_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
+{
+       const void *here = __builtin_return_address(0);
+       int n = atomic_inc_return(&rxrpc_n_rx_skbs);
+       trace_rxrpc_skb(skb, op, 0, n, 0, here);
+}
+
+/*
  * Note the destruction of a socket buffer.
  */
 void rxrpc_free_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
@@ -58,8 +72,9 @@ void rxrpc_free_skb(struct sk_buff *skb, enum rxrpc_skb_trace op)
        if (skb) {
                int n;
                CHECK_SLAB_OKAY(&skb->users);
-               n = atomic_dec_return(select_skb_count(op));
-               trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here);
+               n = atomic_dec_return(select_skb_count(skb));
+               trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n,
+                               rxrpc_skb(skb)->rx_flags, here);
                kfree_skb(skb);
        }
 }
@@ -72,9 +87,10 @@ void rxrpc_purge_queue(struct sk_buff_head *list)
        const void *here = __builtin_return_address(0);
        struct sk_buff *skb;
        while ((skb = skb_dequeue((list))) != NULL) {
-               int n = atomic_dec_return(select_skb_count(rxrpc_skb_rx_purged));
-               trace_rxrpc_skb(skb, rxrpc_skb_rx_purged,
-                               refcount_read(&skb->users), n, here);
+               int n = atomic_dec_return(select_skb_count(skb));
+               trace_rxrpc_skb(skb, rxrpc_skb_purged,
+                               refcount_read(&skb->users), n,
+                               rxrpc_skb(skb)->rx_flags, here);
                kfree_skb(skb);
        }
 }
index fd1f7e7..04b7bd4 100644 (file)
@@ -422,7 +422,7 @@ static __net_init int bpf_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, bpf_net_id);
 
-       return tc_action_net_init(tn, &act_bpf_ops);
+       return tc_action_net_init(net, tn, &act_bpf_ops);
 }
 
 static void __net_exit bpf_exit_net(struct list_head *net_list)
index 32ac04d..2b43cac 100644 (file)
@@ -231,7 +231,7 @@ static __net_init int connmark_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, connmark_net_id);
 
-       return tc_action_net_init(tn, &act_connmark_ops);
+       return tc_action_net_init(net, tn, &act_connmark_ops);
 }
 
 static void __net_exit connmark_exit_net(struct list_head *net_list)
index 9b92882..d3cfad8 100644 (file)
@@ -714,7 +714,7 @@ static __net_init int csum_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, csum_net_id);
 
-       return tc_action_net_init(tn, &act_csum_ops);
+       return tc_action_net_init(net, tn, &act_csum_ops);
 }
 
 static void __net_exit csum_exit_net(struct list_head *net_list)
index 33a1a74..cdd6f38 100644 (file)
@@ -939,7 +939,7 @@ static __net_init int ct_init_net(struct net *net)
                tn->labels = true;
        }
 
-       return tc_action_net_init(&tn->tn, &act_ct_ops);
+       return tc_action_net_init(net, &tn->tn, &act_ct_ops);
 }
 
 static void __net_exit ct_exit_net(struct list_head *net_list)
index 06ef74b..0dbcfd1 100644 (file)
@@ -376,7 +376,7 @@ static __net_init int ctinfo_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, ctinfo_net_id);
 
-       return tc_action_net_init(tn, &act_ctinfo_ops);
+       return tc_action_net_init(net, tn, &act_ctinfo_ops);
 }
 
 static void __net_exit ctinfo_exit_net(struct list_head *net_list)
index 8f0140c..324f1d1 100644 (file)
@@ -278,7 +278,7 @@ static __net_init int gact_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, gact_net_id);
 
-       return tc_action_net_init(tn, &act_gact_ops);
+       return tc_action_net_init(net, tn, &act_gact_ops);
 }
 
 static void __net_exit gact_exit_net(struct list_head *net_list)
index 92ee853..3a31e24 100644 (file)
@@ -890,7 +890,7 @@ static __net_init int ife_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, ife_net_id);
 
-       return tc_action_net_init(tn, &act_ife_ops);
+       return tc_action_net_init(net, tn, &act_ife_ops);
 }
 
 static void __net_exit ife_exit_net(struct list_head *net_list)
index ce2c30a..214a03d 100644 (file)
@@ -61,12 +61,13 @@ static int ipt_init_target(struct net *net, struct xt_entry_target *t,
        return 0;
 }
 
-static void ipt_destroy_target(struct xt_entry_target *t)
+static void ipt_destroy_target(struct xt_entry_target *t, struct net *net)
 {
        struct xt_tgdtor_param par = {
                .target   = t->u.kernel.target,
                .targinfo = t->data,
                .family   = NFPROTO_IPV4,
+               .net      = net,
        };
        if (par.target->destroy != NULL)
                par.target->destroy(&par);
@@ -78,7 +79,7 @@ static void tcf_ipt_release(struct tc_action *a)
        struct tcf_ipt *ipt = to_ipt(a);
 
        if (ipt->tcfi_t) {
-               ipt_destroy_target(ipt->tcfi_t);
+               ipt_destroy_target(ipt->tcfi_t, a->idrinfo->net);
                kfree(ipt->tcfi_t);
        }
        kfree(ipt->tcfi_tname);
@@ -180,7 +181,7 @@ static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,
 
        spin_lock_bh(&ipt->tcf_lock);
        if (ret != ACT_P_CREATED) {
-               ipt_destroy_target(ipt->tcfi_t);
+               ipt_destroy_target(ipt->tcfi_t, net);
                kfree(ipt->tcfi_tname);
                kfree(ipt->tcfi_t);
        }
@@ -350,7 +351,7 @@ static __net_init int ipt_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, ipt_net_id);
 
-       return tc_action_net_init(tn, &act_ipt_ops);
+       return tc_action_net_init(net, tn, &act_ipt_ops);
 }
 
 static void __net_exit ipt_exit_net(struct list_head *net_list)
@@ -399,7 +400,7 @@ static __net_init int xt_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, xt_net_id);
 
-       return tc_action_net_init(tn, &act_xt_ops);
+       return tc_action_net_init(net, tn, &act_xt_ops);
 }
 
 static void __net_exit xt_exit_net(struct list_head *net_list)
index be3f88d..9d1bf50 100644 (file)
@@ -453,7 +453,7 @@ static __net_init int mirred_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, mirred_net_id);
 
-       return tc_action_net_init(tn, &act_mirred_ops);
+       return tc_action_net_init(net, tn, &act_mirred_ops);
 }
 
 static void __net_exit mirred_exit_net(struct list_head *net_list)
index 0f299e3..e168df0 100644 (file)
@@ -375,7 +375,7 @@ static __net_init int mpls_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, mpls_net_id);
 
-       return tc_action_net_init(tn, &act_mpls_ops);
+       return tc_action_net_init(net, tn, &act_mpls_ops);
 }
 
 static void __net_exit mpls_exit_net(struct list_head *net_list)
index 7b858c1..ea4c535 100644 (file)
@@ -327,7 +327,7 @@ static __net_init int nat_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, nat_net_id);
 
-       return tc_action_net_init(tn, &act_nat_ops);
+       return tc_action_net_init(net, tn, &act_nat_ops);
 }
 
 static void __net_exit nat_exit_net(struct list_head *net_list)
index 17360c6..cdfaa79 100644 (file)
@@ -498,7 +498,7 @@ static __net_init int pedit_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, pedit_net_id);
 
-       return tc_action_net_init(tn, &act_pedit_ops);
+       return tc_action_net_init(net, tn, &act_pedit_ops);
 }
 
 static void __net_exit pedit_exit_net(struct list_head *net_list)
index 49cec3e..6315e0f 100644 (file)
@@ -371,7 +371,7 @@ static __net_init int police_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, police_net_id);
 
-       return tc_action_net_init(tn, &act_police_ops);
+       return tc_action_net_init(net, tn, &act_police_ops);
 }
 
 static void __net_exit police_exit_net(struct list_head *net_list)
index 595308d..1022912 100644 (file)
@@ -102,13 +102,17 @@ static int tcf_sample_init(struct net *net, struct nlattr *nla,
        goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
        s->rate = rate;
        s->psample_group_num = psample_group_num;
-       RCU_INIT_POINTER(s->psample_group, psample_group);
+       rcu_swap_protected(s->psample_group, psample_group,
+                          lockdep_is_held(&s->tcf_lock));
 
        if (tb[TCA_SAMPLE_TRUNC_SIZE]) {
                s->truncate = true;
                s->trunc_size = nla_get_u32(tb[TCA_SAMPLE_TRUNC_SIZE]);
        }
        spin_unlock_bh(&s->tcf_lock);
+
+       if (psample_group)
+               psample_group_put(psample_group);
        if (goto_ch)
                tcf_chain_put_by_act(goto_ch);
 
@@ -265,7 +269,7 @@ static __net_init int sample_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, sample_net_id);
 
-       return tc_action_net_init(tn, &act_sample_ops);
+       return tc_action_net_init(net, tn, &act_sample_ops);
 }
 
 static void __net_exit sample_exit_net(struct list_head *net_list)
index 33aefa2..6120e56 100644 (file)
@@ -232,7 +232,7 @@ static __net_init int simp_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, simp_net_id);
 
-       return tc_action_net_init(tn, &act_simp_ops);
+       return tc_action_net_init(net, tn, &act_simp_ops);
 }
 
 static void __net_exit simp_exit_net(struct list_head *net_list)
index 37dced0..6a8d333 100644 (file)
@@ -336,7 +336,7 @@ static __net_init int skbedit_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, skbedit_net_id);
 
-       return tc_action_net_init(tn, &act_skbedit_ops);
+       return tc_action_net_init(net, tn, &act_skbedit_ops);
 }
 
 static void __net_exit skbedit_exit_net(struct list_head *net_list)
index 7da3518..888437f 100644 (file)
@@ -287,7 +287,7 @@ static __net_init int skbmod_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, skbmod_net_id);
 
-       return tc_action_net_init(tn, &act_skbmod_ops);
+       return tc_action_net_init(net, tn, &act_skbmod_ops);
 }
 
 static void __net_exit skbmod_exit_net(struct list_head *net_list)
index 6d0debd..2f83a79 100644 (file)
@@ -600,7 +600,7 @@ static __net_init int tunnel_key_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, tunnel_key_net_id);
 
-       return tc_action_net_init(tn, &act_tunnel_key_ops);
+       return tc_action_net_init(net, tn, &act_tunnel_key_ops);
 }
 
 static void __net_exit tunnel_key_exit_net(struct list_head *net_list)
index a3c9eea..287a30b 100644 (file)
@@ -334,7 +334,7 @@ static __net_init int vlan_init_net(struct net *net)
 {
        struct tc_action_net *tn = net_generic(net, vlan_net_id);
 
-       return tc_action_net_init(tn, &act_vlan_ops);
+       return tc_action_net_init(net, tn, &act_vlan_ops);
 }
 
 static void __net_exit vlan_exit_net(struct list_head *net_list)
index 04faee7..1047825 100644 (file)
@@ -1920,6 +1920,8 @@ static void tc_bind_tclass(struct Qdisc *q, u32 portid, u32 clid,
        cl = cops->find(q, portid);
        if (!cl)
                return;
+       if (!cops->tcf_block)
+               return;
        block = cops->tcf_block(q, cl, NULL);
        if (!block)
                return;
index 732e109..810645b 100644 (file)
@@ -181,11 +181,6 @@ static struct sk_buff *cbs_dequeue_soft(struct Qdisc *sch)
        s64 credits;
        int len;
 
-       if (atomic64_read(&q->port_rate) == -1) {
-               WARN_ONCE(1, "cbs: dequeue() called with unknown port rate.");
-               return NULL;
-       }
-
        if (q->credits < 0) {
                credits = timediff_to_credits(now - q->last, q->idleslope);
 
@@ -303,11 +298,19 @@ static int cbs_enable_offload(struct net_device *dev, struct cbs_sched_data *q,
 static void cbs_set_port_rate(struct net_device *dev, struct cbs_sched_data *q)
 {
        struct ethtool_link_ksettings ecmd;
+       int speed = SPEED_10;
        int port_rate = -1;
+       int err;
+
+       err = __ethtool_get_link_ksettings(dev, &ecmd);
+       if (err < 0)
+               goto skip;
+
+       if (ecmd.base.speed != SPEED_UNKNOWN)
+               speed = ecmd.base.speed;
 
-       if (!__ethtool_get_link_ksettings(dev, &ecmd) &&
-           ecmd.base.speed != SPEED_UNKNOWN)
-               port_rate = ecmd.base.speed * 1000 * BYTES_PER_KBIT;
+skip:
+       port_rate = speed * 1000 * BYTES_PER_KBIT;
 
        atomic64_set(&q->port_rate, port_rate);
        netdev_dbg(dev, "cbs: set %s's port_rate to: %lld, linkspeed: %d\n",
index 11c03cf..ac28f6a 100644 (file)
@@ -46,6 +46,8 @@ EXPORT_SYMBOL(default_qdisc_ops);
  * - updates to tree and tree walking are only done under the rtnl mutex.
  */
 
+#define SKB_XOFF_MAGIC ((struct sk_buff *)1UL)
+
 static inline struct sk_buff *__skb_dequeue_bad_txq(struct Qdisc *q)
 {
        const struct netdev_queue *txq = q->dev_queue;
@@ -71,7 +73,7 @@ static inline struct sk_buff *__skb_dequeue_bad_txq(struct Qdisc *q)
                                q->q.qlen--;
                        }
                } else {
-                       skb = NULL;
+                       skb = SKB_XOFF_MAGIC;
                }
        }
 
@@ -253,8 +255,11 @@ validate:
                return skb;
 
        skb = qdisc_dequeue_skb_bad_txq(q);
-       if (unlikely(skb))
+       if (unlikely(skb)) {
+               if (skb == SKB_XOFF_MAGIC)
+                       return NULL;
                goto bulk;
+       }
        skb = q->dequeue(q);
        if (skb) {
 bulk:
@@ -624,8 +629,12 @@ static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc,
 
        err = skb_array_produce(q, skb);
 
-       if (unlikely(err))
-               return qdisc_drop_cpu(skb, qdisc, to_free);
+       if (unlikely(err)) {
+               if (qdisc_is_percpu_stats(qdisc))
+                       return qdisc_drop_cpu(skb, qdisc, to_free);
+               else
+                       return qdisc_drop(skb, qdisc, to_free);
+       }
 
        qdisc_update_stats_at_enqueue(qdisc, pkt_len);
        return NET_XMIT_SUCCESS;
@@ -688,11 +697,14 @@ static void pfifo_fast_reset(struct Qdisc *qdisc)
                        kfree_skb(skb);
        }
 
-       for_each_possible_cpu(i) {
-               struct gnet_stats_queue *q = per_cpu_ptr(qdisc->cpu_qstats, i);
+       if (qdisc_is_percpu_stats(qdisc)) {
+               for_each_possible_cpu(i) {
+                       struct gnet_stats_queue *q;
 
-               q->backlog = 0;
-               q->qlen = 0;
+                       q = per_cpu_ptr(qdisc->cpu_qstats, i);
+                       q->backlog = 0;
+                       q->qlen = 0;
+               }
        }
 }
 
index cee6971..23cd1c8 100644 (file)
@@ -531,7 +531,7 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt,
                new_hhf_non_hh_weight = nla_get_u32(tb[TCA_HHF_NON_HH_WEIGHT]);
 
        non_hh_quantum = (u64)new_quantum * new_hhf_non_hh_weight;
-       if (non_hh_quantum > INT_MAX)
+       if (non_hh_quantum == 0 || non_hh_quantum > INT_MAX)
                return -EINVAL;
 
        sch_tree_lock(sch);
index e25d414..8d8bc2e 100644 (file)
@@ -477,11 +477,6 @@ static struct sk_buff *taprio_dequeue(struct Qdisc *sch)
        u32 gate_mask;
        int i;
 
-       if (atomic64_read(&q->picos_per_byte) == -1) {
-               WARN_ONCE(1, "taprio: dequeue() called with unknown picos per byte.");
-               return NULL;
-       }
-
        rcu_read_lock();
        entry = rcu_dereference(q->current_entry);
        /* if there's no entry, it means that the schedule didn't
@@ -958,12 +953,20 @@ static void taprio_set_picos_per_byte(struct net_device *dev,
                                      struct taprio_sched *q)
 {
        struct ethtool_link_ksettings ecmd;
-       int picos_per_byte = -1;
+       int speed = SPEED_10;
+       int picos_per_byte;
+       int err;
 
-       if (!__ethtool_get_link_ksettings(dev, &ecmd) &&
-           ecmd.base.speed != SPEED_UNKNOWN)
-               picos_per_byte = div64_s64(NSEC_PER_SEC * 1000LL * 8,
-                                          ecmd.base.speed * 1000 * 1000);
+       err = __ethtool_get_link_ksettings(dev, &ecmd);
+       if (err < 0)
+               goto skip;
+
+       if (ecmd.base.speed != SPEED_UNKNOWN)
+               speed = ecmd.base.speed;
+
+skip:
+       picos_per_byte = div64_s64(NSEC_PER_SEC * 1000LL * 8,
+                                  speed * 1000 * 1000);
 
        atomic64_set(&q->picos_per_byte, picos_per_byte);
        netdev_dbg(dev, "taprio: set %s's picos_per_byte to: %lld, linkspeed: %d\n",
@@ -1249,6 +1252,10 @@ static int taprio_init(struct Qdisc *sch, struct nlattr *opt,
         */
        q->clockid = -1;
 
+       spin_lock(&taprio_list_lock);
+       list_add(&q->taprio_list, &taprio_list);
+       spin_unlock(&taprio_list_lock);
+
        if (sch->parent != TC_H_ROOT)
                return -EOPNOTSUPP;
 
@@ -1266,10 +1273,6 @@ static int taprio_init(struct Qdisc *sch, struct nlattr *opt,
        if (!opt)
                return -EINVAL;
 
-       spin_lock(&taprio_list_lock);
-       list_add(&q->taprio_list, &taprio_list);
-       spin_unlock(&taprio_list_lock);
-
        for (i = 0; i < dev->num_tx_queues; i++) {
                struct netdev_queue *dev_queue;
                struct Qdisc *qdisc;
index 2d47adc..53746ff 100644 (file)
@@ -1336,7 +1336,7 @@ static int __net_init sctp_ctrlsock_init(struct net *net)
        return status;
 }
 
-static void __net_init sctp_ctrlsock_exit(struct net *net)
+static void __net_exit sctp_ctrlsock_exit(struct net *net)
 {
        /* Free the control endpoint.  */
        inet_ctl_sock_destroy(net->sctp.ctl_sock);
index 1cf5bb5..e52b212 100644 (file)
@@ -547,7 +547,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_cmd_seq *commands,
        if (net->sctp.pf_enable &&
           (transport->state == SCTP_ACTIVE) &&
           (transport->error_count < transport->pathmaxrxt) &&
-          (transport->error_count > asoc->pf_retrans)) {
+          (transport->error_count > transport->pf_retrans)) {
 
                sctp_assoc_control_transport(asoc, transport,
                                             SCTP_TRANSPORT_PF,
index 9d1f83b..b083d4e 100644 (file)
@@ -309,7 +309,7 @@ static int sctp_bind(struct sock *sk, struct sockaddr *addr, int addr_len)
        return retval;
 }
 
-static long sctp_get_port_local(struct sock *, union sctp_addr *);
+static int sctp_get_port_local(struct sock *, union sctp_addr *);
 
 /* Verify this is a valid sockaddr. */
 static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt,
@@ -399,9 +399,8 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
         * detection.
         */
        addr->v4.sin_port = htons(snum);
-       if ((ret = sctp_get_port_local(sk, addr))) {
+       if (sctp_get_port_local(sk, addr))
                return -EADDRINUSE;
-       }
 
        /* Refresh ephemeral port.  */
        if (!bp->port)
@@ -413,11 +412,13 @@ static int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
        ret = sctp_add_bind_addr(bp, addr, af->sockaddr_len,
                                 SCTP_ADDR_SRC, GFP_ATOMIC);
 
-       /* Copy back into socket for getsockname() use. */
-       if (!ret) {
-               inet_sk(sk)->inet_sport = htons(inet_sk(sk)->inet_num);
-               sp->pf->to_sk_saddr(addr, sk);
+       if (ret) {
+               sctp_put_port(sk);
+               return ret;
        }
+       /* Copy back into socket for getsockname() use. */
+       inet_sk(sk)->inet_sport = htons(inet_sk(sk)->inet_num);
+       sp->pf->to_sk_saddr(addr, sk);
 
        return ret;
 }
@@ -7173,7 +7174,7 @@ static int sctp_getsockopt_paddr_thresholds(struct sock *sk,
                val.spt_pathmaxrxt = trans->pathmaxrxt;
                val.spt_pathpfthld = trans->pf_retrans;
 
-               return 0;
+               goto out;
        }
 
        asoc = sctp_id2assoc(sk, val.spt_assoc_id);
@@ -7191,6 +7192,7 @@ static int sctp_getsockopt_paddr_thresholds(struct sock *sk,
                val.spt_pathmaxrxt = sp->pathmaxrxt;
        }
 
+out:
        if (put_user(len, optlen) || copy_to_user(optval, &val, len))
                return -EFAULT;
 
@@ -7998,7 +8000,7 @@ static void sctp_unhash(struct sock *sk)
 static struct sctp_bind_bucket *sctp_bucket_create(
        struct sctp_bind_hashbucket *head, struct net *, unsigned short snum);
 
-static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
+static int sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
 {
        struct sctp_sock *sp = sctp_sk(sk);
        bool reuse = (sk->sk_reuse || sp->reuse);
@@ -8108,7 +8110,7 @@ pp_found:
 
                        if (sctp_bind_addr_conflict(&ep2->base.bind_addr,
                                                    addr, sp2, sp)) {
-                               ret = (long)sk2;
+                               ret = 1;
                                goto fail_unlock;
                        }
                }
@@ -8180,7 +8182,7 @@ static int sctp_get_port(struct sock *sk, unsigned short snum)
        addr.v4.sin_port = htons(snum);
 
        /* Note: sk->sk_num gets filled in if ephemeral port request. */
-       return !!sctp_get_port_local(sk, &addr);
+       return sctp_get_port_local(sk, &addr);
 }
 
 /*
index f0de323..6c8f09c 100644 (file)
@@ -76,13 +76,11 @@ static int smc_tx_wait(struct smc_sock *smc, int flags)
        DEFINE_WAIT_FUNC(wait, woken_wake_function);
        struct smc_connection *conn = &smc->conn;
        struct sock *sk = &smc->sk;
-       bool noblock;
        long timeo;
        int rc = 0;
 
        /* similar to sk_stream_wait_memory */
        timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
-       noblock = timeo ? false : true;
        add_wait_queue(sk_sleep(sk), &wait);
        while (1) {
                sk_set_bit(SOCKWQ_ASYNC_NOSPACE, sk);
@@ -97,8 +95,8 @@ static int smc_tx_wait(struct smc_sock *smc, int flags)
                        break;
                }
                if (!timeo) {
-                       if (noblock)
-                               set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
+                       /* ensure EPOLLOUT is subsequently generated */
+                       set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
                        rc = -EAGAIN;
                        break;
                }
index d8679b6..a07b516 100644 (file)
@@ -1970,6 +1970,7 @@ call_bind(struct rpc_task *task)
 static void
 call_bind_status(struct rpc_task *task)
 {
+       struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt;
        int status = -EIO;
 
        if (rpc_task_transmitted(task)) {
@@ -1977,14 +1978,15 @@ call_bind_status(struct rpc_task *task)
                return;
        }
 
-       if (task->tk_status >= 0) {
-               dprint_status(task);
+       dprint_status(task);
+       trace_rpc_bind_status(task);
+       if (task->tk_status >= 0)
+               goto out_next;
+       if (xprt_bound(xprt)) {
                task->tk_status = 0;
-               task->tk_action = call_connect;
-               return;
+               goto out_next;
        }
 
-       trace_rpc_bind_status(task);
        switch (task->tk_status) {
        case -ENOMEM:
                dprintk("RPC: %5u rpcbind out of memory\n", task->tk_pid);
@@ -2003,6 +2005,9 @@ call_bind_status(struct rpc_task *task)
                task->tk_rebind_retry--;
                rpc_delay(task, 3*HZ);
                goto retry_timeout;
+       case -ENOBUFS:
+               rpc_delay(task, HZ >> 2);
+               goto retry_timeout;
        case -EAGAIN:
                goto retry_timeout;
        case -ETIMEDOUT:
@@ -2026,7 +2031,6 @@ call_bind_status(struct rpc_task *task)
        case -ENETDOWN:
        case -EHOSTUNREACH:
        case -ENETUNREACH:
-       case -ENOBUFS:
        case -EPIPE:
                dprintk("RPC: %5u remote rpcbind unreachable: %d\n",
                                task->tk_pid, task->tk_status);
@@ -2043,7 +2047,9 @@ call_bind_status(struct rpc_task *task)
 
        rpc_call_rpcerror(task, status);
        return;
-
+out_next:
+       task->tk_action = call_connect;
+       return;
 retry_timeout:
        task->tk_status = 0;
        task->tk_action = call_bind;
@@ -2090,6 +2096,7 @@ call_connect(struct rpc_task *task)
 static void
 call_connect_status(struct rpc_task *task)
 {
+       struct rpc_xprt *xprt = task->tk_rqstp->rq_xprt;
        struct rpc_clnt *clnt = task->tk_client;
        int status = task->tk_status;
 
@@ -2099,8 +2106,17 @@ call_connect_status(struct rpc_task *task)
        }
 
        dprint_status(task);
-
        trace_rpc_connect_status(task);
+
+       if (task->tk_status == 0) {
+               clnt->cl_stats->netreconn++;
+               goto out_next;
+       }
+       if (xprt_connected(xprt)) {
+               task->tk_status = 0;
+               goto out_next;
+       }
+
        task->tk_status = 0;
        switch (status) {
        case -ECONNREFUSED:
@@ -2117,8 +2133,6 @@ call_connect_status(struct rpc_task *task)
        case -ENETDOWN:
        case -ENETUNREACH:
        case -EHOSTUNREACH:
-       case -EADDRINUSE:
-       case -ENOBUFS:
        case -EPIPE:
                xprt_conditional_disconnect(task->tk_rqstp->rq_xprt,
                                            task->tk_rqstp->rq_connect_cookie);
@@ -2127,17 +2141,20 @@ call_connect_status(struct rpc_task *task)
                /* retry with existing socket, after a delay */
                rpc_delay(task, 3*HZ);
                /* fall through */
+       case -EADDRINUSE:
        case -ENOTCONN:
        case -EAGAIN:
        case -ETIMEDOUT:
                goto out_retry;
-       case 0:
-               clnt->cl_stats->netreconn++;
-               task->tk_action = call_transmit;
-               return;
+       case -ENOBUFS:
+               rpc_delay(task, HZ >> 2);
+               goto out_retry;
        }
        rpc_call_rpcerror(task, status);
        return;
+out_next:
+       task->tk_action = call_transmit;
+       return;
 out_retry:
        /* Check for timeouts before looping back to call_bind */
        task->tk_action = call_bind;
@@ -2365,7 +2382,7 @@ call_status(struct rpc_task *task)
        case -ECONNABORTED:
        case -ENOTCONN:
                rpc_force_rebind(clnt);
-               /* fall through */
+               break;
        case -EADDRINUSE:
                rpc_delay(task, 3*HZ);
                /* fall through */
index 783748d..2e71f54 100644 (file)
@@ -1408,13 +1408,6 @@ xprt_request_transmit(struct rpc_rqst *req, struct rpc_task *snd_task)
                        status = -EBADMSG;
                        goto out_dequeue;
                }
-               if (task->tk_ops->rpc_call_prepare_transmit) {
-                       task->tk_ops->rpc_call_prepare_transmit(task,
-                                       task->tk_calldata);
-                       status = task->tk_status;
-                       if (status < 0)
-                               goto out_dequeue;
-               }
                if (RPC_SIGNALLED(task)) {
                        status = -ERESTARTSYS;
                        goto out_dequeue;
index 44abc8e..241ed22 100644 (file)
@@ -223,7 +223,8 @@ static void tipc_publ_purge(struct net *net, struct publication *publ, u32 addr)
                       publ->key);
        }
 
-       kfree_rcu(p, rcu);
+       if (p)
+               kfree_rcu(p, rcu);
 }
 
 /**
index 4831ad7..327479c 100644 (file)
@@ -2788,7 +2788,7 @@ static void reg_process_pending_hints(void)
 
        /* When last_request->processed becomes true this will be rescheduled */
        if (lr && !lr->processed) {
-               reg_process_hint(lr);
+               pr_debug("Pending regulatory request, waiting for it to be processed...\n");
                return;
        }
 
index d0e35b7..e748378 100644 (file)
@@ -233,25 +233,30 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
 
        switch (params->cipher) {
        case WLAN_CIPHER_SUITE_TKIP:
+               /* Extended Key ID can only be used with CCMP/GCMP ciphers */
+               if ((pairwise && key_idx) ||
+                   params->mode != NL80211_KEY_RX_TX)
+                       return -EINVAL;
+               break;
        case WLAN_CIPHER_SUITE_CCMP:
        case WLAN_CIPHER_SUITE_CCMP_256:
        case WLAN_CIPHER_SUITE_GCMP:
        case WLAN_CIPHER_SUITE_GCMP_256:
-               /* IEEE802.11-2016 allows only 0 and - when using Extended Key
-                * ID - 1 as index for pairwise keys.
+               /* IEEE802.11-2016 allows only 0 and - when supporting
+                * Extended Key ID - 1 as index for pairwise keys.
                 * @NL80211_KEY_NO_TX is only allowed for pairwise keys when
                 * the driver supports Extended Key ID.
                 * @NL80211_KEY_SET_TX can't be set when installing and
                 * validating a key.
                 */
-               if (params->mode == NL80211_KEY_NO_TX) {
-                       if (!wiphy_ext_feature_isset(&rdev->wiphy,
-                                                    NL80211_EXT_FEATURE_EXT_KEY_ID))
-                               return -EINVAL;
-                       else if (!pairwise || key_idx < 0 || key_idx > 1)
+               if ((params->mode == NL80211_KEY_NO_TX && !pairwise) ||
+                   params->mode == NL80211_KEY_SET_TX)
+                       return -EINVAL;
+               if (wiphy_ext_feature_isset(&rdev->wiphy,
+                                           NL80211_EXT_FEATURE_EXT_KEY_ID)) {
+                       if (pairwise && (key_idx < 0 || key_idx > 1))
                                return -EINVAL;
-               } else if ((pairwise && key_idx) ||
-                          params->mode == NL80211_KEY_SET_TX) {
+               } else if (pairwise && key_idx) {
                        return -EINVAL;
                }
                break;
index 83de74c..688aac7 100644 (file)
@@ -365,7 +365,7 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
        umem->pages = kcalloc(umem->npgs, sizeof(*umem->pages), GFP_KERNEL);
        if (!umem->pages) {
                err = -ENOMEM;
-               goto out_account;
+               goto out_pin;
        }
 
        for (i = 0; i < umem->npgs; i++)
@@ -373,6 +373,8 @@ static int xdp_umem_reg(struct xdp_umem *umem, struct xdp_umem_reg *mr)
 
        return 0;
 
+out_pin:
+       xdp_umem_unpin_pages(umem);
 out_account:
        xdp_umem_unaccount_pages(umem);
        return err;
index 74868f9..2ab4859 100644 (file)
@@ -145,8 +145,6 @@ static int xfrmi_create(struct net_device *dev)
        if (err < 0)
                goto out;
 
-       strcpy(xi->p.name, dev->name);
-
        dev_hold(dev);
        xfrmi_link(xfrmn, xi);
 
@@ -177,7 +175,6 @@ static void xfrmi_dev_uninit(struct net_device *dev)
        struct xfrmi_net *xfrmn = net_generic(xi->net, xfrmi_net_id);
 
        xfrmi_unlink(xfrmn, xi);
-       dev_put(xi->phydev);
        dev_put(dev);
 }
 
@@ -294,7 +291,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
        if (tdev == dev) {
                stats->collisions++;
                net_warn_ratelimited("%s: Local routing loop detected!\n",
-                                    xi->p.name);
+                                    dev->name);
                goto tx_err_dst_release;
        }
 
@@ -364,7 +361,7 @@ static netdev_tx_t xfrmi_xmit(struct sk_buff *skb, struct net_device *dev)
                goto tx_err;
        }
 
-       fl.flowi_oif = xi->phydev->ifindex;
+       fl.flowi_oif = xi->p.link;
 
        ret = xfrmi_xmit2(skb, dev, &fl);
        if (ret < 0)
@@ -505,7 +502,7 @@ static int xfrmi_change(struct xfrm_if *xi, const struct xfrm_if_parms *p)
 
 static int xfrmi_update(struct xfrm_if *xi, struct xfrm_if_parms *p)
 {
-       struct net *net = dev_net(xi->dev);
+       struct net *net = xi->net;
        struct xfrmi_net *xfrmn = net_generic(net, xfrmi_net_id);
        int err;
 
@@ -550,7 +547,7 @@ static int xfrmi_get_iflink(const struct net_device *dev)
 {
        struct xfrm_if *xi = netdev_priv(dev);
 
-       return xi->phydev->ifindex;
+       return xi->p.link;
 }
 
 
@@ -576,12 +573,14 @@ static void xfrmi_dev_setup(struct net_device *dev)
        dev->needs_free_netdev  = true;
        dev->priv_destructor    = xfrmi_dev_free;
        netif_keep_dst(dev);
+
+       eth_broadcast_addr(dev->broadcast);
 }
 
 static int xfrmi_dev_init(struct net_device *dev)
 {
        struct xfrm_if *xi = netdev_priv(dev);
-       struct net_device *phydev = xi->phydev;
+       struct net_device *phydev = __dev_get_by_index(xi->net, xi->p.link);
        int err;
 
        dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
@@ -596,13 +595,19 @@ static int xfrmi_dev_init(struct net_device *dev)
 
        dev->features |= NETIF_F_LLTX;
 
-       dev->needed_headroom = phydev->needed_headroom;
-       dev->needed_tailroom = phydev->needed_tailroom;
+       if (phydev) {
+               dev->needed_headroom = phydev->needed_headroom;
+               dev->needed_tailroom = phydev->needed_tailroom;
 
-       if (is_zero_ether_addr(dev->dev_addr))
-               eth_hw_addr_inherit(dev, phydev);
-       if (is_zero_ether_addr(dev->broadcast))
-               memcpy(dev->broadcast, phydev->broadcast, dev->addr_len);
+               if (is_zero_ether_addr(dev->dev_addr))
+                       eth_hw_addr_inherit(dev, phydev);
+               if (is_zero_ether_addr(dev->broadcast))
+                       memcpy(dev->broadcast, phydev->broadcast,
+                              dev->addr_len);
+       } else {
+               eth_hw_addr_random(dev);
+               eth_broadcast_addr(dev->broadcast);
+       }
 
        return 0;
 }
@@ -638,12 +643,6 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev,
        int err;
 
        xfrmi_netlink_parms(data, &p);
-
-       if (!tb[IFLA_IFNAME])
-               return -EINVAL;
-
-       nla_strlcpy(p.name, tb[IFLA_IFNAME], IFNAMSIZ);
-
        xi = xfrmi_locate(net, &p);
        if (xi)
                return -EEXIST;
@@ -652,13 +651,8 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev,
        xi->p = p;
        xi->net = net;
        xi->dev = dev;
-       xi->phydev = dev_get_by_index(net, p.link);
-       if (!xi->phydev)
-               return -ENODEV;
 
        err = xfrmi_create(dev);
-       if (err < 0)
-               dev_put(xi->phydev);
        return err;
 }
 
@@ -672,11 +666,11 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[],
                           struct netlink_ext_ack *extack)
 {
        struct xfrm_if *xi = netdev_priv(dev);
-       struct net *net = dev_net(dev);
-
-       xfrmi_netlink_parms(data, &xi->p);
+       struct net *net = xi->net;
+       struct xfrm_if_parms p;
 
-       xi = xfrmi_locate(net, &xi->p);
+       xfrmi_netlink_parms(data, &p);
+       xi = xfrmi_locate(net, &p);
        if (!xi) {
                xi = netdev_priv(dev);
        } else {
@@ -684,7 +678,7 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[],
                        return -EEXIST;
        }
 
-       return xfrmi_update(xi, &xi->p);
+       return xfrmi_update(xi, &p);
 }
 
 static size_t xfrmi_get_size(const struct net_device *dev)
@@ -715,7 +709,7 @@ static struct net *xfrmi_get_link_net(const struct net_device *dev)
 {
        struct xfrm_if *xi = netdev_priv(dev);
 
-       return dev_net(xi->phydev);
+       return xi->net;
 }
 
 static const struct nla_policy xfrmi_policy[IFLA_XFRM_MAX + 1] = {
index 8ca637a..21e9392 100644 (file)
@@ -912,6 +912,7 @@ restart:
                } else if (delta > 0) {
                        p = &parent->rb_right;
                } else {
+                       bool same_prefixlen = node->prefixlen == n->prefixlen;
                        struct xfrm_policy *tmp;
 
                        hlist_for_each_entry(tmp, &n->hhead, bydst) {
@@ -919,9 +920,11 @@ restart:
                                hlist_del_rcu(&tmp->bydst);
                        }
 
+                       node->prefixlen = prefixlen;
+
                        xfrm_policy_inexact_list_reinsert(net, node, family);
 
-                       if (node->prefixlen == n->prefixlen) {
+                       if (same_prefixlen) {
                                kfree_rcu(n, rcu);
                                return;
                        }
@@ -929,7 +932,6 @@ restart:
                        rb_erase(*p, new);
                        kfree_rcu(n, rcu);
                        n = node;
-                       n->prefixlen = prefixlen;
                        goto restart;
                }
        }
@@ -3269,7 +3271,7 @@ decode_session4(struct sk_buff *skb, struct flowi *fl, bool reverse)
        struct flowi4 *fl4 = &fl->u.ip4;
        int oif = 0;
 
-       if (skb_dst(skb))
+       if (skb_dst(skb) && skb_dst(skb)->dev)
                oif = skb_dst(skb)->dev->ifindex;
 
        memset(fl4, 0, sizeof(struct flowi4));
@@ -3387,7 +3389,7 @@ decode_session6(struct sk_buff *skb, struct flowi *fl, bool reverse)
 
        nexthdr = nh[nhoff];
 
-       if (skb_dst(skb))
+       if (skb_dst(skb) && skb_dst(skb)->dev)
                oif = skb_dst(skb)->dev->ifindex;
 
        memset(fl6, 0, sizeof(struct flowi6));
index 6410bd2..03757cc 100644 (file)
@@ -1,4 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
+ifdef CONFIG_KASAN
+CFLAGS_KASAN_NOSANITIZE := -fno-builtin
+KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET)
+endif
+
 ifdef CONFIG_KASAN_GENERIC
 
 ifdef CONFIG_KASAN_INLINE
@@ -7,8 +12,6 @@ else
        call_threshold := 0
 endif
 
-KASAN_SHADOW_OFFSET ?= $(CONFIG_KASAN_SHADOW_OFFSET)
-
 CFLAGS_KASAN_MINIMAL := -fsanitize=kernel-address
 
 cc-param = $(call cc-option, -mllvm -$(1), $(call cc-option, --param $(1)))
@@ -45,7 +48,3 @@ CFLAGS_KASAN := -fsanitize=kernel-hwaddress \
                $(instrumentation_flags)
 
 endif # CONFIG_KASAN_SW_TAGS
-
-ifdef CONFIG_KASAN
-CFLAGS_KASAN_NOSANITIZE := -fno-builtin
-endif
diff --git a/scripts/tools-support-relr.sh b/scripts/tools-support-relr.sh
new file mode 100755 (executable)
index 0000000..97a2c84
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/sh -eu
+# SPDX-License-Identifier: GPL-2.0
+
+tmp_file=$(mktemp)
+trap "rm -f $tmp_file.o $tmp_file $tmp_file.bin" EXIT
+
+cat << "END" | "$CC" -c -x c - -o $tmp_file.o >/dev/null 2>&1
+void *p = &p;
+END
+"$LD" $tmp_file.o -shared -Bsymbolic --pack-dyn-relocs=relr -o $tmp_file
+
+# Despite printing an error message, GNU nm still exits with exit code 0 if it
+# sees a relr section. So we need to check that nothing is printed to stderr.
+test -z "$("$NM" $tmp_file 2>&1 >/dev/null)"
+
+"$OBJCOPY" -O binary $tmp_file $tmp_file.bin
index 7325f38..957b9e3 100644 (file)
@@ -595,7 +595,7 @@ struct key *request_key_and_link(struct key_type *type,
 
        key = check_cached_key(&ctx);
        if (key)
-               return key;
+               goto error_free;
 
        /* search all the process keyrings for a key */
        rcu_read_lock();
index e73ec04..ecba39c 100644 (file)
@@ -66,6 +66,9 @@ static void request_key_auth_describe(const struct key *key,
 {
        struct request_key_auth *rka = dereference_key_rcu(key);
 
+       if (!rka)
+               return;
+
        seq_puts(m, "key:");
        seq_puts(m, key->description);
        if (key_is_positive(key))
@@ -83,6 +86,9 @@ static long request_key_auth_read(const struct key *key,
        size_t datalen;
        long ret;
 
+       if (!rka)
+               return -EKEYREVOKED;
+
        datalen = rka->callout_len;
        ret = datalen;
 
index 7737b26..6d9592f 100644 (file)
@@ -1835,8 +1835,7 @@ static int snd_seq_ioctl_get_client_pool(struct snd_seq_client *client,
        if (cptr->type == USER_CLIENT) {
                info->input_pool = cptr->data.user.fifo_pool_size;
                info->input_free = info->input_pool;
-               if (cptr->data.user.fifo)
-                       info->input_free = snd_seq_unused_cells(cptr->data.user.fifo->pool);
+               info->input_free = snd_seq_fifo_unused_cells(cptr->data.user.fifo);
        } else {
                info->input_pool = 0;
                info->input_free = 0;
index ea69261..eaaa8b5 100644 (file)
@@ -263,3 +263,20 @@ int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize)
 
        return 0;
 }
+
+/* get the number of unused cells safely */
+int snd_seq_fifo_unused_cells(struct snd_seq_fifo *f)
+{
+       unsigned long flags;
+       int cells;
+
+       if (!f)
+               return 0;
+
+       snd_use_lock_use(&f->use_lock);
+       spin_lock_irqsave(&f->lock, flags);
+       cells = snd_seq_unused_cells(f->pool);
+       spin_unlock_irqrestore(&f->lock, flags);
+       snd_use_lock_free(&f->use_lock);
+       return cells;
+}
index edc6874..b56a7b8 100644 (file)
@@ -53,5 +53,7 @@ int snd_seq_fifo_poll_wait(struct snd_seq_fifo *f, struct file *file, poll_table
 /* resize pool in fifo */
 int snd_seq_fifo_resize(struct snd_seq_fifo *f, int poolsize);
 
+/* get the number of unused cells safely */
+int snd_seq_fifo_unused_cells(struct snd_seq_fifo *f);
 
 #endif
index 9ea3934..7c6d1c2 100644 (file)
@@ -248,7 +248,7 @@ static int pcm_playback_hw_params(struct snd_pcm_substream *substream,
                unsigned int channels = params_channels(hw_params);
 
                mutex_lock(&oxfw->mutex);
-               err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream,
+               err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream,
                                                     rate, channels);
                if (err >= 0)
                        ++oxfw->substreams_count;
index 92390d4..18e6546 100644 (file)
@@ -824,6 +824,8 @@ static void apply_fixup(struct hda_codec *codec, int id, int action, int depth)
        while (id >= 0) {
                const struct hda_fixup *fix = codec->fixup_list + id;
 
+               if (++depth > 10)
+                       break;
                if (fix->chained_before)
                        apply_fixup(codec, fix->chain_id, action, depth + 1);
 
@@ -863,8 +865,6 @@ static void apply_fixup(struct hda_codec *codec, int id, int action, int depth)
                }
                if (!fix->chained || fix->chained_before)
                        break;
-               if (++depth > 10)
-                       break;
                id = fix->chain_id;
        }
 }
index 5bf24fb..10d5023 100644 (file)
@@ -6009,7 +6009,8 @@ int snd_hda_gen_init(struct hda_codec *codec)
        if (spec->init_hook)
                spec->init_hook(codec);
 
-       snd_hda_apply_verbs(codec);
+       if (!spec->skip_verbs)
+               snd_hda_apply_verbs(codec);
 
        init_multi_out(codec);
        init_extra_out(codec);
index 5f199dc..fb9f1a9 100644 (file)
@@ -243,6 +243,7 @@ struct hda_gen_spec {
        unsigned int indep_hp_enabled:1; /* independent HP enabled */
        unsigned int have_aamix_ctl:1;
        unsigned int hp_mic_jack_modes:1;
+       unsigned int skip_verbs:1; /* don't apply verbs at snd_hda_gen_init() */
 
        /* additional mute flags (only effective with auto_mute_via_amp=1) */
        u64 mute_bits;
index 0d51823..6d1fb7c 100644 (file)
@@ -1175,6 +1175,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
        SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE),
        SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ),
        SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ),
+       SND_PCI_QUIRK(0x1102, 0x0027, "Sound Blaster Z", QUIRK_SBZ),
        SND_PCI_QUIRK(0x1102, 0x0033, "Sound Blaster ZxR", QUIRK_SBZ),
        SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI),
        SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI),
index 14298ef..968d3ca 100644 (file)
@@ -611,18 +611,20 @@ static void cxt_fixup_hp_gate_mic_jack(struct hda_codec *codec,
 
 /* update LED status via GPIO */
 static void cxt_update_gpio_led(struct hda_codec *codec, unsigned int mask,
-                               bool enabled)
+                               bool led_on)
 {
        struct conexant_spec *spec = codec->spec;
        unsigned int oldval = spec->gpio_led;
 
        if (spec->mute_led_polarity)
-               enabled = !enabled;
+               led_on = !led_on;
 
-       if (enabled)
-               spec->gpio_led &= ~mask;
-       else
+       if (led_on)
                spec->gpio_led |= mask;
+       else
+               spec->gpio_led &= ~mask;
+       codec_dbg(codec, "mask:%d enabled:%d gpio_led:%d\n",
+                       mask, led_on, spec->gpio_led);
        if (spec->gpio_led != oldval)
                snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
                                    spec->gpio_led);
@@ -633,8 +635,8 @@ static void cxt_fixup_gpio_mute_hook(void *private_data, int enabled)
 {
        struct hda_codec *codec = private_data;
        struct conexant_spec *spec = codec->spec;
-
-       cxt_update_gpio_led(codec, spec->gpio_mute_led_mask, enabled);
+       /* muted -> LED on */
+       cxt_update_gpio_led(codec, spec->gpio_mute_led_mask, !enabled);
 }
 
 /* turn on/off mic-mute LED via GPIO per capture hook */
@@ -656,7 +658,6 @@ static void cxt_fixup_mute_led_gpio(struct hda_codec *codec,
                { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03 },
                {}
        };
-       codec_info(codec, "action: %d gpio_led: %d\n", action, spec->gpio_led);
 
        if (action == HDA_FIXUP_ACT_PRE_PROBE) {
                spec->gen.vmaster_mute.hook = cxt_fixup_gpio_mute_hook;
index e333b3e..c1ddfd2 100644 (file)
@@ -837,9 +837,11 @@ static int alc_init(struct hda_codec *codec)
        if (spec->init_hook)
                spec->init_hook(codec);
 
+       spec->gen.skip_verbs = 1; /* applied in below */
        snd_hda_gen_init(codec);
        alc_fix_pll(codec);
        alc_auto_init_amp(codec, spec->init_amp);
+       snd_hda_apply_verbs(codec); /* apply verbs here after own init */
 
        snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
 
@@ -5797,6 +5799,7 @@ enum {
        ALC286_FIXUP_ACER_AIO_HEADSET_MIC,
        ALC256_FIXUP_ASUS_MIC_NO_PRESENCE,
        ALC299_FIXUP_PREDATOR_SPK,
+       ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -6837,6 +6840,16 @@ static const struct hda_fixup alc269_fixups[] = {
                        { }
                }
        },
+       [ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x14, 0x411111f0 }, /* disable confusing internal speaker */
+                       { 0x19, 0x04a11150 }, /* use as headset mic, without its own jack detect */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -6979,6 +6992,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x103c, 0x82c0, "HP G3 mini premium", ALC221_FIXUP_HP_MIC_NO_PRESENCE),
        SND_PCI_QUIRK(0x103c, 0x83b9, "HP Spectre x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
        SND_PCI_QUIRK(0x103c, 0x8497, "HP Envy x360", ALC269_FIXUP_HP_MUTE_LED_MIC3),
+       SND_PCI_QUIRK(0x103c, 0x84e7, "HP Pavilion 15", ALC269_FIXUP_HP_MUTE_LED_MIC3),
        SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC),
        SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300),
        SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -6995,6 +7009,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK),
        SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A),
        SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
+       SND_PCI_QUIRK(0x1043, 0x17d1, "ASUS UX431FL", ALC294_FIXUP_ASUS_INTSPK_HEADSET_MIC),
        SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
        SND_PCI_QUIRK(0x1043, 0x1a30, "ASUS X705UD", ALC256_FIXUP_ASUS_MIC),
        SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
@@ -7072,6 +7087,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x17aa, 0x312a, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
        SND_PCI_QUIRK(0x17aa, 0x312f, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
        SND_PCI_QUIRK(0x17aa, 0x313c, "ThinkCentre Station", ALC294_FIXUP_LENOVO_MIC_LOCATION),
+       SND_PCI_QUIRK(0x17aa, 0x3151, "ThinkCentre Station", ALC283_FIXUP_HEADSET_MIC),
        SND_PCI_QUIRK(0x17aa, 0x3902, "Lenovo E50-80", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
        SND_PCI_QUIRK(0x17aa, 0x3977, "IdeaPad S210", ALC283_FIXUP_INT_MIC),
        SND_PCI_QUIRK(0x17aa, 0x3978, "Lenovo B50-70", ALC269_FIXUP_DMIC_THINKPAD_ACPI),
@@ -8946,6 +8962,7 @@ static int patch_alc680(struct hda_codec *codec)
 static const struct hda_device_id snd_hda_id_realtek[] = {
        HDA_CODEC_ENTRY(0x10ec0215, "ALC215", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0221, "ALC221", patch_alc269),
+       HDA_CODEC_ENTRY(0x10ec0222, "ALC222", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
        HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
index 54ac2fd..67f06c9 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/acpi.h>
 #include <linux/device.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
index 33eb725..05db311 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include <linux/dmi.h>
+#include <linux/gpio/consumer.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
index 4977b5a..9d65742 100644 (file)
@@ -8,6 +8,7 @@
  *          Mengdong Lin <mengdong.lin@intel.com>
  */
 
+#include <linux/gpio/consumer.h>
 #include <linux/input.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
index 2c03e0f..f70211e 100644 (file)
@@ -550,6 +550,15 @@ int line6_init_pcm(struct usb_line6 *line6,
        line6pcm->volume_monitor = 255;
        line6pcm->line6 = line6;
 
+       spin_lock_init(&line6pcm->out.lock);
+       spin_lock_init(&line6pcm->in.lock);
+       line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
+
+       line6->line6pcm = line6pcm;
+
+       pcm->private_data = line6pcm;
+       pcm->private_free = line6_cleanup_pcm;
+
        line6pcm->max_packet_size_in =
                usb_maxpacket(line6->usbdev,
                        usb_rcvisocpipe(line6->usbdev, ep_read), 0);
@@ -562,15 +571,6 @@ int line6_init_pcm(struct usb_line6 *line6,
                return -EINVAL;
        }
 
-       spin_lock_init(&line6pcm->out.lock);
-       spin_lock_init(&line6pcm->in.lock);
-       line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
-
-       line6->line6pcm = line6pcm;
-
-       pcm->private_data = line6pcm;
-       pcm->private_free = line6_cleanup_pcm;
-
        err = line6_create_audio_out_urbs(line6pcm);
        if (err < 0)
                return err;
index b5927c3..eceab19 100644 (file)
@@ -739,7 +739,6 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
                                       struct uac_mixer_unit_descriptor *desc)
 {
        int mu_channels;
-       void *c;
 
        if (desc->bLength < sizeof(*desc))
                return -EINVAL;
@@ -762,13 +761,6 @@ static int uac_mixer_unit_get_channels(struct mixer_build *state,
                break;
        }
 
-       if (!mu_channels)
-               return 0;
-
-       c = uac_mixer_unit_bmControls(desc, state->mixer->protocol);
-       if (c - (void *)desc + (mu_channels - 1) / 8 >= desc->bLength)
-               return 0; /* no bmControls -> skip */
-
        return mu_channels;
 }
 
@@ -2009,6 +2001,31 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid,
  * Mixer Unit
  */
 
+/* check whether the given in/out overflows bmMixerControls matrix */
+static bool mixer_bitmap_overflow(struct uac_mixer_unit_descriptor *desc,
+                                 int protocol, int num_ins, int num_outs)
+{
+       u8 *hdr = (u8 *)desc;
+       u8 *c = uac_mixer_unit_bmControls(desc, protocol);
+       size_t rest; /* remaining bytes after bmMixerControls */
+
+       switch (protocol) {
+       case UAC_VERSION_1:
+       default:
+               rest = 1; /* iMixer */
+               break;
+       case UAC_VERSION_2:
+               rest = 2; /* bmControls + iMixer */
+               break;
+       case UAC_VERSION_3:
+               rest = 6; /* bmControls + wMixerDescrStr */
+               break;
+       }
+
+       /* overflow? */
+       return c + (num_ins * num_outs + 7) / 8 + rest > hdr + hdr[0];
+}
+
 /*
  * build a mixer unit control
  *
@@ -2137,6 +2154,9 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid,
                if (err < 0)
                        return err;
                num_ins += iterm.channels;
+               if (mixer_bitmap_overflow(desc, state->mixer->protocol,
+                                         num_ins, num_outs))
+                       break;
                for (; ich < num_ins; ich++) {
                        int och, ich_has_controls = 0;
 
index 199fa15..27dcb37 100644 (file)
@@ -1155,17 +1155,17 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
 {
        struct usb_mixer_interface *mixer;
        struct usb_mixer_elem_info *cval;
-       int unitid = 12; /* SamleRate ExtensionUnit ID */
+       int unitid = 12; /* SampleRate ExtensionUnit ID */
 
        list_for_each_entry(mixer, &chip->mixer_list, list) {
-               cval = mixer_elem_list_to_info(mixer->id_elems[unitid]);
-               if (cval) {
+               if (mixer->id_elems[unitid]) {
+                       cval = mixer_elem_list_to_info(mixer->id_elems[unitid]);
                        snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR,
                                                    cval->control << 8,
                                                    samplerate_id);
                        snd_usb_mixer_notify_id(mixer, unitid);
+                       break;
                }
-               break;
        }
 }
 
index 75b9692..e4bbf79 100644 (file)
@@ -339,6 +339,7 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs,
                ep = 0x81;
                ifnum = 2;
                goto add_sync_ep_from_ifnum;
+       case USB_ID(0x1397, 0x0001): /* Behringer UFX1604 */
        case USB_ID(0x1397, 0x0002): /* Behringer UFX1204 */
                ep = 0x81;
                ifnum = 1;
diff --git a/tools/arch/riscv/include/uapi/asm/perf_regs.h b/tools/arch/riscv/include/uapi/asm/perf_regs.h
new file mode 100644 (file)
index 0000000..196f964
--- /dev/null
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#ifndef _ASM_RISCV_PERF_REGS_H
+#define _ASM_RISCV_PERF_REGS_H
+
+enum perf_event_riscv_regs {
+       PERF_REG_RISCV_PC,
+       PERF_REG_RISCV_RA,
+       PERF_REG_RISCV_SP,
+       PERF_REG_RISCV_GP,
+       PERF_REG_RISCV_TP,
+       PERF_REG_RISCV_T0,
+       PERF_REG_RISCV_T1,
+       PERF_REG_RISCV_T2,
+       PERF_REG_RISCV_S0,
+       PERF_REG_RISCV_S1,
+       PERF_REG_RISCV_A0,
+       PERF_REG_RISCV_A1,
+       PERF_REG_RISCV_A2,
+       PERF_REG_RISCV_A3,
+       PERF_REG_RISCV_A4,
+       PERF_REG_RISCV_A5,
+       PERF_REG_RISCV_A6,
+       PERF_REG_RISCV_A7,
+       PERF_REG_RISCV_S2,
+       PERF_REG_RISCV_S3,
+       PERF_REG_RISCV_S4,
+       PERF_REG_RISCV_S5,
+       PERF_REG_RISCV_S6,
+       PERF_REG_RISCV_S7,
+       PERF_REG_RISCV_S8,
+       PERF_REG_RISCV_S9,
+       PERF_REG_RISCV_S10,
+       PERF_REG_RISCV_S11,
+       PERF_REG_RISCV_T3,
+       PERF_REG_RISCV_T4,
+       PERF_REG_RISCV_T5,
+       PERF_REG_RISCV_T6,
+       PERF_REG_RISCV_MAX,
+};
+#endif /* _ASM_RISCV_PERF_REGS_H */
index 66f04a4..43fdbbf 100644 (file)
@@ -363,7 +363,9 @@ static int do_show(int argc, char **argv)
                if (fd < 0)
                        return -1;
 
-               return show_prog(fd);
+               err = show_prog(fd);
+               close(fd);
+               return err;
        }
 
        if (argc)
index 89ac5a1..eaf25ee 100644 (file)
@@ -60,6 +60,10 @@ ifeq ($(SRCARCH),arm64)
   LIBUNWIND_LIBS = -lunwind -lunwind-aarch64
 endif
 
+ifeq ($(SRCARCH),riscv)
+  NO_PERF_REGS := 0
+endif
+
 ifeq ($(SRCARCH),csky)
   NO_PERF_REGS := 0
 endif
@@ -82,7 +86,7 @@ endif
 # Disable it on all other architectures in case libdw unwind
 # support is detected in system. Add supported architectures
 # to the check.
-ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc s390 csky))
+ifneq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc s390 csky riscv))
   NO_LIBDW_DWARF_UNWIND := 1
 endif
 
diff --git a/tools/perf/arch/riscv/Build b/tools/perf/arch/riscv/Build
new file mode 100644 (file)
index 0000000..e4e5f33
--- /dev/null
@@ -0,0 +1 @@
+perf-y += util/
diff --git a/tools/perf/arch/riscv/Makefile b/tools/perf/arch/riscv/Makefile
new file mode 100644 (file)
index 0000000..1aa9dd7
--- /dev/null
@@ -0,0 +1,4 @@
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+endif
+PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET := 1
diff --git a/tools/perf/arch/riscv/include/perf_regs.h b/tools/perf/arch/riscv/include/perf_regs.h
new file mode 100644 (file)
index 0000000..7a8bcde
--- /dev/null
@@ -0,0 +1,96 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#ifndef ARCH_PERF_REGS_H
+#define ARCH_PERF_REGS_H
+
+#include <stdlib.h>
+#include <linux/types.h>
+#include <asm/perf_regs.h>
+
+#define PERF_REGS_MASK ((1ULL << PERF_REG_RISCV_MAX) - 1)
+#define PERF_REGS_MAX  PERF_REG_RISCV_MAX
+#if __riscv_xlen == 64
+#define PERF_SAMPLE_REGS_ABI    PERF_SAMPLE_REGS_ABI_64
+#else
+#define PERF_SAMPLE_REGS_ABI   PERF_SAMPLE_REGS_ABI_32
+#endif
+
+#define PERF_REG_IP    PERF_REG_RISCV_PC
+#define PERF_REG_SP    PERF_REG_RISCV_SP
+
+static inline const char *perf_reg_name(int id)
+{
+       switch (id) {
+       case PERF_REG_RISCV_PC:
+               return "pc";
+       case PERF_REG_RISCV_RA:
+               return "ra";
+       case PERF_REG_RISCV_SP:
+               return "sp";
+       case PERF_REG_RISCV_GP:
+               return "gp";
+       case PERF_REG_RISCV_TP:
+               return "tp";
+       case PERF_REG_RISCV_T0:
+               return "t0";
+       case PERF_REG_RISCV_T1:
+               return "t1";
+       case PERF_REG_RISCV_T2:
+               return "t2";
+       case PERF_REG_RISCV_S0:
+               return "s0";
+       case PERF_REG_RISCV_S1:
+               return "s1";
+       case PERF_REG_RISCV_A0:
+               return "a0";
+       case PERF_REG_RISCV_A1:
+               return "a1";
+       case PERF_REG_RISCV_A2:
+               return "a2";
+       case PERF_REG_RISCV_A3:
+               return "a3";
+       case PERF_REG_RISCV_A4:
+               return "a4";
+       case PERF_REG_RISCV_A5:
+               return "a5";
+       case PERF_REG_RISCV_A6:
+               return "a6";
+       case PERF_REG_RISCV_A7:
+               return "a7";
+       case PERF_REG_RISCV_S2:
+               return "s2";
+       case PERF_REG_RISCV_S3:
+               return "s3";
+       case PERF_REG_RISCV_S4:
+               return "s4";
+       case PERF_REG_RISCV_S5:
+               return "s5";
+       case PERF_REG_RISCV_S6:
+               return "s6";
+       case PERF_REG_RISCV_S7:
+               return "s7";
+       case PERF_REG_RISCV_S8:
+               return "s8";
+       case PERF_REG_RISCV_S9:
+               return "s9";
+       case PERF_REG_RISCV_S10:
+               return "s10";
+       case PERF_REG_RISCV_S11:
+               return "s11";
+       case PERF_REG_RISCV_T3:
+               return "t3";
+       case PERF_REG_RISCV_T4:
+               return "t4";
+       case PERF_REG_RISCV_T5:
+               return "t5";
+       case PERF_REG_RISCV_T6:
+               return "t6";
+       default:
+               return NULL;
+       }
+
+       return NULL;
+}
+
+#endif /* ARCH_PERF_REGS_H */
diff --git a/tools/perf/arch/riscv/util/Build b/tools/perf/arch/riscv/util/Build
new file mode 100644 (file)
index 0000000..1160bb2
--- /dev/null
@@ -0,0 +1,2 @@
+perf-$(CONFIG_DWARF) += dwarf-regs.o
+perf-$(CONFIG_LIBDW_DWARF_UNWIND) += unwind-libdw.o
diff --git a/tools/perf/arch/riscv/util/dwarf-regs.c b/tools/perf/arch/riscv/util/dwarf-regs.c
new file mode 100644 (file)
index 0000000..cd0504c
--- /dev/null
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd.
+ * Mapping of DWARF debug register numbers into register names.
+ */
+
+#include <stddef.h>
+#include <errno.h> /* for EINVAL */
+#include <string.h> /* for strcmp */
+#include <dwarf-regs.h>
+
+struct pt_regs_dwarfnum {
+       const char *name;
+       unsigned int dwarfnum;
+};
+
+#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
+#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
+
+struct pt_regs_dwarfnum riscv_dwarf_regs_table[] = {
+       REG_DWARFNUM_NAME("%zero", 0),
+       REG_DWARFNUM_NAME("%ra", 1),
+       REG_DWARFNUM_NAME("%sp", 2),
+       REG_DWARFNUM_NAME("%gp", 3),
+       REG_DWARFNUM_NAME("%tp", 4),
+       REG_DWARFNUM_NAME("%t0", 5),
+       REG_DWARFNUM_NAME("%t1", 6),
+       REG_DWARFNUM_NAME("%t2", 7),
+       REG_DWARFNUM_NAME("%s0", 8),
+       REG_DWARFNUM_NAME("%s1", 9),
+       REG_DWARFNUM_NAME("%a0", 10),
+       REG_DWARFNUM_NAME("%a1", 11),
+       REG_DWARFNUM_NAME("%a2", 12),
+       REG_DWARFNUM_NAME("%a3", 13),
+       REG_DWARFNUM_NAME("%a4", 14),
+       REG_DWARFNUM_NAME("%a5", 15),
+       REG_DWARFNUM_NAME("%a6", 16),
+       REG_DWARFNUM_NAME("%a7", 17),
+       REG_DWARFNUM_NAME("%s2", 18),
+       REG_DWARFNUM_NAME("%s3", 19),
+       REG_DWARFNUM_NAME("%s4", 20),
+       REG_DWARFNUM_NAME("%s5", 21),
+       REG_DWARFNUM_NAME("%s6", 22),
+       REG_DWARFNUM_NAME("%s7", 23),
+       REG_DWARFNUM_NAME("%s8", 24),
+       REG_DWARFNUM_NAME("%s9", 25),
+       REG_DWARFNUM_NAME("%s10", 26),
+       REG_DWARFNUM_NAME("%s11", 27),
+       REG_DWARFNUM_NAME("%t3", 28),
+       REG_DWARFNUM_NAME("%t4", 29),
+       REG_DWARFNUM_NAME("%t5", 30),
+       REG_DWARFNUM_NAME("%t6", 31),
+       REG_DWARFNUM_END,
+};
+
+#define RISCV_MAX_REGS ((sizeof(riscv_dwarf_regs_table) / \
+                sizeof(riscv_dwarf_regs_table[0])) - 1)
+
+const char *get_arch_regstr(unsigned int n)
+{
+       return (n < RISCV_MAX_REGS) ? riscv_dwarf_regs_table[n].name : NULL;
+}
+
+int regs_query_register_offset(const char *name)
+{
+       const struct pt_regs_dwarfnum *roff;
+
+       for (roff = riscv_dwarf_regs_table; roff->name; roff++)
+               if (!strcmp(roff->name, name))
+                       return roff->dwarfnum;
+       return -EINVAL;
+}
diff --git a/tools/perf/arch/riscv/util/unwind-libdw.c b/tools/perf/arch/riscv/util/unwind-libdw.c
new file mode 100644 (file)
index 0000000..19536e1
--- /dev/null
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
+
+#include <elfutils/libdwfl.h>
+#include "../../util/unwind-libdw.h"
+#include "../../util/perf_regs.h"
+#include "../../util/event.h"
+
+bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg)
+{
+       struct unwind_info *ui = arg;
+       struct regs_dump *user_regs = &ui->sample->user_regs;
+       Dwarf_Word dwarf_regs[32];
+
+#define REG(r) ({                                              \
+       Dwarf_Word val = 0;                                     \
+       perf_reg_value(&val, user_regs, PERF_REG_RISCV_##r);    \
+       val;                                                    \
+})
+
+       dwarf_regs[0]  = 0;
+       dwarf_regs[1]  = REG(RA);
+       dwarf_regs[2]  = REG(SP);
+       dwarf_regs[3]  = REG(GP);
+       dwarf_regs[4]  = REG(TP);
+       dwarf_regs[5]  = REG(T0);
+       dwarf_regs[6]  = REG(T1);
+       dwarf_regs[7]  = REG(T2);
+       dwarf_regs[8]  = REG(S0);
+       dwarf_regs[9]  = REG(S1);
+       dwarf_regs[10] = REG(A0);
+       dwarf_regs[11] = REG(A1);
+       dwarf_regs[12] = REG(A2);
+       dwarf_regs[13] = REG(A3);
+       dwarf_regs[14] = REG(A4);
+       dwarf_regs[15] = REG(A5);
+       dwarf_regs[16] = REG(A6);
+       dwarf_regs[17] = REG(A7);
+       dwarf_regs[18] = REG(S2);
+       dwarf_regs[19] = REG(S3);
+       dwarf_regs[20] = REG(S4);
+       dwarf_regs[21] = REG(S5);
+       dwarf_regs[22] = REG(S6);
+       dwarf_regs[23] = REG(S7);
+       dwarf_regs[24] = REG(S8);
+       dwarf_regs[25] = REG(S9);
+       dwarf_regs[26] = REG(S10);
+       dwarf_regs[27] = REG(S11);
+       dwarf_regs[28] = REG(T3);
+       dwarf_regs[29] = REG(T4);
+       dwarf_regs[30] = REG(T5);
+       dwarf_regs[31] = REG(T6);
+       dwfl_thread_state_register_pc(thread, REG(PC));
+
+       return dwfl_thread_state_registers(thread, 0, PERF_REG_RISCV_MAX,
+                                          dwarf_regs);
+}
index 045f5f7..13f1e8b 100644 (file)
@@ -9,9 +9,10 @@ ifeq ("$(origin O)", "command line")
 endif
 
 turbostat : turbostat.c
-override CFLAGS +=     -Wall -I../../../include
+override CFLAGS +=     -O2 -Wall -I../../../include
 override CFLAGS +=     -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"'
 override CFLAGS +=     -DINTEL_FAMILY_HEADER='"../../../../arch/x86/include/asm/intel-family.h"'
+override CFLAGS +=     -D_FORTIFY_SOURCE=2
 
 %: %.c
        @mkdir -p $(BUILD_OUTPUT)
index 75fc4fb..b2a8643 100644 (file)
@@ -39,7 +39,6 @@ FILE *outf;
 int *fd_percpu;
 struct timeval interval_tv = {5, 0};
 struct timespec interval_ts = {5, 0};
-struct timespec one_msec = {0, 1000000};
 unsigned int num_iterations;
 unsigned int debug;
 unsigned int quiet;
@@ -60,6 +59,7 @@ unsigned int do_irtl_hsw;
 unsigned int units = 1000000;  /* MHz etc */
 unsigned int genuine_intel;
 unsigned int authentic_amd;
+unsigned int hygon_genuine;
 unsigned int max_level, max_extended_level;
 unsigned int has_invariant_tsc;
 unsigned int do_nhm_platform_info;
@@ -100,6 +100,7 @@ unsigned int has_hwp_epp;           /* IA32_HWP_REQUEST[bits 31:24] */
 unsigned int has_hwp_pkg;              /* IA32_HWP_REQUEST_PKG */
 unsigned int has_misc_feature_control;
 unsigned int first_counter_read = 1;
+int ignore_stdin;
 
 #define RAPL_PKG               (1 << 0)
                                        /* 0x610 MSR_PKG_POWER_LIMIT */
@@ -166,6 +167,7 @@ size_t cpu_present_setsize, cpu_affinity_setsize, cpu_subset_size;
 struct thread_data {
        struct timeval tv_begin;
        struct timeval tv_end;
+       struct timeval tv_delta;
        unsigned long long tsc;
        unsigned long long aperf;
        unsigned long long mperf;
@@ -506,6 +508,7 @@ unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAU
 unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC;
 
 #define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
+#define DO_BIC_READ(COUNTER_NAME) (bic_present & COUNTER_NAME)
 #define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME)
 #define BIC_PRESENT(COUNTER_BIT) (bic_present |= COUNTER_BIT)
 #define BIC_NOT_PRESENT(COUNTER_BIT) (bic_present &= ~COUNTER_BIT)
@@ -849,7 +852,6 @@ int dump_counters(struct thread_data *t, struct core_data *c,
                outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
                outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
                outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
-               outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
                outp += sprintf(outp, "cpu_lpi: %016llX\n", p->cpu_lpi);
                outp += sprintf(outp, "sys_lpi: %016llX\n", p->sys_lpi);
                outp += sprintf(outp, "Joules PKG: %0X\n", p->energy_pkg);
@@ -911,7 +913,7 @@ int format_counters(struct thread_data *t, struct core_data *c,
        if (DO_BIC(BIC_TOD))
                outp += sprintf(outp, "%10ld.%06ld\t", t->tv_end.tv_sec, t->tv_end.tv_usec);
 
-       interval_float = tv_delta.tv_sec + tv_delta.tv_usec/1000000.0;
+       interval_float = t->tv_delta.tv_sec + t->tv_delta.tv_usec/1000000.0;
 
        tsc = t->tsc * tsc_tweak;
 
@@ -1287,6 +1289,14 @@ delta_core(struct core_data *new, struct core_data *old)
        }
 }
 
+int soft_c1_residency_display(int bic)
+{
+       if (!DO_BIC(BIC_CPU_c1) || use_c1_residency_msr)
+               return 0;
+
+       return DO_BIC_READ(bic);
+}
+
 /*
  * old = new - old
  */
@@ -1309,6 +1319,7 @@ delta_thread(struct thread_data *new, struct thread_data *old,
         * over-write old w/ new so we can print end of interval values
         */
 
+       timersub(&new->tv_begin, &old->tv_begin, &old->tv_delta);
        old->tv_begin = new->tv_begin;
        old->tv_end = new->tv_end;
 
@@ -1322,7 +1333,8 @@ delta_thread(struct thread_data *new, struct thread_data *old,
 
        old->c1 = new->c1 - old->c1;
 
-       if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) {
+       if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) ||
+           soft_c1_residency_display(BIC_Avg_MHz)) {
                if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
                        old->aperf = new->aperf - old->aperf;
                        old->mperf = new->mperf - old->mperf;
@@ -1404,6 +1416,8 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
        t->tv_begin.tv_usec = 0;
        t->tv_end.tv_sec = 0;
        t->tv_end.tv_usec = 0;
+       t->tv_delta.tv_sec = 0;
+       t->tv_delta.tv_usec = 0;
 
        t->tsc = 0;
        t->aperf = 0;
@@ -1573,6 +1587,9 @@ void compute_average(struct thread_data *t, struct core_data *c,
 
        for_all_cpus(sum_counters, t, c, p);
 
+       /* Use the global time delta for the average. */
+       average.threads.tv_delta = tv_delta;
+
        average.threads.tsc /= topo.num_cpus;
        average.threads.aperf /= topo.num_cpus;
        average.threads.mperf /= topo.num_cpus;
@@ -1714,7 +1731,7 @@ void get_apic_id(struct thread_data *t)
        if (!DO_BIC(BIC_X2APIC))
                return;
 
-       if (authentic_amd) {
+       if (authentic_amd || hygon_genuine) {
                unsigned int topology_extensions;
 
                if (max_extended_level < 0x8000001e)
@@ -1762,19 +1779,20 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
        struct msr_counter *mp;
        int i;
 
-       gettimeofday(&t->tv_begin, (struct timezone *)NULL);
-
        if (cpu_migrate(cpu)) {
                fprintf(outf, "Could not migrate to CPU %d\n", cpu);
                return -1;
        }
 
+       gettimeofday(&t->tv_begin, (struct timezone *)NULL);
+
        if (first_counter_read)
                get_apic_id(t);
 retry:
        t->tsc = rdtsc();       /* we are running on local CPU of interest */
 
-       if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz)) {
+       if (DO_BIC(BIC_Avg_MHz) || DO_BIC(BIC_Busy) || DO_BIC(BIC_Bzy_MHz) ||
+           soft_c1_residency_display(BIC_Avg_MHz)) {
                unsigned long long tsc_before, tsc_between, tsc_after, aperf_time, mperf_time;
 
                /*
@@ -1851,20 +1869,20 @@ retry:
        if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE))
                goto done;
 
-       if (DO_BIC(BIC_CPU_c3)) {
+       if (DO_BIC(BIC_CPU_c3) || soft_c1_residency_display(BIC_CPU_c3)) {
                if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3))
                        return -6;
        }
 
-       if (DO_BIC(BIC_CPU_c6) && !do_knl_cstates) {
+       if ((DO_BIC(BIC_CPU_c6) || soft_c1_residency_display(BIC_CPU_c6)) && !do_knl_cstates) {
                if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6))
                        return -7;
-       } else if (do_knl_cstates) {
+       } else if (do_knl_cstates || soft_c1_residency_display(BIC_CPU_c6)) {
                if (get_msr(cpu, MSR_KNL_CORE_C6_RESIDENCY, &c->c6))
                        return -7;
        }
 
-       if (DO_BIC(BIC_CPU_c7))
+       if (DO_BIC(BIC_CPU_c7) || soft_c1_residency_display(BIC_CPU_c7))
                if (get_msr(cpu, MSR_CORE_C7_RESIDENCY, &c->c7))
                        return -8;
 
@@ -2912,6 +2930,7 @@ int snapshot_cpu_lpi_us(void)
        if (retval != 1) {
                fprintf(stderr, "Disabling Low Power Idle CPU output\n");
                BIC_NOT_PRESENT(BIC_CPU_LPI);
+               fclose(fp);
                return -1;
        }
 
@@ -2938,6 +2957,7 @@ int snapshot_sys_lpi_us(void)
        if (retval != 1) {
                fprintf(stderr, "Disabling Low Power Idle System output\n");
                BIC_NOT_PRESENT(BIC_SYS_LPI);
+               fclose(fp);
                return -1;
        }
        fclose(fp);
@@ -2985,8 +3005,6 @@ static void signal_handler (int signal)
                        fprintf(stderr, "SIGUSR1\n");
                break;
        }
-       /* make sure this manually-invoked interval is at least 1ms long */
-       nanosleep(&one_msec, NULL);
 }
 
 void setup_signal_handler(void)
@@ -3005,29 +3023,38 @@ void setup_signal_handler(void)
 
 void do_sleep(void)
 {
-       struct timeval select_timeout;
+       struct timeval tout;
+       struct timespec rest;
        fd_set readfds;
        int retval;
 
        FD_ZERO(&readfds);
        FD_SET(0, &readfds);
 
-       if (!isatty(fileno(stdin))) {
+       if (ignore_stdin) {
                nanosleep(&interval_ts, NULL);
                return;
        }
 
-       select_timeout = interval_tv;
-       retval = select(1, &readfds, NULL, NULL, &select_timeout);
+       tout = interval_tv;
+       retval = select(1, &readfds, NULL, NULL, &tout);
 
        if (retval == 1) {
                switch (getc(stdin)) {
                case 'q':
                        exit_requested = 1;
                        break;
+               case EOF:
+                       /*
+                        * 'stdin' is a pipe closed on the other end. There
+                        * won't be any further input.
+                        */
+                       ignore_stdin = 1;
+                       /* Sleep the rest of the time */
+                       rest.tv_sec = (tout.tv_sec + tout.tv_usec / 1000000);
+                       rest.tv_nsec = (tout.tv_usec % 1000000) * 1000;
+                       nanosleep(&rest, NULL);
                }
-               /* make sure this manually-invoked interval is at least 1ms long */
-               nanosleep(&one_msec, NULL);
        }
 }
 
@@ -3209,6 +3236,7 @@ int probe_nhm_msrs(unsigned int family, unsigned int model)
                break;
        case INTEL_FAM6_HASWELL_CORE:   /* HSW */
        case INTEL_FAM6_HASWELL_X:      /* HSX */
+       case INTEL_FAM6_HASWELL_ULT:    /* HSW */
        case INTEL_FAM6_HASWELL_GT3E:   /* HSW */
        case INTEL_FAM6_BROADWELL_CORE: /* BDW */
        case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
@@ -3405,6 +3433,7 @@ int has_config_tdp(unsigned int family, unsigned int model)
        case INTEL_FAM6_IVYBRIDGE:      /* IVB */
        case INTEL_FAM6_HASWELL_CORE:   /* HSW */
        case INTEL_FAM6_HASWELL_X:      /* HSX */
+       case INTEL_FAM6_HASWELL_ULT:    /* HSW */
        case INTEL_FAM6_HASWELL_GT3E:   /* HSW */
        case INTEL_FAM6_BROADWELL_CORE: /* BDW */
        case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
@@ -3803,6 +3832,7 @@ double get_tdp_amd(unsigned int family)
 {
        switch (family) {
        case 0x17:
+       case 0x18:
        default:
                /* This is the max stock TDP of HEDT/Server Fam17h chips */
                return 250.0;
@@ -3841,6 +3871,7 @@ void rapl_probe_intel(unsigned int family, unsigned int model)
        case INTEL_FAM6_SANDYBRIDGE:
        case INTEL_FAM6_IVYBRIDGE:
        case INTEL_FAM6_HASWELL_CORE:   /* HSW */
+       case INTEL_FAM6_HASWELL_ULT:    /* HSW */
        case INTEL_FAM6_HASWELL_GT3E:   /* HSW */
        case INTEL_FAM6_BROADWELL_CORE: /* BDW */
        case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
@@ -3982,6 +4013,7 @@ void rapl_probe_amd(unsigned int family, unsigned int model)
 
        switch (family) {
        case 0x17: /* Zen, Zen+ */
+       case 0x18: /* Hygon Dhyana */
                do_rapl = RAPL_AMD_F17H | RAPL_PER_CORE_ENERGY;
                if (rapl_joules) {
                        BIC_PRESENT(BIC_Pkg_J);
@@ -4002,7 +4034,7 @@ void rapl_probe_amd(unsigned int family, unsigned int model)
        rapl_energy_units = ldexp(1.0, -(msr >> 8 & 0x1f));
        rapl_power_units = ldexp(1.0, -(msr & 0xf));
 
-       tdp = get_tdp_amd(model);
+       tdp = get_tdp_amd(family);
 
        rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
        if (!quiet)
@@ -4018,7 +4050,7 @@ void rapl_probe(unsigned int family, unsigned int model)
 {
        if (genuine_intel)
                rapl_probe_intel(family, model);
-       if (authentic_amd)
+       if (authentic_amd || hygon_genuine)
                rapl_probe_amd(family, model);
 }
 
@@ -4032,6 +4064,7 @@ void perf_limit_reasons_probe(unsigned int family, unsigned int model)
 
        switch (model) {
        case INTEL_FAM6_HASWELL_CORE:   /* HSW */
+       case INTEL_FAM6_HASWELL_ULT:    /* HSW */
        case INTEL_FAM6_HASWELL_GT3E:   /* HSW */
                do_gfx_perf_limit_reasons = 1;
        case INTEL_FAM6_HASWELL_X:      /* HSX */
@@ -4251,6 +4284,7 @@ int has_snb_msrs(unsigned int family, unsigned int model)
        case INTEL_FAM6_IVYBRIDGE_X:    /* IVB Xeon */
        case INTEL_FAM6_HASWELL_CORE:   /* HSW */
        case INTEL_FAM6_HASWELL_X:      /* HSW */
+       case INTEL_FAM6_HASWELL_ULT:    /* HSW */
        case INTEL_FAM6_HASWELL_GT3E:   /* HSW */
        case INTEL_FAM6_BROADWELL_CORE: /* BDW */
        case INTEL_FAM6_BROADWELL_GT3E: /* BDW */
@@ -4267,7 +4301,7 @@ int has_snb_msrs(unsigned int family, unsigned int model)
 }
 
 /*
- * HSW adds support for additional MSRs:
+ * HSW ULT added support for C8/C9/C10 MSRs:
  *
  * MSR_PKG_C8_RESIDENCY                0x00000630
  * MSR_PKG_C9_RESIDENCY                0x00000631
@@ -4278,13 +4312,13 @@ int has_snb_msrs(unsigned int family, unsigned int model)
  * MSR_PKGC10_IRTL             0x00000635
  *
  */
-int has_hsw_msrs(unsigned int family, unsigned int model)
+int has_c8910_msrs(unsigned int family, unsigned int model)
 {
        if (!genuine_intel)
                return 0;
 
        switch (model) {
-       case INTEL_FAM6_HASWELL_CORE:
+       case INTEL_FAM6_HASWELL_ULT:    /* HSW */
        case INTEL_FAM6_BROADWELL_CORE: /* BDW */
        case INTEL_FAM6_SKYLAKE_MOBILE: /* SKL */
        case INTEL_FAM6_CANNONLAKE_MOBILE:      /* CNL */
@@ -4568,9 +4602,6 @@ unsigned int intel_model_duplicates(unsigned int model)
        case INTEL_FAM6_XEON_PHI_KNM:
                return INTEL_FAM6_XEON_PHI_KNL;
 
-       case INTEL_FAM6_HASWELL_ULT:
-               return INTEL_FAM6_HASWELL_CORE;
-
        case INTEL_FAM6_BROADWELL_X:
        case INTEL_FAM6_BROADWELL_XEON_D:       /* BDX-DE */
                return INTEL_FAM6_BROADWELL_X;
@@ -4582,7 +4613,11 @@ unsigned int intel_model_duplicates(unsigned int model)
                return INTEL_FAM6_SKYLAKE_MOBILE;
 
        case INTEL_FAM6_ICELAKE_MOBILE:
+       case INTEL_FAM6_ICELAKE_NNPI:
                return INTEL_FAM6_CANNONLAKE_MOBILE;
+
+       case INTEL_FAM6_ATOM_TREMONT_X:
+               return INTEL_FAM6_ATOM_GOLDMONT_X;
        }
        return model;
 }
@@ -4600,6 +4635,8 @@ void process_cpuid()
                genuine_intel = 1;
        else if (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65)
                authentic_amd = 1;
+       else if (ebx == 0x6f677948 && ecx == 0x656e6975 && edx == 0x6e65476e)
+               hygon_genuine = 1;
 
        if (!quiet)
                fprintf(outf, "CPUID(0): %.4s%.4s%.4s ",
@@ -4820,12 +4857,12 @@ void process_cpuid()
                BIC_NOT_PRESENT(BIC_CPU_c7);
                BIC_NOT_PRESENT(BIC_Pkgpc7);
        }
-       if (has_hsw_msrs(family, model)) {
+       if (has_c8910_msrs(family, model)) {
                BIC_PRESENT(BIC_Pkgpc8);
                BIC_PRESENT(BIC_Pkgpc9);
                BIC_PRESENT(BIC_Pkgpc10);
        }
-       do_irtl_hsw = has_hsw_msrs(family, model);
+       do_irtl_hsw = has_c8910_msrs(family, model);
        if (has_skl_msrs(family, model)) {
                BIC_PRESENT(BIC_Totl_c0);
                BIC_PRESENT(BIC_Any_c0);
@@ -5123,7 +5160,7 @@ int initialize_counters(int cpu_id)
 
 void allocate_output_buffer()
 {
-       output_buffer = calloc(1, (1 + topo.num_cpus) * 1024);
+       output_buffer = calloc(1, (1 + topo.num_cpus) * 2048);
        outp = output_buffer;
        if (outp == NULL)
                err(-1, "calloc output buffer");
@@ -5269,7 +5306,7 @@ int get_and_dump_counters(void)
 }
 
 void print_version() {
-       fprintf(outf, "turbostat version 19.03.20"
+       fprintf(outf, "turbostat version 19.08.31"
                " - Len Brown <lenb@kernel.org>\n");
 }
 
index 1fdeef8..666b325 100644 (file)
@@ -9,8 +9,9 @@ ifeq ("$(origin O)", "command line")
 endif
 
 x86_energy_perf_policy : x86_energy_perf_policy.c
-override CFLAGS +=     -Wall -I../../../include
+override CFLAGS +=     -O2 -Wall -I../../../include
 override CFLAGS +=     -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"'
+override CFLAGS +=     -D_FORTIFY_SOURCE=2
 
 %: %.c
        @mkdir -p $(BUILD_OUTPUT)
index 17db1c3..78c6361 100644 (file)
@@ -40,7 +40,7 @@ in the same processor package.
 Hardware P-States (HWP) are effectively an expansion of hardware
 P-state control from the opportunistic turbo-mode P-state range
 to include the entire range of available P-states.
-On Broadwell Xeon, the initial HWP implementation, EBP influenced HWP.
+On Broadwell Xeon, the initial HWP implementation, EPB influenced HWP.
 That influence was removed in subsequent generations,
 where it was moved to the
 Energy_Performance_Preference (EPP) field in
index 34a796b..3fe1eed 100644 (file)
@@ -545,7 +545,7 @@ void cmdline(int argc, char **argv)
 
        progname = argv[0];
 
-       while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw",
+       while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw:",
                                long_options, &option_index)) != -1) {
                switch (opt) {
                case 'a':
@@ -1259,6 +1259,15 @@ void probe_dev_msr(void)
                if (system("/sbin/modprobe msr > /dev/null 2>&1"))
                        err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
 }
+
+static void get_cpuid_or_exit(unsigned int leaf,
+                            unsigned int *eax, unsigned int *ebx,
+                            unsigned int *ecx, unsigned int *edx)
+{
+       if (!__get_cpuid(leaf, eax, ebx, ecx, edx))
+               errx(1, "Processor not supported\n");
+}
+
 /*
  * early_cpuid()
  * initialize turbo_is_enabled, has_hwp, has_epb
@@ -1266,15 +1275,10 @@ void probe_dev_msr(void)
  */
 void early_cpuid(void)
 {
-       unsigned int eax, ebx, ecx, edx, max_level;
+       unsigned int eax, ebx, ecx, edx;
        unsigned int fms, family, model;
 
-       __get_cpuid(0, &max_level, &ebx, &ecx, &edx);
-
-       if (max_level < 6)
-               errx(1, "Processor not supported\n");
-
-       __get_cpuid(1, &fms, &ebx, &ecx, &edx);
+       get_cpuid_or_exit(1, &fms, &ebx, &ecx, &edx);
        family = (fms >> 8) & 0xf;
        model = (fms >> 4) & 0xf;
        if (family == 6 || family == 0xf)
@@ -1288,7 +1292,7 @@ void early_cpuid(void)
                bdx_highest_ratio = msr & 0xFF;
        }
 
-       __get_cpuid(0x6, &eax, &ebx, &ecx, &edx);
+       get_cpuid_or_exit(0x6, &eax, &ebx, &ecx, &edx);
        turbo_is_enabled = (eax >> 1) & 1;
        has_hwp = (eax >> 7) & 1;
        has_epb = (ecx >> 3) & 1;
@@ -1306,7 +1310,7 @@ void parse_cpuid(void)
 
        eax = ebx = ecx = edx = 0;
 
-       __get_cpuid(0, &max_level, &ebx, &ecx, &edx);
+       get_cpuid_or_exit(0, &max_level, &ebx, &ecx, &edx);
 
        if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
                genuine_intel = 1;
@@ -1315,7 +1319,7 @@ void parse_cpuid(void)
                fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
                        (char *)&ebx, (char *)&edx, (char *)&ecx);
 
-       __get_cpuid(1, &fms, &ebx, &ecx, &edx);
+       get_cpuid_or_exit(1, &fms, &ebx, &ecx, &edx);
        family = (fms >> 8) & 0xf;
        model = (fms >> 4) & 0xf;
        stepping = fms & 0xf;
@@ -1340,7 +1344,7 @@ void parse_cpuid(void)
                errx(1, "CPUID: no MSR");
 
 
-       __get_cpuid(0x6, &eax, &ebx, &ecx, &edx);
+       get_cpuid_or_exit(0x6, &eax, &ebx, &ecx, &edx);
        /* turbo_is_enabled already set */
        /* has_hwp already set */
        has_hwp_notify = eax & (1 << 8);
diff --git a/tools/testing/selftests/arm64/.gitignore b/tools/testing/selftests/arm64/.gitignore
new file mode 100644 (file)
index 0000000..e8fae8d
--- /dev/null
@@ -0,0 +1 @@
+tags_test
diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile
new file mode 100644 (file)
index 0000000..a61b2e7
--- /dev/null
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# ARCH can be overridden by the user for cross compiling
+ARCH ?= $(shell uname -m 2>/dev/null || echo not)
+
+ifneq (,$(filter $(ARCH),aarch64 arm64))
+TEST_GEN_PROGS := tags_test
+TEST_PROGS := run_tags_test.sh
+endif
+
+include ../lib.mk
diff --git a/tools/testing/selftests/arm64/run_tags_test.sh b/tools/testing/selftests/arm64/run_tags_test.sh
new file mode 100755 (executable)
index 0000000..745f113
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+echo "--------------------"
+echo "running tags test"
+echo "--------------------"
+./tags_test
+if [ $? -ne 0 ]; then
+       echo "[FAIL]"
+else
+       echo "[PASS]"
+fi
diff --git a/tools/testing/selftests/arm64/tags_test.c b/tools/testing/selftests/arm64/tags_test.c
new file mode 100644 (file)
index 0000000..5701163
--- /dev/null
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <sys/prctl.h>
+#include <sys/utsname.h>
+
+#define SHIFT_TAG(tag)         ((uint64_t)(tag) << 56)
+#define SET_TAG(ptr, tag)      (((uint64_t)(ptr) & ~SHIFT_TAG(0xff)) | \
+                                       SHIFT_TAG(tag))
+
+int main(void)
+{
+       static int tbi_enabled = 0;
+       unsigned long tag = 0;
+       struct utsname *ptr;
+       int err;
+
+       if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0)
+               tbi_enabled = 1;
+       ptr = (struct utsname *)malloc(sizeof(*ptr));
+       if (tbi_enabled)
+               tag = 0x42;
+       ptr = (struct utsname *)SET_TAG(ptr, tag);
+       err = uname(ptr);
+       free(ptr);
+
+       return err;
+}
index c085964..96752eb 100644 (file)
@@ -34,6 +34,9 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test
 BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c)))
 TEST_GEN_FILES = $(BPF_OBJ_FILES)
 
+BTF_C_FILES = $(wildcard progs/btf_dump_test_case_*.c)
+TEST_FILES = $(BTF_C_FILES)
+
 # Also test sub-register code-gen if LLVM has eBPF v3 processor support which
 # contains both ALU32 and JMP32 instructions.
 SUBREG_CODEGEN := $(shell echo "int cal(int a) { return a > 0; }" | \
@@ -68,7 +71,8 @@ TEST_PROGS := test_kmod.sh \
 TEST_PROGS_EXTENDED := with_addr.sh \
        with_tunnels.sh \
        tcp_client.py \
-       tcp_server.py
+       tcp_server.py \
+       test_xdp_vlan.sh
 
 # Compile but not part of 'make run_tests'
 TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr test_skb_cgroup_id_user \
index f7a0744..5dc109f 100644 (file)
@@ -34,3 +34,4 @@ CONFIG_NET_MPLS_GSO=m
 CONFIG_MPLS_ROUTING=m
 CONFIG_MPLS_IPTUNNEL=m
 CONFIG_IPV6_SIT=m
+CONFIG_BPF_JIT=y
index 8f85082..6e75dd3 100644 (file)
@@ -97,6 +97,13 @@ int test_btf_dump_case(int n, struct btf_dump_test_case *test_case)
        }
 
        snprintf(test_file, sizeof(test_file), "progs/%s.c", test_case->name);
+       if (access(test_file, R_OK) == -1)
+               /*
+                * When the test is run with O=, kselftest copies TEST_FILES
+                * without preserving the directory structure.
+                */
+               snprintf(test_file, sizeof(test_file), "%s.c",
+                       test_case->name);
        /*
         * Diff test output and expected test output, contained between
         * START-EXPECTED-OUTPUT and END-EXPECTED-OUTPUT lines in test case.
index 2fc4625..6557290 100644 (file)
@@ -20,9 +20,9 @@ int main(int argc, char **argv)
                BPF_MOV64_IMM(BPF_REG_2, 0), /* flags, not used */
                BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0,
                             BPF_FUNC_get_local_storage),
-               BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_0, 0),
+               BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
                BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 0x1),
-               BPF_STX_MEM(BPF_W, BPF_REG_0, BPF_REG_3, 0),
+               BPF_STX_MEM(BPF_DW, BPF_REG_0, BPF_REG_3, 0),
 
                BPF_LD_MAP_FD(BPF_REG_1, 0), /* map fd */
                BPF_MOV64_IMM(BPF_REG_2, 0), /* flags, not used */
@@ -30,7 +30,7 @@ int main(int argc, char **argv)
                             BPF_FUNC_get_local_storage),
                BPF_MOV64_IMM(BPF_REG_1, 1),
                BPF_STX_XADD(BPF_DW, BPF_REG_0, BPF_REG_1, 0),
-               BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
+               BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
                BPF_ALU64_IMM(BPF_AND, BPF_REG_1, 0x1),
                BPF_MOV64_REG(BPF_REG_0, BPF_REG_1),
                BPF_EXIT_INSN(),
index fb679ac..0e66527 100644 (file)
@@ -13,6 +13,7 @@
 #include <bpf/bpf.h>
 
 #include "cgroup_helpers.h"
+#include "bpf_endian.h"
 #include "bpf_rlimit.h"
 #include "bpf_util.h"
 
@@ -232,7 +233,8 @@ static struct sock_test tests[] = {
                        /* if (ip == expected && port == expected) */
                        BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
                                    offsetof(struct bpf_sock, src_ip6[3])),
-                       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0x01000000, 4),
+                       BPF_JMP_IMM(BPF_JNE, BPF_REG_7,
+                                   __bpf_constant_ntohl(0x00000001), 4),
                        BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
                                    offsetof(struct bpf_sock, src_port)),
                        BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0x2001, 2),
@@ -261,7 +263,8 @@ static struct sock_test tests[] = {
                        /* if (ip == expected && port == expected) */
                        BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
                                    offsetof(struct bpf_sock, src_ip4)),
-                       BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0x0100007F, 4),
+                       BPF_JMP_IMM(BPF_JNE, BPF_REG_7,
+                                   __bpf_constant_ntohl(0x7F000001), 4),
                        BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
                                    offsetof(struct bpf_sock, src_port)),
                        BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0x1002, 2),
index 8219a30..0fc1b6d 100644 (file)
@@ -448,6 +448,59 @@ cleanup:
 }
 
 /*
+ * The test creates a cgroups and freezes it. Then it creates a child cgroup
+ * and populates it with a task. After that it checks that the child cgroup
+ * is frozen and the parent cgroup remains frozen too.
+ */
+static int test_cgfreezer_mkdir(const char *root)
+{
+       int ret = KSFT_FAIL;
+       char *parent, *child = NULL;
+       int pid;
+
+       parent = cg_name(root, "cg_test_mkdir_A");
+       if (!parent)
+               goto cleanup;
+
+       child = cg_name(parent, "cg_test_mkdir_B");
+       if (!child)
+               goto cleanup;
+
+       if (cg_create(parent))
+               goto cleanup;
+
+       if (cg_freeze_wait(parent, true))
+               goto cleanup;
+
+       if (cg_create(child))
+               goto cleanup;
+
+       pid = cg_run_nowait(child, child_fn, NULL);
+       if (pid < 0)
+               goto cleanup;
+
+       if (cg_wait_for_proc_count(child, 1))
+               goto cleanup;
+
+       if (cg_check_frozen(child, true))
+               goto cleanup;
+
+       if (cg_check_frozen(parent, true))
+               goto cleanup;
+
+       ret = KSFT_PASS;
+
+cleanup:
+       if (child)
+               cg_destroy(child);
+       free(child);
+       if (parent)
+               cg_destroy(parent);
+       free(parent);
+       return ret;
+}
+
+/*
  * The test creates two nested cgroups, freezes the parent
  * and removes the child. Then it checks that the parent cgroup
  * remains frozen and it's possible to create a new child
@@ -815,6 +868,7 @@ struct cgfreezer_test {
        T(test_cgfreezer_simple),
        T(test_cgfreezer_tree),
        T(test_cgfreezer_forkbomb),
+       T(test_cgfreezer_mkdir),
        T(test_cgfreezer_rmdir),
        T(test_cgfreezer_migrate),
        T(test_cgfreezer_ptrace),
index c5c93d5..f9ebeac 100755 (executable)
@@ -212,6 +212,8 @@ check_output()
                        printf "        ${out}\n"
                        printf "    Expected:\n"
                        printf "        ${expected}\n\n"
+               else
+                       echo "      WARNING: Unexpected route entry"
                fi
        fi
 
@@ -274,7 +276,7 @@ ipv6_fcnal()
 
        run_cmd "$IP nexthop get id 52"
        log_test $? 0 "Get nexthop by id"
-       check_nexthop "id 52" "id 52 via 2001:db8:91::2 dev veth1"
+       check_nexthop "id 52" "id 52 via 2001:db8:91::2 dev veth1 scope link"
 
        run_cmd "$IP nexthop del id 52"
        log_test $? 0 "Delete nexthop by id"
@@ -479,12 +481,12 @@ ipv6_fcnal_runtime()
        run_cmd "$IP -6 nexthop add id 85 dev veth1"
        run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 85"
        log_test $? 0 "IPv6 route with device only nexthop"
-       check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 85 dev veth1"
+       check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 85 dev veth1 metric 1024 pref medium"
 
        run_cmd "$IP nexthop add id 123 group 81/85"
        run_cmd "$IP ro replace 2001:db8:101::1/128 nhid 123"
        log_test $? 0 "IPv6 multipath route with nexthop mix - dev only + gw"
-       check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 85 nexthop via 2001:db8:91::2 dev veth1 nexthop dev veth1"
+       check_route6 "2001:db8:101::1" "2001:db8:101::1 nhid 123 metric 1024 nexthop via 2001:db8:91::2 dev veth1 weight 1 nexthop dev veth1 weight 1 pref medium"
 
        #
        # IPv6 route with v4 nexthop - not allowed
@@ -538,7 +540,7 @@ ipv4_fcnal()
 
        run_cmd "$IP nexthop get id 12"
        log_test $? 0 "Get nexthop by id"
-       check_nexthop "id 12" "id 12 via 172.16.1.2 src 172.16.1.1 dev veth1 scope link"
+       check_nexthop "id 12" "id 12 via 172.16.1.2 dev veth1 scope link"
 
        run_cmd "$IP nexthop del id 12"
        log_test $? 0 "Delete nexthop by id"
@@ -685,7 +687,7 @@ ipv4_withv6_fcnal()
        set +e
        run_cmd "$IP ro add 172.16.101.1/32 nhid 11"
        log_test $? 0 "IPv6 nexthop with IPv4 route"
-       check_route "172.16.101.1" "172.16.101.1 nhid 11 via ${lladdr} dev veth1"
+       check_route "172.16.101.1" "172.16.101.1 nhid 11 via inet6 ${lladdr} dev veth1"
 
        set -e
        run_cmd "$IP nexthop add id 12 via 172.16.1.2 dev veth1"
@@ -694,11 +696,11 @@ ipv4_withv6_fcnal()
        run_cmd "$IP ro replace 172.16.101.1/32 nhid 101"
        log_test $? 0 "IPv6 nexthop with IPv4 route"
 
-       check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1"
+       check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via inet6 ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1"
 
        run_cmd "$IP ro replace 172.16.101.1/32 via inet6 ${lladdr} dev veth1"
        log_test $? 0 "IPv4 route with IPv6 gateway"
-       check_route "172.16.101.1" "172.16.101.1 via ${lladdr} dev veth1"
+       check_route "172.16.101.1" "172.16.101.1 via inet6 ${lladdr} dev veth1"
 
        run_cmd "$IP ro replace 172.16.101.1/32 via inet6 2001:db8:50::1 dev veth1"
        log_test $? 2 "IPv4 route with invalid IPv6 gateway"
@@ -785,10 +787,10 @@ ipv4_fcnal_runtime()
        log_test $? 0 "IPv4 route with device only nexthop"
        check_route "172.16.101.1" "172.16.101.1 nhid 85 dev veth1"
 
-       run_cmd "$IP nexthop add id 122 group 21/85"
-       run_cmd "$IP ro replace 172.16.101.1/32 nhid 122"
+       run_cmd "$IP nexthop add id 123 group 21/85"
+       run_cmd "$IP ro replace 172.16.101.1/32 nhid 123"
        log_test $? 0 "IPv4 multipath route with nexthop mix - dev only + gw"
-       check_route "172.16.101.1" "172.16.101.1 nhid 85 nexthop via 172.16.1.2 dev veth1 nexthop dev veth1"
+       check_route "172.16.101.1" "172.16.101.1 nhid 123 nexthop via 172.16.1.2 dev veth1 weight 1 nexthop dev veth1 weight 1"
 
        #
        # IPv4 with IPv6
@@ -820,7 +822,7 @@ ipv4_fcnal_runtime()
        run_cmd "$IP ro replace 172.16.101.1/32 nhid 101"
        log_test $? 0 "IPv4 route with mixed v4-v6 multipath route"
 
-       check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1"
+       check_route "172.16.101.1" "172.16.101.1 nhid 101 nexthop via inet6 ${lladdr} dev veth1 weight 1 nexthop via 172.16.1.2 dev veth1 weight 1"
 
        run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1"
        log_test $? 0 "IPv6 nexthop with IPv4 route"
index 5445943..7a1bf94 100755 (executable)
@@ -106,6 +106,13 @@ do_overlap()
     #
     # 10.0.0.0/24 and 10.0.1.0/24 nodes have been merged as 10.0.0.0/23.
     ip -net $ns xfrm policy add src 10.1.0.0/24 dst 10.0.0.0/23 dir fwd priority 200 action block
+
+    # similar to above: add policies (with partially random address), with shrinking prefixes.
+    for p in 29 28 27;do
+      for k in $(seq 1 32); do
+       ip -net $ns xfrm policy add src 10.253.1.$((RANDOM%255))/$p dst 10.254.1.$((RANDOM%255))/$p dir fwd priority $((200+k)) action block 2>/dev/null
+      done
+    done
 }
 
 do_esp_policy_get_check() {
index 720b2d8..464c9b7 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 CFLAGS += -g -I../../../../usr/include/ -lpthread
 
-TEST_GEN_PROGS := pidfd_test pidfd_open_test
+TEST_GEN_PROGS := pidfd_test pidfd_open_test pidfd_poll_test pidfd_wait
 
 include ../lib.mk
 
index 8452e91..c6bc683 100644 (file)
 
 #include "../kselftest.h"
 
+#ifndef P_PIDFD
+#define P_PIDFD 3
+#endif
+
+#ifndef CLONE_PIDFD
+#define CLONE_PIDFD 0x00001000
+#endif
+
+#ifndef __NR_pidfd_open
+#define __NR_pidfd_open -1
+#endif
+
+#ifndef __NR_pidfd_send_signal
+#define __NR_pidfd_send_signal -1
+#endif
+
+#ifndef __NR_clone3
+#define __NR_clone3 -1
+#endif
+
 /*
  * The kernel reserves 300 pids via RESERVED_PIDS in kernel/pid.c
  * That means, when it wraps around any pid < 300 will be skipped.
@@ -53,5 +73,15 @@ again:
        return WEXITSTATUS(status);
 }
 
+static inline int sys_pidfd_open(pid_t pid, unsigned int flags)
+{
+       return syscall(__NR_pidfd_open, pid, flags);
+}
+
+static inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
+                                       unsigned int flags)
+{
+       return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
+}
 
 #endif /* __PIDFD_H */
index 0377133..b9fe75f 100644 (file)
 #include "pidfd.h"
 #include "../kselftest.h"
 
-static inline int sys_pidfd_open(pid_t pid, unsigned int flags)
-{
-       return syscall(__NR_pidfd_open, pid, flags);
-}
-
 static int safe_int(const char *numstr, int *converted)
 {
        char *err = NULL;
diff --git a/tools/testing/selftests/pidfd/pidfd_poll_test.c b/tools/testing/selftests/pidfd/pidfd_poll_test.c
new file mode 100644 (file)
index 0000000..4b11544
--- /dev/null
@@ -0,0 +1,117 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <linux/types.h>
+#include <linux/wait.h>
+#include <poll.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syscall.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "pidfd.h"
+#include "../kselftest.h"
+
+static bool timeout;
+
+static void handle_alarm(int sig)
+{
+       timeout = true;
+}
+
+int main(int argc, char **argv)
+{
+       struct pollfd fds;
+       int iter, nevents;
+       int nr_iterations = 10000;
+
+       fds.events = POLLIN;
+
+       if (argc > 2)
+               ksft_exit_fail_msg("Unexpected command line argument\n");
+
+       if (argc == 2) {
+               nr_iterations = atoi(argv[1]);
+               if (nr_iterations <= 0)
+                       ksft_exit_fail_msg("invalid input parameter %s\n",
+                                       argv[1]);
+       }
+
+       ksft_print_msg("running pidfd poll test for %d iterations\n",
+               nr_iterations);
+
+       for (iter = 0; iter < nr_iterations; iter++) {
+               int pidfd;
+               int child_pid = fork();
+
+               if (child_pid < 0) {
+                       if (errno == EAGAIN) {
+                               iter--;
+                               continue;
+                       }
+                       ksft_exit_fail_msg(
+                               "%s - failed to fork a child process\n",
+                               strerror(errno));
+               }
+
+               if (child_pid == 0) {
+                       /* Child process just sleeps for a min and exits */
+                       sleep(60);
+                       exit(EXIT_SUCCESS);
+               }
+
+               /* Parent kills the child and waits for its death */
+               pidfd = sys_pidfd_open(child_pid, 0);
+               if (pidfd < 0)
+                       ksft_exit_fail_msg("%s - pidfd_open failed\n",
+                                       strerror(errno));
+
+               /* Setup 3 sec alarm - plenty of time */
+               if (signal(SIGALRM, handle_alarm) == SIG_ERR)
+                       ksft_exit_fail_msg("%s - signal failed\n",
+                                       strerror(errno));
+               alarm(3);
+
+               /* Send SIGKILL to the child */
+               if (sys_pidfd_send_signal(pidfd, SIGKILL, NULL, 0))
+                       ksft_exit_fail_msg("%s - pidfd_send_signal failed\n",
+                                       strerror(errno));
+
+               /* Wait for the death notification */
+               fds.fd = pidfd;
+               nevents = poll(&fds, 1, -1);
+
+               /* Check for error conditions */
+               if (nevents < 0)
+                       ksft_exit_fail_msg("%s - poll failed\n",
+                                       strerror(errno));
+
+               if (nevents != 1)
+                       ksft_exit_fail_msg("unexpected poll result: %d\n",
+                                       nevents);
+
+               if (!(fds.revents & POLLIN))
+                       ksft_exit_fail_msg(
+                               "unexpected event type received: 0x%x\n",
+                               fds.revents);
+
+               if (timeout)
+                       ksft_exit_fail_msg(
+                               "death notification wait timeout\n");
+
+               close(pidfd);
+               /* Wait for child to prevent zombies */
+               if (waitpid(child_pid, NULL, 0) < 0)
+                       ksft_exit_fail_msg("%s - waitpid failed\n",
+                                       strerror(errno));
+
+       }
+
+       ksft_test_result_pass("pidfd poll test: pass\n");
+       return ksft_exit_pass();
+}
index b632965..7aff2d3 100644 (file)
 #include "pidfd.h"
 #include "../kselftest.h"
 
-#ifndef __NR_pidfd_send_signal
-#define __NR_pidfd_send_signal -1
-#endif
-
 #define str(s) _str(s)
 #define _str(s) #s
 #define CHILD_THREAD_MIN_WAIT 3 /* seconds */
 
 #define MAX_EVENTS 5
 
-#ifndef CLONE_PIDFD
-#define CLONE_PIDFD 0x00001000
-#endif
-
 static pid_t pidfd_clone(int flags, int *pidfd, int (*fn)(void *))
 {
        size_t stack_size = 1024;
@@ -47,12 +39,6 @@ static pid_t pidfd_clone(int flags, int *pidfd, int (*fn)(void *))
 #endif
 }
 
-static inline int sys_pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
-                                       unsigned int flags)
-{
-       return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
-}
-
 static int signal_received;
 
 static void set_signal_received_on_sigusr1(int sig)
diff --git a/tools/testing/selftests/pidfd/pidfd_wait.c b/tools/testing/selftests/pidfd/pidfd_wait.c
new file mode 100644 (file)
index 0000000..7079f8e
--- /dev/null
@@ -0,0 +1,271 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <signal.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sched.h>
+#include <string.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "pidfd.h"
+#include "../kselftest.h"
+
+#define ptr_to_u64(ptr) ((__u64)((uintptr_t)(ptr)))
+
+static pid_t sys_clone3(struct clone_args *args)
+{
+       return syscall(__NR_clone3, args, sizeof(struct clone_args));
+}
+
+static int sys_waitid(int which, pid_t pid, siginfo_t *info, int options,
+                     struct rusage *ru)
+{
+       return syscall(__NR_waitid, which, pid, info, options, ru);
+}
+
+static int test_pidfd_wait_simple(void)
+{
+       const char *test_name = "pidfd wait simple";
+       int pidfd = -1, status = 0;
+       pid_t parent_tid = -1;
+       struct clone_args args = {
+               .parent_tid = ptr_to_u64(&parent_tid),
+               .pidfd = ptr_to_u64(&pidfd),
+               .flags = CLONE_PIDFD | CLONE_PARENT_SETTID,
+               .exit_signal = SIGCHLD,
+       };
+       int ret;
+       pid_t pid;
+       siginfo_t info = {
+               .si_signo = 0,
+       };
+
+       pidfd = open("/proc/self", O_DIRECTORY | O_RDONLY | O_CLOEXEC);
+       if (pidfd < 0)
+               ksft_exit_fail_msg("%s test: failed to open /proc/self %s\n",
+                                  test_name, strerror(errno));
+
+       pid = sys_waitid(P_PIDFD, pidfd, &info, WEXITED, NULL);
+       if (pid == 0)
+               ksft_exit_fail_msg(
+                       "%s test: succeeded to wait on invalid pidfd %s\n",
+                       test_name, strerror(errno));
+       close(pidfd);
+       pidfd = -1;
+
+       pidfd = open("/dev/null", O_RDONLY | O_CLOEXEC);
+       if (pidfd == 0)
+               ksft_exit_fail_msg("%s test: failed to open /dev/null %s\n",
+                                  test_name, strerror(errno));
+
+       pid = sys_waitid(P_PIDFD, pidfd, &info, WEXITED, NULL);
+       if (pid == 0)
+               ksft_exit_fail_msg(
+                       "%s test: succeeded to wait on invalid pidfd %s\n",
+                       test_name, strerror(errno));
+       close(pidfd);
+       pidfd = -1;
+
+       pid = sys_clone3(&args);
+       if (pid < 0)
+               ksft_exit_fail_msg("%s test: failed to create new process %s\n",
+                                  test_name, strerror(errno));
+
+       if (pid == 0)
+               exit(EXIT_SUCCESS);
+
+       pid = sys_waitid(P_PIDFD, pidfd, &info, WEXITED, NULL);
+       if (pid < 0)
+               ksft_exit_fail_msg(
+                       "%s test: failed to wait on process with pid %d and pidfd %d: %s\n",
+                       test_name, parent_tid, pidfd, strerror(errno));
+
+       if (!WIFEXITED(info.si_status) || WEXITSTATUS(info.si_status))
+               ksft_exit_fail_msg(
+                       "%s test: unexpected status received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, parent_tid, pidfd, strerror(errno));
+       close(pidfd);
+
+       if (info.si_signo != SIGCHLD)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_signo value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_signo, parent_tid, pidfd,
+                       strerror(errno));
+
+       if (info.si_code != CLD_EXITED)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_code value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_code, parent_tid, pidfd,
+                       strerror(errno));
+
+       if (info.si_pid != parent_tid)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_pid value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_pid, parent_tid, pidfd,
+                       strerror(errno));
+
+       ksft_test_result_pass("%s test: Passed\n", test_name);
+       return 0;
+}
+
+static int test_pidfd_wait_states(void)
+{
+       const char *test_name = "pidfd wait states";
+       int pidfd = -1, status = 0;
+       pid_t parent_tid = -1;
+       struct clone_args args = {
+               .parent_tid = ptr_to_u64(&parent_tid),
+               .pidfd = ptr_to_u64(&pidfd),
+               .flags = CLONE_PIDFD | CLONE_PARENT_SETTID,
+               .exit_signal = SIGCHLD,
+       };
+       int ret;
+       pid_t pid;
+       siginfo_t info = {
+               .si_signo = 0,
+       };
+
+       pid = sys_clone3(&args);
+       if (pid < 0)
+               ksft_exit_fail_msg("%s test: failed to create new process %s\n",
+                                  test_name, strerror(errno));
+
+       if (pid == 0) {
+               kill(getpid(), SIGSTOP);
+               kill(getpid(), SIGSTOP);
+               exit(EXIT_SUCCESS);
+       }
+
+       ret = sys_waitid(P_PIDFD, pidfd, &info, WSTOPPED, NULL);
+       if (ret < 0)
+               ksft_exit_fail_msg(
+                       "%s test: failed to wait on WSTOPPED process with pid %d and pidfd %d: %s\n",
+                       test_name, parent_tid, pidfd, strerror(errno));
+
+       if (info.si_signo != SIGCHLD)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_signo value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_signo, parent_tid, pidfd,
+                       strerror(errno));
+
+       if (info.si_code != CLD_STOPPED)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_code value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_code, parent_tid, pidfd,
+                       strerror(errno));
+
+       if (info.si_pid != parent_tid)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_pid value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_pid, parent_tid, pidfd,
+                       strerror(errno));
+
+       ret = sys_pidfd_send_signal(pidfd, SIGCONT, NULL, 0);
+       if (ret < 0)
+               ksft_exit_fail_msg(
+                       "%s test: failed to send signal to process with pid %d and pidfd %d: %s\n",
+                       test_name, parent_tid, pidfd, strerror(errno));
+
+       ret = sys_waitid(P_PIDFD, pidfd, &info, WCONTINUED, NULL);
+       if (ret < 0)
+               ksft_exit_fail_msg(
+                       "%s test: failed to wait WCONTINUED on process with pid %d and pidfd %d: %s\n",
+                       test_name, parent_tid, pidfd, strerror(errno));
+
+       if (info.si_signo != SIGCHLD)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_signo value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_signo, parent_tid, pidfd,
+                       strerror(errno));
+
+       if (info.si_code != CLD_CONTINUED)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_code value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_code, parent_tid, pidfd,
+                       strerror(errno));
+
+       if (info.si_pid != parent_tid)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_pid value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_pid, parent_tid, pidfd,
+                       strerror(errno));
+
+       ret = sys_waitid(P_PIDFD, pidfd, &info, WUNTRACED, NULL);
+       if (ret < 0)
+               ksft_exit_fail_msg(
+                       "%s test: failed to wait on WUNTRACED process with pid %d and pidfd %d: %s\n",
+                       test_name, parent_tid, pidfd, strerror(errno));
+
+       if (info.si_signo != SIGCHLD)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_signo value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_signo, parent_tid, pidfd,
+                       strerror(errno));
+
+       if (info.si_code != CLD_STOPPED)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_code value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_code, parent_tid, pidfd,
+                       strerror(errno));
+
+       if (info.si_pid != parent_tid)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_pid value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_pid, parent_tid, pidfd,
+                       strerror(errno));
+
+       ret = sys_pidfd_send_signal(pidfd, SIGKILL, NULL, 0);
+       if (ret < 0)
+               ksft_exit_fail_msg(
+                       "%s test: failed to send SIGKILL to process with pid %d and pidfd %d: %s\n",
+                       test_name, parent_tid, pidfd, strerror(errno));
+
+       ret = sys_waitid(P_PIDFD, pidfd, &info, WEXITED, NULL);
+       if (ret < 0)
+               ksft_exit_fail_msg(
+                       "%s test: failed to wait on WEXITED process with pid %d and pidfd %d: %s\n",
+                       test_name, parent_tid, pidfd, strerror(errno));
+
+       if (info.si_signo != SIGCHLD)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_signo value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_signo, parent_tid, pidfd,
+                       strerror(errno));
+
+       if (info.si_code != CLD_KILLED)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_code value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_code, parent_tid, pidfd,
+                       strerror(errno));
+
+       if (info.si_pid != parent_tid)
+               ksft_exit_fail_msg(
+                       "%s test: unexpected si_pid value %d received after waiting on process with pid %d and pidfd %d: %s\n",
+                       test_name, info.si_pid, parent_tid, pidfd,
+                       strerror(errno));
+
+       close(pidfd);
+
+       ksft_test_result_pass("%s test: Passed\n", test_name);
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       ksft_print_header();
+       ksft_set_plan(2);
+
+       test_pidfd_wait_simple();
+       test_pidfd_wait_states();
+
+       return ksft_exit_pass();
+}
index affa7f2..9539cff 100644 (file)
@@ -64,7 +64,7 @@ class SubPlugin(TdcPlugin):
             cmdlist.insert(0, self.args.NAMES['NS'])
             cmdlist.insert(0, 'exec')
             cmdlist.insert(0, 'netns')
-            cmdlist.insert(0, 'ip')
+            cmdlist.insert(0, self.args.NAMES['IP'])
         else:
             pass
 
@@ -78,16 +78,16 @@ class SubPlugin(TdcPlugin):
         return command
 
     def _ports_create(self):
-        cmd = 'ip link add $DEV0 type veth peer name $DEV1'
+        cmd = '$IP link add $DEV0 type veth peer name $DEV1'
         self._exec_cmd('pre', cmd)
-        cmd = 'ip link set $DEV0 up'
+        cmd = '$IP link set $DEV0 up'
         self._exec_cmd('pre', cmd)
         if not self.args.namespace:
-            cmd = 'ip link set $DEV1 up'
+            cmd = '$IP link set $DEV1 up'
             self._exec_cmd('pre', cmd)
 
     def _ports_destroy(self):
-        cmd = 'ip link del $DEV0'
+        cmd = '$IP link del $DEV0'
         self._exec_cmd('post', cmd)
 
     def _ns_create(self):
@@ -97,16 +97,16 @@ class SubPlugin(TdcPlugin):
         '''
         self._ports_create()
         if self.args.namespace:
-            cmd = 'ip netns add {}'.format(self.args.NAMES['NS'])
+            cmd = '$IP netns add {}'.format(self.args.NAMES['NS'])
             self._exec_cmd('pre', cmd)
-            cmd = 'ip link set $DEV1 netns {}'.format(self.args.NAMES['NS'])
+            cmd = '$IP link set $DEV1 netns {}'.format(self.args.NAMES['NS'])
             self._exec_cmd('pre', cmd)
-            cmd = 'ip -n {} link set $DEV1 up'.format(self.args.NAMES['NS'])
+            cmd = '$IP -n {} link set $DEV1 up'.format(self.args.NAMES['NS'])
             self._exec_cmd('pre', cmd)
             if self.args.device:
-                cmd = 'ip link set $DEV2 netns {}'.format(self.args.NAMES['NS'])
+                cmd = '$IP link set $DEV2 netns {}'.format(self.args.NAMES['NS'])
                 self._exec_cmd('pre', cmd)
-                cmd = 'ip -n {} link set $DEV2 up'.format(self.args.NAMES['NS'])
+                cmd = '$IP -n {} link set $DEV2 up'.format(self.args.NAMES['NS'])
                 self._exec_cmd('pre', cmd)
 
     def _ns_destroy(self):
@@ -115,7 +115,7 @@ class SubPlugin(TdcPlugin):
         devices as well)
         '''
         if self.args.namespace:
-            cmd = 'ip netns delete {}'.format(self.args.NAMES['NS'])
+            cmd = '$IP netns delete {}'.format(self.args.NAMES['NS'])
             self._exec_cmd('post', cmd)
 
     def _exec_cmd(self, stage, command):
index 44efc2f..0d09048 100644 (file)
@@ -211,6 +211,12 @@ static void vgic_hw_irq_spending(struct kvm_vcpu *vcpu, struct vgic_irq *irq,
        vgic_irq_set_phys_active(irq, true);
 }
 
+static bool is_vgic_v2_sgi(struct kvm_vcpu *vcpu, struct vgic_irq *irq)
+{
+       return (vgic_irq_is_sgi(irq->intid) &&
+               vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V2);
+}
+
 void vgic_mmio_write_spending(struct kvm_vcpu *vcpu,
                              gpa_t addr, unsigned int len,
                              unsigned long val)
@@ -223,6 +229,12 @@ void vgic_mmio_write_spending(struct kvm_vcpu *vcpu,
        for_each_set_bit(i, &val, len * 8) {
                struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
 
+               /* GICD_ISPENDR0 SGI bits are WI */
+               if (is_vgic_v2_sgi(vcpu, irq)) {
+                       vgic_put_irq(vcpu->kvm, irq);
+                       continue;
+               }
+
                raw_spin_lock_irqsave(&irq->irq_lock, flags);
                if (irq->hw)
                        vgic_hw_irq_spending(vcpu, irq, is_uaccess);
@@ -270,6 +282,12 @@ void vgic_mmio_write_cpending(struct kvm_vcpu *vcpu,
        for_each_set_bit(i, &val, len * 8) {
                struct vgic_irq *irq = vgic_get_irq(vcpu->kvm, vcpu, intid + i);
 
+               /* GICD_ICPENDR0 SGI bits are WI */
+               if (is_vgic_v2_sgi(vcpu, irq)) {
+                       vgic_put_irq(vcpu->kvm, irq);
+                       continue;
+               }
+
                raw_spin_lock_irqsave(&irq->irq_lock, flags);
 
                if (irq->hw)
index 96aab77..b00aa30 100644 (file)
@@ -184,7 +184,10 @@ void vgic_v2_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
                if (vgic_irq_is_sgi(irq->intid)) {
                        u32 src = ffs(irq->source);
 
-                       BUG_ON(!src);
+                       if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n",
+                                          irq->intid))
+                               return;
+
                        val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT;
                        irq->source &= ~(1 << (src - 1));
                        if (irq->source) {
index 0c653a1..a4ad431 100644 (file)
@@ -167,7 +167,10 @@ void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr)
                    model == KVM_DEV_TYPE_ARM_VGIC_V2) {
                        u32 src = ffs(irq->source);
 
-                       BUG_ON(!src);
+                       if (WARN_RATELIMIT(!src, "No SGI source for INTID %d\n",
+                                          irq->intid))
+                               return;
+
                        val |= (src - 1) << GICH_LR_PHYSID_CPUID_SHIFT;
                        irq->source &= ~(1 << (src - 1));
                        if (irq->source) {
index 13d4b38..e7bde65 100644 (file)
@@ -254,6 +254,13 @@ static int vgic_irq_cmp(void *priv, struct list_head *a, struct list_head *b)
        bool penda, pendb;
        int ret;
 
+       /*
+        * list_sort may call this function with the same element when
+        * the list is fairly long.
+        */
+       if (unlikely(irqa == irqb))
+               return 0;
+
        raw_spin_lock(&irqa->irq_lock);
        raw_spin_lock_nested(&irqb->irq_lock, SINGLE_DEPTH_NESTING);